private static void ValidateWithSpotRestrictions( SmoothBreak theSmoothBreak, Programme programme, SalesArea salesArea, IReadOnlyCollection <Spot> spotsForBreak, SmoothResources smoothResources, IReadOnlyCollection <Break> breaksBeingSmoothed, IReadOnlyCollection <Programme> scheduleProgrammes, SmoothFailureMessagesForSpotsCollection result) { var anyRestrictions = CheckRestrictionsForSpots( spotsForBreak, theSmoothBreak.TheBreak, programme, salesArea, smoothResources, breaksBeingSmoothed, scheduleProgrammes); foreach (var item in anyRestrictions) { foreach (var failure in item.Value.Failures) { result.Add(item.Key, failure.FailureMessage, failure.Restriction); } } }
HasClashExceptionIncludesAndExcludes( SmoothBreak theSmoothBreak, bool respectClashExceptions, SmoothResources smoothResources, SmoothFailureMessagesForSpotsCollection result, Spot spot, Guid spotUid) { (bool spotHasClashExceptionIncludes, bool spotHasClashExceptionExcludes)clashExceptionResults = (false, false); if (!respectClashExceptions) { return(clashExceptionResults); } var checkClashExceptionsResults = smoothResources .ClashExceptionChecker.CheckClashExceptions(theSmoothBreak, spot); clashExceptionResults.spotHasClashExceptionIncludes = checkClashExceptionsResults .Any(cer => cer.ClashException.IncludeOrExclude == IncludeOrExclude.I); clashExceptionResults.spotHasClashExceptionExcludes = checkClashExceptionsResults .Any(cer => cer.ClashException.IncludeOrExclude == IncludeOrExclude.E); if (clashExceptionResults.spotHasClashExceptionIncludes) { result.Add(spotUid, SmoothFailureMessages.T1_ProductClash); } return(clashExceptionResults); }
public SmoothScenarioCreator( SmoothResources smoothResources, IReadOnlyDictionary <Guid, SpotInfo> spotInfos) { _smoothResources = smoothResources; _spotInfos = spotInfos; }
private void SetupTestData( out IReadOnlyCollection<Break> breaksBeingSmoothed, out SmoothBreak theSmoothBreak, out IReadOnlyCollection<Programme> scheduleProgrammes, out List<Spot> spotsForBreak, out SalesArea salesArea, out IReadOnlyDictionary<string, Clash> clashesByExternalRef, out IReadOnlyDictionary<Guid, SpotInfo> spotInfos, out ProductClashRules productClashRule, out SmoothResources smoothResources, out IClashExposureCountService clashExposureCountService, out SponsorshipRestrictionService sponsorshipRestrictionsService) { breaksBeingSmoothed = _repositoryWrapper.LoadAllTestBreaks().ToList(); theSmoothBreak = new SmoothBreak(breaksBeingSmoothed.First(), 1); scheduleProgrammes = _repositoryWrapper.LoadAllProgrammes().ToList(); spotsForBreak = new List<Spot>() { _spot }; salesArea = _repositoryWrapper.LoadAllSalesArea().First(); clashesByExternalRef = _repositoryWrapper.LoadAllClashes().ToDictionary(c => c.Externalref); spotInfos = SpotInfo.Factory( spotsForBreak, _repositoryWrapper.LoadAllProducts().ToDictionary(p => p.Externalidentifier), clashesByExternalRef ); productClashRule = ProductClashRules.LimitOnExposureCount; smoothResources = new SmoothResources(); clashExposureCountService = ClashExposureCountService.Create(); sponsorshipRestrictionsService = SponsorshipRestrictionService.Factory( spotInfos, new SponsorshipRestrictionFilterService(ImmutableList.Create<Sponsorship>()), new SmoothSponsorshipTimelineManager(new List<SmoothSponsorshipTimeline>()), scheduleProgrammes.First(), DebugLogger); }
public BestBreakEvaluator( ISmoothDiagnostics smoothDiagnostics, SmoothResources smoothResources, IClashExposureCountService clashExposureCountService) { _smoothDiagnostics = smoothDiagnostics; _smoothResources = smoothResources; _bestBreakFactorService = new BestBreakFactorService(clashExposureCountService); _bestBreakFactorForGroupService = new BestBreakFactorForGroupService(_bestBreakFactorService); }
private static void CheckProductClashRulesWhenClashLimitsAreAllowed( IReadOnlyDictionary <Guid, SpotInfo> spotInfos, IReadOnlyDictionary <string, Clash> clashesByExternalRef, SmoothResources smoothResources, IClashExposureCountService clashExposureCountService, SmoothFailureMessagesForSpotsCollection result, IReadOnlyDictionary <string, int> spotChildClashCodeCount, IReadOnlyDictionary <string, int> spotParentClashCodeCount, IReadOnlyCollection <Spot> spotsAlreadyInTheBreak, Spot spot, SpotInfo spotInfo, IReadOnlyCollection <Spot> childProductClashSpots) { if (childProductClashSpots.Count > 0 && !String.IsNullOrEmpty(spotInfo.ProductClashCode)) { CheckProductClashExposureCount( clashesByExternalRef, clashExposureCountService, result, spotChildClashCodeCount, spot, spotInfo, childProductClashSpots); } // Check parent clashes var parentProductClashSpots = smoothResources.ProductClashChecker .GetProductClashesForSingleSpot( spot, spotsAlreadyInTheBreak, spotInfos, ClashCodeLevel.Parent) .ToList(); if (parentProductClashSpots.Count > 0 && !String.IsNullOrEmpty(spotInfo.ParentProductClashCode)) { CheckProductParentClashExposure( clashesByExternalRef, clashExposureCountService, result, spotParentClashCodeCount, spot, spotInfo, parentProductClashSpots); } }
public SmoothPassBookedExecuter( ISmoothDiagnostics smoothDiagnostics, SmoothResources smoothResources, SmoothProgramme smoothProgramme, SponsorshipRestrictionService sponsorshipRestrictionService, IReadOnlyCollection <Programme> allProgrammesForPeriodAndSalesArea, Action <string> raiseInfo, Action <string, Exception> raiseException ) { _smoothDiagnostics = smoothDiagnostics; _smoothResources = smoothResources; _sponsorshipRestrictionService = sponsorshipRestrictionService; _allProgrammesForPeriodAndSalesArea = allProgrammesForPeriodAndSalesArea; _smoothProgramme = smoothProgramme; RaiseInfo = raiseInfo; RaiseException = raiseException; }
private static SmoothFailureMessagesForSpotsCollection CheckRestrictionsForSpots( IReadOnlyCollection <Spot> spotsForBreak, Break theBreak, Programme programme, SalesArea salesArea, SmoothResources smoothResources, IReadOnlyCollection <Break> breaksBeingSmoothed, IReadOnlyCollection <Programme> scheduleProgrammes) { var result = new SmoothFailureMessagesForSpotsCollection(); foreach (var spot in spotsForBreak) { var restrictionCheckerResults = smoothResources .RestrictionChecker.CheckRestrictions( programme, theBreak, spot, salesArea, breaksBeingSmoothed, scheduleProgrammes ); foreach (var restrictionCheckerResult in restrictionCheckerResults .Where(r => r.Reason != RestrictionReasons.None) ) { var failureMessage = Map(restrictionCheckerResult.Reason); if (failureMessage == SmoothFailureMessages.T0_NoFailure) { continue; } result.Add( spot.Uid, failureMessage, restrictionCheckerResult.Restriction ); } } return(result); }
public SmoothPassUnplacedExecuter( ISmoothDiagnostics smoothDiagnostics, SmoothResources smoothResources, SmoothProgramme smoothProgramme, SponsorshipRestrictionService sponsorshipRestrictionService, IReadOnlyCollection <Programme> allProgrammesForPeriodAndSalesArea, ISmoothConfiguration smoothConfiguration, IClashExposureCountService clashExposureCountService, IImmutableDictionary <string, Clash> clashesByExternalRef, Action <string, Exception> raiseException ) { _smoothDiagnostics = smoothDiagnostics; _smoothConfiguration = smoothConfiguration; _smoothResources = smoothResources; _smoothProgramme = smoothProgramme; _clashExposureCountService = clashExposureCountService; _sponsorshipRestrictionService = sponsorshipRestrictionService; _allProgrammesForPeriodAndSalesArea = allProgrammesForPeriodAndSalesArea; _clashesByExternalRef = clashesByExternalRef; RaiseException = raiseException; }
/// <summary> /// Evaluate whether spots can be added to break. We consider time /// remaining, break type, product clashes, campaign clashes, spot end /// time (some spots may required to be position in the first N mins of /// the programme), sponsor rules. /// </summary> public static SmoothFailureMessagesForSpotsCollection ValidateAddSpots( SmoothBreak theSmoothBreak, Programme programme, SalesArea salesArea, IReadOnlyCollection <Spot> spotsForBreak, IReadOnlyDictionary <Guid, SpotInfo> spotInfos, IReadOnlyList <SmoothBreak> progSmoothBreaks, ProductClashRules productClashRule, bool respectCampaignClash, bool respectSpotTime, bool respectRestrictions, bool respectClashExceptions, SpotPositionRules breakPositionRules, SpotPositionRules requestedPositionInBreakRules, IReadOnlyDictionary <string, Clash> clashesByExternalRef, bool canSplitMultipartSpotsOverBreaks, SmoothResources smoothResources, IReadOnlyCollection <Break> breaksBeingSmoothed, IReadOnlyCollection <Programme> scheduleProgrammes, IClashExposureCountService clashExposureCountService, SponsorshipRestrictionService sponsorshipRestrictionsService) { var result = new SmoothFailureMessagesForSpotsCollection(theSmoothBreak); foreach (Guid spotUid in spotsForBreak.Select(s => s.Uid)) { result.InitialiseForSpot(spotUid); } if (!IsSufficientRemainingDurationToAddSpots( theSmoothBreak.RemainingAvailability, spotsForBreak)) { foreach (Guid spotUid in spotsForBreak.Select(s => s.Uid)) { result.Add( spotUid, SmoothFailureMessages.T1_InsufficentRemainingDuration); } } var(spotChildClashCodeCount, spotParentClashCodeCount) = ClashCodesForSpotsCount(spotsForBreak, spotInfos); // Check basics of whether we can add this spot to the break, // correct break type, sufficient time remaining, product clashes, // campaign clashes var spotsAlreadyInTheBreak = theSmoothBreak.SmoothSpots .ConvertAll(s => s.Spot); var canAddSpotService = CanAddSpotService.Factory(theSmoothBreak); foreach (Spot spot in spotsForBreak) { ValidateWithSponsorshipRestrictions( theSmoothBreak, sponsorshipRestrictionsService, result, spotsAlreadyInTheBreak, spot); Guid spotUid = spot.Uid; if (!canAddSpotService.CanAddSpotWithBreakType(spot.BreakType)) { result.Add(spotUid, SmoothFailureMessages.T1_InvalidBreakType); } if (respectSpotTime && !canAddSpotService.CanAddSpotWithTime(spot.StartDateTime, spot.EndDateTime)) { result.Add(spotUid, SmoothFailureMessages.T1_InvalidSpotTime); } var(spotHasClashExceptionIncludes, spotHasClashExceptionExcludes) = HasClashExceptionIncludesAndExcludes( theSmoothBreak, respectClashExceptions, smoothResources, result, spot, spotUid); bool shouldCheckProductClashRules = ( productClashRule == ProductClashRules.NoClashes || productClashRule == ProductClashRules.LimitOnExposureCount ) && !spotHasClashExceptionIncludes && !spotHasClashExceptionExcludes; if (shouldCheckProductClashRules) { var childProductClashSpots = smoothResources.ProductClashChecker .GetProductClashesForSingleSpot( spot, spotsAlreadyInTheBreak, spotInfos, ClashCodeLevel.Child); switch (productClashRule) { case ProductClashRules.NoClashes: var output = CheckProductClashRulesWhenNoClashesAreAllowed( childProductClashSpots); if (output != SmoothFailureMessages.T0_NoFailure) { result.Add(spotUid, output); } break; case ProductClashRules.LimitOnExposureCount: CheckProductClashRulesWhenClashLimitsAreAllowed( spotInfos, clashesByExternalRef, smoothResources, clashExposureCountService, result, spotChildClashCodeCount, spotParentClashCodeCount, spotsAlreadyInTheBreak, spot, spotInfos[spotUid], childProductClashSpots); break; } } if (respectCampaignClash && smoothResources.CampaignClashChecker .GetCampaignClashesForNewSpots( new List <Spot> { spot }, spotsAlreadyInTheBreak) .Count > 0) { result.Add(spotUid, SmoothFailureMessages.T1_CampaignClash); } } var multipartSpots = spotsForBreak .Where(s => s.IsMultipartSpot) .ToList(); var nonMultipartSpots = spotsForBreak .Except(multipartSpots) .ToList(); if (nonMultipartSpots.Count > 0) { ValidateNonMultipartSpots( progSmoothBreaks, breakPositionRules, requestedPositionInBreakRules, canAddSpotService, result, nonMultipartSpots); } if (multipartSpots.Count > 0) { ValidateMultipartSpots( progSmoothBreaks, breakPositionRules, requestedPositionInBreakRules, canSplitMultipartSpotsOverBreaks, canAddSpotService, result, spotsAlreadyInTheBreak, multipartSpots); } if (respectRestrictions) { ValidateWithSpotRestrictions( theSmoothBreak, programme, salesArea, spotsForBreak, smoothResources, breaksBeingSmoothed, scheduleProgrammes, result); } IndicateIfMultipartTopTailSameBreakSpotsCannotBeAdded( result, multipartSpots); return(RemoveDuplicateFailureMessages(spotsForBreak, result)); }