feat(erp): annoter un objet figé — la date URSSAF portée par une pièce jointe

Doctrine posée par l'opérateur le 13/08 : si une donnée fautive est déjà en
production et sans incidence insurmontable sur l'exercice, on ne force pas la
correction — on annote l'objet. Le registre reste append-only et l'écriture
n'est pas maquillée.

La règle est juste, son canal habituel est fermé ici : sur ce déploiement,
AUCUNE écriture sur une charge sociale n'aboutit — ni la date, ni le montant,
NI MÊME LA NOTE PUBLIQUE. Toutes passent par le même UPDATE et échouent sur
« multiple assignments to same column fk_user_modif » (erp#87).

Ce qui fonctionne est un autre chemin : attacher un document, le téléversement
n'étant pas un UPDATE sur l'objet. La charge n°1 (URSSAF 1re échéance, 493 EUR)
porte désormais deux pièces : l'appel de cotisations officiel, et une note de
correction expliquant que le 22/05 est la date du PRÉLÈVEMENT quand l'échéance
officielle est le 05/05 — 17 jours de retard, écart resté dans le même mois et
le même exercice.

annotateObject.ts écrit la note publique d'un objet et REFUSE explicitement
quand le bug la bloque. Ce garde-fou vient d'un faux positif qui a bien failli
passer : la page de retour de Dolibarr ré-affiche le texte soumis, si bien qu'un
contrôle « le texte est là » réussit sur un enregistrement qui n'a jamais eu
lieu. J'ai d'abord conclu que le chemin des notes échappait au bug — il ne lui
échappe pas. Relire l'objet, jamais la page de retour. Le script reste utile sur
les objets non affectés par erp#87.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
2026-08-13 23:57:19 +02:00
co-authored by Claude Opus 5
parent 480888937f
commit 775daacd18
3 changed files with 207 additions and 0 deletions
@@ -32,6 +32,45 @@ réels payées personnellement par le gérant — le tiers y est le fournisseur,
jamais le gérant. Un modèle qui contredit celui déjà en place est presque
toujours le mauvais.
## Une charge sociale est TOTALEMENT figée — écrire juste du premier coup
> [!CAUTION]
> Sur ce déploiement (Dolibarr 22.0.4 + PostgreSQL), **aucune écriture sur une
> charge sociale n'aboutit** : ni la date, ni le montant, **ni même la note
> publique**. Toutes échouent sur
> `ERROR 42601: multiple assignments to same column "fk_user_modif"` —
> `ChargeSociales::update()` affecte deux fois la même colonne, ce que MySQL
> tolère et PostgreSQL rejette. Suivi : [erp#87](https://gitea.arcodange.lab/arcodange-org/erp/issues/87).
**La règle générale — « si c'est déjà en production et sans incidence sur
l'exercice, annoter l'objet suffit » — reste juste, mais son canal habituel est
fermé ici.** Le champ note passe par le même `UPDATE`.
Ce qui fonctionne, parce que c'est un autre chemin : **attacher un document**.
Le téléversement n'est pas un `UPDATE` sur l'objet.
```bash
curl -s -X POST https://erp.arcodange.lab/api/index.php/documents/upload \
-H "DOLAPIKEY: $(cat test/.ai_agent_prod_prod_write.key)" \
-H 'Content-Type: application/json' -d @- <<JSON
{"filename":"NOTE-<sujet>-<date>.md","modulepart":"tax","subdir":"<ID DE LA CHARGE>",
"filecontent":"<BASE64>","fileencoding":"base64","overwriteifexists":1}
JSON
```
Vérifier sur `/compta/sociales/document.php?id=<ID>` que le compteur a bougé.
Première application : la charge n°1 (URSSAF 1re échéance) porte le 22/05, date
du *prélèvement*, quand l'échéance officielle est le 05/05 — l'écart, resté dans
le même mois et le même exercice, est porté par une note attachée plutôt que
forcé dans la donnée.
`test/annotateObject.ts` écrit la note publique d'un objet **et refuse
explicitement** quand le bug la bloque, au lieu de croire une page qui ré-affiche
le formulaire. Ce faux positif a bien failli passer : la page de retour contient
le texte soumis, donc un contrôle naïf « le texte est là » réussit sur un
enregistrement qui n'a jamais eu lieu. **Relire l'objet, jamais la page de
retour.** Le script reste utile sur les objets non affectés par erp#87.
## Le compte courant d'associé : deux usages à ne pas confondre
Le compte bancaire **`CCA1` (id 3)** porte le numéro comptable **45511** et son