在特定国家/地区交货时,从购物车总计中扣除税款

时间:2014-07-10 13:00:55

标签: c# nopcommerce

已更新

我正在开设一家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;
    }

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

2 个答案:

答案 0 :(得分:1)

除了 OrderTotalCalculationService 之外,您还应该查看 TaxService 。此外,按国家/地区分类插件应该足够灵活,以处理您提到的方案。

答案 1 :(得分:0)

@TomAalbers

我启用了默认的税收插件(Tax.CountryStateZip)&amp;成为主要的税务提供者。 我通过对免税的国家(现有)税收类别应用0%来配置插件。 对于我想要收税的国家,我已经设定了每个税种的百分比。

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