public int MakeBooking(MakeBookingInfoDto makeBookingInfo, CurrentUser user) { DateTime from = makeBookingInfo.GetFromDateTime(); DateTime to = makeBookingInfo.GetToDateTime(); if (!user.PhoneConfirmed) { throw new ServiceException("User does not have such permissions"); } if (from < _dateService.NowUtc.Date) { throw new ServiceException($"Booking is invalid for this action \r\n ____ from less than date now. From='{from}' Date='{_dateService.NowUtc.Date}'"); } if (GetBookingsForPeriod(from, to).Any()) { string bookingIds = GetBookingsForPeriod(from, to).Select(x => x.Id.ToString()) .Aggregate((s1, s2) => s1 + "," + s2); throw new ServiceException($"Booking is invalid for this action \r\n ____ has bookings for period. From='{from}' To='{to}' Ids='{bookingIds}'"); } // TODO: Implement checking schedule BookingCostDto bookingCost = _costEvaluationService.EvaluateBookingCost(from, to, makeBookingInfo.PromoCode); var booking = new BookingEntity { From = from, To = to, Status = BookingStatusEnum.Unpaid, Guid = Guid.NewGuid(), Cost = bookingCost.TotalCost, PromoCodeId = bookingCost.PromoCode?.Id, UserId = user.UserId }; _bookingRepository.Save(booking); return(booking.Id); }
public BookingCostDto EvaluateBookingCost(DateTime from, DateTime to, string promoCode) { StudioSchedule schedule = EvaluateStudioSchedule(); PromoCodeInfoDto promoCodeInfo = EvaluatePromoCodeInfo(promoCode); var result = new BookingCostDto { PromoCode = promoCodeInfo }; schedule.Cost *= promoCodeInfo.CostModifier; foreach (var scheduleSpecialCost in schedule.SpecialCosts) { scheduleSpecialCost.Cost *= promoCodeInfo.CostModifier; } if (schedule.SpecialCosts == null || schedule.SpecialCosts.Length == 0) { return(SetupIntervals(result, new[] { CreateIntervalCost(from, to, schedule.Cost) })); } ICollection <IntervalCostDto> intervalCosts = new Collection <IntervalCostDto>(); ICollection <Interval> intervals = ParseToIntervals(from, to); foreach (var interval in intervals) { var specialCosts = schedule.SpecialCosts .Where(x => x.DayType.HasFlag(interval.DayType)) .Select(x => new { From = interval.From.Date.AddHours(x.Start), To = interval.From.Date.AddHours(x.End + 1), x.Cost }) .OrderBy(x => x.From); DateTime intervalStart = interval.From; foreach (var specialCost in specialCosts) { if (intervalStart >= specialCost.To) { continue; } if (interval.To <= specialCost.From) { intervalCosts.Add(CreateIntervalCost(intervalStart, interval.To, schedule.Cost)); intervalStart = interval.To; break; } if (intervalStart < specialCost.From) { intervalCosts.Add(CreateIntervalCost(intervalStart, specialCost.From, schedule.Cost)); intervalStart = specialCost.From; } if (interval.To <= specialCost.To) { intervalCosts.Add(CreateIntervalCost(intervalStart, interval.To, specialCost.Cost)); intervalStart = interval.To; break; } else { intervalCosts.Add(CreateIntervalCost(intervalStart, specialCost.To, specialCost.Cost)); intervalStart = specialCost.To; } } if (intervalStart < interval.To) { intervalCosts.Add(CreateIntervalCost(intervalStart, interval.To, schedule.Cost)); } } return(SetupIntervals(result, intervalCosts)); }
private BookingCostDto SetupIntervals(BookingCostDto bookingCost, ICollection <IntervalCostDto> intervals) { bookingCost.IntervalCosts = intervals; bookingCost.TotalCost = intervals.Select(x => x.Cost).Sum(); return(bookingCost); }