public async Task <PurchasePriceCountingResult> CountPurchasePriceAsync(IUnitOfWork unitOfWork, PurchasePriceCountingParams queryParams, Vendor vendor = null) { if (queryParams == null) { throw new HttpRequestException("You should provide the countParams"); } if (queryParams.IsGetLatestQuotation) { if (vendor == null) { var vendorRepository = unitOfWork.GetRepository <Vendor>(); vendor = await vendorRepository.GetQueryable().Where(v => v.Id == queryParams.VendorId) .Include(v => v.Zones) .FirstOrDefaultAsync(); if (vendor == null) { throw new HttpRequestException("Cannot find vendor"); } } var zonesByCountry = vendor.Zones.Where(z => z.Countries.Contains(queryParams.DestinationCountry)).ToList(); if (!zonesByCountry.Any()) { throw new HttpRequestException( $"Cannot find zone of country {queryParams.DestinationCountry} of Vendor {vendor.Name}"); } var vendorServiceMappingRepo = unitOfWork.GetRepository <ParcelServiceVendor>(); var mappedServiceNames = await vendorServiceMappingRepo.GetQueryable() .Where(vs => vs.VendorId == vendor.Id) .Include(v => v.ParcelService) .Select(v => v.ParcelService.Name).ToArrayAsync(); var zone = this.GetAppropriateZone(zonesByCountry, mappedServiceNames, queryParams.ServiceName); if (zone == null) { this.logger.LogError( $"[Handled] Cannot find zone of country {queryParams.DestinationCountry} of Vendor {vendor.Name} with service {queryParams.ServiceName}"); } return(CountVendorNetPriceInUsd(vendor, queryParams, zone)); } return(this.CountVendorNetPriceInUsdWithCurrentQuotation(queryParams)); }
private PurchasePriceCountingResult CountVendorNetPriceInUsdWithCurrentQuotation( PurchasePriceCountingParams @params) { var result = new PurchasePriceCountingResult(); var orderedQuotationByWeight = @params.BillQuotations.OrderBy(v => v.EndWeight).ToList(); // get quotation by weight var quotationByWeight = orderedQuotationByWeight.FirstOrDefault(vq => vq.EndWeight >= @params.WeightInKg) ?? orderedQuotationByWeight.Last(); var countPerOneKg = quotationByWeight.StartWeight.HasValue; var quotationPriceInUsd = quotationByWeight.PriceInUsd ?? 0; this.Count(@params, countPerOneKg, quotationPriceInUsd, result); return(result); }
private void Count(PurchasePriceCountingParams @params, bool shouldCountPerOneKg, double quotationPriceInUsd, PurchasePriceCountingResult result, double?priceIncreasePercent = null) { var netPriceInUsd = !shouldCountPerOneKg ? quotationPriceInUsd : @params.WeightInKg * quotationPriceInUsd; var purchasePriceInUsd = netPriceInUsd + @params.OtherFeeInUsd; if (@params.FuelChargePercent > 0) { purchasePriceInUsd = purchasePriceInUsd * @params.FuelChargePercent; result.FuelChargeFeeInUsd = Math.Round(purchasePriceInUsd / 100, 4); result.FuelChargeFeeInVnd = (int)(result.FuelChargeFeeInUsd * @params.UsdExchangeRate); } var purchasePriceAfterVatInUsd = purchasePriceInUsd; if (@params.Vat.HasValue && @params.Vat.Value > 0) { purchasePriceAfterVatInUsd += purchasePriceInUsd * (@params.Vat.Value / 100); } result.PurchasePriceInUsd = Math.Round(purchasePriceInUsd, 4); result.PurchasePriceInVnd = (int)(purchasePriceInUsd * @params.UsdExchangeRate); result.PurchasePriceAfterVatInUsd = Math.Round(purchasePriceAfterVatInUsd, 4); result.PurchasePriceAfterVatInVnd = (int)(purchasePriceAfterVatInUsd * @params.UsdExchangeRate); if (priceIncreasePercent.HasValue && priceIncreasePercent.Value > 0) { result.PurchasePriceAfterVatInUsd += (result.PurchasePriceAfterVatInUsd * (priceIncreasePercent.Value / 100)); result.PurchasePriceAfterVatInVnd = (int)(result.PurchasePriceAfterVatInUsd * @params.UsdExchangeRate); } result.VendorNetPriceInUsd = Math.Round(netPriceInUsd, 4); result.QuotationPriceInUsd = quotationPriceInUsd; result.Service = @params.ServiceName; result.VendorId = @params.VendorId; }
/// <summary> /// PurchasePrice = ((NetPrice + OtherFee) * FuelChargePercent) * VAT * USD Exchange Rate /// Entry 1kg NetPrice = weight * Quotation Price /// Normal NetPrice = Quotation Price /// </summary> /// <param name="vendor"></param> /// <param name="params"></param> /// <param name="zone"></param> /// <param name="priceIncreasePercent"></param> /// <returns></returns> public PurchasePriceCountingResult CountVendorNetPriceInUsd(Vendor vendor, PurchasePriceCountingParams @params, Zone zone, double?priceIncreasePercent = null) { var result = new PurchasePriceCountingResult(); if (zone == null) { return(result); } result.ZoneName = zone.Name; if (vendor.VendorQuotations == null || !vendor.VendorQuotations.Any()) { return(result); } var orderedQuotationByWeight = vendor.VendorQuotations.OrderBy(v => v.EndWeight).ToList(); // get quotation by weight var quotationByWeight = orderedQuotationByWeight.FirstOrDefault(vq => (@params.WeightInKg >= vq.StartWeight || !vq.StartWeight.HasValue) && @params.WeightInKg <= vq.EndWeight); if (quotationByWeight == null) { return(result); } // get quotation by zone var fixedZone = quotationByWeight.ZonePrices.FirstOrDefault(z => z.ZoneId == zone.Id); if (fixedZone == null) { return(result); } var countPerOneKg = quotationByWeight.StartWeight.HasValue; var quotationPriceInUsd = fixedZone.PriceInUsd ?? 0; this.Count(@params, countPerOneKg, quotationPriceInUsd, result, priceIncreasePercent); var billQuotations = new List <BillQuotation>(); foreach (var vendorQuotation in orderedQuotationByWeight) { var price = vendorQuotation.ZonePrices.FirstOrDefault(z => z.ZoneId == zone.Id); billQuotations.Add(new BillQuotation { StartWeight = vendorQuotation.StartWeight, EndWeight = vendorQuotation.EndWeight, PriceInUsd = price?.PriceInUsd }); } result.BillQuotations = billQuotations.ToArray(); result.LastUpdatedQuotation = vendor.LastUpdatedQuotation; return(result); }
public Task <PurchasePriceCountingResult> CountPurchasePrice(PurchasePriceCountingParams queryParams) { return(this.billService.CountPurchasePriceAsync(this.UnitOfWork, queryParams)); }
public async Task <List <QuotationReport> > GetQuotationReport(QuotationReportParams queryParams) { var vendorRepository = this.UnitOfWork.GetRepository <Vendor>(); var availableVendors = await vendorRepository.GetQueryable() .Include(v => v.Zones) .Where(v => !v.IsStopped && v.Zones != null && v.Zones.Any()) .ToListAsync(); var vendorHasQuotations = availableVendors.Where(v => v.VendorQuotations != null && v.VendorQuotations.Any() && v.Zones.Any(z => z.Countries.Contains(queryParams.DestinationCountry))).ToList(); var increasePercent = await this.GetIncreasePercent(queryParams); var result = new List <QuotationReport>(); foreach (var vendor in vendorHasQuotations) { var report = new QuotationReport { VendorName = vendor.Name, OtherFeeInUsd = vendor.OtherFeeInUsd, FuelChargePercent = vendor.FuelChargePercent, }; var reportDetail = new List <QuotationReportDetail>(); var zonesByCountry = vendor.Zones.Where(z => z.Countries.Contains(queryParams.DestinationCountry)) .ToList(); foreach (var zone in zonesByCountry) { var zoneSplit = this.SplitZoneName(zone.Name); var countingParams = new PurchasePriceCountingParams { Vat = queryParams.Vat, UsdExchangeRate = queryParams.UsdExchangeRate, WeightInKg = queryParams.WeightInKg, DestinationCountry = queryParams.DestinationCountry, FuelChargePercent = vendor.FuelChargePercent ?? 0, OtherFeeInUsd = vendor.OtherFeeInUsd ?? 0 }; var price = this.billService.CountVendorNetPriceInUsd(vendor, countingParams, zone, increasePercent); if (price.PurchasePriceInUsd > 0) { reportDetail.Add(new QuotationReportDetail { Service = zoneSplit.serviceName, Zone = zoneSplit.zoneName, PurchasePriceInUsd = price.PurchasePriceInUsd, PurchasePriceInVnd = price.PurchasePriceInVnd, PurchasePriceAfterVatInUsd = price.PurchasePriceAfterVatInUsd, PurchasePriceAfterVatInVnd = price.PurchasePriceAfterVatInVnd, QuotationPriceInUsd = price.QuotationPriceInUsd, VendorNetPriceInUsd = price.VendorNetPriceInUsd }); } } if (reportDetail.Any()) { report.Quotation.AddRange(reportDetail.OrderBy(rd => rd.PurchasePriceAfterVatInVnd)); } if (report.Quotation.Any()) { result.Add(report); } } return(result.OrderBy(r => r.Quotation, new QuotationReportComparer()).ToList()); }