I'm not sure if this is a bug or if it is by design, but when you have a discount set using a code word/ the discount is applied AFTER the tax has been calculated on the order total. So this happens:
Order total: $10.00
Order Tax (7%): $0.70
Order discount (20%): $2.00
Order total after discount: $8.00
Order tax after discount: $0.70 <-- should be $0.56
Order total after discount plus tax: $8.70 <-- should be $8.56
The customer ends up paying tax on the discount, which is money that they don't have to pay - so why are they paying tax on it?? This may not be a big deal on small orders, but it makes a big difference in large orders. Not to mention the difference in tax amount if you have a payment processor that does its own tax calculation - like Paypal - and that calculation is different from nopCommerce's and the customer can see that.
Anyway... I have a fix for this, but it is complicated, maybe too complicated to post the code here... I don't think anyone would understand it. Is this something that an issue can be created for and the nopCommerce team can fix?
To explain shorty, my fix is this:
I send the OrderSubTotal with GetTaxTotal. I use OrderSubTotal and this code:
Discount orderDiscount; //<-- requires .promo.discounts import
Decimal appliedDiscount = decimal.Zero;
appliedDiscount = ShoppingCartManager.GetOrderDiscount(NopContext.Current.User, OrderSubTotal, out orderDiscount);
Decimal discountTax = 1m;
discountTax = discountTax - (appliedDiscount / OrderSubTotal);
to obtain discountTax, which is the percentage of the order that should be taxed. The formula goes:
OrderSubTotal ($10.00)
appliedDiscount ($2.00)
discountTax = 1 - ($2.00 / $10.00) = .80 <-- amount of order that should be charged tax
I then take discountTax and multiply it by the different tax totals at the end of each tax total section:
itemsTaxTotal = itemsTaxTotal * discountTax;
checkoutAttributesTax = checkoutAttributesTax * discountTax;
shippingTax = shippingTax * discountTax;
paymentMethodAdditionalFeeTax = paymentMethodAdditionalFeeTax * discountTax;
This gives me the correct amount of tax for each section, or so I thought. It turns out that there was a variance between this and what is SHOULD be. I found the variance when I noticed that TaxManager.GetPrice rounds the price... giving you something like this:
Price: $2.09
Tax: 7%
Price with tax (in decimal): 2.2363
GetPrice says: price = Math.Round(price, 2);
Price = $2.24
Difference = 0.0037
If you have a bunch of items this can add up. Even one penny off and it can lose you a sale with a customer.
I fixed this by adding a boolean flag to GetPrice called roundTax that determines if I need to round the tax or not. I had to do this for GetCheckoutAttributePrice too. In TaxManager the total tax is rounded before it is sent back, so each item does not need to be rounded individually.
If you understand that, you can fix it. If you don't then there is a LOT of code to post and you can try to figure out... or the nopCommerce team can fix it.
Can the nopCommerce team fix it?