feat(payment): first-class transaction_id when recording a règlement

Make the originating bank transaction id a first-class input on payment-record.sh
so every règlement is tied to the real bank movement at write time.

- `transaction_id` is the canonical field (the Qonto/Wise feed tx id); `num` stays
  as a back-compat alias. It's stored on the payment's bank line (llx_bank.num_chq),
  the reconciliation key.
- Recording WITHOUT a transaction_id prints a stderr warning (still posts, but won't
  auto-reconcile) — nudges the agent to always carry it.
- Output normalises to {id, bank_transaction_id, transaction_id}.
- Promote: manifests' payment ops carry transaction_id; promote-plan shows it
  (tx=… or tx=MISSING).

Proven live: customer + supplier record with transaction_id; the `num` alias maps
to the same field; the no-tx warning fires; promote plan/apply carry it through.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-30 00:34:10 +02:00
parent d81bff0ed3
commit b945c8de47
5 changed files with 42 additions and 28 deletions

View File

@@ -96,8 +96,8 @@ to leave a draft. Emits `{id, ref, ref_supplier, total_ht, total_ttc, statut}`.
### 3 · Payment (règlement) — `scripts/payment-record.sh`
```sh
echo '{"invoice_id":19,"mode":"VIR","account_id":1,"num":"QONTO-TX-1234"}' | scripts/payment-record.sh
echo '{"invoice_id":13,"kind":"supplier","mode":"VIR","account_id":1,"amount":96,"num":"WISE-TX-5678"}' \
echo '{"invoice_id":19,"mode":"VIR","account_id":1,"transaction_id":"QONTO-TX-1234"}' | scripts/payment-record.sh
echo '{"invoice_id":13,"kind":"supplier","mode":"VIR","account_id":1,"amount":96,"transaction_id":"WISE-TX-5678"}' \
| scripts/payment-record.sh
```
The invoice must be **validated** first. `mode`: `VIR|CB|CHQ|LIQ`. Customer
@@ -105,12 +105,16 @@ payments settle the full remaining amount and mark the invoice paid; **supplier*
payments require an explicit `amount`. `account_id` is the bank account id — list
them with `scripts/bank-accounts.sh` (`ai_agent_sandbox` now holds `banque lire`).
Emits **`{id, bank_transaction_id, num}`**. `bank_transaction_id` is the Dolibarr
bank line (`llx_bank`) the payment created — the id bank reconciliation
(`arcodange-bank-reco`) keys on to link a règlement to a statement line. Put the
**originating bank transaction id** (the Qonto/Wise tx id) in `num`: it is stored
on that bank line (`num_chq`), so the feed reconciles by id rather than by fuzzy
amount/date. Both ends of the reconciliation are therefore captured at write time.
**Always pass `transaction_id`** — the originating bank transaction id (the
Qonto/Wise tx id from the feed). It is the first-class way to tie a règlement to
the real bank movement: stored on the payment's bank line (`llx_bank.num_chq`), so
reconciliation matches **by id** rather than by fuzzy amount/date. (`num` is a
back-compat alias for the same field.) Recording without it prints a warning — the
payment still posts, but it won't auto-reconcile.
Emits **`{id, bank_transaction_id, transaction_id}`**. `bank_transaction_id` is the
Dolibarr bank line (`llx_bank.fk_bank_line`) the payment created — the id the
reconciliation (`arcodange-bank-reco`) keys on. Both ends are captured at write time.
### 4 · Credit note (avoir) — `scripts/creditnote-create.sh`