OCA / server-tools

Tools for Odoo Administrators to improve some technical features on Odoo.
https://odoo-community.org/psc-teams/tools-30
GNU Affero General Public License v3.0
688 stars 1.48k forks source link

RFC: sequence_nogap #2040

Open thomaspaulb opened 3 years ago

thomaspaulb commented 3 years ago

Odoo's ir.sequence nogap implementation is problematic, it can block the system. There's even a module that changes all the sequences by default to standard for this reason, so that nogap is avoided altogether. But, the standard implementation cannot guarantee sequential numbering, which is mandatory in some jurisdictions.

Together with someone who has worked with other enterprise software implentations requiring "nogap" sequences, we came up with the following design to implement a truly "nogap" sequence type.

The idea is that the next number is always next_number, unless there is any id in free_ids, then that one is given out first. Upon giving out, it's added to 'reserved_ids' together with the Postgres transaction id that's using it, like so:

[reserved_id, txid, reserved_id, txid, ...]

We implement this by overriding _next_do() and have it call our own function for "true_nogap" sequences:

We can then write a simple test:

Note: we have to pay some attention to correct handling of next_number when a sequence switches from one type to another.

hbrunn commented 1 year ago

as we discussed privately, this can cause invoices of an earlier date have a higher number than one of a later date, which might or might not be a problem depending on the legislation this happens in. If that's fine, I think your solution it beautiful technically.

Taking a step back, this is a technical problem created by law with how we do transactions and their rollbacks. If the letter of the law says: 'There must be an invoice document for every number', can't we simply when rolling back a transaction that has reserved a number create a 0 EUR invoice to some dummy partner with this number? This way we could just keep using the standard sequences, have fast transactions and adhere to the letter of the law. But before doing such a thing I'd like to hear from a person knowledgeable about some legislation where no gap is enforced if this would be accepted by accountants/tax office.

thomaspaulb commented 1 year ago

Have set out the question to financial people in several legislations. Copying the text of my question here for reference:

What we know is that the tax office in Netherlands says that invoice numbers must be consecutive within their sequence, and that no gaps may exist between them. We also assume that other countries have similar legislation.

But what we don't know is whether that legislation allows for leaving gaps, and filling those gaps at a later point in time, so for example:

10:14 INV1234 is created
10:20 INV1235 is created
10:24 Program claims the number INV1236 for 10 minutes. Tries to create INV1236, but fails to do so for some reason. Database transaction is rolled back.
10:25 INV1237 is created
10:30 INV1238 is created
10:34 The INV1236 number is freed up again and is now the first eligible free number in the pool
10:38 INV1236 is created
10:41 INV1239 is created

The end result will be a consecutive list of invoices in the system, but there will have been some "smuggling" done, which on closer inspection would be visible from the creation dates of the records. Is this, or is this not allowed? Could you point us to the legal texts in which the requirement is described?

Another suggestion by a colleague was to instead go for the simpler solution of:

10:14 INV1234 is created
10:20 INV1235 is created
10:24 Program tries to create INV1236, but fails to do so for some reason. Database transaction is rolled back. INV1236 is still created in the system, but as a dummy 0.00 invoice to a dummy customer, or even as a Cancelled invoice.
10:25 INV1237 is created
10:30 INV1238 is created
10:41 INV1239 is created

@hbrunn Note that the latter of the two solutions that was proposed by you, should we go for Cancelled invoices, is actually almost similar to a situation that you would encounter in real life with a nogap sequence. Transactions/invoices get cancelled all the time. And the records would be truly consecutive in this case, so it avoids the legal discussion as to which is the exact letter of the law. It could also be quite simple to implement that technically:

thomaspaulb commented 1 year ago

I've received reply from at least one accountant who prefers the second option:

The way I see it is that we can compare it to a manual invoice book (before systems) which will have been numbered in sequence. If I now skip a page (and invoice number) I will have record that there is no sales on that invoice number and would possibly strike through with a “cancelled” on the page to indicate that it was not used. Therefor I do not foresee a problem if we have the full sequence of our invoices with a start and end number for the period, and what we would see as “gaps” shows as “invoice not completed” with an audit trail. What I want to avoid is the system going back to a gap and then issuing it at a later transaction date, simply to fill the gaps.