/// <summary> /// If order passes midnight their might be two rows of same pricetype, merge these to one /// Also check if two duplicate rows have less or equal compensation time together. Then it should be reduced, e.g. 23:45-00:45 (should be two 30 min periods not three) /// </summary> public static IEnumerable <PriceRowBase> MergePriceListRowsAndReduceForMealBreak(IEnumerable <PriceRowBase> pricePerType, IDictionary <PriceListRowType, int> mealbreakDictionary = null) { int newQuantity = 0; var duplicatesPriceListrows = pricePerType.GroupBy(x => x.PriceListRow.PriceListRowId) .Where(g => g.Count() > 1) .Select(g => g.Key) .Distinct().ToList(); if (!duplicatesPriceListrows.Any()) { if (mealbreakDictionary != null) { List <PriceRowBase> pl = pricePerType.Where(pr => pr.PriceListRow.PriceListRowType != PriceListRowType.BigHolidayWeekendIWH && pr.PriceListRow.PriceListRowType != PriceListRowType.WeekendIWH && pr.PriceListRow.PriceListRowType != PriceListRowType.InconvenientWorkingHours).ToList(); foreach (PriceRowBase pricerow in pricePerType.Where(pr => pr.PriceListRow.PriceListRowType == PriceListRowType.BigHolidayWeekendIWH || pr.PriceListRow.PriceListRowType == PriceListRowType.WeekendIWH || pr.PriceListRow.PriceListRowType == PriceListRowType.InconvenientWorkingHours)) { //reduce quantity with mealbreaks, check if quantity > 0 before adding newQuantity = GetReducedQuantityForMealbreak(pricerow, mealbreakDictionary[pricerow.PriceListRow.PriceListRowType]); if (newQuantity > 0) { pricerow.Quantity = newQuantity; pl.Add(pricerow); } } return(pl); } else { return(pricePerType); } } else { List <PriceRowBase> mergedList = new List <PriceRowBase>(); foreach (int priceListRowId in duplicatesPriceListrows) { PriceRowBase newPriceRow = pricePerType.OrderBy(pr => pr.StartAt).First(pr => pr.PriceListRow.PriceListRowId == priceListRowId); var noOfMinutes = pricePerType.Where(pr => pr.PriceListRow.PriceListRowId == priceListRowId).Sum(pr => pr.Minutes); //reduce noOfMinutes with mealbreak minutes if (mealbreakDictionary != null && mealbreakDictionary.ContainsKey(newPriceRow.PriceListRow.PriceListRowType)) { noOfMinutes -= mealbreakDictionary[newPriceRow.PriceListRow.PriceListRowType]; } var compensationPeriod = newPriceRow.PriceListRow.MaxMinutes; newQuantity = compensationPeriod == 0 ? newPriceRow.Quantity : noOfMinutes % compensationPeriod > 0 ? (noOfMinutes / compensationPeriod) + 1 : noOfMinutes / compensationPeriod; newPriceRow.Quantity = newQuantity; newPriceRow.EndAt = pricePerType.OrderBy(pr => pr.EndAt).Last(pr => pr.PriceListRow.PriceListRowId == priceListRowId).EndAt; if (newQuantity > 0) { newPriceRow.Quantity = newQuantity; mergedList.Add(newPriceRow); } } mergedList.AddRange(pricePerType.Where(pri => !duplicatesPriceListrows.Contains(pri.PriceListRow.PriceListRowId))); return(mergedList); } }
private static PriceRowBase GetPriceInformation(DateTimeOffset startAt, DateTimeOffset endAt, PriceListRowType rowType, List <PriceListRow> prices) { PriceListRow priceInfo = prices.Single(r => r.PriceListRowType == rowType); var priceTime = new PriceRowBase { StartAt = startAt, EndAt = endAt, PriceRowType = PriceRowType.InterpreterCompensation }; priceTime.Quantity = priceTime.Minutes / priceInfo.MaxMinutes; if (priceTime.Minutes % priceInfo.MaxMinutes > 0) { priceTime.Quantity++; } priceTime.PriceListRow = priceInfo; priceTime.Price = priceInfo.Price; return(priceTime); }
private PriceInformation CompletePricesWithExtraCharges(DateTimeOffset startAt, DateTimeOffset endAt, CompetenceLevel competenceLevel, List <PriceRowBase> priceListRowsPerPriceType, int rankingId, decimal?travelCost, DateTimeOffset orderCreatedDate, decimal?outlay = null, PriceRowBase requestBrokerFeeForRequisition = null) { List <PriceRowBase> allPriceRows = new List <PriceRowBase> { GetPriceRowSocialInsuranceCharge(startAt, endAt, priceListRowsPerPriceType), GetPriceRowAdministrativeCharge(startAt, endAt, priceListRowsPerPriceType), GetPriceRowBrokerFee(startAt, endAt, competenceLevel, rankingId, requestBrokerFeeForRequisition, orderCreatedDate) }; allPriceRows.AddRange(priceListRowsPerPriceType); if (travelCost != null && travelCost > 0) { allPriceRows.Add(GetTravelCostRow(startAt.Date, startAt.Date.AddDays(1).ToDateTimeOffsetSweden(), travelCost, PriceRowType.TravelCost)); } if (outlay != null && outlay > 0) { allPriceRows.Add(GetTravelCostRow(startAt.Date, startAt.Date.AddDays(1).ToDateTimeOffsetSweden(), outlay, PriceRowType.Outlay)); } allPriceRows.Add(GetRoundedPriceRow(startAt, endAt, allPriceRows)); var priceInformation = new PriceInformation { PriceRows = allPriceRows }; return(priceInformation); }
private PriceRowBase GetPriceRowBrokerFee(DateTimeOffset startAt, DateTimeOffset endAt, CompetenceLevel competenceLevel, int rankingId, PriceRowBase brokerFeeToUse, DateTimeOffset orderCreatedDate) { if (brokerFeeToUse != null) { return(brokerFeeToUse); } else { //One broker fee per day int days = GetNoOfDays(startAt, endAt); //if there is no priceRowBrokerFee for the orderStart, try to get if for the orderCreatedDate (contract has ended, but order was created when contract/ranking was valid) var priceRow = _cacheService.BrokerFeePriceList.Where(br => br.RankingId == rankingId && br.CompetenceLevel == competenceLevel && br.StartDate.Date <= startAt.Date && br.EndDate.Date >= startAt.Date).Count() == 1 ? _cacheService.BrokerFeePriceList.Single(br => br.RankingId == rankingId && br.CompetenceLevel == competenceLevel && br.StartDate.Date <= startAt.Date && br.EndDate.Date >= startAt.Date) : _cacheService.BrokerFeePriceList.Single(br => br.RankingId == rankingId && br.CompetenceLevel == competenceLevel && br.StartDate.Date <= orderCreatedDate.Date && br.EndDate.Date >= orderCreatedDate.Date); return(new PriceRowBase { StartAt = startAt.Date.ToDateTimeOffsetSweden(), EndAt = endAt.Date.ToDateTimeOffsetSweden(), PriceRowType = PriceRowType.BrokerFee, Quantity = days, Price = priceRow.PriceToUse, PriceListRowId = priceRow.PriceListRowId }); } }
private static int GetReducedQuantityForMealbreak(PriceRowBase newPriceRow, int mealbreakMinutes) { int reducedMinutes = newPriceRow.Minutes - mealbreakMinutes; return(reducedMinutes > 0 ? reducedMinutes % newPriceRow.PriceListRow.MaxMinutes > 0 ? (reducedMinutes / newPriceRow.PriceListRow.MaxMinutes) + 1 : reducedMinutes / newPriceRow.PriceListRow.MaxMinutes : 0); }