Facturation + Comptabilité pour PME
Un message désordonné → facture, journal des dépenses et le prochain brouillon de rappel. Pas de compte, pas d'abonnement, pas de verrouillage — votre argent, dans des fichiers que vous possédez.
Les petites entreprises n'échouent pas à cause du travail. Elles échouent à cause de l'attente : environ 55 % des factures B2B en Amérique du Nord sont payées en retard (Atradius, via Crestmont Capital, mise à jour 2026), les petites entreprises américaines ont attendu en moyenne 29,3 jours pour être payées au T2 2026, ~9 jours après la date d'échéance (Xero Small Business Insights, via Foundrly, août 2026), et 82 % des faillites de petites entreprises sont attribuables à des problèmes de trésorerie (US Chamber of Commerce, via Crestmont, 2026). La probabilité de recouvrer chute rapidement avec l'âge — plus de 95 % dans les 30 premiers jours avec un suivi proactif, jusqu'à 20–30 % au-delà de 120 jours (Crestmont, 2026). La facture est la partie facile. La relance est le produit — et partout ailleurs la relance est payante : les rappels automatiques sont réservés aux versions Pro chez Wave (19 $/mois) et Invoice Ninja (14 $/mois) (pages de tarification éditeur, nov. 2026), Wave ne peut pas envoyer de factures en dehors des États-Unis/Canada (assistance Wave, 8 sept. 2026), et le niveau gratuit de Zoho Invoice plafonne à 500 factures/an et supprime les données inactives après 180 jours (zoho.com/invoice/pricing, consulté le 11/11/2026). Cette compétence rédige la relance gratuitement.
Version 0.2.0. Reconstruite à partir de la revue contradictoire de la v0.1.0 (20 lacunes, toutes corrigées ou consignées dans
MEASUREMENTS.md§11) et des corrections issues de recherches approfondies (research-notes-v2.md§1). Ce qui a changé se trouve dansCHANGELOG.md. Les chiffres ci-dessous sont des exécutions réelles sur les échantillons de données fournis, pas des estimations.
Ceci n'est pas un conseil juridique, fiscal ou financier. Cette compétence vous aide à créer des factures et à suivre l'argent. Les taux d'imposition, les seuils d'enregistrement et les exigences en matière de factures diffèrent selon les pays et évoluent dans le temps. Définissez votre propre taux d'imposition et confirmez les règles applicables à votre entreprise auprès de votre autorité fiscale locale (au Bangladesh : le National Board of Revenue, nbr.gov.bd) ou d'un comptable qualifié. Cette clause de non-responsabilité est également imprimée dans le pied de page de chaque facture et reçu généré — en bengali sur les documents en bengali. Pour les règles de tenue de registres sous-jacentes (quoi conserver, TIN/BIN sur les factures, formulaires Mushak, rétention), voir le compagnon de référence : la compétence
bd-bookkeepingd'OpenAccountants (openaccountants/openaccountants, 484★, mise à jour le 11/11/2026) — un guide de référence en anglais, explicitement « référence générale seulement… non examiné pour les faits propres à une personne donnée ». Elle ne génère pas de factures. Cette compétence le fait.
Exécution
python3 scripts/bookkeeper.py <commande>
Python ≥ 3.9, bibliothèque standard uniquement. Aucune étape d'installation, aucune dépendance, aucun appel réseau, aucune clé API, aucun compte. Les données vivent dans des fichiers JSON simples que vous pouvez ouvrir, copier et emporter partout.
Règles monétaires — à lire avant de faire confiance à un chiffre
Voici les règles qui rendent les totaux fiables, et celles que la revue de la v0.1.0 a identifiées comme étant violées par cette compétence :
- L'argent est arrondi moitié-sup (
ROUND_HALF_UP), comme un commerçant arrondit avec une calculatrice — jamais l'arrondi bancaire. ৳2,345 fait ৳2,35. - Les quantités sont exactes, jamais arrondies comme de l'argent. Une qté de 1,005 est 1,005 ; seul le total de la ligne est arrondi. Les quantités s'impriment sans zéros de fin (3, jamais 3,00).
- La taxe est par ligne, sur le montant de la ligne après remise — la taxe de chaque ligne est arrondie moitié-sup sur cette ligne, puis additionnée (comme le font Wave / Xero / FreshBooks). 3 lignes de ৳0,35 à 15 % de taxe donne ৳0,15, pas ৳0,16.
- Le statut de paiement provient du solde, jamais de la chaîne de statut. Une facture marquée « payée » avec encore 4 000 ৳ dus signale 4 000 ৳ dus, et le rapport indique que le statut est erroné. Le statut est un indicateur ; l'état de retard est dérivé de la date d'échéance et du solde.
- L'argent n'est jamais additionné entre devises. Un grand livre avec devises mixtes signale des totaux par devise (5 000 ৳ + 100 $) et refuse un total fusionné et un net fusionné — la compétence n'a pas de taux de change et le précise.
- Un problème dans le grand livre est signalé de manière explicite et provoque une
sortie avec le code 2.
overdueetcashflowsortent avec le code 2 lorsqu'une ligne est ignorée (données invalides), un numéro est dupliqué, une facture « payée » a encore un solde, un paiement est en trop, ou un paiement n'a pas depaid_date. Le rapport s'imprime quand même ; le code de sortie indique de corriger le grand livre avant de lui faire confiance. - L'argent négatif s'imprime avec le moins en premier : −4 100 ৳ — une convention, partout.
Le flux de travail : une entrée → facture → reçu → rappel → flux de trésorerie
1. Facture, devis ou reçu à partir d'une entrée JSON
python3 scripts/bookkeeper.py invoice --input samples/invoice-input.json --out out/invoice.html --config config/bd.json
python3 scripts/bookkeeper.py invoice --input samples/invoice-input-bn.json --out out/invoice-bn.html --config config/bd.json --lang bn
python3 scripts/bookkeeper.py invoice --input my-quote.json --out out/quote.html --format md
python3 scripts/bookkeeper.py receipt --input samples/invoice-input.json --out out/receipt.html --paid-date 2026-11-05 --amount-paid 4500
- L'entrée est un petit fichier JSON : entreprise + client + articles
(description, quantité, prix unitaire) + numéro de facture + date d'émission +
date d'échéance. Voir
samples/invoice-input.jsonpour la structure exacte. - Devis → facture → reçu est un seul cycle de vie, un seul modèle de données.
type: "quote"nécessitevalid_untilau lieu d'une date d'échéance ; une facture nécessite une date d'échéance réelle sur le calendrier, pas seulement « Net 30 » ; un reçu est généré à partir d'une facture payée avec--paid-dateet--amount-paidet affiche le বাকি (solde dû) restant si le paiement était partiel. Un reçu avec un montant de 0 est refusé — un reçu confirme de l'argent reçu. Un devis n'affiche jamais de lignes de paiement/solde (rien n'est dû sur une proposition), en HTML ou Markdown, et son numéro est étiqueté « Numéro de devis », pas « Numéro de facture ». - La facture porte les champs dont toute facture a besoin (notes de recherche
§3.1) : le mot « Facture », un numéro séquentiel unique, la date d'émission,
la date d'échéance, les coordonnées du vendeur, les coordonnées de l'acheteur, des
descriptions spécifiques, les articles, la taxe sur sa propre ligne, les instructions
de paiement + le total dû. Un numéro de devis est référencé sur la facture lorsqu'il en
existe un ; un numéro de commande du client et le numéro d'enregistrement fiscal
du vendeur (
tax_id— au Bangladesh, le BIN à 13 chiffres) s'impriment sur la facture lorsqu'ils sont fournis. - La numérotation est séquentielle (
INV-2026-001,INV-2026-002, …). Ne sautez ni ne réutilisez jamais un numéro — un trou ou un doublon ressemble à un manque à gagner ou à une dépense inventée au moment de la déclaration fiscale. Les commandes du grand livre avertissent fortement et sortent avec le code 2 en cas de numéro en double. Lenumbering_prefixde la configuration est vérifié par rapport au numéro de facture (un avertissement, pas une erreur) ;default_termsremplit la ligne Conditions lorsque l'entrée n'en a pas. - La sortie est du HTML propre et imprimable (ouvrez-le dans un navigateur, imprimez-le
en PDF) ou du Markdown (
--format md). Pas de ressources externes dans le HTML, donc il s'imprime exactement comme il apparaît — les échantillons fournis ont été rendus dans Chromium sans tête et imprimés en PDF une fois (voirMEASUREMENTS.md§11.6, captures d'écran dansdocs/). - L'argent est calculé avec
Decimal, jamaisfloat. La remise est un pourcentage du sous-total, appliquée par ligne ; la taxe est par ligne sur le montant après remise (voir « Règles monétaires »). - La validation est stricte et le code de sortie est 2 en cas de mauvaise entrée : date d'échéance manquante, quantité ou prix négatif, taux de taxe en dehors de 0–100 %, mauvaises dates, JSON malformé, fichier manquant, date d'échéance avant la date d'émission, un paiement daté avant la date d'émission. Une facture avec zéro article est autorisée (total 0 ৳) mais imprime un avertissement — c'est un brouillon, pas une erreur à cacher. Un paiement en trop sur un document imprime un avertissement sur les deux commandes de document (un reçu ne devrait jamais afficher « Solde dû : -825 ৳ »).
2. Taxe — un paramètre que vous tapez, jamais un taux codé en dur
# Dans l'entrée de la facture (c'est le SEUL endroit où vit un taux) :
"tax": {"name": "VAT", "rate_percent": 15}
- Aucun outil ne code en dur un taux, et cette compétence non plus. Chaque outil de facturation (Zoho, FreshBooks, Wave, Xero — notes de recherche §5.1) permet à l'utilisateur de définir une taxe nommée + un pourcentage, l'applique par ligne, et l'affiche comme une ligne séparée. Cette compétence copie cela exactement : la taxe est une taxe nommée + un taux % dans l'entrée, par défaut 0 % / pas de taxe.
- Les préréglages de pays dans
config/fournissent le libellé de la taxe, la devise, les modes de paiement, les conditions par défaut et le préfixe de numérotation — jamais un taux.config/bd.json(Bangladesh : ৳, « TVA », bKash / Nagad / Rocket / virement bancaire / espèces) etconfig/us.json(États-Unis : $, « Taxe de vente », Net 30).tax_rate_percentdans les deux configurations estnullà dessein. Untax_iddans la configuration (votre BIN) remplit la facture lorsque l'entrée n'en a pas. - La facture d'exemple utilise 15 % de TVA parce que l'entrée d'exemple le dit — le taux de TVA standard du Bangladesh est de 15 % en vertu de la loi de 2012 sur la TVA et les droits supplémentaires (ArthiKalap, mise à jour 25 juillet 2026 ; TRW, exercice 2026-27 ; TaxDo, 2026 ; SDTT Academy, début 2026) — mais la compétence ne le sait pas et ne doit jamais être citée comme le sachant. Les déclarations de TVA sont à nouveau mensuelles (à déposer sous 15 jours) : la loi de finances 2026 les a rendues trimestrielles à compter du 1er juillet 2026, mais une ordonnance modificative publiée au journal officiel le 14 octobre 2026 a rétabli les déclarations mensuelles (TRW « Doing Business in Bangladesh 2026 », droit en vigueur au 24 octobre 2026 ; entrepreneurs.bd, 2026). Toute mention « trimestrielle » dans des notes plus anciennes est désormais erronée.
- Les seuils d'enregistrement ne sont PAS codés en dur dans cette compétence. Trois guides indépendants d'octobre–novembre 2026 convergent désormais vers les mêmes chiffres — enregistrement obligatoire au-dessus d'un chiffre d'affaires annuel de Tk 50 lakhs ; enrôlement pour Tk 30–50 lakhs avec un impôt sur le chiffre d'affaires de 4 % ; certaines activités s'enregistrent quel que soit leur chiffre d'affaires (TRW « TVA au Bangladesh 2026 », position du 18 octobre 2026 ; TRW « Enregistrement TVA » ; entrepreneurs.bd, 2026 ; Aniday, vérifié sept. 2026). Mais une vérification directe auprès du NBR n'a pas été réalisée : la page d'accueil du NBR (chargée le 11/11/2026) ne contient aucun texte de seuil, et vat.gov.bd était inaccessible ce jour-là. Ces chiffres sont donc rapportés ici comme sources secondaires convergentes, pas un fait vérifié par le NBR — la compétence n'énonce jamais de seuil comme le sien, et oriente les utilisateurs vers nbr.gov.bd. Le BIN comporte 13 chiffres (liste des services de la page d'accueil du NBR, 11/11/2026 — une étiquette, pas un journal officiel ; confirmez le nombre de chiffres dans le guide d'enregistrement TVA du NBR lorsque vous vérifiez les seuils).
- Les prix TTC sont pris en charge :
"tax": {"name": "VAT", "rate_percent": 15, "inclusive": true}extrait la taxe du prix brut (TVA = brut × 15 ÷ 115). Mesuré dansMEASUREMENTS.md§5 : 1 150 ৳ brut → 150 ৳ de TVA, le total reste 1 150 ৳.
3. Journal des dépenses — langage simple, fichiers simples
python3 scripts/bookkeeper.py expense add --ledger expenses.json --date 2026-11-11 --category Materials --amount 1200 --note "fil de cuivre, 20 m"
python3 scripts/bookkeeper.py expense list --ledger expenses.json --month 2026-11
python3 scripts/bookkeeper.py expense export --ledger expenses.json --out expenses.csv
- Une dépense = date, catégorie, montant, note. Le grand livre est une liste
JSON ;
exportécrit un CSV qui s'ouvre dans n'importe quel tableur. - Les catégories sont en langage simple, pas un plan comptable : Achats,
Transport, Outils, Mobile/Internet, Repas, Loyer, Main-d'œuvre, Emballage,
Autre. Une catégorie inconnue est une erreur, jamais acceptée silencieusement.
Les montants négatifs sont rejetés.
--monthdoit être unYYYY-MMréel (2026-1est rejeté — une correspondance de préfixe brut fusionnerait silencieusement octobre et novembre). - Une ligne du grand livre qui n'est pas un objet est ignorée bruyamment avec un
avertissement et une sortie avec le code 2 — jamais une trace de pile, jamais
silencieuse.
expense addrefuse de réécrire un grand livre qui contient une ligne cassée (corrigez-la d'abord).
4. Suivi des retards + brouillons de rappel — le cœur de la compétence
python3 scripts/bookkeeper.py overdue --invoices samples/invoices.json --as-of 2026-11-11
python3 scripts/bookkeeper.py overdue --invoices samples/invoices.json --as-of 2026-11-11 --lang bn --json
- Analyse le grand livre des factures, liste chaque facture ouverte par tranche d'âge (en cours / 1–30 / 31–60 / 61–90 / 90+ jours de retard), et rédige le prochain rappel au stade approprié pour chacune.
- La séquence en 6 étapes (le consensus à 5 touches entre Raoura, vérifié en juillet 2026 ; InvoiceCub, 31 octobre 2026 ; InvoiceFly, ~nov. 2026 ; HeroThemes, ~août 2026 ; FreelanceDesk, ~juin 2026 — avant échéance, date d'échéance, 7, 14, 30 jours — plus le rappel amical précoce pour 1–6 jours de retard de la version à 7 touches ; la touche supplémentaire à 21 jours de la version à 7 touches n'est pas une étape séparée, son terrain est couvert par le brouillon à 14 jours dont la prochaine touche est à 30 jours) : 3 jours avant l'échéance, le jour de l'échéance, 7 jours de retard, 14 jours de retard, 30 jours de mise en demeure, plus la relance pour 1–6 jours. Escalade progressive, jamais d'accusation en premier : supposez une bonne intention au début (oubli / enfoui / dans une file d'approbation) ; mentionnez une pénalité de retard uniquement lorsque l'accord le prévoit et que la facture est en retard d'environ 2 semaines. Chaque brouillon réitère le numéro de facture, le montant, la date d'échéance d'origine — et le nombre réel de jours de retard (une facture à 8 jours se voit dire « 8 jours de retard », jamais le numéro de l'étape).
- Brouillons seulement — la compétence n'envoie jamais rien. Vous envoyez le
rappel. Le rapport imprime également la date de la prochaine relance, de sorte que
l'escalade ne dépend pas de la mémoire. Une prochaine relance déjà passée s'imprime
comme « envoyer maintenant (était dû le …) », jamais comme une date nue dans le
passé. La mise en demeure finale donne un délai d'au moins 7 jours à partir
d'aujourd'hui (
max(échéance + 37 jours, date de référence + 7 jours)) — une demande dont le délai est déjà passé est pire que pas de demande du tout. - Mesuré sur les échantillons (au 11/11/2026) : 6 factures ouvertes, 48 650 ৳
qui vous sont dus (বাকি), 4 en retard totalisant 28 250 ৳ — une à
chaque étape de la relance à la mise en demeure. Voir
MEASUREMENTS.md§3. - Les factures en brouillon sont exclues du « dû à vous » — une facture non envoyée n'est pas encore de l'argent dû. Les factures payées (solde 0) sont également exclues. (Les entreprises qui assurent un suivi sur 100 % des factures en retard ont 76 % plus de chances d'être payées dans la semaine — Chaser 2026 AR Report, via Raoura, de seconde main.)
5. Vue simple du flux de trésorerie — les chiffres que le propriétaire vérifie réellement
python3 scripts/bookkeeper.py cashflow --invoices samples/invoices.json --expenses samples/expenses.json --as-of 2026-11-11
- Rassemble dans un affichage unique ce que l'entreprise a gagné (factures payées), ce qu'elle a dépensé (dépenses enregistrées), ce qui lui est dû (factures en cours) et la trésorerie nette disponible (encaissé − dépensé), filtré par mois.
- Utilise la même logique que
overduepour déduire l'état de paiement — ne fait jamais confiance à la chaîne de statut. Les brouillons sont exclus des totaux. Les devis sont exclus (une proposition n'est pas une dette). Un solde négatif (avoir client) est imprimé « Avoir client » — pas un passif de facturation, pas une erreur. - Si le même fichier d'entrée contient des factures dans plusieurs devises, les flux de trésorerie sont signalés par devise. Aucun total fusionné.
6. Tableau de bord — consolidation d'un mois
python3 scripts/bookkeeper.py dashboard --invoices samples/invoices.json --expenses samples/expenses.json --as-of 2026-11-11 --month 2026-11
- Résumé d'un mois : factures émises, payées, en retard, dépenses, trésorerie nette.
- Conçu pour un propriétaire d'entreprise qui veut un seul chiffre : « ce mois-ci, j'ai 5 000 ৳ de plus que la semaine dernière ».
overdueimprime la date de la prochaine relance pour chaque facture ;cashflowaffiche l'argent dans une vue temporelle ;dashboardcolle tout cela sur une page de résumé. Couvre les trois questions que le propriétaire pose dans n'importe quel ordre.
Fichiers de configuration
Deux préréglages sont inclus :
| Fichier | Pays | Devise | Libellé de taxe | Modes de paiement |
|---|---|---|---|---|
config/bd.json | Bangladesh | ৳ | TVA | bKash, Nagad, Rocket, virement, espèces |
config/us.json | États-Unis | $ | Taxe de vente | Carte / virement / espèces / PayPal (pas de Stripe — éviter une autre couche) |
config/generate.py crée un fichier de configuration vide pour un autre pays en
vous posant six questions. Aucune dépendance, aucune connexion.
Langue
--lang en (défaut) pour la sortie en anglais. --lang bn pour la sortie en bengali.
Les brouillons de relance sont en bengali simple (langue de la rue) dans ce mode.
Journal des modifications
Voir CHANGELOG.md.
Licence
Licence MIT — voir LICENSE.md. Cette compétence est un outil utilitaire pratique, pas un
produit commercial. Vous pouvez l'utiliser, le modifier et le redistribuer.