public async Task <TotalPriceModel> CalculatePrice(CustomerCostsPeriodModel timeframe) { timeframe.StartDate = DateInDays(timeframe.StartDate); timeframe.EndDate = DateInDays(timeframe.EndDate); _context.Services.Load <Service>(); _context.Contracts.Load <Contract>(); var customer = await GetCustomer(timeframe.CustomerId); var serviceEvents = await _context.UseServiceEvents. Where(e => e.Customer == customer && e.Contract != null). OrderBy(e => e.StartDate). ToListAsync(); var freeDict = new Dictionary <Service, long>(); double price = 0; foreach (UseServiceEvent evnt in serviceEvents) { var service = evnt.Contract.Service; if (freeDict.ContainsKey(service)) { if (freeDict[service] - CalcDays(evnt, timeframe, service) >= 0) { freeDict[service] -= CalcDays(evnt, timeframe, service); } else { price += evnt.Contract.SpecialPrice * (CalcDays(evnt, timeframe, service) - freeDict[service]) * (1 + evnt.Contract.Discount / 100); freeDict[service] = 0; } } else { var pricedDays = CalcDays(evnt, timeframe, service); if (customer.FreeDays - pricedDays >= 0) { freeDict[service] = customer.FreeDays - CalcDays(evnt, timeframe, service); } else { price += evnt.Contract.SpecialPrice * (pricedDays - customer.FreeDays) * (1 - evnt.Contract.Discount / 100); } } } return(new TotalPriceModel { Price = price }); }
public async Task <ActionResult <TotalPriceModel> > GetCustomerCosts([FromBody] CustomerCostsPeriodModel customerModel) { var result = await _contractService.CalculatePrice(customerModel); return(Ok(result)); }
private long CalcDays(UseServiceEvent use, CustomerCostsPeriodModel timeframe, Service service) { var endStartDiff = DaysDiff(use.EndDate, timeframe.StartDate); var startEndDiff = DaysDiff(use.StartDate, timeframe.EndDate); // No overlap if (endStartDiff > 0 || startEndDiff < 0) { return(0); } var startDiff = DaysDiff(timeframe.StartDate, use.StartDate); var endDiff = DaysDiff(use.EndDate, timeframe.EndDate); var useDiff = DaysDiff(use.StartDate, use.EndDate); var sDate = DateTime.MinValue; var eDate = DateTime.MinValue; if (startDiff >= 0 && endDiff >= 0) { sDate = use.StartDate; eDate = use.EndDate; } else if (startDiff < 0 && endDiff < 0) { sDate = timeframe.StartDate; eDate = timeframe.EndDate; } else if (startDiff < 0) { sDate = timeframe.StartDate; eDate = use.EndDate; } else { sDate = use.StartDate; eDate = timeframe.EndDate; } if (service.LastBillableDay > service.FirstBillableDay) { var daysStart = 0; if (sDate.DayOfWeek != service.FirstBillableDay) { daysStart = service.LastBillableDay - sDate.DayOfWeek + 1; } var daysEnd = 0; if (eDate.DayOfWeek != service.LastBillableDay) { daysEnd = eDate.DayOfWeek - service.FirstBillableDay; } var totalDays = DaysDiff(sDate, eDate); var weeks = totalDays / 7 * (service.LastBillableDay - service.FirstBillableDay + 1); return(weeks + daysStart + daysEnd); } else { return(DaysDiff(sDate, eDate)); } }