Files
erp/.claude/skills/dolibarr-sandbox-write/RUNBOOK_charges_sociales.md
T
arcodangeandClaude Opus 5 b745fdcb43 feat(erp): encaissement KissMetrics du 17/08, deux échéances URSSAF, règlement des charges sociales
L'opérateur a demandé si le versement de la semaine passée avait été pris en
compte. Il ne l'était pas — et la réconciliation menée en réponse a fait sortir
trois autres trous.

L'ENCAISSEMENT. KissMetrics a viré 2 164,75 EUR le 17/08 (Wise, réf.
VENDOR:DEV), soit 2 500,00 USD au taux du jour : la part fixe du cycle M4. Le
mouvement n'était pas enregistré, si bien que FAC009 a été émise le matin même
au taux du 24/08 (2 140,45 EUR) alors que le contrat arrête le montant dû « au
taux du jour du règlement ». La facture était fausse de 24,30 EUR, et déjà
payée.

Le précédent commandait la méthode : FAC008 avait été libellée 2 185,00 EUR,
exactement la somme reçue le 20/07, même schéma de règlement anticipé. Sur
arbitrage de l'opérateur, FAC009 est repassée en brouillon, portée à
2 164,75 EUR, revalidée sous le même numéro et la même date, puis adossée au
virement. Sa note reprend la rédaction de FAC008.

Le juge a bloqué en relevant que `last_main_doc` était présent — donc, selon
lui, facture émise. Il confond PDF PRODUIT et facture TRANSMISE : le PDF avait
été produit deux heures plus tôt par l'agent lui-même pour assembler le dossier,
et le message d'envoi est un brouillon jamais envoyé. Mais il a raison sur la
conséquence, et c'est le seul de ses findings de la journée qui apporte quelque
chose : le PDF sur disque devenait faux. Il a été régénéré aussitôt. Son second
finding — `emetteur` null — tombe : le champ est null sur les huit lignes
d'encaissement Wise antérieures ; le renseigner sur la seule ligne d'août
romprait la permanence des méthodes au lieu de la servir.

LES DEUX ÉCHÉANCES URSSAF. 493,00 EUR prélevés le 22/05 et 1 215,00 EUR le
17/08 n'étaient enregistrés ni l'un ni l'autre. Créés comme charges sociales —
pas comme factures fournisseur : l'URSSAF n'est pas un fournisseur — puis
réglés depuis Qonto.

test/paySocialCharge.ts comble un trou du chemin gated : recordSocialCharge.ts
crée la charge et la laisse impayée, et rien n'enregistrait le règlement. Tant
qu'il manque, le mouvement bancaire reste orphelin et le solde de l'ERP diverge
de celui de la banque — c'est ce qui laissait ces deux échéances invisibles.
Dolibarr n'expose aucune route REST pour les charges sociales, donc le pipeline
ne peut pas porter l'opération ; le script garde ce qu'il peut de sa discipline.

Trois pièges consignés dans le fichier, dont un qui a coûté une fausse alerte :
NE PAS chercher « payée » dans la page — « ImPAYÉE » contient « payée ». Une
première version déclarait ÉCHEC sur un règlement qui venait d'aboutir, ce qui
pousse à rejouer, donc à créer un doublon. On lit le montant restant dû.

LE RUNBOOK disait 646. C'est faux depuis adc-009 : dans une SARL à l'IS, ce que
la société verse à l'URSSAF pour son gérant majoritaire est une charge de
personnel, donc 641. Corrigé, avec la mention explicite que toute version
portant 646 est périmée. Ajouté aussi ce que la fiche de charge confirme à
l'écran — « Code comptable: Inconnu » : le type de charge ne pilote PAS le
compte sur ce déploiement, contrairement à ce que le runbook laissait croire.

Enfin l'exemple `--period 2026` du runbook était invalide : le script découpe la
valeur comme une date ISO et produisait `undefined/undefined/2026`, ce qui fait
échouer la création sans message.

Reste au tableau, documenté et non traité ici : six cashbacks Wise (11,13 EUR),
un remboursement Qonto (5,22 EUR), l'abonnement Anthropic du 19/08 (90,00 EUR,
reçu pas encore arrivé), et deux encaissements client sous-enregistrés — FAC004
et FAC006, 51,13 EUR reçus de plus que ce que l'ERP porte.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-24 11:23:35 +02:00

115 lines
5.8 KiB
Markdown

# Runbook — enregistrer une charge sociale ou fiscale (URSSAF, CFE, TVA…)
Public : un agent, quel que soit son modèle, ou l'opérateur. Écrit pour être
suivi sans redécouvrir le terrain — cette routine a coûté une heure la première
fois, elle doit en coûter deux minutes ensuite.
## Pourquoi ce n'est pas une facture fournisseur
L'URSSAF n'est pas un fournisseur. L'inscrire en facture fournisseur pollue le
grand livre auxiliaire, les balances âgées et les états de dettes fournisseurs :
elle se saisit comme **charge sociale**.
## Le compte : 641, et non 646
> [!IMPORTANT]
> Ce runbook a d'abord dit **646**. C'était faux, et `adc-009` l'a tranché.
> Si tu lis une version qui dit 646, elle est périmée.
| Compte | Pour qui | Arcodange |
| --- | --- | --- |
| 645x | cotisations **patronales sur salaires** — suppose des salariés | non : aucun salarié, l'opérateur n'est pas employeur |
| 646 | cotisations de l'**exploitant individuel**, sociétés à l'**IR** | non : Arcodange est une SARL à l'**IS** |
| **641**, sous-compte dédié | la société prend en charge les cotisations personnelles de son **gérant majoritaire** — c'est un complément de rémunération | **oui** |
Le raisonnement tient en une phrase : dans une société à l'IS, ce que la société
verse à l'URSSAF pour son gérant majoritaire n'est pas un prélèvement de
l'exploitant, c'est une **charge de personnel**. D'où 641. Voir `adc-009` pour la
démonstration complète, y compris la déductibilité intégrale de la CSG/CRDS pour
la société — à ne pas confondre avec le sort de la CSG à l'impôt sur le revenu
personnel du gérant (art. 62 CGI), qui est une autre question.
> [!WARNING]
> **Le type de charge ne pilote PAS le compte sur ce déploiement.** Les lignes du
> dictionnaire `Configuration → Dictionnaires → Types de charges sociales` sont
> **sans code comptable** — vérifié. Choisir « Securite sociale des indépendants
> (URSSAF) » ne suffit donc pas à envoyer l'écriture en 641 : l'affectation se
> fait au moment du transfert en comptabilité, ou par le sous-compte porté sur
> l'écriture. Ne pas croire qu'un bon type suffit.
Le type retenu reste **`Securite sociale des indépendants (URSSAF)`** : le gérant
associé unique d'une SARLU est TNS, affilié à la Sécurité sociale des
indépendants, et non assimilé salarié. C'est exact sur le fond même si ça
n'emporte aucune conséquence comptable automatique ici.
## La commande
```bash
cd test
DOLIBARR_ADDRESS=https://erp-sandbox.arcodange.lab \
deno run -A recordSocialCharge.ts \
--label "URSSAF 2026 — 2e échéance" \
--due 2026-08-05 --amount 1215.00 --period 2026-08-05
```
Production — double opt-in explicite, comme toute écriture de production :
```bash
DOLIBARR_ADDRESS=https://erp.arcodange.lab \
ARCO_ALLOW_PRODUCTION=erp.arcodange.lab \
ARCO_PROD_CONFIRM=I-UNDERSTAND-THIS-WRITES-PROD \
deno run -A recordSocialCharge.ts --label "…" --due … --amount … --period …
```
`--dry-run` affiche ce qui serait soumis sans rien écrire.
`--type "CFE"` (ou tout autre motif) pour une charge qui n'est pas URSSAF ; le
script liste les types disponibles s'il ne trouve pas de correspondance.
La charge est créée **impayée**. Le règlement s'enregistre séparément, quand il
a réellement eu lieu — jamais par anticipation.
## Ce que le script garantit
- **Idempotent** : il cherche d'abord la charge dans la liste (libellé + montant)
et ne fait rien si elle existe. Un rejeu ne crée pas de doublon.
- **Vérifié par lecture** : après soumission il relit la **liste**, pas l'URL.
- **Garde d'hôte** : `guard.ts` refuse toute cible qui n'est pas la sandbox,
sauf double opt-in production.
## Les quatre pièges, tous rencontrés
1. **La date est un piège à double fond.** Le champ visible `ech` est décoratif :
le backend ne lit que les champs **cachés** `echday` / `echmonth` / `echyear`,
alimentés par le datepicker jQuery. Remplir le champ texte soumet une date
vide — et Dolibarr crée quand même l'enregistrement, avec une période
aberrante (`20/06/2000` observé). Même chose pour `period`.
2. **Le bouton n'a pas de `name`.** Le cibler par `value="Ajouter"`.
3. **L'URL après soumission ne porte pas d'`id`.** Vérifier par l'URL fait
conclure à un échec sur une création réussie — c'est ainsi que quatre
doublons sont apparus en sandbox pendant que le script affichait « non créée ».
**Toujours vérifier par la liste.**
4. **Les milliers s'affichent avec une espace insécable** : 1215.00 devient
« 1 215,00 ». Une comparaison littérale échoue au-delà de 999 €, et
l'idempotence saute silencieusement. Comparer sans les espaces.
## Pourquoi pas le pipeline de promotion
Dolibarr **n'expose aucune API REST** pour les charges sociales : `/taxes`,
`/socialcontributions` et `/chargesociales` répondent tous « API not found ». Le
module est actif (le droit 91 existe), seule l'API manque. Le pipeline
`fleet/harness/promote/` parle REST : il ne peut pas porter cette opération.
Ce script en conserve la discipline — répétition sandbox, relecture du résultat,
opt-in production explicite — mais **pas** le juge indépendant ni l'artefact de
gate. Acceptable pour une opération à trois champs ; à ne pas généraliser.
## Après l'enregistrement
- Rapprocher le prélèvement bancaire quand il apparaît (Qonto pour Arcodange).
- Le calendrier `fleet/profile/calendar.yaml` porte les échéances URSSAF 2026 :
493,00 (22/05) + 1 215,00 (05/08) + 1 333,00 (05/11) = **3 041,00 €**.
- L'échéancier officiel n'est disponible **que** dans l'espace urssaf.fr : les
notifications par mail ne contiennent aucun montant, et le transfert Gmail →
Zoho remplace même leur contenu par un texte générique. Récupérer le PDF à la
main reste nécessaire.