Tax is calculated on pre-discount amount

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
13 anos atrás
miles wrote:
well 1.8 is quite different to 1.7 when it comes to discounts I think - I'm talking specifically 1.8 here.

download it and take a peek. Dirty hacks are just that though, I feel filthy !

if you want to test your fix then try:

Product 1 (tax exempt) with a 10% discount at variant level
Product 2 (taxable)
15% voucher discount to whole cart

That should keep you busy, hehe


Damn! That doesn't work...

But I have an idea that may work. I have a meeting in a few mintues, so I'll try this a bit later today. I'm THINKING it will work, but I don't know.

What I'm going to do it keep a running total of taxable items (items, shipping, checkout atts) and use that instead of the subtotal. Then at the end I'll multiply taxTotal by the taxable percentage after discount. Sound good... we'll see if it works.
13 anos atrás
I have a working fix for this problem (tax based on pre-discount subtotal). I originally developed it for 1.70, but did not publish it here because it was supposed to be fixed in the current version (1.80). I just completed updating it for 1.80 and it works as a new discount type named "Applied to order subtotal" (reusing the name from the previous version). It doesn't replace the new nopCommerce discount type ("Applied to order total").

Since the discount applies to the subtotal, shipping and payment fees are not discounted and the tax is applied to the post-discount subtotal. It works with non-taxable products and products with different tax rates as well.

If anyone's interested, I can post the code here or submit it to the nopCommerce team.

.
13 anos atrás
hey mb, post the code here, I for one will buy you a drink ! (code for 1.7 and 1.8 would be great)
13 anos atrás
Ok... after going about it all wrong for two days, I finally figured out how to do this.

All you have to do it figure out what the discount percent is in relation to the order total (i.e. 20%, 30%) and multiply that by the tax total.

This fix requires minor changes to TaxManager.cs, ShoppingCartManager.cs, OrderTotals.ascx.cs, and OrderManager.cs.

The first thing you need to do is add the order subtotal to the GetTaxTotal method in TaxManager (around line 180).

public static decimal GetTaxTotal(ShoppingCart cart, int paymentMethodId, Customer customer, decimal OrderSubTotal, ref String error)
{
   ...
}

I use "OrderSubTotal", but you can use whatever you like.

This change will require fixing the broken method calls in other pages:

OrderManger.cs line 3095

paymentInfo.PaymentMethodId, customer, orderSubTotalExclTax, ref taxerror);

OrderTotals.ascx.cs line 143

decimal shoppingCartTaxBase = TaxManager.GetTaxTotal(cart, paymentMethodId, NopContext.Current.User, subtotalBaseWithoutPromo, ref TaxError);

ShoppingCartManager.cs line 342

decimal shoppingCartTax = TaxManager.GetTotalTax(cart, paymentMentodId, customer, subtotalBaseWithoutPromo, ref taxerror);

Next we go back to TaxManager and add this to the using/imports section:

using NopSolutions.NopCommerce.BusinessLogic.Promo.Discounts;

For the last step we go down to the end of GetTaxTotal (around line 276) and find the lines:

taxTotal = itemsTaxTotal + checkoutAttributesTax + shippingTax + paymentMethodAdditionalFeeTax;
taxTotal = Math.Round(taxTotal, 2);
return taxTotal;

and add a few lines in between them like this:

taxTotal = itemsTaxTotal + checkoutAttributesTax + shippingTax + paymentMethodAdditionalFeeTax;
Discount orderDiscount = null;
Decimal appliedDiscount = ShoppingCartManager.GetOrderDiscount(NopContext.Current.User, OrderSubTotal, out orderDiscount);
taxTotal = taxTotal - (taxTotal * (appliedDiscount / OrderSubTotal));
taxTotal = Math.Round(taxTotal, 2);
return taxTotal;

I'm using 1.70 by the way.

This fix presupposes that no matter what the total or tax or discount amount is, the discount CAN be broken down into a percent of the total. This discount percent is then subtracted from the tax total leaving you with the proper tax.

I know of one alternative way to get OrderSubTotal without having to add it to the GetTaxTotal method, but it requires totalling up the order myself inside GetTaxTotal and I didn't like that way. Does anyone know of a way to get the order subtotal without having to import it in using GetTaxTotal? I'd be happy to know that... otherwise this should work just fine.

I have it working correctly with a discount on product variants in a cart that has a discount code applied to it with two different taxes on two different items as well as and item that has no tax on it. And to the best of my knowledge, when I figure out what the tax should be with a calulator, it matches up.

Any problems with this, let me know.
13 anos atrás
good work Barry, that fixes it in 1.7 - feel free to collect a free drink next time you are in Herefordshire, UK :)

I made a small change  to your code in TaxManager.cs, added an if statement to prevent divide by zero error if you have 100% discount (i.e. free products)

if (taxTotal > 0)
{
     taxTotal = taxTotal - (taxTotal * (appliedDiscount / OrderSubTotal));
}



Look forward to seeing MB's code for 1.8
13 anos atrás
miles wrote:
good work Barry, that fixes it in 1.7 - feel free to collect a free drink next time you are in Herefordshire, UK :)

I made a small change  to your code in TaxManager.cs, added an if statement to prevent divide by zero error if you have 100% discount (i.e. free products)

if (taxTotal > 0)
{
     taxTotal = taxTotal - (taxTotal * (appliedDiscount / OrderSubTotal));
}

Look forward to seeing MB's code for 1.8


Thanks miles,

I thought of the divide by Zero error, but I figured that if there was no discount then it would be:

0 divided by ordersubtotal = 0 <-- fine

or if there was no subtotal there would be no discount... but what if it was a zero dollar order, then it would be:

0 divided by 0 = undefined :)

didn't think about totalTax being zero.

So maybe it also needs this:

if (taxtotal > 0)
{
   if (OrderSubTotal > 0) {
      taxTotal = taxTotal - (taxTotal * (appliedDiscount / OrderSubTotal));
   }
}

If you're giving away free stuff that requires tax...  :)

Anyway... what you said.
13 anos atrás
After seeing Barry's method of discounting the tax, I updated my version to implement the same logic (previously I was discounting individual cart items) as it is much simpler. Version 1.80 can display individual tax rates so I had to make a few changes. I'll update the install instructions and post the code later.

In the meantime, here is a screenshot of the subtotal discount in 1.80.

It shows two products; one is taxed at 10% and the other has a product variant discount of $1 and is taxed at %7. The checkout attribute of $5 is taxed at %5 ($.22 after discount). Shipping is also taxed at %5 ($.25, no discount). The payment method additional fee of  $10 is taxed at 10% ($1, no discount). The discount is fixed at $25 and only applies to the subtotal (cart items and checkout attributes).

.
13 anos atrás
bfranklin825 wrote:
...
taxTotal = itemsTaxTotal + checkoutAttributesTax + shippingTax + paymentMethodAdditionalFeeTax;
Discount orderDiscount = null;
Decimal appliedDiscount = ShoppingCartManager.GetOrderDiscount(NopContext.Current.User, OrderSubTotal, out orderDiscount);
taxTotal = taxTotal - (taxTotal * (appliedDiscount / OrderSubTotal));
taxTotal = Math.Round(taxTotal, 2);
return taxTotal;
...


Barry, you probably don't want to use taxTotal since it includes the shipping and payment method additional fee taxes and the shipping charges and payment method fees are not part of the OrderSubTotal.

.
13 anos atrás
mb wrote:
...
taxTotal = itemsTaxTotal + checkoutAttributesTax + shippingTax + paymentMethodAdditionalFeeTax;
Discount orderDiscount = null;
Decimal appliedDiscount = ShoppingCartManager.GetOrderDiscount(NopContext.Current.User, OrderSubTotal, out orderDiscount);
taxTotal = taxTotal - (taxTotal * (appliedDiscount / OrderSubTotal));
taxTotal = Math.Round(taxTotal, 2);
return taxTotal;
...

Barry, you probably don't want to use taxTotal since it includes the shipping and payment method additional fee taxes and the shipping charges and payment method fees are not part of the OrderSubTotal.

.


Are you talking about the underlined part? That was just what was there already, I hadn't even thought about what was or wasn't part of the subtotal... I may have to change that. You see, that is why an open source community is so good...

And by the way, I was doing it for each item at first too, but then I figured why do that when I can just do it on the total?
13 anos atrás
New code for the end:

Discount orderDiscount = null;
Decimal appliedDiscount = ShoppingCartManager.GetOrderDiscount(NopContext.Current.User, OrderSubTotal, out orderDiscount);
decimal taxSubtotal = itemsTaxTotal + checkoutAttributesTax;
taxSubtotal = taxSubtotal - (taxSubtotal * (appliedDiscount / OrderSubTotal));
taxTotal = taxSubtotal + shippingTax + paymentMethodAdditionalFeeTax;
taxTotal = Math.Round(taxTotal, 2);
return taxTotal;
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.