/// <summary> /// Gets tax total /// </summary> /// <param name="taxTotalRequest">Tax total request</param> /// <returns>Tax total</returns> public async Task <TaxTotalResult> GetTaxTotalAsync(TaxTotalRequest taxTotalRequest) { if (!(_httpContextAccessor.HttpContext.Items.TryGetValue("nop.TaxTotal", out var result) && result is TaxTotalResult taxTotalResult)) { var taxRates = new SortedDictionary <decimal, decimal>(); //order sub total (items + checkout attributes) var(_, _, _, _, orderSubTotalTaxRates) = await _orderTotalCalculationService .GetShoppingCartSubTotalAsync(taxTotalRequest.ShoppingCart, false); var subTotalTaxTotal = decimal.Zero; foreach (var kvp in orderSubTotalTaxRates) { var taxRate = kvp.Key; var taxValue = kvp.Value; subTotalTaxTotal += taxValue; if (taxRate > decimal.Zero && taxValue > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, taxValue); } else { taxRates[taxRate] = taxRates[taxRate] + taxValue; } } } //shipping var shippingTax = decimal.Zero; if (_taxSettings.ShippingIsTaxable) { var(shippingExclTax, _, _) = await _orderTotalCalculationService .GetShoppingCartShippingTotalAsync(taxTotalRequest.ShoppingCart, false); var(shippingInclTax, taxRate, _) = await _orderTotalCalculationService .GetShoppingCartShippingTotalAsync(taxTotalRequest.ShoppingCart, true); if (shippingExclTax.HasValue && shippingInclTax.HasValue) { shippingTax = shippingInclTax.Value - shippingExclTax.Value; if (shippingTax < decimal.Zero) { shippingTax = decimal.Zero; } if (taxRate > decimal.Zero && shippingTax > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, shippingTax); } else { taxRates[taxRate] = taxRates[taxRate] + shippingTax; } } } } //add at least one tax rate (0%) if (!taxRates.Any()) { taxRates.Add(decimal.Zero, decimal.Zero); } var taxTotal = subTotalTaxTotal + shippingTax; if (taxTotal < decimal.Zero) { taxTotal = decimal.Zero; } taxTotalResult = new TaxTotalResult { TaxTotal = taxTotal, TaxRates = taxRates }; _httpContextAccessor.HttpContext.Items.TryAdd("nop.TaxTotal", taxTotalResult); } //payment method additional fee if (taxTotalRequest.UsePaymentMethodAdditionalFee && _taxSettings.PaymentMethodAdditionalFeeIsTaxable) { var paymentMethodSystemName = taxTotalRequest.Customer != null ? await _genericAttributeService.GetAttributeAsync <string>(taxTotalRequest.Customer, NopCustomerDefaults.SelectedPaymentMethodAttribute, taxTotalRequest.StoreId) : string.Empty; var paymentMethodAdditionalFee = await _paymentService.GetAdditionalHandlingFeeAsync(taxTotalRequest.ShoppingCart, paymentMethodSystemName); var(paymentMethodAdditionalFeeExclTax, _) = await _taxService .GetPaymentMethodAdditionalFeeAsync(paymentMethodAdditionalFee, false, taxTotalRequest.Customer); var(paymentMethodAdditionalFeeInclTax, taxRate) = await _taxService .GetPaymentMethodAdditionalFeeAsync(paymentMethodAdditionalFee, true, taxTotalRequest.Customer); var paymentMethodAdditionalFeeTax = paymentMethodAdditionalFeeInclTax - paymentMethodAdditionalFeeExclTax; if (paymentMethodAdditionalFeeTax < decimal.Zero) { paymentMethodAdditionalFeeTax = decimal.Zero; } taxTotalResult.TaxTotal += paymentMethodAdditionalFeeTax; if (taxRate > decimal.Zero && paymentMethodAdditionalFeeTax > decimal.Zero) { if (!taxTotalResult.TaxRates.ContainsKey(taxRate)) { taxTotalResult.TaxRates.Add(taxRate, paymentMethodAdditionalFeeTax); } else { taxTotalResult.TaxRates[taxRate] = taxTotalResult.TaxRates[taxRate] + paymentMethodAdditionalFeeTax; } } } return(taxTotalResult); }