diff --git a/fleet/profile/decisions/adc-011-tenue-comptable-et-discretion.md b/fleet/profile/decisions/adc-011-tenue-comptable-et-discretion.md index 216c0a5..bfeee6c 100644 --- a/fleet/profile/decisions/adc-011-tenue-comptable-et-discretion.md +++ b/fleet/profile/decisions/adc-011-tenue-comptable-et-discretion.md @@ -40,10 +40,16 @@ Le document le dit expressément, et les pièces sont produites sur demande. La règle est donc *pouvoir répondre simplement en cas d'enquête*, jamais *anticiper l'enquête en publiant*. -**Limite qui inverse la règle :** un flux financier entre la société et son -dirigeant se déclare, même non demandé, dès lors que le document porte -précisément sur l'absence d'un tel flux. Taire ce qui contredirait le document -n'est pas de la discrétion, c'est une omission. +**Limite qui inverse la règle — et elle est étroite :** ne se déclare, même non +demandé, que ce qui rendrait le document **faux** si on le taisait. Le critère +est la véracité de ce qui est affirmé, pas l'exhaustivité. + +Une attestation d'absence de rémunération n'a pas à mentionner une indemnité +d'occupation : celle-ci n'est pas une rémunération, elle ne contredit donc rien. +La mentionner, c'est publier une relation financière que personne n'a demandée — +et un lecteur pressé y verrait une rémunération là où il n'y en a pas. Une +première rédaction l'avait fait, en s'abritant derrière la transparence ; c'était +une erreur d'analyse : la discrétion et la sincérité ne s'opposaient pas ici. ### 2. Permanence des méthodes diff --git a/fleet/profile/exercices/2026/manifest.json b/fleet/profile/exercices/2026/manifest.json new file mode 100644 index 0000000..6fe5e16 --- /dev/null +++ b/fleet/profile/exercices/2026/manifest.json @@ -0,0 +1,1117 @@ +{ + "meta": { + "exercice": 2026, + "source": "https://erp.arcodange.lab", + "extracted_at": "2026-08-14T15:54:36.583Z", + "replayable": true, + "note": "Manifeste d'exercice — description des faits, non des écritures comptables. Les factures client sont marquées delivered:true : elles existent chez le client et se reproduisent à l'identique, jamais ne se recalculent." + }, + "exclusions": [ + { + "ref": "FAC001-CL00001", + "date": "2026-01-29", + "total_ttc": "510.00000000", + "motif": "Référence malformée (CL00001 au lieu de CL0001001) — défaut de configuration du masque. JAMAIS REMISE AU CLIENT : vérifié le 2026-08-14, aucune trace d'envoi ; KissMetrics a été facturé via Wise en février 2026, et le document qu'il détient référence FAC001-CL0001001. La séquence FAC reste continue (FAC001 à FAC008), la réémission portant elle aussi FAC001." + }, + { + "ref": "AVC001-CL0001001", + "date": "2026-01-29", + "total_ttc": "-510.00000000", + "motif": "Avoir émis le 24/02/2026 pour annuler FAC001-CL00001. Sans objet dès lors que la facture annulée n'a jamais quitté la société : il ne documentait qu'un faux pas interne, non un événement commercial. La séquence AVC devient vide." + } + ], + "anomalies": { + "libelles_generiques": 20, + "detail": "lignes bancaires portant un libellé Dolibarr générique — à remplacer au rejeu" + }, + "tiers": [ + { + "id": "1", + "name": "KissMetrics", + "code_client": "CL0001", + "code_fournisseur": null, + "client": "1", + "fournisseur": "0", + "country_id": "11", + "tva_intra": "", + "code_compta": null, + "code_compta_fournisseur": null + }, + { + "id": "2", + "name": "Wise Europe SA", + "code_client": null, + "code_fournisseur": "FO0001", + "client": "0", + "fournisseur": "1", + "country_id": "2", + "tva_intra": "", + "code_compta": null, + "code_compta_fournisseur": "401WISEEU" + }, + { + "id": "3", + "name": "Greffe du tribunal de commerce Évry", + "code_client": null, + "code_fournisseur": "FO0002", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "FR09326467370", + "code_compta": null, + "code_compta_fournisseur": "401GREFFE" + }, + { + "id": "4", + "name": "YOLAW", + "code_client": null, + "code_fournisseur": "FO0003", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "FR18753892926", + "code_compta": null, + "code_compta_fournisseur": "401YOLAW" + }, + { + "id": "5", + "name": "Medialex", + "code_client": null, + "code_fournisseur": "FO0004", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "", + "code_compta": null, + "code_compta_fournisseur": "401MEDIAL" + }, + { + "id": "6", + "name": "Qonto", + "code_client": null, + "code_fournisseur": "FO0005", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "FR10819489626", + "code_compta": null, + "code_compta_fournisseur": "401QONTO" + }, + { + "id": "7", + "name": "OVH", + "code_client": null, + "code_fournisseur": "FO0006", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "FR22424761419", + "code_compta": null, + "code_compta_fournisseur": "401OVH" + }, + { + "id": "8", + "name": "La Poste", + "code_client": null, + "code_fournisseur": "FO0007", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "FR39356000000", + "code_compta": null, + "code_compta_fournisseur": "401LAPOST" + }, + { + "id": "9", + "name": "Infogreffe", + "code_client": null, + "code_fournisseur": "FO0008", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "FR69338885718", + "code_compta": null, + "code_compta_fournisseur": "401INFOGR" + }, + { + "id": "10", + "name": "Darnis Operations", + "code_client": null, + "code_fournisseur": "FO0009", + "client": "0", + "fournisseur": "1", + "country_id": "1", + "tva_intra": "FR51920267531", + "code_compta": null, + "code_compta_fournisseur": "401DARNIS" + }, + { + "id": "11", + "name": "Anthropic Ireland Limited", + "code_client": null, + "code_fournisseur": "FO0010", + "client": "0", + "fournisseur": "1", + "country_id": null, + "tva_intra": "", + "code_compta": null, + "code_compta_fournisseur": "401ANTHRO" + }, + { + "id": "12", + "name": "Mistral AI SAS", + "code_client": null, + "code_fournisseur": "FO0011", + "client": "0", + "fournisseur": "1", + "country_id": null, + "tva_intra": "", + "code_compta": null, + "code_compta_fournisseur": "401MISTRA" + } + ], + "invoices": [ + { + "ref": "FAC001-CL0001001", + "socid": "1", + "date": "2026-01-29", + "date_lim_reglement": "2026-02-08", + "type": "0", + "total_ht": "510.00000000", + "total_tva": "0.00000000", + "total_ttc": "510.00000000", + "multicurrency_code": "EUR", + "statut": "2", + "paye": "1", + "delivered": true, + "lines": [ + { + "desc": "TVA non applicable – Article 259-1 du CGI – Prestation de services localisée hors de France (USA)", + "subprice": "510.00000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "510.00000000", + "type": "VIR", + "date": "2026-02-05 12:00:00", + "ref": "REC002-####002" + } + ] + }, + { + "ref": "FAC002-CL0001002", + "socid": "1", + "date": "2026-02-23", + "date_lim_reglement": "2026-03-30", + "type": "0", + "total_ht": "5100.00000000", + "total_tva": "0.00000000", + "total_ttc": "5100.00000000", + "multicurrency_code": "EUR", + "statut": "2", + "paye": "1", + "delivered": true, + "lines": [ + { + "desc": "TVA non applicable – Article 259-1 du CGI – Prestation de services localisée hors de France (USA)", + "subprice": "510.00000000", + "qty": "10", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "5100.00000000", + "type": "VIR", + "date": "2026-03-12 12:00:00", + "ref": "REC003-CL00002" + } + ] + }, + { + "ref": "FAC003-CL0001003", + "socid": "1", + "date": "2026-02-23", + "date_lim_reglement": "2026-03-30", + "type": "0", + "total_ht": "2550.00000000", + "total_tva": "0.00000000", + "total_ttc": "2550.00000000", + "multicurrency_code": "EUR", + "statut": "2", + "paye": "1", + "delivered": true, + "lines": [ + { + "desc": "TVA non applicable – Article 259-1 du CGI – Prestation de services localisée hors de France (USA)", + "subprice": "510.00000000", + "qty": "5", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "2550.00000000", + "type": "VIR", + "date": "2026-04-20 12:00:00", + "ref": "REC001-CL0001001" + } + ] + }, + { + "ref": "FAC004-CL0001004", + "socid": "1", + "date": "2026-05-22", + "date_lim_reglement": "2026-06-29", + "type": "0", + "total_ht": "2145.92000000", + "total_tva": "0.00000000", + "total_ttc": "2145.92000000", + "multicurrency_code": "EUR", + "statut": "2", + "paye": "1", + "delivered": true, + "lines": [ + { + "desc": "Conseil et accompagnement infrastructure cloud - Cycle M1 (part fixe) - periode du 23/04/2026 au 23/05/2026.\nTVA non applicable - Articles 259, 1 et 283-2 du CGI - prestation de services a un preneur assujetti etabli hors UE (Etats-Unis).", + "subprice": "2145.92000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "2145.92000000", + "type": "VIR", + "date": "2026-05-29 00:00:00", + "ref": "REC002-######001" + } + ] + }, + { + "ref": "FAC005-CL0001005", + "socid": "1", + "date": "2026-05-22", + "date_lim_reglement": "2026-08-22", + "type": "0", + "total_ht": "2575.11000000", + "total_tva": "0.00000000", + "total_ttc": "2575.11000000", + "multicurrency_code": "EUR", + "statut": "1", + "paye": "0", + "delivered": true, + "lines": [ + { + "desc": "Conseil et accompagnement infrastructure cloud - Cycle M1 (part differee) - periode du 23/04/2026 au 23/05/2026.\nPaiement differe a 3 mois - echeance 23/08/2026.\nTVA non applicable - Articles 259, 1 et 283-2 du CGI - prestation de services a un preneur assujetti etabli hors UE (Etats-Unis).", + "subprice": "2575.11000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [] + }, + { + "ref": "FAC006-CL0001006", + "socid": "1", + "date": "2026-06-22", + "date_lim_reglement": "2026-07-30", + "type": "0", + "total_ht": "2145.92000000", + "total_tva": "0.00000000", + "total_ttc": "2145.92000000", + "multicurrency_code": "EUR", + "statut": "2", + "paye": "1", + "delivered": true, + "lines": [ + { + "desc": "Conseil et accompagnement infrastructure cloud - Cycle M2 (part fixe) - periode du 23/05/2026 au 23/06/2026.\nTVA non applicable - Articles 259, 1 et 283-2 du CGI - prestation de services a un preneur assujetti etabli hors UE (Etats-Unis).", + "subprice": "2145.92000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "2145.92000000", + "type": "VIR", + "date": "2026-06-25 00:00:00", + "ref": "REC002-######002" + } + ] + }, + { + "ref": "FAC007-CL0001007", + "socid": "1", + "date": "2026-06-22", + "date_lim_reglement": "2026-09-22", + "type": "0", + "total_ht": "2575.11000000", + "total_tva": "0.00000000", + "total_ttc": "2575.11000000", + "multicurrency_code": "EUR", + "statut": "1", + "paye": "0", + "delivered": true, + "lines": [ + { + "desc": "Conseil et accompagnement infrastructure cloud - Cycle M2 (part differee) - periode du 23/05/2026 au 23/06/2026.\nPaiement differe a 3 mois - echeance 23/09/2026.\nTVA non applicable - Articles 259, 1 et 283-2 du CGI - prestation de services a un preneur assujetti etabli hors UE (Etats-Unis).", + "subprice": "2575.11000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [] + }, + { + "ref": "FAC008-CL0001008", + "socid": "1", + "date": "2026-07-22", + "date_lim_reglement": "2026-08-21", + "type": "0", + "total_ht": "2185.00000000", + "total_tva": "0.00000000", + "total_ttc": "2185.00000000", + "multicurrency_code": "EUR", + "statut": "2", + "paye": "1", + "delivered": true, + "lines": [ + { + "desc": "Conseil et accompagnement infrastructure cloud — Cycle M3 (part fixe) — période d'exécution du 23/06/2026 au 23/07/2026. Contrat cadre du 23/04/2026, art. 6 ; avenant art. 2 et 4. Montant contractuel 2 500,00 USD converti à 2 185,00 € (taux du jour du paiement).\nPrestation de services au sens des articles 259, 1° et 283-2 du Code général des impôts. TVA française non applicable — preneur assujetti établi hors de l'Union européenne (États-Unis). Auto-liquidation par le preneur dans son pays d'établissement le cas échéant. / Services rendered pursuant to Articles 259, 1° and 283-2 of the French General Tax Code. French VAT not applicable — recipient is a taxable person established outside the European Union (United States). Reverse charge by the recipient in its country of establishment if applicable.", + "subprice": "2185.00000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "2185.00000000", + "type": "VIR", + "date": "2026-07-20 00:00:00", + "ref": "REC003-######003" + } + ] + } + ], + "supplierInvoices": [ + { + "ref": "FAF2026001", + "ref_supplier": "PLAN_ORDER_CHECKOUT-invoice-23917601", + "socid": "2", + "date": "2026-01-25", + "total_ht": "50.00000000", + "total_tva": "0.00000000", + "total_ttc": "50.00000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Ouverture compte - Exonération de TVA – Article 261 C du CGI", + "subprice": "50.00000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "50.00000000", + "type": "VIR", + "date": "2026-01-26 12:00:00", + "ref": "REF2026001" + } + ] + }, + { + "ref": "FAF2026002", + "ref_supplier": "26004975", + "socid": "3", + "date": "2026-01-08", + "total_ht": "47.69000000", + "total_tva": "9.54000000", + "total_ttc": "57.23000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Déclaration relative au bénéficiaire effectif lors de la demande
\r\nd'immatriculation 16,951", + "subprice": "16.95000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + }, + { + "desc": "Immatriculation Personne Morale sur création", + "subprice": "23.30000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + }, + { + "desc": "Dépôts d'actes ou de pièces", + "subprice": "6.36000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + }, + { + "desc": "Acte de greffe (Réclamation de renseignements ou pièces manquantes (C.
\r\ncom., R 123-97 al 2))", + "subprice": "1.08000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "55.93000000", + "type": "CB", + "date": "2026-01-09 12:00:00", + "ref": "REF2026002" + }, + { + "amount": "1.30000000", + "type": "CB", + "date": "2026-01-15 12:00:00", + "ref": "REF2026003" + } + ] + }, + { + "ref": "FAF2026003", + "ref_supplier": "1091237202601", + "socid": "4", + "date": "2026-01-03", + "total_ht": "1.66000000", + "total_tva": "0.33000000", + "total_ttc": "1.99000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Modèle Statuts EURL", + "subprice": "1.66000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "1.99000000", + "type": "CB", + "date": "2026-01-04 12:00:00", + "ref": "REF2026004" + } + ] + }, + { + "ref": "FAF2026004", + "ref_supplier": "74389798", + "socid": "5", + "date": "2026-01-08", + "total_ht": "124.00000000", + "total_tva": "24.80000000", + "total_ttc": "148.80000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "AVIS DE CONSTITUTION SARLU ARCODANGE
\r\nIdentifiant annonce: 22565141
\r\nparution le 10/01/2026 sur 20 Minutes Essonne", + "subprice": "124.00000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "148.80000000", + "type": "CB", + "date": "2026-01-09 12:00:00", + "ref": "REF2026005" + } + ] + }, + { + "ref": "FAF2026005", + "ref_supplier": "06-01-26-payment-366753", + "socid": "6", + "date": "2026-01-05", + "total_ht": "169.00000000", + "total_tva": "33.80000000", + "total_ttc": "202.80000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Pack Qonto Basic
\r\nVotre pack inclut :
\r\n- Prestation dépôt de capital en ligne- 12 mois d'abonnement Qonto au
\r\nforfait Basic (à partir de la date devérification réglementaire de votre
\r\nnouvelle entreprise", + "subprice": "169.00000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "202.80000000", + "type": "CB", + "date": "2026-01-06 12:00:00", + "ref": "REF2026006" + } + ] + }, + { + "ref": "FAF2026006", + "ref_supplier": "210000003184C", + "socid": "8", + "date": "2026-01-11", + "total_ht": "8.43000000", + "total_tva": "0.00000000", + "total_ttc": "8.43000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Lettre recommandée: 22 g
\r\nExonération de TVA, article 261-4-1° du CGI", + "subprice": "8.43000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "8.43000000", + "type": "CB", + "date": "2026-01-12 12:00:00", + "ref": "REF2026007" + } + ] + }, + { + "ref": "FAF2026007", + "ref_supplier": "60117-ZMHMT", + "socid": "9", + "date": "2026-01-16", + "total_ht": "2.67000000", + "total_tva": "0.53000000", + "total_ttc": "3.20000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Extrait KBIS et frais d'emission
\r\nFormat electronique", + "subprice": "2.67000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "3.20000000", + "type": "CB", + "date": "2026-01-17 12:00:00", + "ref": "REF2026008" + } + ] + }, + { + "ref": "FAF2026008", + "ref_supplier": "F1040", + "socid": "10", + "date": "2026-02-27", + "total_ht": "510.00000000", + "total_tva": "102.00000000", + "total_ttc": "612.00000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Apport d'affaire Arcodange ", + "subprice": "510.00000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "612.00000000", + "type": "VIR", + "date": "2026-03-13 12:00:00", + "ref": "REF2026009" + } + ] + }, + { + "ref": "FAF2026009", + "ref_supplier": "F1042", + "socid": "10", + "date": "2026-02-27", + "total_ht": "255.00000000", + "total_tva": "51.00000000", + "total_ttc": "306.00000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Apport d'affaire Arcodange ", + "subprice": "510.00000000", + "qty": "0.5", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "306.00000000", + "type": "VIR", + "date": "2026-05-10 12:00:00", + "ref": "REF2026010" + } + ] + }, + { + "ref": "FAF2026010", + "ref_supplier": "F1046", + "socid": "10", + "date": "2026-06-28", + "total_ht": "219.50000000", + "total_tva": "43.90000000", + "total_ttc": "263.40000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Apport d affaire Arcodange - Projet — juin 2026 (Hiway F1046)", + "subprice": "219.50000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "263.40000000", + "type": "VIR", + "date": "2026-06-29 00:00:00", + "ref": "REF2026012" + } + ] + }, + { + "ref": "FAF2026011", + "ref_supplier": "9BF0758D-695749", + "socid": "11", + "date": "2026-04-11", + "total_ht": "180.00000000", + "total_tva": "0.00000000", + "total_ttc": "180.00000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Claude Pro — abonnement avril 2026 (facture 9BF0758D-695749, autoliquidation UE)", + "subprice": "180.00000000", + "qty": "1", + "tva_tx": "0.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "180.00000000", + "type": "CB", + "date": "2026-04-13 00:00:00", + "ref": "REF2026014" + } + ] + }, + { + "ref": "FAF2026012", + "ref_supplier": "MSTRL-API-814045-001", + "socid": "12", + "date": "2026-04-01", + "total_ht": "143.90000000", + "total_tva": "28.78000000", + "total_ttc": "172.68000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "", + "subprice": "0.00000000", + "qty": "0", + "tva_tx": "0.0000", + "product_type": "0" + } + ], + "payments": [ + { + "amount": "172.68000000", + "type": "CB", + "date": "2026-04-03 00:00:00", + "ref": "REF2026013" + } + ] + }, + { + "ref": "FAF2026013", + "ref_supplier": "F1045", + "socid": "10", + "date": "2026-06-29", + "total_ht": "214.70000000", + "total_tva": "42.94000000", + "total_ttc": "257.64000000", + "statut": "2", + "paye": "1", + "lines": [ + { + "desc": "Apport d'affaire Arcodange - Projet — juin 2026 (facture Hiway F1045 du 30/06/2026)", + "subprice": "214.70000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [ + { + "amount": "257.64000000", + "type": "VIR", + "date": "2026-06-29 00:00:00", + "ref": "REF2026011" + } + ] + }, + { + "ref": "FAF2026014", + "ref_supplier": "F1048", + "socid": "10", + "date": "2026-08-30", + "total_ht": "218.50000000", + "total_tva": "43.70000000", + "total_ttc": "262.20000000", + "statut": "1", + "paye": "0", + "lines": [ + { + "desc": "Apport d'affaire Arcodange — commission 10 % sur encaissement KM du 20/07/2026", + "subprice": "218.50000000", + "qty": "1", + "tva_tx": "20.0000", + "product_type": "1" + } + ], + "payments": [] + } + ], + "accounts": [ + { + "id": "1", + "label": "QONTO", + "ref": "QON1", + "account_number": "51211", + "accountancy_journal": "BQ1", + "currency_code": "EUR", + "balance": 4158.28, + "lines": [ + { + "date": "2026-01-06", + "amount": 1000, + "label": "(Solde initial)", + "generic_label": false, + "num_releve": "202601" + }, + { + "date": "2026-01-25", + "amount": -50, + "label": "ouverture compte WISE", + "generic_label": false, + "num_releve": "202601" + }, + { + "date": "2026-03-12", + "amount": 5000, + "label": "virement du compte international vers le compte principal", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-03-12", + "amount": -612, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-04-02", + "amount": -172.68, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-04-12", + "amount": -180, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-05-09", + "amount": -306, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-06-28", + "amount": -257.64, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-06-28", + "amount": -263.4, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + } + ] + }, + { + "id": "2", + "label": "WISE EURO", + "ref": "WIS2", + "account_number": "51212", + "accountancy_journal": "BQ2", + "currency_code": "EUR", + "balance": 9636.84, + "lines": [ + { + "date": "2026-01-25", + "amount": 0, + "label": "Solde initial", + "generic_label": false, + "num_releve": "202601" + }, + { + "date": "2026-01-25", + "amount": 50, + "label": "ouverture compte WISE", + "generic_label": false, + "num_releve": "202601" + }, + { + "date": "2026-01-25", + "amount": -50, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": "202601" + }, + { + "date": "2026-02-04", + "amount": 510, + "label": "", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-02-04", + "amount": 510, + "label": "", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-02-04", + "amount": -510, + "label": "(CustomerInvoicePaymentBack)", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-03-11", + "amount": 5100, + "label": "(CustomerInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-03-12", + "amount": -5000, + "label": "virement du compte international vers le compte principal", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-04-19", + "amount": 2550, + "label": "(CustomerInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-05-28", + "amount": 2145.92, + "label": "(CustomerInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-06-24", + "amount": 2145.92, + "label": "(CustomerInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-07-19", + "amount": 2185, + "label": "(CustomerInvoicePayment)", + "generic_label": true, + "num_releve": null + } + ] + }, + { + "id": "3", + "label": "G.RADUREAU Compte Courant Asso", + "ref": "CCA1", + "account_number": "45511", + "accountancy_journal": "CCA1", + "currency_code": "EUR", + "balance": -1912.98, + "lines": [ + { + "date": "2025-10-23", + "amount": -7.3, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-03", + "amount": -1.99, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-05", + "amount": -202.8, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-08", + "amount": -55.93, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-08", + "amount": -148.8, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-11", + "amount": -8.43, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-14", + "amount": -1.3, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-15", + "amount": 0, + "label": "Solde initial", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-01-16", + "amount": -3.2, + "label": "(SupplierInvoicePayment)", + "generic_label": true, + "num_releve": null + }, + { + "date": "2026-01-30", + "amount": -163.23, + "label": "Indemnité d'occupation — janvier 2026", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-02-27", + "amount": -220, + "label": "Indemnité d'occupation — février 2026", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-03-30", + "amount": -220, + "label": "Indemnité d'occupation — mars 2026", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-04-29", + "amount": -220, + "label": "Indemnité d'occupation — avril 2026", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-05-30", + "amount": -220, + "label": "Indemnité d'occupation — mai 2026", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-06-29", + "amount": -220, + "label": "Indemnité d'occupation — juin 2026", + "generic_label": false, + "num_releve": null + }, + { + "date": "2026-07-30", + "amount": -220, + "label": "Indemnité d'occupation — juillet 2026", + "generic_label": false, + "num_releve": null + } + ] + } + ] +} \ No newline at end of file diff --git a/test/extractExercise.ts b/test/extractExercise.ts new file mode 100644 index 0000000..b92264c --- /dev/null +++ b/test/extractExercise.ts @@ -0,0 +1,245 @@ +/* + Extrait d'une instance Dolibarr le MANIFESTE D'UN EXERCICE : la description + complète et ordonnée des faits qui le composent. + + POURQUOI. Un exercice ouvert n'a d'engagement envers personne — aucun compte + déposé, aucune liasse, aucun FEC remis. Tant qu'il en va ainsi, une erreur de + MODÉLISATION (mauvais compte, auxiliaire manquant, libellé illisible) se + corrige mieux en rejouant depuis les pièces qu'en la contournant : la piste + d'audit fiable demande que l'écriture reflète sa pièce, et rejouer resserre ce + lien là où une rustine le distend. + + Ce fichier ne fait que LIRE. Il produit le manifeste ; le rejeu est un autre + outil, et il ne s'exécute que sur une cible vierge. + + CE QUI EST REJOUABLE, ET CE QUI NE L'EST PAS. La ligne de partage n'est pas + technique, elle est juridique : + + rejouable : factures fournisseur enregistrées, lignes bancaires, paiements + divers, charges sociales, tiers — tout ce qui est interne ; + FIGÉ : toute pièce déjà remise à un tiers (facture client ENVOYÉE, + dépôt au greffe, déclaration transmise) et tout exercice clos. + + Une facture partie chez le client existe chez lui : aucun rejeu ne l'efface. + Le manifeste les extrait quand même — il décrit l'exercice — mais les marque + `delivered: true`, et le rejeu devra les reproduire à l'identique plutôt que + les recalculer. + + LE RÉFÉRENT DE VÉRIFICATION. Les mouvements bancaires sont la seule partie de + l'exercice qu'on ne peut pas réécrire : Qonto et Wise sont hors de Dolibarr. + Le manifeste les embarque donc intégralement, et le test d'acceptation d'un + rejeu est qu'ils soient retrouvés au centime et à la date. + + Usage : + DENO_TLS_CA_STORE=system \ + DOLIBARR_URL=https://erp.arcodange.lab DOLAPIKEY=$(cat test/....key) \ + deno run -A test/extractExercise.ts --year 2026 --out manifest.json + + `DENO_TLS_CA_STORE=system` n'est pas décoratif : les hôtes du lab portent un + certificat signé par une autorité interne, présente dans le trousseau système + mais absente du magasin que Deno embarque. Sans lui, `fetch` échoue sur + « invalid peer certificate: UnknownIssuer » — alors que curl et Playwright, + qui lisent le trousseau système, passent sans rien dire. +*/ +import "load_dotenv"; + +const argv = Deno.args; +const pick = (f: string, d = "") => (argv.includes(f) ? argv[argv.indexOf(f) + 1] : d); + +const base = pick("--url", Deno.env.get("DOLIBARR_URL") ?? "https://erp.arcodange.lab"); +const key = Deno.env.get("DOLAPIKEY") ?? ""; +const year = Number(pick("--year", "2026")); +const out = pick("--out", `manifest-${year}.json`); + +/** + * Pièces volontairement écartées du rejeu, avec leur motif. + * + * Une exclusion n'est légitime que si la pièce N'A JAMAIS ÉTÉ REMISE À UN TIERS. + * Le motif est consigné dans le manifeste : un auditeur doit pouvoir lire + * pourquoi une référence manque, sans avoir à le deviner ni à nous croire. + */ +const EXCLUSIONS: Record = { + "FAC001-CL00001": + "Référence malformée (CL00001 au lieu de CL0001001) — défaut de configuration du masque. " + + "JAMAIS REMISE AU CLIENT : vérifié le 2026-08-14, aucune trace d'envoi ; KissMetrics a été " + + "facturé via Wise en février 2026, et le document qu'il détient référence FAC001-CL0001001. " + + "La séquence FAC reste continue (FAC001 à FAC008), la réémission portant elle aussi FAC001.", + "AVC001-CL0001001": + "Avoir émis le 24/02/2026 pour annuler FAC001-CL00001. Sans objet dès lors que la facture " + + "annulée n'a jamais quitté la société : il ne documentait qu'un faux pas interne, non un " + + "événement commercial. La séquence AVC devient vide.", +}; + +if (!key) { + console.error("DOLAPIKEY requis (lecture seule)."); + Deno.exit(2); +} + +async function api(path: string): Promise { + const r = await fetch(`${base}/api/index.php${path}`, { headers: { DOLAPIKEY: key } }); + if (!r.ok) return null; + try { + return await r.json() as T; + } catch { + return null; + } +} + +/** Dolibarr rend des epochs ; on les fige en ISO dans le fuseau du serveur. */ +const iso = (ts: unknown): string | null => { + const n = Number(ts); + if (!n) return null; + return new Date(n * 1000).toISOString().slice(0, 10); +}; + +const inYear = (ts: unknown) => { + const d = iso(ts); + return !!d && d.startsWith(String(year)); +}; + +type Any = Record; + +console.log(`source : ${base}`); +console.log(`exercice : ${year}\n`); + +// --- tiers ------------------------------------------------------------------ +const tiers = (await api("/thirdparties?limit=500") ?? []).map((t) => ({ + id: t.id, + name: t.name, + code_client: t.code_client, + code_fournisseur: t.code_fournisseur, + client: t.client, + fournisseur: t.fournisseur, + country_id: t.country_id, + tva_intra: t.tva_intra, + code_compta: t.code_compta, + code_compta_fournisseur: t.code_compta_fournisseur, +})); +console.log(`tiers : ${tiers.length}`); + +// --- factures client -------------------------------------------------------- +// `delivered: true` : elles sont parties chez le client. Un rejeu les reproduit +// à l'identique — référence, date, montant — il ne les recalcule pas. +const invoices = []; +const excluded: Any[] = []; +for (const f of await api("/invoices?limit=500") ?? []) { + if (!inYear(f.date)) continue; + const motif = EXCLUSIONS[String(f.ref)]; + if (motif) { + excluded.push({ ref: f.ref, date: iso(f.date), total_ttc: f.total_ttc, motif }); + continue; + } + const payments = await api(`/invoices/${f.id}/payments`) ?? []; + invoices.push({ + ref: f.ref, + socid: f.socid, + date: iso(f.date), + date_lim_reglement: iso(f.date_lim_reglement), + type: f.type, + total_ht: f.total_ht, + total_tva: f.total_tva, + total_ttc: f.total_ttc, + multicurrency_code: f.multicurrency_code, + statut: f.statut, + paye: f.paye, + delivered: true, + lines: (f.lines as Any[] ?? []).map((l) => ({ + desc: l.desc, subprice: l.subprice, qty: l.qty, tva_tx: l.tva_tx, product_type: l.product_type, + })), + payments: payments.map((p) => ({ amount: p.amount, type: p.type, date: p.date, ref: p.ref })), + }); +} +console.log(`factures client : ${invoices.length} (figées — déjà remises au client)`); +for (const e of excluded) console.log(` ⊘ exclue : ${e.ref} (${e.total_ttc} EUR) — ${String(e.motif).slice(0, 72)}…`); + +// --- factures fournisseur --------------------------------------------------- +const supplierInvoices = []; +for (const f of await api("/supplierinvoices?limit=500") ?? []) { + if (!inYear(f.date)) continue; + const payments = await api(`/supplierinvoices/${f.id}/payments`) ?? []; + supplierInvoices.push({ + ref: f.ref, + ref_supplier: f.ref_supplier, + socid: f.socid, + date: iso(f.date), + total_ht: f.total_ht, + total_tva: f.total_tva, + total_ttc: f.total_ttc, + statut: f.statut, + paye: f.paye, + lines: (f.lines as Any[] ?? []).map((l) => ({ + desc: l.desc, subprice: l.subprice, qty: l.qty, tva_tx: l.tva_tx, product_type: l.product_type, + })), + payments: payments.map((p) => ({ amount: p.amount, type: p.type, date: p.date, ref: p.ref })), + }); +} +console.log(`factures fournisseur : ${supplierInvoices.length}`); + +// --- comptes et mouvements bancaires --------------------------------------- +// LE RÉFÉRENT. Tout le reste se vérifie contre ces lignes. +const accounts = []; +let bankLineCount = 0; +for (const a of await api("/bankaccounts") ?? []) { + const lines = (await api(`/bankaccounts/${a.id}/lines?limit=1000`) ?? []) + .map((l) => ({ + date: iso(l.datev ?? l.dateo), + amount: Number(l.amount), + label: l.label, + // Les libellés générés par Dolibarr — « SupplierInvoicePayment », + // « CustomerInvoicePayment » — traversent le grand livre tels quels et y + // sont illisibles. Le rejeu doit les remplacer par le libellé de la pièce. + generic_label: /^\(?(Customer|Supplier)InvoicePayment\)?$/.test(String(l.label ?? "")), + num_releve: l.num_releve, + })) + .filter((l) => l.date) + .sort((x, y) => String(x.date).localeCompare(String(y.date))); + bankLineCount += lines.length; + accounts.push({ + id: a.id, + label: a.label, + ref: a.ref, + account_number: a.account_number, + accountancy_journal: a.accountancy_journal, + currency_code: a.currency_code, + balance: Number(lines.reduce((s, l) => s + l.amount, 0).toFixed(2)), + lines, + }); +} +console.log(`comptes bancaires : ${accounts.length} (${bankLineCount} mouvements — référent de vérification)`); + +const generics = accounts.flatMap((a) => a.lines).filter((l) => l.generic_label).length; + +const manifest = { + meta: { + exercice: year, + source: base, + extracted_at: new Date().toISOString(), + // Un exercice clos ne se rejoue pas : la clôture est la limite dure. + replayable: true, + note: "Manifeste d'exercice — description des faits, non des écritures comptables. " + + "Les factures client sont marquées delivered:true : elles existent chez le client " + + "et se reproduisent à l'identique, jamais ne se recalculent.", + }, + exclusions: excluded, + anomalies: { + libelles_generiques: generics, + detail: generics + ? "lignes bancaires portant un libellé Dolibarr générique — à remplacer au rejeu" + : "aucune", + }, + tiers, + invoices, + supplierInvoices, + accounts, +}; + +await Deno.writeTextFile(out, JSON.stringify(manifest, null, 2)); + +const totalClient = invoices.reduce((s, f) => s + Number(f.total_ttc ?? 0), 0); +const totalFourn = supplierInvoices.reduce((s, f) => s + Number(f.total_ttc ?? 0), 0); +console.log(`\n--- récapitulatif ---`); +console.log(` produits facturés : ${totalClient.toFixed(2)} EUR`); +console.log(` achats facturés : ${totalFourn.toFixed(2)} EUR`); +for (const a of accounts) console.log(` ${String(a.label).padEnd(32)} ${a.balance.toFixed(2)} EUR`); +console.log(` libellés génériques : ${generics} ← à corriger au rejeu`); +console.log(`\nmanifeste écrit : ${out}`);