mollie / mollie-api-python

Mollie API client for Python
http://www.mollie.com
BSD 2-Clause "Simplified" License
113 stars 55 forks source link

VAT calculations #158

Closed dmalis closed 4 years ago

dmalis commented 4 years ago

Expected VAT amount to be 6.50 (38.97 (20.00% / 120.00%)), got 6.49.

38.97 * (20.0 / (100.0 + 20.0)) 6.494999999999999 round that to 2 decimals -> 6.49 not 6.50

How does your server calculate vat amount to 6.50 from provided 38.97 and 20% vat rate?

dmalis commented 4 years ago

Assuming money amounts are handled with 4 decimal precision

round(38.97 * (20.0 / (100.0 + 20.0)), 4) -> 6.495 -> round(6.495, 2) -> 6.5

whyscream commented 4 years ago

The calculation of VAT amounts is done in the API, not in the API client. The VAT calculation itself is documented at f.i. https://docs.mollie.com/reference/v2/orders-api/create-order (search for vatAmount).

Regarding your python code, I can say that using float for money calulation is in general a recipe for disaster. You should use Decimal for everything, and control everything as you need:

Python 3.8.2 (default, Feb 26 2020, 02:56:10) 
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> amount = decimal.Decimal("38.97")
>>> vat_amount = amount * (decimal.Decimal("0.20") / decimal.Decimal("1.20"))
>>> vat_amount
Decimal('6.495000000000000000000000001')
>>> vat_amount.quantize(decimal.Decimal("0.01"), decimal.ROUND_HALF_UP)
Decimal('6.50')
dmalis commented 4 years ago

Understood and thank you - much appreciated.