public void ModifyWithOverlapSetsDtoCorrectly() { // Arrange IPeriodManager managerMock = MockRepository.GenerateMock<IPeriodManager>(); Period mockPeriod = new Period { PricingPeriodError = PricingPeriodError.SeasonOverSeason, PeriodDateRanges = new List<PeriodDateRange> { new PeriodDateRange { PricingPeriodError = PricingPeriodError.SeasonOverSeason } } }; managerMock.Expect(pm => pm.ModifyPeriod(Arg<Period>.Matches(p => p.PeriodType.PeriodTypeEnum == PeriodTypeEnum.Season), Arg<string>.Is.Equal(ENGLISH_CULTURE))).Return(mockPeriod); // Stub the BusinessCache to be used by our service method CacheHelper.StubBusinessCacheSingleBusiness(VALID_BUSINESS_ID); // invalidate the cache so we make sure our business is loaded into the cache Cache.Business.Invalidate(); PropertyManagementSystemService.PeriodManager = managerMock; // Act PeriodDto resultPeriodDto = PropertyManagementSystemService.ModifySeason(VALID_BUSINESS_ID, new PeriodDto { BusinessId = VALID_BUSINESS_ID }, ENGLISH_CULTURE); // Assert Assert.IsNotNull(resultPeriodDto, "Period Dto should not be null"); Assert.AreEqual(PricingPeriodErrorDto.SeasonOverSeason, resultPeriodDto.PricingPeriodError.Value, "Overlap error didn't get mapped correctly"); managerMock.VerifyAllExpectations(); CacheHelper.ReAssignBusinessDaoToBusinessCache(); }
/// <summary> /// Check if date ranges for a given period have overlap with others of the same type /// </summary> /// <param name="period">period to check</param> /// <returns>true if they overlap</returns> private bool DoDateRangesOverlap(Period period) { foreach (PeriodDateRange periodDateRange in period.PeriodDateRanges) { if (periodDateRangeDao.IsDateRangeForPeriodTypeOverlapping(period.PeriodType.PeriodTypeEnum, period.BusinessId, periodDateRange)) { periodDateRange.PricingPeriodError = GetOverlapError(period.PeriodType.PeriodTypeEnum); period.PricingPeriodError = periodDateRange.PricingPeriodError; // return with overlap error recorded in object return true; } } return false; }
/// <summary> /// Validate the date ranges and period for modify/create /// </summary> /// <param name="period">period to check</param> /// <param name="cultureCode">culture</param> /// <param name="isCreate">true if it is a create</param> private void ValidatePeriod(Period period, string cultureCode, bool isCreate) { string callMethod = isCreate ? "PeriodManager.CreatePeriod" : "PeriodManager.ModifyPeriod"; if (!period.IsValid()) { //Throw validation exception here SRVEX30082 throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30082, callMethod, additionalDescriptionParameters: (new object[] { period }), arguments: new object[] { period, cultureCode })); } if (period.PeriodDateRanges.Exists(pdr => pdr.IsValid() == false)) { PeriodDateRange invalidPeriodDateRange = period.PeriodDateRanges.First(pdr => pdr.IsValid() == false); // more than 365 day exception here if ((invalidPeriodDateRange.EndDate - invalidPeriodDateRange.StartDate).Days > 365) { // throw exception for a bad date range throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30029, callMethod, additionalDescriptionParameters: (new object[] { invalidPeriodDateRange.StartDate, invalidPeriodDateRange.EndDate }), arguments: new object[] { period, cultureCode })); } else { // throw exception for a bad date range throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30002, callMethod, additionalDescriptionParameters: (new object[] { invalidPeriodDateRange.StartDate, invalidPeriodDateRange.EndDate }), arguments: new object[] { period, cultureCode })); } } }
/// <summary> /// Create a period /// Assumes that if period id is filled in then it is adding a date range /// Otherwise creates full new period /// </summary> /// <param name="period">Period to create</param> /// <param name="cultureCode">culture for translation</param> /// <returns>Period with id filled in</returns> public Period CreatePeriod(Period period, string cultureCode) { ValidatePeriod(period, cultureCode, true); // check for duplicate name only when creating new period if (period.Id == default(int) && periodDao.DoesPeriodNameAlreadyExist(period.BusinessId, period.Name)) { // set error code period.PricingPeriodError = PricingPeriodError.DuplicateName; return period; } // check for any overlaps if (DoDateRangesOverlap(period)) { return period; } string reference = string.Empty; bool isModify = false; using (var bex = new BusinessTransaction()) { //First check if period has an ID, that determines logic for rest of method if (period.Id <= default(int)) { //get the next colour to use for the create period.PeriodColor = periodColorDao.GetNextPeriodColorForPeriodType(period.BusinessId, period.PeriodType.PeriodTypeEnum, cultureCode); period.PeriodColorId = period.PeriodColor.Id; //create of period using the next colour for the type periodDao.Create(period, cultureCode); } else { // it is modify isModify = true; } if (period.PeriodColor == null || period.PeriodColorId == default(int) || period.PeriodColor.Id == default(int)) { //Fetch the colour for the period that exists period.PeriodColor = periodColorDao.GetByPeriodId(period.Id, cultureCode); period.PeriodColorId = period.PeriodColor.Id; } // add date range to it since period and colour should be good now foreach (PeriodDateRange periodDateRange in period.PeriodDateRanges) { // Only create new date ranges for periods that exist in the db if (periodDateRange.PeriodId == default(int) || periodDateRange.Id == default(int)) { periodDateRange.PeriodId = period.Id; periodDateRangeDao.Create(periodDateRange); // add to reference string reference = reference + periodDateRange.StartDate.ToString(StandardDateTimeFormatProvider.GetShortDBFormat()) + ","; reference = reference + periodDateRange.EndDate.ToString(StandardDateTimeFormatProvider.GetShortDBFormat()) + ","; } } bex.Commit(); } BusinessEventTypesEnum businessEvent = GetBusinessEventForPeriodType(period.PeriodType.PeriodTypeEnum, isCreate: !isModify, isEdit: isModify); // event for creation of period / date range here eventTrackingManager.CreateBusinessEventAsync(period.BusinessId, businessEvent, reference.TrimEnd(',')); return period; }
/// <summary> /// Modify a period by changing the date range specified /// </summary> /// <remarks> /// Assumes only date range changes are possible at the moment /// </remarks> /// <param name="period">Period to modify</param> /// <param name="cultureCode">culture for translation</param> /// <returns>Period with date changed</returns> public Period ModifyPeriod(Period period, string cultureCode) { ValidatePeriod(period, cultureCode, false); // Make sure period date range id is set if (period.PeriodDateRanges == null || period.PeriodDateRanges.Any() == false || period.PeriodDateRanges.Any(pdr => pdr.Id == default(int))) { throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30084, "PricingManager.ModifyPeriod", arguments: new object[] { period, cultureCode })); } // only one date range modify per call if (period.PeriodDateRanges.Count > 1) { // only one period can be modified at a time throw new ValidationException(ErrorFactory.CreateAndLogError(Errors.SRVEX30143, "PricingManager.ModifyPeriod", arguments: new object[] { period, cultureCode })); } // check for any overlaps if (DoDateRangesOverlap(period)) { return period; } BusinessEventTypesEnum businessEvent = BusinessEventTypesEnum.Unknown; string reference = string.Empty; List<PeriodDateRange> existingDateRanges = periodDateRangeDao.GetAllByPeriodId(period.Id); // All ok, so modify the date ranges using (var bex = new BusinessTransaction()) { if (period.PeriodColor == null || period.PeriodColorId == default(int) || period.PeriodColor.Id == default(int)) { //Fetch the colour for the period that exists period.PeriodColor = periodColorDao.GetByPeriodId(period.Id, cultureCode); period.PeriodColorId = period.PeriodColor.Id; } PeriodDateRange pdr = period.PeriodDateRanges.First(); periodDateRangeDao.Modify(pdr); if (period.PeriodDateRanges.Count == 1) { // get the one being modified: if (existingDateRanges.Any(p => p.Id == pdr.Id)) { PeriodDateRange modifyPdr = existingDateRanges.FirstOrDefault(e => e.Id == pdr.Id); reference = reference + modifyPdr.StartDate.ToString(StandardDateTimeFormatProvider.GetShortDBFormat()) + ","; reference = reference + modifyPdr.EndDate.ToString(StandardDateTimeFormatProvider.GetShortDBFormat()) + ","; } // get the new dates as well reference = reference + pdr.StartDate.ToString(StandardDateTimeFormatProvider.GetShortDBFormat()) + ","; reference = reference + pdr.EndDate.ToString(StandardDateTimeFormatProvider.GetShortDBFormat()) + ","; } businessEvent = GetBusinessEventForPeriodType(period.PeriodType.PeriodTypeEnum, isEdit: true); bex.Commit(); } // event for modify of period / date range here eventTrackingManager.CreateBusinessEventAsync(period.BusinessId, businessEvent, reference.TrimEnd(',')); return period; }
/// <summary> /// Create non evergreen occupant rate plan from base rate plan /// </summary> /// <param name="baseRatePlan">BaseRatePlan</param> /// <param name="roomTypeName">>RoomType name</param> /// <param name="ratePlanRate">RatePlanRate</param> /// <param name="period">Period</param> /// <param name="occupancyRateType">OccupancyRateType</param> /// <returns>RatePlan</returns> private VariantRatePlan CreateNonEvergreenOccupantRatePlan(BaseRatePlan baseRatePlan, string roomTypeName, RatePlanRate ratePlanRate, Period period, OccupancyRateType occupancyRateType) { var occupantRatePlan = CreateVariantFromBase(baseRatePlan, roomTypeName); occupantRatePlan.Id = 0; occupantRatePlan.RatePlanType = new RatePlanType { Type = RatePlanTypeEnum.Base }; occupantRatePlan.Period = period; occupantRatePlan.PeriodId = period.Id; occupantRatePlan.Rates = GetNulRates(occupantRatePlan); GetDefaultVariantEvergreenBaseRates(occupantRatePlan); occupantRatePlan.Rates.Id = 0; occupantRatePlan.Rates.RatePlanId = baseRatePlan.Id; occupantRatePlan.Rates.OccupancyRateType = occupancyRateType; occupantRatePlan.UseOccupancyRates = true; return occupantRatePlan; }
/// <summary> /// Create collection of VariantRatePlanPeriod /// </summary> /// <param name="variantRatePlanPeriod"></param> /// <returns></returns> private List<VariantRatePlanPeriod> CreateVariantRatePlanPeriods(Period period) { return new List<VariantRatePlanPeriod>() { new VariantRatePlanPeriod() { PeriodId = period.Id, BusinessId = period.BusinessId, Name = period.Name, PeriodColor = period.PeriodColor, PeriodDateRanges = period.PeriodDateRanges, UpdatedByUserId = period.UpdatedByUserId, Id = period.Id } }; }
/// <summary> /// Create a period and assigns colour to it /// </summary> /// <param name="period">period to create</param> /// <param name="cultureCode">culture for names</param> public void Create(Period period, string cultureCode) { const string SQL_STATEMENT = @" INSERT INTO Pricing.Period ( BusinessId, Name, PeriodTypeCode, PeriodColorId, UpdatedByUserId ) VALUES ( @BusinessId, @Name, @PeriodTypeCode, @PeriodColorId, @UpdatedByUserId ) SELECT @Id = SCOPE_IDENTITY()"; var parameters = new List<SqlParameter> { DbHelper.CreateParameter(PeriodMapper.Parameters.BusinessId, period.BusinessId), DbHelper.CreateParameter(PeriodMapper.Parameters.Name, period.Name), DbHelper.CreateParameter(PeriodMapper.Parameters.PeriodColorId, period.PeriodColor.Id), DbHelper.CreateParameter(PeriodMapper.Parameters.PeriodTypeCode, period.PeriodType.PeriodTypeEnum.GetCode()) }; // Add auditing parameters AuditFieldsHelper.PopulateAuditFields(parameters); SqlParameter outputKey; parameters.Add(outputKey = DbHelper.CreateParameterOut<int>(PeriodMapper.Parameters.Id, SqlDbType.Int)); DbHelper.ExecuteNonQueryCommand(SQL_STATEMENT, parameters: parameters); period.Id = DbHelper.ParameterValue<int>(outputKey); }
/// <summary> /// Handles calling each sub dao for the period in question /// </summary> /// <param name="period">period to fill in</param> /// <param name="cultureCode">culture for names</param> private void CallSubDaosForPeriod(Period period, string cultureCode) { period.PeriodColor = periodColorDao.GetByKey(period.PeriodColorId, cultureCode); period.PeriodDateRanges = periodDateRangeDao.GetAllByPeriodId(period.Id); }
public void CreatePeriodWithValidDataIsSuccessful() { // Arrange PeriodColor color = periodColorDao.GetNextPeriodColorForPeriodType(BUSINESS1_ID, PeriodTypeEnum.Season, ENGLISH_CULTURE); Period periodToCreate = new Period { PeriodColor = color, PeriodColorId = color.Id, Name = "new period", PeriodType = new PeriodType { PeriodTypeEnum = PeriodTypeEnum.Season, Name = Enum.GetName(typeof(PeriodTypeEnum), PeriodTypeEnum.Season) }, BusinessId = BUSINESS1_ID }; // Act periodDao.Create(periodToCreate, ENGLISH_CULTURE); // Assert Assert.AreNotEqual(default(int), periodToCreate.Id, "Id was not assigned after create"); }