Contributors mailing list archives


Accounting: writing on debit/credit fields

Alexinux, Alexis de Lattre
- 29/05/2019 12:48:26
Dear OCA friends,

Stéphane Bidoul and me would like to warn all Odoo developers about an important problem we found a few weeks ago with some of our customers using Odoo for their accounting. Let me explain the problem:

TL;DR: when you create/write an account.move.line, you MUST round the debit and credit before calling create/write.

If you are interested in the details, read on.

on account.move.line, the fields "debit" and "credit" are defined as fields.Monetary with currency_field='company_currency_id', cf

For a company with EUR currency, we have a decimal precision of 2. Technically, on a recordset of the EUR currency, the field decimal_places = 2.

The problem is the following: if you do:
   'account_id': 42,
   'name': 'TEST',
   'debit': 10.0 / 3,
   'credit': 0,
then, in the database, you get:
o2_test1=# select id, debit, credit from account_move_line where id=2;
 id |       debit        | credit
  2 | 3.3333333333333335 |    0.0

Then, if you use the OCA trial balance (with the module account_financial_report from, as the trial balance is doing sums in SQL but displays values with 2 digits, the total sum of the balance is not 0, but has a value of a few cents.

So, when you create/write an account.move.line, you MUST round the debit and credit before calling create/write.

In the OCA account_cutoff_prepaid, we computed some pro-rata to make the cutoff and then generate an account.move, and the code of that module didn't call round() on debit/credit before creating the account.move.
This was reported in this bug report:
It was fixed in v10 in this PR (still needs to be ported to other versions):
If you used account_cutoff_prepaid to generate journal entries, you certainly need to fix your debit/credit in the database. You can have a look at the script I used to fix the data and use it (at your own risks) :

We should also review all the OCA code that create account.move to see if the debit/credit are properly rounded before calling create/write.

So, for float fields with a decimal precision or monetary fields, the rounding is only done when you enter an amount via a form view, not when you call write/create nor when you read the data via a recordset. 
As you can see in the ORM in the Monetary class (same for Float), the method convert_to_cache() as a rounding logic, but not the convert_to_write(), cf :

We talked about this problem with Joss from Odoo SA ; he is now aware of this problem and will talk about it with his collegues.

Alexis de Lattre