コード例 #1
0
 public void Add(ClashException item)
 {
     lock (_session)
     {
         _session.Store(item);
     }
 }
コード例 #2
0
        public IHttpActionResult Put(int id, [FromBody] UpdateClashException command)
        {
            // MUST BE REWORKED!
            var offsetHours = 6;

            if (id == 0 || command == null)
            {
                return(this.Error().InvalidParameters());
            }

            var clashException = _clashExceptionRepository.Find(id);

            if (clashException == null)
            {
                return(NotFound());
            }
            ClashException.Validation(clashException.StartDate, command.EndDate, command.TimeAndDows);

            var ValidationPayload = new[]
            {
                MapToClashExceptionForValidation(command, clashException)
            };

            var validationResult = ValidateForSave(ValidationPayload);

            if (!validationResult.Successful)
            {
                return(this.Error().BadRequest(ApiError.BadRequest(validationResult.Message)));
            }

            MapToClashExceptions(command, ref clashException);
            _clashExceptionRepository.Add(clashException);
            _clashExceptionRepository.SaveChanges();
            return(Ok(_clashExceptionRepository.GetWithDescriptions(clashException.Id)));
        }
コード例 #3
0
        public void Add(ClashException item)
        {
            List <ClashException> items = new List <ClashException>()
            {
                item
            };

            InsertItems(_folder, _type, items, items.ConvertAll(i => i.Id.ToString()));
        }
コード例 #4
0
 private static bool DoClashExceptionsHaveSameFromAndToProperties(
     ClashException givenClashException,
     ClashException existingClashException)
 {
     return(givenClashException.FromType == existingClashException.FromType &&
            givenClashException.ToType == existingClashException.ToType &&
            givenClashException.FromValue == existingClashException.FromValue &&
            givenClashException.ToValue == existingClashException.ToValue);
 }
コード例 #5
0
        private void ValidateInput(List <CreateClashException> command)
        {
            command.ToList()
            .ForEach(_ => ClashException.Validation(_.StartDate, _.EndDate, _.FromValue, _.ToValue, _.TimeAndDows));

            var isAllAdvertiser = command.Where(_ => _.FromType == ClashExceptionType.Advertiser).EmptyIfNull()
                                  .All(_ => _.ToType == ClashExceptionType.Advertiser);

            if (!isAllAdvertiser)
            {
                throw new Exception(
                          "Clash exception to type should be advertiser if the from type is advertiser");
            }

            ValidateFromToValue(command.ToList());
        }
コード例 #6
0
        public void ValidateClashExceptionSameStructureRulesViolation(
            ClashException clashException,
            CustomValidationResult expectedResult
            )
        {
            _ = _fakeClashRepository
                .Setup(r => r.FindByExternal(It.IsAny <string>()))
                .Returns <string>(externalIdentifier =>
                                  ClashExceptionValidationTestData.BunchOfClashes.Where(c => c.Externalref == externalIdentifier)
                                  );

            var result =
                _clashExceptionValidations.ValidateClashExceptionForSameStructureRulesViolation(clashException);

            Assert.Multiple(() =>
            {
                Assert.AreEqual(result.Successful, expectedResult.Successful);
                Assert.AreEqual(result.Message, expectedResult.Message);
            });
        }
コード例 #7
0
        private static bool DoesOverlapExistOnDaysOfWeek(
            TimeAndDow givenClashExceptionTimeAndDow,
            ClashException existingClashException,
            int offsetHours)
        {
            var daysOfWeekOfGivenClashException = givenClashExceptionTimeAndDow.DaysOfWeek.ParseDayOfWeekDayCode();

            return(existingClashException.TimeAndDows.Any(existingClashExceptionTimeAndDow =>
            {
                var daysOfWeekOfExistingClashException = existingClashExceptionTimeAndDow.DaysOfWeek.ParseDayOfWeekDayCode();

                var intersection = daysOfWeekOfExistingClashException.Intersect(daysOfWeekOfGivenClashException);
                if (intersection.Any())
                {
                    return DoesOverlapExistOnTimeRanges(givenClashExceptionTimeAndDow, existingClashExceptionTimeAndDow, offsetHours);
                }

                return false;
            }));
        }
コード例 #8
0
        private bool DoesOverlapExistWithExistingClashExceptions(
            ClashException givenClashException,
            IEnumerable <ClashException> existingExceptions,
            int offsetHours)
        {
            return(existingExceptions
                   .Where(e => e.Id != givenClashException.Id)
                   .Any(existingClashException =>
            {
                var range = (existingClashException.StartDate, existingClashException.EndDate);

                if ((range.EndDate == null || givenClashException.StartDate <= range.EndDate) &&
                    (givenClashException.EndDate == null || givenClashException.EndDate >= range.StartDate))
                {
                    if (DoClashExceptionsHaveSameFromAndToProperties(givenClashException, existingClashException))
                    {
                        return givenClashException.TimeAndDows.Any(givenClashExceptionTimeAndRow =>
                                                                   DoesOverlapExistOnDaysOfWeek(givenClashExceptionTimeAndRow, existingClashException, offsetHours));
                    }
                }

                return false;
            }));
        }
コード例 #9
0
        /// <summary>Gets the clash product code.</summary>
        /// <param name="clashException">The clash exception.</param>
        /// <param name="products">The products.</param>
        /// <param name="clashes">The clashes.</param>
        /// <param name="fromCodes">From codes.</param>
        /// <param name="toCodes">To codes.</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        private void GetClashProductCode(ClashException clashException, IReadOnlyCollection <Product> products,
                                         IReadOnlyCollection <Clash> clashes,
                                         out List <string> fromCodes, out List <string> toCodes)
        {
            switch (clashException.FromType)
            {
            case ClashExceptionType.Clash:
                fromCodes = GetRelatedClashCodes(clashes, clashException.FromValue) ??
                            new List <string> {
                    clashException.FromValue
                };
                break;

            case ClashExceptionType.Product:
                fromCodes = new List <string> {
                    clashException.FromValue
                };
                break;

            case ClashExceptionType.Advertiser:
                fromCodes = products?
                            .Where(_ => _.AdvertiserIdentifier.Equals(clashException.FromValue,
                                                                      StringComparison.OrdinalIgnoreCase))
                            .Select(_ => _.Externalidentifier).ToList() ??
                            new List <string> {
                    "0"
                };                                        // if No products return list with default value
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            switch (clashException.ToType)
            {
            case ClashExceptionType.Clash:
                toCodes = GetRelatedClashCodes(clashes, clashException.ToValue) ??
                          new List <string> {
                    clashException.ToValue
                };
                break;

            case ClashExceptionType.Product:
                toCodes = new List <string> {
                    clashException.ToValue
                };
                break;

            case ClashExceptionType.Advertiser:
                toCodes = products?
                          .Where(_ => _.AdvertiserIdentifier.Equals(clashException.ToValue,
                                                                    StringComparison.OrdinalIgnoreCase))
                          .Select(_ => _.Externalidentifier).ToList()
                          ?? new List <string> {
                    "0"
                };                                         // if No products return list with default value
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #10
0
        /// <summary>
        /// Checks the clash exception
        /// </summary>
        /// <param name="smoothBreak"></param>
        /// <param name="spotToPlace"></param>
        /// <param name="clashException"></param>
        /// <returns></returns>
        private CheckClashExceptionActions CheckClashException(
            SmoothBreak smoothBreak,
            Spot spotToPlace,
            ClashException clashException)
        {
            // Check date & time
            Break theBreak = smoothBreak.TheBreak;

            if (smoothBreak.TheBreak.ScheduledDate.Date < clashException.StartDate.Date)
            {
                // Outside of date range
                return(CheckClashExceptionActions.NoAction);
            }

            if (clashException.EndDate != null && theBreak.ScheduledDate.Date > clashException.EndDate)
            {
                // Outside of date range
                return(CheckClashExceptionActions.NoAction);
            }

            // Assume that to time & DOWs means any time Check if outside of
            // time range
            if (clashException.TimeAndDows?.Count > 0)
            {
                var daysOfWeek = new List <DayOfWeek>()
                {
                    DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday
                };
                bool isWithinTimeRange = false;
                foreach (var timeAndDow in clashException.TimeAndDows)
                {
                    if (timeAndDow.DaysOfWeek.Substring(daysOfWeek.IndexOf(theBreak.ScheduledDate.DayOfWeek), 1) == "1")
                    {
                        if ((timeAndDow.StartTime == null || theBreak.ScheduledDate.TimeOfDay >= timeAndDow.StartTime) &&
                            (timeAndDow.EndTime == null || theBreak.ScheduledDate.TimeOfDay <= timeAndDow.EndTime))
                        {
                            isWithinTimeRange = true;
                            break;
                        }
                    }
                }

                if (!isWithinTimeRange)
                {
                    return(CheckClashExceptionActions.NoAction);
                }
            }

            // Get From products
            var fromProducts = new List <Product>();

            switch (clashException.FromType)
            {
            case ClashExceptionType.Advertiser:
                fromProducts.AddRange(
                    _products.Where(p => p.AdvertiserIdentifier == clashException.FromValue)
                    );

                break;

            case ClashExceptionType.Clash:
                var clashExternalRefs = _clashes
                                        .Where(c => c.Externalref == clashException.FromValue || c.ParentExternalidentifier == clashException.FromValue)
                                        .Select(c => c.Externalref)
                                        .Distinct()
                                        .ToList();

                fromProducts.AddRange(
                    _products.Where(p => clashExternalRefs.Contains(p.ClashCode))
                    );

                break;

            case ClashExceptionType.Product:
                var productExternalRefs = _products
                                          .Where(p => p.Externalidentifier == clashException.FromValue || p.ParentExternalidentifier == clashException.FromValue)
                                          .Select(p => p.Externalidentifier)
                                          .Distinct()
                                          .ToList();

                fromProducts.AddRange(
                    _products.Where(p => productExternalRefs.Contains(p.Externalidentifier))
                    );

                break;
            }

            // Get To products
            var toProducts = new List <Product>();

            var clashExceptionToValue = clashException.ToValue;

            switch (clashException.ToType)
            {
            case ClashExceptionType.Advertiser:
                toProducts.AddRange(
                    _products.Where(p => p.AdvertiserIdentifier == clashExceptionToValue)
                    );

                break;

            case ClashExceptionType.Clash:
                var clashExternalRefs = _clashes
                                        .Where(c => c.Externalref == clashExceptionToValue || c.ParentExternalidentifier == clashExceptionToValue)
                                        .Select(c => c.Externalref)
                                        .ToList();

                toProducts.AddRange(
                    _products.Where(p => clashExternalRefs.Contains(p.ClashCode))
                    );

                break;

            case ClashExceptionType.Product:
                var productExternalRefs = _products
                                          .Where(p => p.Externalidentifier == clashExceptionToValue || p.ParentExternalidentifier == clashExceptionToValue)
                                          .Select(p => p.Externalidentifier)
                                          .Distinct()
                                          .ToList();

                toProducts.AddRange(
                    _products.Where(p => productExternalRefs.Contains(p.Externalidentifier))
                    );

                break;
            }

            // Check include/exclude for spots
            bool hasIncludes = false;
            bool hasExcludes = false;

            foreach (var breakSmoothSpot in smoothBreak.SmoothSpots)
            {
                // Check From spot -> To break spot to place
                var spotToPlaceFromProducts = fromProducts.Where(p => p.Externalidentifier == spotToPlace.Product);
                var spotInBreakToProducts   = toProducts.Where(p => p.Externalidentifier == breakSmoothSpot.Spot.Product);

                if (spotToPlaceFromProducts.Any() && spotInBreakToProducts.Any())
                {
                    switch (clashException.IncludeOrExclude)
                    {
                    case IncludeOrExclude.I:
                        hasIncludes = true;
                        break;

                    case IncludeOrExclude.E:
                        hasExcludes = true;
                        break;
                    }
                }

                // Check From break spots -> To spot to place
                var spotToPlaceToProducts    = toProducts.Where(p => p.Externalidentifier == spotToPlace.Product);
                var spotsInBreakFromProducts = fromProducts.Where(p => p.Externalidentifier == breakSmoothSpot.Spot.Product);
                if (spotToPlaceToProducts.Any() && spotsInBreakFromProducts.Any())
                {
                    switch (clashException.IncludeOrExclude)
                    {
                    case IncludeOrExclude.I:
                        hasIncludes = true;
                        break;

                    case IncludeOrExclude.E:
                        hasExcludes = true;
                        break;
                    }
                }

                if (hasIncludes || (hasIncludes && hasExcludes))
                {
                    // No point in checking further spots
                    break;
                }
            }

            if (hasIncludes)
            {
                return(CheckClashExceptionActions.Includes);
            }

            if (hasExcludes)
            {
                return(CheckClashExceptionActions.Excludes);
            }

            return(CheckClashExceptionActions.NoAction);
        }
コード例 #11
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());
        }
コード例 #12
0
 public CheckClashExceptionResult(ClashException clashException) =>
コード例 #13
0
 private void MapToClashExceptions(UpdateClashException command, ref ClashException clashException)
 {
     clashException.EndDate          = (command.EndDate == null ? (DateTime?)null : command.EndDate.Value.Date);
     clashException.IncludeOrExclude = command.IncludeOrExclude;
     clashException.TimeAndDows      = command.TimeAndDows;
 }
コード例 #14
0
 private ClashException MapToClashExceptionForValidation(UpdateClashException command, ClashException clashException)
 {
     return(new ClashException()
     {
         Id = clashException.Id,
         FromType = clashException.FromType,
         ToType = clashException.ToType,
         FromValue = clashException.FromValue,
         ToValue = clashException.ToValue,
         StartDate = clashException.StartDate,
         EndDate = command.EndDate,
         TimeAndDows = command.TimeAndDows,
         IncludeOrExclude = command.IncludeOrExclude
     });
 }