【问题标题】:Deduct taxes from shopping cart total when delivery is in certain country在特定国家/地区交货时从购物车总额中扣除税款
【发布时间】:2014-07-10 13:00:54
【问题描述】:

我正在开发一个 nopcommerce 网上商店,该网上商店的标准显示他的所有价格包括税 (21%)。因此,购物车中显示的小计已包含税费。在客户决定购买哪些产品并开始完成订单后,它应该检查客户的位置(通过送货地址)

我想要做的是当客户完成订单时它应该扣除(或不取决于客户居住的国家/地区)税。

例如,如果居住在荷兰,则应该从总订单价格中扣除税款,但如果居住在美国,则应该取消 21% 的税款,然后从总订单价格中扣除该税款。

我尝试过在 nop commerce 管理中使用一些设置

 Configuration -> Settings -> Tax Settings

我目前的税务设置是:

Prices include tax: YES
Allow customers to select tax display type: NO
Tax display type: Including Tax
Display tax suffix: YES
Display all applied tax rates: YES
Hide zero tax: NO
Hide tax in order summary: NO
Force tax exclusion from order subtotal: NO
Tax based on: Shipping address
Country: Netherlands
Shipping is taxable: YES
Shipping price includes tax: YES
Payment method additional fee is taxable: YES
Payment method additional fee includes tax: YES
EU VAT enabled: NO

还有

 Configuration -> Tax -> Tax Providers
 Configuration -> Tax -> Tax Categories

税务提供者的选项是 Fixed tax rate providerTax By Country & State & Zip(这是主要提供者)

我似乎找不到正确的设置。我还尝试通过在完成订单时使用的OrderTotalCalculationService.cs 类中的代码进行调试。但我真的找不到让我印象深刻的正确代码。

我不确定是设置问题还是代码问题。

编辑:对不起,我没有提到任何代码。但我一直在查看 nopcommerce 的这个功能。

    public virtual decimal? GetShoppingCartTotal(IList<ShoppingCartItem> cart,
        out decimal discountAmount, out Discount appliedDiscount,
        out List<AppliedGiftCard> appliedGiftCards,
        out int redeemedRewardPoints, out decimal redeemedRewardPointsAmount,
        bool ignoreRewardPonts = false, bool usePaymentMethodAdditionalFee = true)
    {
        redeemedRewardPoints = 0;
        redeemedRewardPointsAmount = decimal.Zero;

        var customer = cart.GetCustomer();
        string paymentMethodSystemName = "";
        if (customer != null)
        {
            paymentMethodSystemName = customer.GetAttribute<string>(
                SystemCustomerAttributeNames.SelectedPaymentMethod,
                _genericAttributeService,
                _storeContext.CurrentStore.Id);
        }


        //subtotal without tax
        decimal subtotalBase = decimal.Zero;
        decimal orderSubTotalDiscountAmount = decimal.Zero;
        Discount orderSubTotalAppliedDiscount = null;
        decimal subTotalWithoutDiscountBase = decimal.Zero;
        decimal subTotalWithDiscountBase = decimal.Zero;
        GetShoppingCartSubTotal(cart, false,
            out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscount,
            out subTotalWithoutDiscountBase, out subTotalWithDiscountBase);
        //subtotal with discount
        subtotalBase = subTotalWithDiscountBase;



        //shipping without tax
        decimal? shoppingCartShipping = GetShoppingCartShippingTotal(cart, false);



        //payment method additional fee without tax
        decimal paymentMethodAdditionalFeeWithoutTax = decimal.Zero;
        if (usePaymentMethodAdditionalFee && !String.IsNullOrEmpty(paymentMethodSystemName))
        {
            decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, paymentMethodSystemName);
            paymentMethodAdditionalFeeWithoutTax = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee,
                false, customer);
        }




        //tax
        decimal shoppingCartTax = GetTaxTotal(cart, usePaymentMethodAdditionalFee);




        //order total
        decimal resultTemp = decimal.Zero;
        resultTemp += subtotalBase;
        if (shoppingCartShipping.HasValue)
        {
            resultTemp += shoppingCartShipping.Value;
        }
        resultTemp += paymentMethodAdditionalFeeWithoutTax;
        resultTemp += shoppingCartTax;
        if (_shoppingCartSettings.RoundPricesDuringCalculation) 
            resultTemp = Math.Round(resultTemp, 2);

        #region Order total discount

        discountAmount = GetOrderTotalDiscount(customer, resultTemp, out appliedDiscount);

        //sub totals with discount        
        if (resultTemp < discountAmount)
            discountAmount = resultTemp;

        //reduce subtotal
        resultTemp -= discountAmount;

        if (resultTemp < decimal.Zero)
            resultTemp = decimal.Zero;
        if (_shoppingCartSettings.RoundPricesDuringCalculation) 
            resultTemp = Math.Round(resultTemp, 2);

        #endregion

        #region Applied gift cards

        //let's apply gift cards now (gift cards that can be used)
        appliedGiftCards = new List<AppliedGiftCard>();
        if (!cart.IsRecurring())
        {
            //we don't apply gift cards for recurring products
            var giftCards = _giftCardService.GetActiveGiftCardsAppliedByCustomer(customer);
            if (giftCards!=null)
                foreach (var gc in giftCards)
                    if (resultTemp > decimal.Zero)
                    {
                        decimal remainingAmount = gc.GetGiftCardRemainingAmount();
                        decimal amountCanBeUsed = decimal.Zero;
                        if (resultTemp > remainingAmount)
                            amountCanBeUsed = remainingAmount;
                        else
                            amountCanBeUsed = resultTemp;

                        //reduce subtotal
                        resultTemp -= amountCanBeUsed;

                        var appliedGiftCard = new AppliedGiftCard();
                        appliedGiftCard.GiftCard = gc;
                        appliedGiftCard.AmountCanBeUsed = amountCanBeUsed;
                        appliedGiftCards.Add(appliedGiftCard);
                    }
        }

        #endregion

        if (resultTemp < decimal.Zero)
            resultTemp = decimal.Zero;
        if (_shoppingCartSettings.RoundPricesDuringCalculation)
            resultTemp = Math.Round(resultTemp, 2);

        decimal? orderTotal = null;
        if (!shoppingCartShipping.HasValue)
        {
            //return null if we have errors
            orderTotal = null;
            return orderTotal;
        }
        else
        {
            //return result if we have no errors
            orderTotal = resultTemp;
        }

        #region Reward points

        if (_rewardPointsSettings.Enabled && 
            !ignoreRewardPonts &&
            customer.GetAttribute<bool>(SystemCustomerAttributeNames.UseRewardPointsDuringCheckout,
            _genericAttributeService, _storeContext.CurrentStore.Id))
        {
            int rewardPointsBalance = customer.GetRewardPointsBalance();
            if (CheckMinimumRewardPointsToUseRequirement(rewardPointsBalance))
            {
                decimal rewardPointsBalanceAmount = ConvertRewardPointsToAmount(rewardPointsBalance);
                if (orderTotal.HasValue && orderTotal.Value > decimal.Zero)
                {
                    if (orderTotal.Value > rewardPointsBalanceAmount)
                    {
                        redeemedRewardPoints = rewardPointsBalance;
                        redeemedRewardPointsAmount = rewardPointsBalanceAmount;
                    }
                    else
                    {
                        redeemedRewardPointsAmount = orderTotal.Value;
                        redeemedRewardPoints = ConvertAmountToRewardPoints(redeemedRewardPointsAmount);
                    }
                }
            }
        }
        #endregion

        if (orderTotal.HasValue)
        {
            orderTotal = orderTotal.Value - redeemedRewardPointsAmount;
            if (_shoppingCartSettings.RoundPricesDuringCalculation) 
                orderTotal = Math.Round(orderTotal.Value, 2);
            return orderTotal;
        }
        else
            return null;
    }

这段代码似乎计算了订单流中购物车的总数。但是我在美国找不到检查送货地址并从订单总额中扣除税款的部分。有人知道代码在哪里查税吗?

【问题讨论】:

  • 这个问题似乎是题外话,因为它是关于 NOPCommerce 的管理。
  • 它与代码无关。我们是一个关于编程的 QA 网站。
  • 好吧,老实说,这似乎是一个编程问题。考虑到他查看了OrderTotalCalculationService.cs,这似乎是 NopCommerce 的 TaxProvider 插件的问题。 @Tom:你调试过CountryStateZip plugin 做了什么吗?
  • 我已经更新了我的问题
  • 这对 SO 来说绝对是个好问题。因为他试图通过代码解决问题,而不仅仅是通过 nop 的管理员

标签: c# nopcommerce


【解决方案1】:

除了 OrderTotalCalculationService,您还应该查看 TaxService。此外,Tax By Country 插件应该足够灵活,可以处理您提到的场景。

【讨论】:

    【解决方案2】:

    @TomAalbers

    我启用了默认税务插件 (Tax.CountryStateZip) 并使其成为主要税务提供商。 我通过对免税国家/地区的(现有)税收类别应用 0% 来配置插件。 对于我想收税的国家/地区,我为每个税种设置了一个百分比。

    我希望这很清楚,如果不是,我可以用屏幕截图更新我的答案。

    【讨论】:

      猜你喜欢
      • 2021-06-10
      • 2018-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-17
      相关资源
      最近更新 更多