FIX never close an invoice the recorded payments do not cover - #31
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
setPaidFlag() closes the invoice as soon as the source announces "paid", without checking that a single cent is recorded against it. A shop has one paid/unpaid state where accounting has a running balance, so a cheque schedule, a deposit or a part-voucher part-transfer settlement is announced as paid the day the arrangement is agreed, while the invoice is only extinguished when the last movement lands. Count what the invoice already carries — payments, credit notes and deposits — and leave it open when that does not cover the total, logging a warning. Mirrors the philosophy of the payments-list protections: recorded money outranks the source's opinion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 12, 2026
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
setPaidFlag()(InvoiceMainTrait) closes the invoice as soon as the source announces paid, without checking that a single cent is recorded against it. The source's opinion is allowed to extinguish a receivable on its own.A shop has one paid/unpaid state where accounting has a running balance. A schedule of cheques, a deposit, a settlement part vouchers part transfer — all are announced as paid the day the arrangement is agreed, while the invoice is only extinguished when the last movement lands. The connector closes it on day one.
Combined with a source that mis-reports its paid flag (see SplashSync/Wordpress#19), invoices are closed with nothing behind them at all.
Observed in production on one shop: 3 invoices closed by the
splashsyncuser with no payment covering them, 704.85 € of receivables that disappeared from the books while still owed — one of them 612.85 € with zero recorded against it.An invoice closed early is also an encaissement that will never be declared: under the French e-invoicing regime each payment is reported with its own date.
Fix
Before closing, count what the invoice already carries — payments, credit notes and deposits — and leave it open when that does not cover the total, logging a warning. Credit notes and deposits count, because an invoice closed by a payment plus a discount is settled just as surely as one closed by payments alone.
A human may still close a residue by hand in Dolibarr; writing off a few cents is a decision. A connector may not.
This is the symmetric half of #30 (never unpay an invoice that carries real payments): together they say that the money recorded in Dolibarr decides, in both directions. The two touch different branches of the same
if/elseand merge cleanly in either order.🤖 Generated with Claude Code