示例#1
0
        public async Task <TaxTotalResult> GetTaxTotalAsync(TaxTotalRequest taxTotalRequest)
        {
            if (_httpContextAccessor.HttpContext.Items.TryGetValue("nop.TaxTotal", out var result) &&
                result is (TaxTotalResult taxTotalResult, decimal paymentTax))
            {
                //short-circuit to avoid circular reference when calculating payment method additional fee during the checkout process
                if (!taxTotalRequest.UsePaymentMethodAdditionalFee)
                {
                    return new TaxTotalResult {
                               TaxTotal = taxTotalResult.TaxTotal - paymentTax
                    }
                }
                ;

                return(taxTotalResult);
            }

            var taxRates = new SortedDictionary <decimal, decimal>();
            var taxTotal = decimal.Zero;

            taxTotal += await GetSubtotalTaxTotalAsync(taxRates, taxTotalRequest);

            taxTotal += await GetShippingTaxAsync(taxRates, taxTotalRequest);

            //short-circuit to avoid circular reference when calculating payment method additional fee during the checkout process
            if (!taxTotalRequest.UsePaymentMethodAdditionalFee)
            {
                return new TaxTotalResult {
                           TaxTotal = taxTotal
                }
            }
            ;

            var paymentMethodAdditionalFeeTax = await GetPaymentMethodAdditionalFeeTaxAsync(taxRates, taxTotalRequest);

            taxTotal += paymentMethodAdditionalFeeTax;

            //add at least one tax rate (0%)
            if (!taxRates.Any())
            {
                taxRates.Add(decimal.Zero, decimal.Zero);
            }

            if (taxTotal < decimal.Zero)
            {
                taxTotal = decimal.Zero;
            }

            taxTotalResult = new TaxTotalResult {
                TaxTotal = taxTotal, TaxRates = taxRates,
            };

            //store values within the scope of the request to avoid duplicate calculations
            _httpContextAccessor.HttpContext.Items.TryAdd("nop.TaxTotal", (taxTotalResult, paymentMethodAdditionalFeeTax));

            return(taxTotalResult);
        }
示例#2
0
        /// <summary>
        /// Gets tax total
        /// </summary>
        /// <param name="taxTotalRequest">Tax total request</param>
        /// <returns>
        /// A task that represents the asynchronous operation
        /// The task result contains the ax total
        /// </returns>
        public async Task <TaxTotalResult> GetTaxTotalAsync(TaxTotalRequest taxTotalRequest)
        {
            //cache tax total within the request
            var key = $"nop.TaxTotal-{taxTotalRequest.UsePaymentMethodAdditionalFee}";

            if (!(_actionContextAccessor.ActionContext.HttpContext.Items.TryGetValue(key, out var result) &&
                  result is TaxTotalResult taxTotalResult))
            {
                //create a transaction
                var transaction = await _avalaraTaxManager.CreateTaxTotalTransactionAsync(taxTotalRequest);

                if (transaction?.totalTax == null)
                {
                    return new TaxTotalResult {
                               Errors = new List <string> {
                                   "No response from the service"
                               }
                    }
                }
                ;

                //and get tax details
                taxTotalResult = new TaxTotalResult {
                    TaxTotal = transaction.totalTax.Value
                };
                transaction.summary?
                .Where(summary => summary.rate.HasValue && summary.tax.HasValue)
                .Select(summary => new { Rate = summary.rate.Value * 100, Value = summary.tax.Value })
                .ToList().ForEach(taxRate =>
                {
                    if (taxTotalResult.TaxRates.ContainsKey(taxRate.Rate))
                    {
                        taxTotalResult.TaxRates[taxRate.Rate] += taxRate.Value;
                    }
                    else
                    {
                        taxTotalResult.TaxRates.Add(taxRate.Rate, taxRate.Value);
                    }
                });

                _actionContextAccessor.ActionContext.HttpContext.Items.TryAdd(key, taxTotalResult);
            }

            return(taxTotalResult);
        }
        /// <summary>
        /// Gets tax total
        /// </summary>
        /// <param name="taxTotalRequest">Tax total request</param>
        /// <returns>Tax total</returns>
        public TaxTotalResult GetTaxTotal(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)
                _orderTotalCalculationService
                .GetShoppingCartSubTotal(taxTotalRequest.ShoppingCart, false, out _, out _, out _, out _, out var orderSubTotalTaxRates);
                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 = _orderTotalCalculationService
                                          .GetShoppingCartShippingTotal(taxTotalRequest.ShoppingCart, false, out _);
                    var shippingInclTax = _orderTotalCalculationService
                                          .GetShoppingCartShippingTotal(taxTotalRequest.ShoppingCart, true, out var taxRate);
                    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
                    ? _genericAttributeService.GetAttribute <string>(taxTotalRequest.Customer,
                                                                     NopCustomerDefaults.SelectedPaymentMethodAttribute, taxTotalRequest.StoreId)
                    : string.Empty;

                var paymentMethodAdditionalFee        = _paymentService.GetAdditionalHandlingFee(taxTotalRequest.ShoppingCart, paymentMethodSystemName);
                var paymentMethodAdditionalFeeExclTax = _taxService
                                                        .GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, false, taxTotalRequest.Customer, out _);
                var paymentMethodAdditionalFeeInclTax = _taxService
                                                        .GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, true, taxTotalRequest.Customer, out var taxRate);
                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);
        }
 /// <summary>
 /// Ctor
 /// </summary>
 /// <param name="taxTotalRequest">Tax total request</param>
 /// <param name="taxTotalResult">Tax total result</param>
 public TaxTotalCalculatedEvent(TaxTotalRequest taxTotalRequest, TaxTotalResult taxTotalResult)
 {
     TaxTotalRequest = taxTotalRequest;
     TaxTotalResult  = taxTotalResult;
 }
        /// <summary>
        /// Gets tax total
        /// </summary>
        /// <param name="taxTotalRequest">Tax total request</param>
        /// <returns>
        /// A task that represents the asynchronous operation
        /// The task result contains the ax total
        /// </returns>
        public async Task <TaxTotalResult> GetTaxTotalAsync(TaxTotalRequest taxTotalRequest)
        {
            if (_httpContextAccessor.HttpContext.Items.TryGetValue("nop.TaxTotal", out var result) &&
                result is (TaxTotalResult taxTotalResult, decimal paymentTax))
            {
                //short-circuit to avoid circular reference when calculating payment method additional fee during the checkout process
                if (!taxTotalRequest.UsePaymentMethodAdditionalFee)
                {
                    return new TaxTotalResult {
                               TaxTotal = taxTotalResult.TaxTotal - paymentTax
                    }
                }
                ;

                return(taxTotalResult);
            }

            var taxRates = new SortedDictionary <decimal, decimal>();
            var taxTotal = decimal.Zero;

            //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;
                    }
                }
            }
            taxTotal += subTotalTaxTotal;

            //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;
                        }
                    }
                }
            }
            taxTotal += shippingTax;

            //short-circuit to avoid circular reference when calculating payment method additional fee during the checkout process
            if (!taxTotalRequest.UsePaymentMethodAdditionalFee)
            {
                return new TaxTotalResult {
                           TaxTotal = taxTotal
                }
            }
            ;

            //payment method additional fee
            var paymentMethodAdditionalFeeTax = decimal.Zero;

            if (_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);

                paymentMethodAdditionalFeeTax = paymentMethodAdditionalFeeInclTax - paymentMethodAdditionalFeeExclTax;
                if (paymentMethodAdditionalFeeTax < decimal.Zero)
                {
                    paymentMethodAdditionalFeeTax = decimal.Zero;
                }

                if (taxRate > decimal.Zero && paymentMethodAdditionalFeeTax > decimal.Zero)
                {
                    if (!taxRates.ContainsKey(taxRate))
                    {
                        taxRates.Add(taxRate, paymentMethodAdditionalFeeTax);
                    }
                    else
                    {
                        taxRates[taxRate] = taxRates[taxRate] + paymentMethodAdditionalFeeTax;
                    }
                }
            }
            taxTotal += paymentMethodAdditionalFeeTax;

            //add at least one tax rate (0%)
            if (!taxRates.Any())
            {
                taxRates.Add(decimal.Zero, decimal.Zero);
            }

            if (taxTotal < decimal.Zero)
            {
                taxTotal = decimal.Zero;
            }

            taxTotalResult = new TaxTotalResult {
                TaxTotal = taxTotal, TaxRates = taxRates,
            };

            //store values within the scope of the request to avoid duplicate calculations
            _httpContextAccessor.HttpContext.Items.TryAdd("nop.TaxTotal", (taxTotalResult, paymentMethodAdditionalFeeTax));

            return(taxTotalResult);
        }
 /// <summary>
 /// Ctor
 /// </summary>
 /// <param name="taxTotalResult">Tax total result</param>
 public TaxTotalCalculatedEvent(TaxTotalResult taxTotalResult)
 {
     TaxTotalResult = taxTotalResult;
 }