예제 #1
0
        public CustomValidationResult ValidateExposureCountDifferences(Clash clash, IEnumerable <Clash> allClashes)
        {
            if (!string.IsNullOrWhiteSpace(clash.ParentExternalidentifier))
            {
                var parentClash = _clashRepository.FindByExternal(clash.ParentExternalidentifier).FirstOrDefault();

                if (parentClash != null)
                {
                    var validationResult = ValidateParentCountDifferences(clash.Differences, parentClash);

                    if (validationResult != CustomValidationResult.Success())
                    {
                        return(validationResult);
                    }
                }
            }

            var childClashes = allClashes
                               .Where(c => c.ParentExternalidentifier == clash.Externalref && c.Differences.Any()).ToList();

            if (childClashes.Any())
            {
                return(ValidateChildCountDifferences(childClashes, clash));
            }

            return(CustomValidationResult.Success());
        }
예제 #2
0
        public CustomValidationResult ValidateClashExceptionForSameStructureRulesViolation(ClashException clashException)
        {
            if (clashException.FromType != ClashExceptionType.Clash ||
                clashException.ToType != ClashExceptionType.Clash)
            {
                return(CustomValidationResult.Success());
            }

            var fromClash = _clashRepository.FindByExternal(clashException.FromValue).FirstOrDefault();

            if (fromClash is null)
            {
                return(CustomValidationResult.Failed(
                           $"Could not find Clash with external reference {clashException.FromValue}"));
            }

            var toClash = _clashRepository.FindByExternal(clashException.ToValue).FirstOrDefault();

            if (toClash is null)
            {
                return(CustomValidationResult.Failed(
                           $"Could not find Clash with external reference {clashException.ToValue}"));
            }

            bool clashesAreFromTheSameStructure;

            try
            {
                clashesAreFromTheSameStructure = AreClashesFromTheSameStructure(fromClash, toClash);
            }
            catch (ArgumentException exception)
            {
                return(CustomValidationResult.Failed(exception.Message));
            }

            if (clashesAreFromTheSameStructure)
            {
                if (clashException.IncludeOrExclude == IncludeOrExclude.I)
                {
                    return(CustomValidationResult.Failed(
                               $"Clash exception with Include rule and values from: {clashException.FromValue}, " +
                               $"to: {clashException.ToValue} is not allowed as clashes are from the same structure"));
                }
            }

            return(CustomValidationResult.Success());
        }
예제 #3
0
        private void ValidateClashCodes(List <string> clashCodes)
        {
            var clashes = _clashRepository
                          .FindByExternal(clashCodes)
                          .Select(x => x.Externalref)
                          .Distinct(StringComparer.CurrentCultureIgnoreCase);

            var invalidClashCodes = clashCodes.Except(clashes, StringComparer.CurrentCultureIgnoreCase).ToList();

            if (invalidClashCodes.Any())
            {
                throw new DataSyncException(DataSyncErrorCode.ClashCodeNotFound, $"Invalid clash code: {string.Join(", ", invalidClashCodes)}");
            }
        }
예제 #4
0
        public IHttpActionResult Get(Guid id)
        {
            var item = _clashRepository.Find(id);

            if (item == null)
            {
                return(NotFound());
            }
            var parentclash = string.IsNullOrWhiteSpace(item.ParentExternalidentifier)
                ? null
                : _clashRepository.FindByExternal(item.ParentExternalidentifier)?.FirstOrDefault();

            return(Ok(_mapper.Map <ClashModel>(Tuple.Create(item, parentclash))));
        }
예제 #5
0
        public override void Handle(IBulkClashDeleted command)
        {
            var clashes = _clashRepository.FindByExternal(command.Data.Select(c => c.Externalref).ToList()).ToList();

            if (clashes.Any())
            {
                _clashRepository.DeleteRange(clashes.Select(c => c.Uid));
                _clashRepository.SaveChanges();
            }
            else
            {
                _logger.Warn("Clashes can't be found with specified external references.");
            }
        }
예제 #6
0
        public static Clash CheckClashByExternalRef(this IClashRepository repository, string externalRef)
        {
            if (repository is null)
            {
                throw new ArgumentNullException(nameof(repository));
            }

            var clash = repository.FindByExternal(externalRef)
                        .SingleOrDefault();

            if (clash is null)
            {
                throw new DataSyncException(DataSyncErrorCode.ExternalReferenceNotFound,
                                            "Clash can't be found with specified external reference.");
            }

            return(clash);
        }
예제 #7
0
        public override void Handle(IBulkClashCreatedOrUpdated command)
        {
            var clashModels = _mapper.Map <List <GamePlan.Domain.BusinessRules.Clashes.Objects.Clash> >(command.Data);

            _clashRepository.CheckClashParents(clashModels);

            var externalRefs = command.Data.Select(x => x.Externalref).ToList();
            var dbClashes    = _clashRepository.FindByExternal(externalRefs);
            var newEntities  = new List <GamePlan.Domain.BusinessRules.Clashes.Objects.Clash>();

            foreach (var item in clashModels)
            {
                var existingClash = dbClashes.SingleOrDefault(x => x.Externalref.Equals(item.Externalref, StringComparison.OrdinalIgnoreCase));

                foreach (var difference in item.Differences)
                {
                    difference.TimeAndDow = new GamePlan.Domain.Generic.Types.TimeAndDowAPI
                    {
                        StartTime = new TimeSpan(6, 0, 0),
                        EndTime   = new TimeSpan(5, 59, 59)
                    };
                    difference.TimeAndDow.SetDaysOfWeek("1111111");
                }

                if (existingClash == null)
                {
                    newEntities.Add(item);
                }
                else
                {
                    existingClash.ParentExternalidentifier = item.ParentExternalidentifier;
                    existingClash.Description = item.Description;
                    existingClash.DefaultOffPeakExposureCount = item.ExposureCount;
                    existingClash.DefaultPeakExposureCount    = item.ExposureCount;
                    existingClash.Differences = item.Differences;
                }
            }

            _clashRepository.Add(newEntities);
            _clashRepository.UpdateRange(dbClashes);
            _clashRepository.SaveChanges();
        }
예제 #8
0
        public IEnumerable <SpotModel> Create(IReadOnlyCollection <Spot> spots)
        {
            if (spots is null || spots.Count == 0)
            {
                return(Enumerable.Empty <SpotModel>());
            }

            var clashes = new List <Clash>();

            var campaignExternalIds = spots.Select(s => s.ExternalCampaignNumber)
                                      .Where(s => !string.IsNullOrWhiteSpace(s)).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
            var campaigns = _campaignRepository.FindByRefs(campaignExternalIds).ToList();

            var productExternalIds = spots.Select(s => s.Product).Where(s => !string.IsNullOrWhiteSpace(s))
                                     .Distinct(StringComparer.OrdinalIgnoreCase).ToList();
            var products = _productRepository.FindByExternal(productExternalIds).ToList();

            if (products.Count != 0)
            {
                var clashExternalIds = products.Select(p => p.ClashCode).Where(p => !string.IsNullOrWhiteSpace(p))
                                       .Distinct(StringComparer.OrdinalIgnoreCase).ToList();
                clashes = _clashRepository.FindByExternal(clashExternalIds).ToList();
            }

            return(spots.Select(spot =>
            {
                var campaign =
                    campaigns.FirstOrDefault(c => c.ExternalId.Equals(spot.ExternalCampaignNumber,
                                                                      StringComparison.OrdinalIgnoreCase));
                var product = products.FirstOrDefault(
                    p => p.Externalidentifier.Equals(spot.Product, StringComparison.OrdinalIgnoreCase));

                var clashList = product != null
                    ? clashes.Where(
                    c => c.Externalref.Equals(product.ClashCode, StringComparison.OrdinalIgnoreCase)).ToList()
                    : null;
                return _mapper.Map <SpotModel>(Tuple.Create(spot, campaign, product, clashList));
            }));
        }
예제 #9
0
        /// <summary>
        /// Validates the schedule data needed (i.e. Breaks, spots etc) for
        /// starting run.
        /// </summary>
        /// <param name="run"></param>
        /// <param name="campaigns"></param>
        /// <param name="salesAreas"></param>
        /// <param name="demographicsCount"></param>
        private List <SystemMessage> ValidateScheduleDataForStartRun(Run run, IReadOnlyCollection <CampaignReducedModel> campaigns, IEnumerable <SalesArea> salesAreas, int demographicsCount)
        {
            List <SystemMessage> messages = new List <SystemMessage>();

            var tenantSettings                = _tenantSettingsRepository.Get();
            var minDocumentRestriction        = tenantSettings?.RunRestrictions?.MinDocRestriction;
            var minRunSizeDocumentRestriction = tenantSettings?.RunRestrictions?.MinRunSizeDocRestriction;

            if (minDocumentRestriction == null || minRunSizeDocumentRestriction == null)
            {
                messages.Add(FormatSystemMessage(SystemMessage.RunRestrictionsMissing, null));
                return(messages);
            }

            var daysCount = (run.EndDate - run.StartDate).Days + 1;

            if (_featureManager.IsEnabled(nameof(ProductFeature.NineValidationMinSpot)))
            {
                var minSpotDocument = minRunSizeDocumentRestriction.Spots * daysCount * salesAreas.Count();
                if (_spotRepository.Count(x => x.StartDateTime >= run.StartDate && x.StartDateTime <= run.EndDate) < minSpotDocument)
                {
                    messages.Add(FormatSystemMessage(SystemMessage.SpotDataMissing, null));
                }
            }

            var countBreaksAndProgrammes = _scheduleRepository.CountBreaksAndProgrammes(run.StartDate, run.EndDate);

            var minBreakDocument = minRunSizeDocumentRestriction.Breaks * daysCount * salesAreas.Count();

            if (countBreaksAndProgrammes.breaksCount < minBreakDocument)
            {
                messages.Add(FormatSystemMessage(SystemMessage.BreakDataMissing, null));
            }

            var minProgrammeDocuments = minRunSizeDocumentRestriction.Programmes * daysCount * salesAreas.Count();

            if (countBreaksAndProgrammes.programmesCount < minProgrammeDocuments)
            {
                messages.Add(FormatSystemMessage(SystemMessage.ProgrammeDataMissing, null));
            }

            if (campaigns.Count < minDocumentRestriction.Campaigns)
            {
                messages.Add(FormatSystemMessage(SystemMessage.CampaignDataMissing, null));
            }
            else
            {
                // Check that campaign CustomId is set
                var campaignsWithInvalidCustomId = campaigns.Where(c => c.CustomId == 0);
                foreach (var campaignWithInvalidCustomId in campaignsWithInvalidCustomId)
                {
                    messages.Add(FormatSystemMessage(SystemMessage.CampaignDataInvalid, new Dictionary <string, string>()
                    {
                        { _placeholderCampaignName, campaignWithInvalidCustomId.Name }, { _placeholderInvalidData, "Custom ID is not set" }
                    }));
                }

                // Check that campaign CustomId is unique
                var campaignsWithCustomId    = campaigns.Where(c => c.CustomId > 0).ToList();
                var campaignCustomIdsGrouped = campaignsWithCustomId
                                               .GroupBy(c => c.CustomId)
                                               .ToDictionary(x => x.Key, x => x.Count());

                foreach (var campaign in campaignsWithCustomId)
                {
                    if (!campaignCustomIdsGrouped.ContainsKey(campaign.CustomId) || campaignCustomIdsGrouped[campaign.CustomId] > 1)
                    {
                        messages.Add(FormatSystemMessage(SystemMessage.CampaignDataInvalid, new Dictionary <string, string>()
                        {
                            { _placeholderCampaignName, campaign.Name }, { _placeholderInvalidData, "Custom ID is not unique" }
                        }));
                    }
                }
            }

            if (_clearanceRepository.CountAll < minDocumentRestriction.ClearanceCodes)
            {
                messages.Add(FormatSystemMessage(SystemMessage.ClearanceDataMissing, null));
            }

            if (_clashRepository.CountAll < minDocumentRestriction.Clashes)
            {
                messages.Add(FormatSystemMessage(SystemMessage.ClashDataMissing, null));
            }

            if (demographicsCount < minDocumentRestriction.Demographics)
            {
                messages.Add(FormatSystemMessage(SystemMessage.DemographicDataMissing, null));
            }

            if (_productRepository.CountAll < minDocumentRestriction.Products)
            {
                messages.Add(FormatSystemMessage(SystemMessage.ProductDataMissing, null));
            }

            var campaignProductRefs = campaigns
                                      .Where(c => !string.IsNullOrEmpty(c.Product))
                                      .Select(c => c.Product)
                                      .Distinct()
                                      .ToList();

            var existingProducts = _productRepository
                                   .FindByExternal(campaignProductRefs)
                                   .ToDictionary(x => x.Externalidentifier, x => x);

            var productClashCodes = existingProducts
                                    .Where(p => !string.IsNullOrEmpty(p.Value.ClashCode))
                                    .Select(p => p.Value.ClashCode)
                                    .Distinct()
                                    .ToList();

            var existingClashCodes = new HashSet <string>(_clashRepository
                                                          .FindByExternal(productClashCodes)
                                                          .Select(c => c.Externalref));

            foreach (var campaign in campaigns)
            {
                if (string.IsNullOrEmpty(campaign.Product))
                {
                    messages.Add(FormatSystemMessage(SystemMessage.CampaignDataInvalid,
                                                     new Dictionary <string, string>
                    {
                        { _placeholderCampaignName, campaign.ExternalId },
                        { _placeholderInvalidData, "Campaign is missing a Product" }
                    }));

                    continue;
                }

                var product = existingProducts.ContainsKey(campaign.Product) ? existingProducts[campaign.Product] : null;
                if (product is null)
                {
                    messages.Add(FormatSystemMessage(SystemMessage.CampaignDataInvalid,
                                                     new Dictionary <string, string>
                    {
                        { _placeholderCampaignName, campaign.ExternalId },
                        { _placeholderInvalidData, $"Product: {campaign.Product} is missing" }
                    }));
                }
                else if (!string.IsNullOrEmpty(product.ClashCode) && !existingClashCodes.Contains(product.ClashCode))
                {
                    messages.Add(FormatSystemMessage(SystemMessage.CampaignDataInvalid,
                                                     new Dictionary <string, string>
                    {
                        { _placeholderCampaignName, campaign.ExternalId },
                        { _placeholderInvalidData, $"Product: {product.Externalidentifier}, Clash Code: {product.ClashCode} is missing" }
                    }));
                }
            }

            return(messages);
        }