Automatic computation will often result in numbers requiring to be rounded. This note will show how to round properly in erp5 accounting.
Table of Contents
Inventory API¶
Inventory API¶ will support a precision= parameter, which can be used in getInventory, in that case, the query would be:
SELECT SUM(ROUND(stock.quantity, precision)) as inventory ....
getMovementHistoryList also support the precision= parameter, the query is:
SELECT ROUND(stock.quantity, precision) as total_quantity ....
The value we pass to precision= must be the result of resource.getQuantityPrecision(), delivery.getQuantityPrecisionFromResource(delivery.getResource()) or movement.getQuantityPrecisionFromResource(movement.getResource()).
Note: getQuantityPrecisionFromResource is here for performance, because the result is cached, and it does not need to access the resource object in the ZODB.
In single currency mode, Forms such as Account_viewAccountingTransactionList or Entity_viewAccountingTransactionList will use the precision defined on the default currency of the preferred section. This allows for producing a view which is compatible with fiscal rules.
In multiple currency mode, Forms such as Account_viewAccountingTransactionList or Entity_viewAccountingTransactionList will use the max of all precisions defined on all currencies. This allows for displaying debits and credits in a uniform way yet provide a view which is compatible with all currencies.
Reports like Trial Balance, General Ledger etc have to use the same quantity precision.
User Interface¶
Fields showing currency values should set the precision property according to the currency precision, for example, we can use:
python: here.getQuantityPrecisionFromResource(here.getResource())
FIXME: open problem, floatfields uses python representations, and sometimes displays scientific notation, like 10e9
Simulation¶
Q. Do we have to round in simulation movements ?
A. Probably not, because if you have 10 lines with qty 1 and price 0.001, with precision 2, your total price would be 0.
Q. Do we have to round after build accounting lines ?
A. Yes, and you may also want to change some quantities to make sure total debit == total credit. If you consider the following invoice lines, with a currency precision of 2:
invoice_line1
|
qty=1
|
price=0.023
|
resource=r1
|
invoice_line2
|
qty=1
|
price=0.033
|
resource=r2
|
if you have an invoice transaction rule like this one:
resource r1
|
source=account1
|
qty=1
|
source=account2
|
qty=-1
|
resource r2
|
source=account1
|
qty=1
|
source=account3
|
qty=-1
|
This will build:
node
|
quantity formula
|
quantity
|
account1
|
round(0.023 + 0.033, 2)
|
0.06
|
account2
|
round(0.023, 2)
|
-0.02
|
account3
|
round(0.033, 2)
|
-0.03
|
Here debit != credit. One solution is, in addition to rounding, adjust quantities to make debit == credit, taking care not to blindly round if debit really != credit due to misconfiguration.
Q. If we round some accounting lines quantities, delivery will be divergent, how to solve this ?
A. A good configuration of divergence tester can accept a quantity change with a delta under a certain value without making the movement divergent.
0.6 * resource.getBaseUnitQuantity() seems a good value
Related Articles¶