Never rewrite the lines of a validated invoice - #40
Open
Pichinov-Jose wants to merge 1 commit into
Open
Pichinov-Jose wants to merge 1 commit into
Pichinov-Jose wants to merge 1 commit into
Conversation
Invoice lines are written with FactureLigne::update() / insert() and Facture::update_price(), which do not check the invoice status the way Facture::updateline() / addline() do. When the invoice does not go back to draft first, the source's lines land in the validated invoice: amounts change under the same reference, and nothing reaches the unalterable log because BILL_MODIFY is not a logged event. The invoice status is captured when payments are loaded, before the request writes anything. An invoice that was already validated when loaded, and is still not a draft when its lines arrive, keeps them as issued; the source's lines are ignored with a warning. Invoices created by the request, invoices that did go back to draft, orders, quotes and supplier orders are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
BaseItemsTrait::setItemsFields()writes invoice lines withFactureLigne::update()/insert()and then callsFacture::update_price(). UnlikeFacture::updateline()/addline(), none of these check the invoice status.As a result, when a source order changes after invoicing, its lines are written into the validated invoice whenever the invoice does not go back to draft first. That happens when the source status keeps it validated or paid, or when the back-to-draft is refused, as proposed in #38.
The amounts change under the same reference. Nothing reaches the unalterable log, because
BILL_MODIFYis not a logged event. The only trace is an agenda eventAC_BILL_MODIFYby the Splash user.Seen in production (Dolibarr 23, Splash 2.23.3, WooCommerce, blockedlog active):
With the unalterable log active — mandatory in France — a validated invoice must never be edited. A change made in the source after invoicing must become a credit note.
Fix
loadPayments()records the invoice status as it stands in database, before the request writes anything (invoiceStatusAtLoad). It readsfactureorfacture_fourn, so it works for customer invoices, credit notes and supplier invoices.setItemsFields()keeps the lines as issued, and ignores the source's lines with a Splash warning, when the invoice:What does not change:
Relation to the other PRs:
Tests
Real invoices and orders, through
load()thensetItemsFields("lines", …)with a 10% discount added on one line, in a rolled-back transaction with Splash triggers disabled:Deployed in production on the instance where the issue was found. Replaying the WooCommerce lines above against the restored invoice leaves it at 950.00.
🤖 Generated with Claude Code