WooCommerce calculates the VAT (in this case 20%) per line (wrong), but really should calculate VAT per item (right).
For example, we have a product that is 0.13p (excl VAT), which shows as 0.16p (inc VAT) on the frontend. This is fine as 0.13p + 20% = 0.156p and is rounded up to 0.16p. If you add 5 of these to the cart you would expect to see 0.16p x 5 = 0.80p but instead we get 0.78p. My guess is that WooCommerce is calculating the VAT per line and not per item (e.g. 0.13p x 5 = 0.65p and then 0.65p + 20% = 0.78p). See below.Wrong Amount
I have tried all sorts of different settings with no success, this is how they are now (see pic attached).Tax Settings
Has anyone experienced the same issue? Have you found a solution? Obviously, I can't launch this with such a bug.. Many thanks!
Related
I'm using Zapier to export orders from WooCommerce to my account software when an order is created. The data is sent via WooCommerce REST API.
Everything works fine but I noticed that the unit price in the order meta data sometimes displays product prices with more than 2 decimal places. This happens when more than one of the same item is ordered. It seems to always happen when the item price has two decimal places and is ordered in multiples of odd numbers.
My accounting software only accepts up to 2 decimal places. So there is an error every time the unit price has more than two decimal places. This is how I discovered this issue.
I have checked the item price and the prices are correct. I also tested by enabling and disabling "Round tax at subtotal level, instead of rounding per line". Nothing seems to resolve the issue.
I would like to filter the unit price when an order is generated in WooCommerce so that they are converted to two decimal places. Any thoughts or suggestions on how to go about resolving this would be appreciated.
Here is an example of just one order where the item is displaying with more than 2 decimal places:
isCreditInvoice:false
customer:d58ca99b-07f3-45fa-80ae-164ebbc881f1
invoiceDate:2021-03-07T09:18:06+02:00
quantity:1,1,1,1,1,1,2,6,6,5,7,7,4,10,10,1,1,1,1,1,1,1,1
yourReference:Order Number 6631
deliveryDate:{{111079934__date_completed}}
ourReference:Order Number 6631
unitPrice:22.5,22.5,26.25,25,34.95,34.95,23.76,6.95,6.95,6.95,9.950000000000001,9.950000000000001,9.95,1.6,1.6,14.95,23.4,8.4,30,21.36,25,12.5,26.5
Update: This is a WooCommerce Plugin Core issue and has already been reported to WooCommerce on Github
https://github.com/woocommerce/woocommerce/issues/27911
Use the following patch to temporarily fix the issue:
Navigate to line 172 of woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php
Replace:
$data['price'] = $item->get_quantity() ? $item->get_total() / $item->get_quantity() : 0;
With:
$data['price'] = $item->get_quantity() ? wc_format_decimal( $item->get_total() / $item->get_quantity() ): 0;
Tested and works.
Now the unitPrice will be rounded to two decimal places.
I am using WooCommerce Points and Rewards plugin. The issue I have is when applying points to cart, it is rounding up to the nearest integer. I would like for it to apply in cents.
For example: 10 points = 1 dollar. If customer has 11 points so the discount should be $1.10, but not $2.00. I've looked through the plugin code but do not see where this is being force to round up.
Any advise or thoughts?
This plugin round the points on the displayed cart notice… You can't apply in cents… You can only tune in the plugin settings the "Earn Points Rounding Mode" and the best round mode is: "Round to nearest integer"…
What you can do is to fix a minimal number of points to get the discount and display the related notice with the folowing code (Fixed to 100 points below):
// Points and rewards conditional redeem points message display up to 100 points
add_filter( 'wc_points_rewards_redeem_points_message', 'conditional_redeem_points_message', 10, 2 );
function conditional_redeem_points_message( $message, $discount_available ){
$points = WC_Points_Rewards_Manager::calculate_points_for_discount( $discount_available );
if( $points >= 100 )
return $message;
else
return '';
}
And in the plugin settings you will Fix the same number for "Maximum Points Discount".
So the notice will be displayed only for this minimal number of points and the available cart discount will be a real corresponding integer amount…
I haven't find already another way.
On my Woocommerce shop I have a percentage based shipping cost. The percentage is set to 5 ([fee percent="5"]) which returns a wrong calculation, but interestingly enough it seems to be the separator that is placed wrong (see attached example). 5% in the example is 14.5 GBP, but Woocommerce returns the calculation as 1.45.
Any suggestions?
THANKS
i am working on a plugin for prestashop, i am done with it, but i have stumbled on to an issue.
The program flow is as follows:
A person places an order at the eCommerce website, the order is accepted, the order details such as items, prices, taxes, discounts etc is send to an external invoice API service.
An example of an order could be:
(These prices include taxes)
1x T-shirt 20.64
1x Shipping 125
1x Discount -18.58
(In this particular test case, the discount is 90% off the product, the math is simple 20.64 * 0.90 = 18.58)
Order total after tax is applied: 127.06
This is all fine, but, when i send the details off to the API, the order is saved as the following:
(These prices are saved without tax applied, the tax rate being 25%)
1x T-shirt 16.51
1x Shipping 100
1x Discount -14
Order total after tax is applied: 128.14
As you see, the order totals do not mach, the difference is 1.08, i am thinking this a discount & tax issue.
Its worth noting that the external site does its own math on the values sent, e.g products, tax etc. I cannot influence the way the external invoicing site does its calculations. I think the issue occurs in the order of which the operations are performed on the different platforms.
Its also worth mentioning that the code works perfectly fine when there is no discount present.
What can i do prior to sending the values, so that i get the prestashop price at the external service?
Let the value of the items be v_1 (t-shirt), v_2 (shipping) untaxed values, respectively.
Case 1.
1.25*v_1+1.25*v_2-0.9*1.25*v_1 = 127.06
Case 2 (tax at end)
(v_1+v_2-0.9*v_1)*1.25 = Same as Case 1 after expanding the brackets.
The figure which is amiss is, as you suggest, the -14 discount, which is more like -0.9*16.51=-14.86.
1.08 difference
There is a difference of 86 cents/pence, whatever, between the untaxed discount values. After taxes this difference grows to, 0.86*1.25=1.08, which explains the discrepancy.
To fix the code, the discount calculation needs to be fixed, unless there are other tax considerations that apply to discounts, etc. In other words why is -14 being used, rather than -14.86?
To you second point about the order of events, this should not impact anything - unless discounts are taxed differently.
Fix
Either
The discount calculation is wrong (i.e. 14 should be 14.86), or
The discount value of 14 is correct, in which case a different (tax/discount) methodology than what is being assumed and this needs to be ascertained before you can make a fix for it.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I allow users to enter prices of products into an inventory, in either NET or Gross. If they enter the price in Gross, the NET is computed for them before being stored and uses the following code:
var vatrate = 12;
IsuppGross = parseInt(suppGross * 100); // makes it an integer
// calc net
var revVR = parseFloat('1.'+vatrate);
Net = ( ( IsuppGross / revVR) / 100 ).toFixed(2);
I struggled to get that working and am not sure if that is where the problem lies.
If I enter '100.00' as a gross figure and my VAT rate is 12%, it returns Net as '112.00', so it seems to be working.
So I enter a product with a Gross price of $100.00 and the net price is computed to be '$89.29' (which I'm assuming to right).
When creating an invoice for 10 of the above items, the bottom of the invoice looks like this:
Net Subtotal $892.90
VAT $107.15
Grand Total $1000.05
What I am expecting is:
Net Subtotal $892.90
VAT $107.10
Grand Total $1000.00
...especially since, when selling just one of the above, results in:
Net Subtotal $89.29
VAT $10.71
Grand Total $100.00
...which expected. It would therefore be reasonable to assume that purchasing 10 of the same items, would cost exactly ten times as much.
Here is the formula I'm using to add the VAT to the Net subtotal:
quantity x net price x 0.12 (10 x 89.29 x 0.12) = 107.148
The above then rounds to 107.15 which when added to the net subtotal is 1000.05.
What formula do I need to arrive at 1000 when I add the VAT back on please?
To Summarize / Clarify
This formula...
quantity x net price x 0.12 (10 x 89.29 x 0.12)
Gives me 107.148, but what I think I need it to give me is 107.10 instead.
So what javascript function can I used to make that happen (or how do I need to adjust my formula / convert it to code)?
UPDATE
#jakub is on the right track I think. I've found an easy way to test it by doing something like:
alert( (892.90 * 0.12).toFixed(2) ); // should equal 107.10
(still equals 107.15)
The above was based on input from Jakub, below. Notice that I'm not multiplying by 10 separately here, because I noticed that we're working at the subtotal level.
One way to do that would be to put rounding at a different place
round(quantity * price) != quantity * round(price)
The same goes for VAT, rounding the result is slightly different from rounding VAT from one product and then multiplying by quantity. Also, you know, that quantity has to be an integer, not a float (if not, it is a different case), so multiplying after rounding should never produce more decimal places.
I hope this helps a little bit.
Ok, to respond to your edit:
You have
(quantity * price * VAT).toFixed(2) = (10 * 89.29 * 0.12).toFixed(2) = (107.148).toFixed(2) = 107.15
You should have
quantity * (price * VAT).toFixed(2) = 10 * (89.29 * 0.12).toFixed(2) = 10 * (10.7148).toFixed(2) = 10 * 10.71 = 107.10
I think I'm correct in saying that the legal position is that the VAT amount invoiced must be the correct percentage of the goods & services invoiced, so one should not sum the VAT-inclusive line-item prices.
One system I worked on which showed VAT per line modified the last line's VAT amount to eliminate rounding errors. They will always be there unless you show your prices with 5 decimal places (assuming you have a VAT rate with 3 significant digits).
Basically the reason for this issue is that the computer is not able to represent most base 10 real numbers using floating point numbers, since the computer uses base 2.
Check this thread:
Why not use Double or Float to represent currency?
So one first step is to always use integers for the currency, in this case measured in cents instead of dollars, I presume.