Repository: SplashSync/Dolibarr
Module version: 2.23.3 (+ Advance Pack 2.23.0)
Dolibarr: 23.0.0
Type: feature gap
Summary
The module already carries a working CreditNote object: src/Objects/CreditNote.php builds on the
invoice traits, Invoice/CRUDTrait sets type = Facture::TYPE_CREDIT_NOTE on create, and
Invoice/TriggersTrait dispatches Dolibarr credit notes back under the CreditNote type. What it
cannot do is say which invoice the credit note corrects.
fk_facture_source — the native column Dolibarr uses for that link — is never exposed as a field:
grep -rn "fk_facture_source\|SourceInvoice" src/Objects/ -> no match
So a credit note pushed from a shop lands detached. Dolibarr shows it nowhere on the invoice it is
supposed to correct, and the accounting relationship between the two documents exists only in the
operator's memory.
Where the module does set the type
src/Objects/Invoice/CRUDTrait.php:
// line 125
if ($this instanceof CreditNote) {
$this->object->type = Facture::TYPE_CREDIT_NOTE;
}
...
// line 219
if ($this instanceof CreditNote) {
$object->type = Facture::TYPE_CREDIT_NOTE;
}
src/Objects/Invoice/TriggersTrait.php:164:
$this->objectType = (Facture::TYPE_CREDIT_NOTE == $objectType) ? "CreditNote" : "Invoice";
The type is handled everywhere. The link is handled nowhere.
Why this is the right column
fk_facture_source is what Dolibarr itself writes and reads. Measured on a production instance
running Dolibarr 24 with this module:
|
|
credit notes (type = 2) |
78 |
carrying fk_facture_source |
71 |
rows in llx_element_element for those credit notes |
2 |
So the generic link table is not the mechanism — the dedicated column is. The 7 credit notes without
one are deliberate standalone credit notes, which the field should therefore allow to stay empty.
Advance Pack does not cover it
splashadvancepack/src/Objects/Extensions/InvoicesLinksExtension.php links orders to invoices
(setOrderLink(), detectOrderByRef()). There is nothing for invoice ↔ credit note.
Suggested fix
Expose a writable object field on CreditNote, in the same shape as the existing order link:
- identifier
source_invoice, type ObjectId on Invoice
- read:
fk_facture_source
- write: accept an
Invoice object id, and — as detectOrderByRef() already does for orders — fall
back to resolving by the source invoice's ref / ref_client when the shop only knows its own
reference
- empty is a legal value, for standalone credit notes
Secondary: gateway payment references never reach ext_payment_id
Related, and relevant to the same reconciliation workflow.
src/Objects/Invoice/PaymentsTrait.php:483 writes only:
$payment->num_payment = $lineData["number"] ?? "";
llx_paiement also has ext_payment_id and ext_payment_site, which is where Dolibarr's own Stripe
module and third-party bank-reconciliation modules look first for a gateway reference. On this
install:
|
|
| payments |
1 164 |
carrying a Stripe id in num_paiement |
978 |
carrying ext_payment_id |
0 |
The information is being received and stored, just in the field that reconciliation tools query last
instead of first. Setting ext_payment_site from the connector's own site identifier and
ext_payment_id alongside num_payment would cost nothing and make Stripe payments — and the
refunds from the companion issue — machine-matchable.
Related
SplashSync/Wordpress never emits refunds at all: no CreditNote object, no refund hook. Filed
separately. The two changes compose — one produces the credit note, the other attaches it.
Repository: SplashSync/Dolibarr
Module version: 2.23.3 (+ Advance Pack 2.23.0)
Dolibarr: 23.0.0
Type: feature gap
Summary
The module already carries a working
CreditNoteobject:src/Objects/CreditNote.phpbuilds on theinvoice traits,
Invoice/CRUDTraitsetstype = Facture::TYPE_CREDIT_NOTEon create, andInvoice/TriggersTraitdispatches Dolibarr credit notes back under theCreditNotetype. What itcannot do is say which invoice the credit note corrects.
fk_facture_source— the native column Dolibarr uses for that link — is never exposed as a field:So a credit note pushed from a shop lands detached. Dolibarr shows it nowhere on the invoice it is
supposed to correct, and the accounting relationship between the two documents exists only in the
operator's memory.
Where the module does set the type
src/Objects/Invoice/CRUDTrait.php:src/Objects/Invoice/TriggersTrait.php:164:The type is handled everywhere. The link is handled nowhere.
Why this is the right column
fk_facture_sourceis what Dolibarr itself writes and reads. Measured on a production instancerunning Dolibarr 24 with this module:
type = 2)fk_facture_sourcellx_element_elementfor those credit notesSo the generic link table is not the mechanism — the dedicated column is. The 7 credit notes without
one are deliberate standalone credit notes, which the field should therefore allow to stay empty.
Advance Pack does not cover it
splashadvancepack/src/Objects/Extensions/InvoicesLinksExtension.phplinks orders to invoices(
setOrderLink(),detectOrderByRef()). There is nothing for invoice ↔ credit note.Suggested fix
Expose a writable object field on
CreditNote, in the same shape as the existing order link:source_invoice, typeObjectIdonInvoicefk_facture_sourceInvoiceobject id, and — asdetectOrderByRef()already does for orders — fallback to resolving by the source invoice's
ref/ref_clientwhen the shop only knows its ownreference
Secondary: gateway payment references never reach
ext_payment_idRelated, and relevant to the same reconciliation workflow.
src/Objects/Invoice/PaymentsTrait.php:483writes only:llx_paiementalso hasext_payment_idandext_payment_site, which is where Dolibarr's own Stripemodule and third-party bank-reconciliation modules look first for a gateway reference. On this
install:
num_paiementext_payment_idThe information is being received and stored, just in the field that reconciliation tools query last
instead of first. Setting
ext_payment_sitefrom the connector's own site identifier andext_payment_idalongsidenum_paymentwould cost nothing and make Stripe payments — and therefunds from the companion issue — machine-matchable.
Related
SplashSync/Wordpressnever emits refunds at all: noCreditNoteobject, no refund hook. Filedseparately. The two changes compose — one produces the credit note, the other attaches it.