예제 #1
0
        /// <summary>
        /// A pass for Booked spots. Don't store results, no spots placed.
        /// </summary>
        private void ExecuteBookedPass(
            SmoothPassBooked specificSmoothPass,
            IReadOnlyCollection <Break> breaksForThePeriodBeingSmoothed,
            ISet <Guid> spotIdsUsed,
            SmoothBatchOutput smoothBatchOutput)
        {
            SmoothPassResult result = _smoothPassBookedExecuter.Execute(
                specificSmoothPass,
                breaksForThePeriodBeingSmoothed,
                spotIdsUsed);

            smoothBatchOutput.BookedSpotsUnplacedDueToRestrictions +=
                result.BookedSpotIdsUnplacedDueToRestrictions.Count;
        }
예제 #2
0
        private void ExecuteDefaultPass(
            SmoothPassDefault specificSmoothPass,
            IReadOnlyCollection <Break> breaksForThePeriodBeingSmoothed,
            ISet <Guid> spotIdsUsed,
            List <SmoothPassResult> smoothPassResults)
        {
            SmoothPassResult result = _smoothPassDefaultExecuter.Execute(
                specificSmoothPass,
                breaksForThePeriodBeingSmoothed,
                spotIdsUsed,
                _programmeSpots,
                _spotInfos);

            smoothPassResults.Add(result);
        }
예제 #3
0
        /// <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);
예제 #4
0
        /// <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);
예제 #5
0
        /// <summary>
        /// Executes a Smooth pass. Checks booked spots, unplaces any spots with
        /// a restriction
        /// </summary>
        /// <param name="smoothPass"></param>
        /// <param name="breaksForThePeriodBeingSmoothed"></param>
        /// <param name="spotIdsUsed"></param>
        /// <returns></returns>
        public SmoothPassResult Execute(
            SmoothPassBooked smoothPass,
            IReadOnlyCollection <Break> breaksForThePeriodBeingSmoothed,
            ISet <Guid> spotIdsUsed
            )
        {
            var smoothPassResult = new SmoothPassResult(smoothPass.Sequence);
            var programme        = _smoothProgramme.Programme;
            var salesArea        = _smoothProgramme.SalesArea;

            // Check booked spots within each break
            foreach (var smoothBreak in _smoothProgramme.ProgrammeSmoothBreaks)
            {
                var breakSpotsToCheck = new List <SmoothSpot>(
                    smoothBreak.SmoothSpots.Where(s => !s.IsCurrent));

                Break theBreak = smoothBreak.TheBreak;

                bool AnySponsorshipRestrictions(Spot spotToCheckForRestrictions)
                {
                    IReadOnlyCollection <(Guid spotUid, SmoothFailureMessages failureMessage)> result =
                        _sponsorshipRestrictionService.CheckSponsorshipRestrictions(
                            spotToCheckForRestrictions,
                            theBreak.ExternalBreakRef,
                            theBreak.ScheduledDate,
                            theBreak.Duration,
                            smoothBreak.SmoothSpots.Select(s => s.Spot).ToList()
                            );

                    return(result
                           .Where(r => r.spotUid == spotToCheckForRestrictions.Uid)
                           .Select(r => r.failureMessage)
                           .Any(r => _sponsorshipRestrictionFailures.Contains(r)));
                }

                foreach (var smoothSpot in breakSpotsToCheck)
                {
                    Spot spot = smoothSpot.Spot;

                    try
                    {
                        if (AnySponsorshipRestrictions(spot))
                        {
                            UnplaceRestrictedSpot(
                                smoothPass,
                                smoothSpot,
                                smoothBreak,
                                "Sponsorship restrictions found: spot is a competitor to the sponsor",
                                spotIdsUsed
                                );

                            continue;
                        }

                        var restrictionResults = _smoothResources.RestrictionChecker
                                                 .CheckRestrictions(
                            programme,
                            theBreak,
                            spot,
                            salesArea,
                            breaksForThePeriodBeingSmoothed,
                            _allProgrammesForPeriodAndSalesArea);

                        if (restrictionResults.Count == 0)
                        {
                            continue;
                        }

                        UnplaceRestrictedSpot(
                            smoothPass,
                            smoothSpot,
                            smoothBreak,
                            $"Restrictions {GetRestrictionResultsDescription(restrictionResults)}",
                            spotIdsUsed
                            );

                        smoothPassResult.BookedSpotIdsUnplacedDueToRestrictions.Add(spot.Uid);
                    }
                    catch (Exception exception)
                    {
                        RaiseException(
                            $"Error checking booked spot {spot.ExternalSpotRef} " +
                            $"on pass {Log(smoothPass.Sequence)}",
                            exception
                            );
                    }
                }
            }

            return(smoothPassResult);
        }