# 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. C'est une **charge sociale**, saisie comme telle. ## Quel compte — et pourquoi ce n'est pas 646 > [!IMPORTANT] > **Arcodange est une SARL à l'IS. Le compte est 641, pas 646.** > Le **646** (« cotisations sociales de l'exploitant ») est réservé à > l'**entreprise individuelle et aux sociétés à l'IR**. Il ne s'applique pas à > une société. Quand la société règle les cotisations personnelles de son gérant > majoritaire, c'est un **complément de rémunération** : compte **641**, dans un > sous-compte dédié (`641150` « Sécurité sociale des indépendants » par exemple), > et c'est **déductible** du résultat de la société. | Compte | Pour qui | Arcodange | | --- | --- | --- | | **641** (sous-compte dédié) | rémunération + cotisations du **gérant majoritaire TNS** | ← **celui-ci** | | 646 | cotisations de l'**exploitant individuel** / société à l'IR | sans objet | | 645 | cotisations **sur salaires** | vide — aucun salarié | | 631 / 633 | contributions **de l'employeur** (formation, apprentissage) | vide — **Gabriel n'est pas employeur** | Contrepartie **431** (Sécurité sociale), soldée par **512** au paiement. Régularisation à la clôture : 641 contre **4286** (autres charges à payer). L'appel URSSAF se comptabilise **globalement** dans ce sous-compte 641 : pas de ventilation entre cotisations, CFP et CSG/CRDS. En particulier, la contribution à la formation professionnelle d'un TNS **n'est pas** la participation employeur du compte 6333 — Arcodange n'emploie personne ; c'est une contribution personnelle, elle suit les cotisations. > [!WARNING] > **Le piège CSG.** L'appel URSSAF porte une mention « montant de CSG déductible > fiscalement : N € ». Elle vise l'**impôt sur le revenu personnel du gérant** > (art. 62 CGI), **pas l'IS de la société**. Pour la SARL, la CSG/CRDS est > **intégralement déductible** : aucune réintégration extra-comptable. Ne pas > transposer le raisonnement de l'entreprise individuelle, où la CSG non > déductible se reclasse en compte de l'exploitant. ### Ce que Dolibarr ne fait pas Le type de charge **ne pilote aucune écriture**. Vérifié le 2026-08-13 dans **Configuration → Dictionnaires → Types de charges sociales ou fiscales** (`/admin/dict.php?id=7`) : la colonne **« Code comptable » est vide pour tous les types**, `TAXSSI` compris. Le module comptabilité n'est pas déployé — `/accountancy/*` répond 404. Conséquence pratique : **le choix du compte ne se joue pas dans l'ERP**. Dolibarr porte les faits (montant, échéance, justificatif) ; l'imputation vit dans le grand livre de l'expert-comptable. Choisir le type `Securite sociale des indépendants (URSSAF)` pour la lisibilité, sans croire qu'il décide de quoi que ce soit. ## 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. > [!CAUTION] > **Une charge sociale est IMMUABLE sur ce déploiement. La date doit être juste > du premier coup.** Toute soumission du formulaire d'édition échoue — > y compris en ne touchant que le montant : > `ERROR 42601: multiple assignments to same column "fk_user_modif"`. > `ChargeSociales::update()` affecte deux fois la même colonne dans son `UPDATE` ; > MySQL l'accepte, **PostgreSQL le rejette**. Vérifié le 2026-08-13 en sandbox sur > la date et sur le montant. Le défaut est propre à cet objet — la mise à jour > d'un tiers via REST fonctionne. `test/updateSocialCharge.ts` conserve le cas de > reproduction et diagnostique l'erreur. > > Relire la date **avant** de soumettre : `--dry-run` l'affiche. ## 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). - **Attacher le justificatif à la charge.** L'appel de cotisations est la pièce qui la justifie ; sans lui la charge n'est qu'une affirmation. ```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 @- <","filecontent":"","fileencoding":"base64", "overwriteifexists":1} JSON ``` **`subdir` doit être l'identifiant nu de la charge** (`2`), rien d'autre. L'API accepte silencieusement n'importe quel chemin (`sociales/2`, `tax/2`…) et y dépose un fichier que l'onglet Documents ne montrera jamais. Vérifier sur `/compta/sociales/document.php?id=` : « Nombre de fichiers liés » doit passer à 1. `modulepart=tax` avec `ref` renvoie 500, c'est normal. - Le calendrier `fleet/profile/calendar.yaml` porte les échéances URSSAF 2026 : 493,00 (05/05) + 1 215,00 (05/08) + 1 333,00 (05/11) = **3 041,00 €**. - **Échéance ≠ prélèvement.** L'appel donne des dates d'échéance au 5 du mois ; le débit bancaire tombe plus tard (22/05 pour l'échéance du 05/05). Enregistrer la charge à la **date d'échéance** — c'est elle qui fait foi et qui détermine un éventuel retard. - **Les montants sont provisoires.** Tant que l'activité est en début d'activité, ils sont calculés sur une base forfaitaire et **régularisés** après déclaration des revenus. L'assiette est la **rémunération du gérant**, jamais le chiffre d'affaires — ne pas anticiper de régularisation à partir du CA encaissé. - 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.