/// <summary> /// Возвращает период действия условия правила отмены /// </summary> /// <param name="condition">Условие правила отмены</param> /// <param name="referencePointDateTime">Локальная для провайдера точка отсчёта правила отмены</param> /// <returns>Кортеж: StartDate; EndDate</returns> public static Tuple <DateTime, DateTime> GetActivityPeriod(CancellationRuleCondition condition, DateTime referencePointDateTime) { if (condition == null) { throw new ArgumentNullException("condition"); } return(GetActivityPeriod(condition.CancellationBeforeArrivalMatching, condition.CancellationBeforeArrivalUnit, condition.CancellationBeforeArrivalValue, condition.CancellationBeforeArrivalValueMax, referencePointDateTime)); }
public decimal Calculate(CancellationRuleCondition cancellationRuleCondition, Booking booking) { decimal penalty = 0; switch (cancellationRuleCondition.PenaltyCalcMode) { case CancellationPenaltyCalcMode.Percent: penalty = booking.AmountBeforeTax * cancellationRuleCondition.PenaltyValue / 100; break; case CancellationPenaltyCalcMode.Fixed: penalty = Math.Min(booking.AmountBeforeTax, cancellationRuleCondition.PenaltyValue); break; case CancellationPenaltyCalcMode.FirstNightPercent: penalty = (booking.AmountBeforeTax / booking.RoomTypeCount) * cancellationRuleCondition.PenaltyValue / 100; break; case CancellationPenaltyCalcMode.PrepaymentPercent: penalty = booking.PrepaySum * cancellationRuleCondition.PenaltyValue / 100; break; case CancellationPenaltyCalcMode.FirstNights: penalty = (booking.AmountBeforeTax / booking.RoomTypeCount) * cancellationRuleCondition.PenaltyValue; break; } int k = 1; if (cancellationRuleCondition.CancellationBeforeArrivalUnit != TimeUnit.None) { switch (cancellationRuleCondition.CancellationBeforeArrivalMatching) { case CancellationBeforeArrivalMatching.AtLeast: k = cancellationRuleCondition.CancellationBeforeArrivalUnit == TimeUnit.Day ? cancellationRuleCondition.CancellationBeforeArrivalValue * 24 : cancellationRuleCondition.CancellationBeforeArrivalValue; break; case CancellationBeforeArrivalMatching.Between: int betweenValue = cancellationRuleCondition.CancellationBeforeArrivalValueMax - cancellationRuleCondition.CancellationBeforeArrivalValue; k = cancellationRuleCondition.CancellationBeforeArrivalUnit == TimeUnit.Day ? betweenValue * 24 : betweenValue; break; case CancellationBeforeArrivalMatching.NoMatter: k = _maxCancellationBeforeArrivalValue + 1; break; } } // _logger.Info( $"\t\tcondition: {cancellationRuleCondition}, penalty: {penalty} * k:{k} = {penalty * k}" ); return(penalty * k); }
/// <summary> /// Проверяет действует ли условие правила отмены на указанную дату /// </summary> /// <param name="condition">Условие правила отмены</param> /// <param name="cancellationDateTimeLocalForProvider">Локальная для провайдера дата отмены</param> /// <param name="referencePointDateTime">Локальная для провайдера точка отсчёта правила отмены</param> /// <returns>true, если условие правила отмены действует на указанную дату; иначе false</returns> public static bool IsConditionActualForDate(CancellationRuleCondition condition, DateTime cancellationDateTimeLocalForProvider, DateTime referencePointDateTime) { if (condition == null) { throw new ArgumentNullException("condition"); } bool isActual = false; DateTime dateMargin = condition.CancellationBeforeArrivalUnit == TimeUnit.Day ? referencePointDateTime.AddDays(-condition.CancellationBeforeArrivalValue) : referencePointDateTime.AddHours(-condition.CancellationBeforeArrivalValue); switch (condition.CancellationBeforeArrivalMatching) { case CancellationBeforeArrivalMatching.NoMatter: isActual = true; break; case CancellationBeforeArrivalMatching.AtLeast: isActual = cancellationDateTimeLocalForProvider <= dateMargin; break; case CancellationBeforeArrivalMatching.NoMoreThan: isActual = cancellationDateTimeLocalForProvider >= dateMargin; break; case CancellationBeforeArrivalMatching.Between: DateTime dateMarginMax = dateMargin; dateMargin = condition.CancellationBeforeArrivalUnit == TimeUnit.Day ? referencePointDateTime.AddDays(-condition.CancellationBeforeArrivalValueMax) : referencePointDateTime.AddHours(-condition.CancellationBeforeArrivalValueMax); isActual = cancellationDateTimeLocalForProvider >= dateMargin && cancellationDateTimeLocalForProvider <= dateMarginMax; break; } return(isActual); }
public decimal Calculate(CancellationRuleCondition cancellationRuleCondition, Booking booking) { decimal penalty = 0; switch (cancellationRuleCondition.PenaltyCalcMode) { case CancellationPenaltyCalcMode.Percent: penalty = booking.AmountBeforeTax * cancellationRuleCondition.PenaltyValue / 100; break; case CancellationPenaltyCalcMode.Fixed: penalty = Math.Min(booking.AmountBeforeTax, cancellationRuleCondition.PenaltyValue); break; case CancellationPenaltyCalcMode.FirstNightPercent: penalty = (booking.AmountBeforeTax / booking.NightsCount) * cancellationRuleCondition.PenaltyValue / 100; break; case CancellationPenaltyCalcMode.PrepaymentPercent: penalty = booking.AmountBeforeTax * cancellationRuleCondition.PenaltyValue / 100; break; case CancellationPenaltyCalcMode.FirstNights: penalty = (booking.AmountBeforeTax / booking.NightsCount) * cancellationRuleCondition.PenaltyValue; break; } if (cancellationRuleCondition.CancellationBeforeArrivalMatching == CancellationBeforeArrivalMatching.NoMatter) { // Заметно увеличиваем штраф, в случае, когда срок применения правила не зависит от времени до заезда penalty *= 10; } _logger.Info($"\t\tcondition: {cancellationRuleCondition}, penalty: {penalty}"); return(penalty); }
/// <summary> /// Проверяет истекло ли условие правила отмены из брони /// </summary> /// <param name="cancellationCondition">Условие правила отмены</param> /// <param name="paymentDateTimeLocalForProvider">Локальная для провайдера дата и время бронирования</param> /// <param name="referencePointDateTime">Локальная для провайдера точка отсчёта правила отмены</param> /// <returns>true, если условие правило отмены истекло; иначе false</returns> public static bool IsConditionExpired(CancellationRuleCondition cancellationCondition, DateTime paymentDateTimeLocalForProvider, DateTime referencePointDateTime) { Tuple <DateTime, DateTime> activityPeriod = GetActivityPeriod(cancellationCondition, referencePointDateTime); return(paymentDateTimeLocalForProvider > activityPeriod.Item2); }