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);
        }