Reputation: 4924
I am working on a nopcommerce webshop which standard shows all his prices including taxes (21%). So the subtotals that are shown in the shopping cart have the taxes included. After the customer decided which products to buy and starts to finishing the order it should check the location of the customer (this by the shipping address)
What I am trying to do is when a customer is finishing up the order it should deduct (or not depending on what country the customer is living.) the taxes.
e.g when living in the Netherlands it should not deduct the taxes from the total order price but when living in the United States it should remove the 21% tax en deduct that from the total order price.
I've tried playing with some settings in the nop commerce admin in
Configuration -> Settings -> Tax Settings
My current tax settings are:
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
Also
Configuration -> Tax -> Tax Providers
Configuration -> Tax -> Tax Categories
Options for Tax providers are Fixed tax rate provider
and Tax By Country & State & Zip
(which is the primary provider)
I can't seem to find the right settings. Also I have tried to debug through the code in the OrderTotalCalculationService.cs
class which is used when finishing up the order. But I couldn't really find what struck me as the right code to look in.
I'm not sure if it is a settings problem or a code problem.
EDIT: Sorry that I didn't mention any code. But I've been looking through this function from 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;
}
This piece of code seems to calculate the total of the shoppingcart in the order flow. But I can't find the part that checks the shipping address and deducts the tax from the order total when in the united states. Does anybody know where the code checks for the tax?
Upvotes: 1
Views: 1084
Reputation: 10345
@TomAalbers
I enabled the default tax plugin (Tax.CountryStateZip) & made it primary tax provider. I configured the plugin by applying 0% on (existing) tax categories for the countries that are free from taxations. And for the countries I want to receive taxes I've set a percentage per tax category.
I hope this is clear, if not I can update my answer with screenshots.
Upvotes: 0
Reputation: 1364
Other than OrderTotalCalculationService, you should also be looking at TaxService. Also, Tax By Country plugin should be flexible enough to handle the scenario you mentioned.
Upvotes: 1