/// <summary> /// Try and place unplaced spots, spots where there /// wasn't sufficient time in any break. /// </summary> private void ExecuteUnplacedPass( SmoothPassUnplaced specificSmoothPass, IReadOnlyCollection <Break> breaksForThePeriodBeingSmoothed, ISet <Guid> spotIdsUsed, SmoothBatchOutput smoothBatchOutput, List <Spot> progSpotsNotUsed, List <SmoothPassResult> smoothPassResults) { progSpotsNotUsed.Clear(); var unbookedSpots = GetUnbookedSpots(_programmeSpots, spotIdsUsed); if (!unbookedSpots.Any()) { return; } progSpotsNotUsed.AddRange(unbookedSpots); SmoothPassResult result = _smoothPassUnplacedExecuter.Execute( specificSmoothPass, breaksForThePeriodBeingSmoothed, spotIdsUsed, progSpotsNotUsed, _spotInfos); smoothPassResults.Add(result); if (result.CountPlacedSpots == 0) { return; } smoothBatchOutput.SpotsSetAfterMovingOtherSpots += result.CountPlacedSpots; // Update list of unplaced spots so that we can calculate // break avail adjustment. We placed previously unplaced // spots after moving other spots about. unbookedSpots = GetUnbookedSpots(_programmeSpots, spotIdsUsed); progSpotsNotUsed.Clear(); progSpotsNotUsed.AddRange(unbookedSpots);
/// <summary> /// Attempt to place unplaced spots by moving other spots. These are /// spots that couldn't be placed during the main pass, should only be /// spots that couldn't be placed due to no break with sufficient /// remaining time. /// </summary> public SmoothPassResult Execute( SmoothPassUnplaced smoothPass, IReadOnlyCollection <Break> breaksBeingSmoothed, ISet <Guid> spotIdsUsed, IReadOnlyCollection <Spot> spots, IReadOnlyDictionary <Guid, SpotInfo> spotInfos) { var smoothPassResult = new SmoothPassResult(smoothPass.Sequence); if (MaximumOfTwoBreaksWithRemainingTime(_smoothProgramme.ProgrammeSmoothBreaks)) { return(smoothPassResult); } // Get all spots for pass, order by priority for processing var spotFilter = new SpotFilter() { Sponsored = null, Preemptable = null, MinPreemptLevel = null, // Any MaxPreemptLevel = null, // Any HasBreakRequest = null, // Any BreakRequests = null, HasPositionInBreakRequest = null, // Any PositionInBreakRequestsToExclude = null, // Any HasMultipartSpots = null, MultipartSpots = null, // Any HasProductClashCode = null, ProductClashCodesToExclude = null, ExternalCampaignRefsToExclude = _smoothConfiguration.ExternalCampaignRefsToExclude, HasSpotEndTime = null, MinSpotLength = null, MaxSpotLength = null, SpotIdsToExclude = spotIdsUsed }; // Order the spots by priority var spotsToPlace = GetSpots(spotFilter, spots, spotInfos); var spotsOrdered = _smoothConfiguration.SortSpotsToPlace( spotsToPlace, (_smoothProgramme.Programme.StartDateTime, _smoothProgramme.Programme.Duration) ); // Try and place spots foreach (var spot in spotsOrdered) { try { PlaceSpotsResult placeSpotsResult = PlaceSpot( smoothPass, spot, spotInfos, _smoothProgramme.ProgrammeSmoothBreaks, breaksBeingSmoothed, spotIdsUsed); smoothPassResult.PlaceSpotsResultList.Add(placeSpotsResult); } catch (Exception exception) { RaiseException($"Error trying to place unplaced spot {spot.ExternalSpotRef}", exception); } } return(smoothPassResult);