Enregistrez les coûts payés d'avance comme des actifs, puis libérez la part mensuelle en charges avec des transactions Beancount ordinaires. Le script ci-dessous imprime des journaux complets et reproductibles pour l'assurance, les logiciels, une provision et la dépréciation d'équipement. Il nécessite Python 3 et aucune bibliothèque tierce.
Par exemple, une police d'assurance automobile de six mois coûte 600 $ payés d'avance. Six libérations mensuelles de 100 $ séparent le paiement en espèces de la comptabilisation des charges et vous aident à établir un budget efficacement.
Qu'est-ce que l'amortissement ?
L'amortissement étale le coût d'un actif incorporel ou d'un élément payé d'avance sur les périodes qu'il bénéficie. Ces exemples utilisent une convention mensuelle simple pour le reporting de gestion. Ils ne déterminent pas une déduction fiscale ou une méthode d'amortissement légale.
La solution Beancount : fava.plugins.amortize_over
Compatibilité vérifiée le 2026-09-07 : fava.plugins.amortize_over est absent du répertoire des plugins du Fava standard 1.30.16. Ajouter sa directive plugin à cette installation standard produit une erreur d'importation. Les exemples portables ici ont été testés avec Beancount 3.2.3, beanquery 0.2.0 et Fava 1.30.16.
Le code source personnalisé de Beancount.io contient bien une implémentation d'amortize_over. Elle attend un paiement séparé et une transaction de calendrier avec exactement deux écritures et des métadonnées amortize_months. Ses dates mensuelles suivent le jour original du calendrier, et elle omet les copies futures au moment du chargement. Sa règle d'arrondi répartit les centimes sur les périodes restantes. Cette preuve issue du code source n'établit pas quelle version un déploiement hébergé exécute actuellement. Les calendriers explicites ci-dessous ont leurs propres dates indiquées et leur règle d'arrondi pour la période finale.
Étape 1 : Activer le plugin
Il n'y a aucun plugin à activer pour ce flux de travail. Enregistrez le bloc Python de l'étape 3 sous le nom amortize.py. Installez uv pour exécuter les commandes de validation et de requête avec les versions utilisées ici. Fava n'est nécessaire que si vous souhaitez les rapports web.
Le script écrit des transactions ordinaires sur la sortie standard. Redirigez cette sortie vers un nouveau fichier d'exemple, inspectez-le et validez-le avant d'incorporer les écritures dans vos livres. Réexécuter avec > remplace ce fichier d'exemple généré ; ajouter avec >> dupliquerait les transactions.
Étape 2 : Structurer vos comptes
Chaque fichier généré est un journal d'exemple autonome. L'exemple d'assurance ouvre ces comptes et fournit un solde bancaire initial illustratif de 600 $ avant de payer la prime :
| Compte | Objectif |
|---|---|
Assets:Bank:Checking | Espèces utilisées pour le paiement |
Assets:Prepaid:Insurance | Prime en attente de comptabilisation des charges |
Expenses:Insurance:Auto | Charge d'assurance mensuelle |
Equity:Opening-Balances | Contrepartie des espèces initiales de l'exemple |
Lorsque vous adaptez les transactions générées à un journal existant, utilisez vos ouvertures de comptes et votre solde bancaire réels. N'ajoutez pas les espèces initiales de l'exemple à un compte déjà financé, et n'enregistrez pas un achat déjà présent dans vos livres.
Étape 3 : Enregistrer la transaction amortie
Enregistrez ce programme complet sous le nom amortize.py. Chaque scénario spécifie la date de paiement, le nombre de libérations mensuelles, l'actif acheté, le compte de charge et le compte crédité par les libérations. La première libération a lieu à la date de paiement ; les libérations suivantes tombent le même jour des mois suivants, écrêtées à la fin du mois si nécessaire.
import argparse
import calendar
from datetime import date
from decimal import Decimal, ROUND_HALF_EVEN
# amount, months, payment date, purchase asset, expense, release credit account
SCENARIOS = {
"insurance": (
"600.00", 6, "2024-06-01", "Assets:Prepaid:Insurance",
"Expenses:Insurance:Auto", "Assets:Prepaid:Insurance",
),
"software": (
"1200.00", 12, "2024-01-15", "Assets:Prepaid:Software",
"Expenses:Software:Adobe", "Assets:Prepaid:Software",
),
"retainer": (
"4500.00", 3, "2024-01-05", "Assets:Prepaid:Professional",
"Expenses:Professional:Legal", "Assets:Prepaid:Professional",
),
"equipment": (
"3000.00", 36, "2024-01-20", "Assets:Equipment:Computers:Cost",
"Expenses:Depreciation:Computers", "Assets:Equipment:Computers:AccumDep",
),
}
parser = argparse.ArgumentParser()
parser.add_argument("scenario", choices=SCENARIOS)
args = parser.parse_args()
amount, months, paid, asset, expense, credit = SCENARIOS[args.scenario]
total = Decimal(amount)
start = date.fromisoformat(paid)
monthly = (total / months).quantize(Decimal("0.01"), rounding=ROUND_HALF_EVEN)
bank = "Assets:Bank:Checking"
equity = "Equity:Opening-Balances"
def transaction(day, narration, debit, credit_account, value):
print(f'\n{day} * "{narration}"')
print(f" {debit} {value:.2f} USD")
print(f" {credit_account} {-value:.2f} USD")
print('option "operating_currency" "USD"')
for account in sorted({bank, equity, asset, expense, credit}):
print(f"2024-01-01 open {account} USD")
transaction("2024-01-01", "Example opening cash", bank, equity, total)
transaction(paid, f"Pay {args.scenario}", asset, bank, total)
for index in range(months):
year, month_index = divmod(start.year * 12 + start.month - 1 + index, 12)
month = month_index + 1
day = min(start.day, calendar.monthrange(year, month)[1])
release_date = date(year, month, day)
# Put the entire rounding remainder into the final release exactly once.
release = monthly if index < months - 1 else total - monthly * (months - 1)
transaction(release_date, f"{args.scenario} release {index + 1}/{months}",
expense, credit, release)Exécutez ce bloc de commandes depuis le répertoire contenant amortize.py :
python3 amortize.py insurance > insurance.beancount
uvx --from beancount-io==0.1.0 bea --file insurance.beancount checkLe paiement crédite le compte courant de 600.00 USD et débite l'assurance payée d'avance du même montant. Chaque libération débite la charge et crédite l'assurance payée d'avance de 100.00 USD. Il y a six libérations, les 1er juin, 1er juillet, 1er août, 1er septembre, 1er octobre et 1er novembre 2024. Le solde payé d'avance est de 500.00 USD après la libération de juin, 400.00 USD après celle de juillet, et zéro après celle de novembre.
Exemples pratiques
Licence logicielle annuelle
Utilisez le même script enregistré pour générer un exemple logiciel distinct et autonome :
python3 amortize.py software > software.beancount
uvx --from beancount-io==0.1.0 bea --file software.beancount checkLe paiement de la licence de 1 200 $ a lieu le 15 janvier 2024. Douze libérations de 100.00 USD s'étendent du 15 janvier au 15 décembre 2024. Cet exemple comptabilise un mois complet à chaque début de mois ; il ne proratise pas janvier. Après la dernière libération, Assets:Prepaid:Software est à zéro et Expenses:Software:Adobe totalise 1200.00 USD.
Provision pour services professionnels
Cet exemple distinct traite le paiement de 4 500 $ du 5 janvier comme des frais payés d'avance consommés également sur janvier, février et mars :
python3 amortize.py retainer > retainer.beancount
uvx --from beancount-io==0.1.0 bea --file retainer.beancount checkTrois libérations de 1500.00 USD, datées des 5 janvier, 5 février et 5 mars 2024, laissent Assets:Prepaid:Professional à zéro et Expenses:Professional:Legal à 4500.00 USD. Pour une provision gagnée au fur et à mesure de la prestation des services, remplacez cette hypothèse par le calendrier de services réel.
Dépréciation d'équipement (actifs immobilisés)
La dépréciation des actifs immobilisés utilise un compte de contre-actif pour préserver le coût d'achat. Cet exemple suppose une durée d'utilité de trois ans, une valeur résiduelle nulle et une comptabilisation mensuelle complète commençant le 20 janvier 2024 :
python3 amortize.py equipment > equipment.beancount
uvx --from beancount-io==0.1.0 bea --file equipment.beancount checkL'achat débite Assets:Equipment:Computers:Cost de 3000.00 USD une seule fois. Les 36 libérations débitent Expenses:Depreciation:Computers et créditent Assets:Equipment:Computers:AccumDep. Les libérations 1 à 35 sont de 83.33 USD ; la libération 36 du 20 décembre 2026 est de 83.45 USD. Ainsi, 35 × 83.33 + 83.45 = 3000.00. Utiliser 83.33 USD pour les 36 laisserait 0.12 USD non dépréciés.
À l'achèvement, le coût reste de 3000.00 USD, la dépréciation accumulée est de -3000.00 USD, et leur valeur nette comptable est nulle. Le compte de contre-actif lui-même ne revient pas à zéro tant que l'équipement est toujours enregistré.
Reporting et vérification
1. Surveiller les soldes payés d'avance avec des assertions
Beancount vérifie un solde au début de sa date, avant les transactions de ce jour. Ajoutez ce bloc d'assertions contextuel au fichier insurance.beancount généré, puis réexécutez sa commande bea check :
2024-06-02 balance Assets:Prepaid:Insurance 500.00 USD
2024-07-02 balance Assets:Prepaid:Insurance 400.00 USD
2024-07-02 balance Expenses:Insurance:Auto 200.00 USD
2024-11-02 balance Assets:Prepaid:Insurance 0.00 USD
2024-11-02 balance Expenses:Insurance:Auto 600.00 USDLe 2 juillet suit deux libérations, celles du 1er juin et du 1er juillet. Une assertion de 500.00 USD au 2 juillet est incorrecte. Ces assertions nécessitent le journal d'assurance généré ; elles ne sont pas des transactions autonomes.
2. Vérification avancée avec bea query
Avec le fichier d'assurance généré, cette commande exécutable renvoie les soldes cumulés jusqu'au 1er juillet, en utilisant une coupure exclusive au 2 juillet :
uvx --from beancount-io==0.1.0 bea --file insurance.beancount query "SELECT account, sum(position) WHERE date < 2024-07-02 AND account ~ '^(Assets:Prepaid:Insurance|Expenses:Insurance:Auto)$' GROUP BY account ORDER BY account"Attendez-vous à Assets:Prepaid:Insurance à 400.00 USD et Expenses:Insurance:Auto à 200.00 USD. Grouper par date afficherait plutôt le mouvement de chaque jour qu'un solde cumulé.
Pour afficher tout fichier généré dans la version locale de Fava testée, utilisez :
uv run --no-project --with beancount==3.2.3 --with beanquery==0.2.0 --with fava==1.30.16 fava insurance.beancountOuvrez l'URL locale que Fava affiche. Consultez la référence des options Fava pour la configuration. Sélectionnez explicitement la période de reporting : le générateur émet le calendrier entier, y compris les dates futures, donc un total sans restriction inclut les libérations futures. Pour des fichiers de planification séparés, consultez le flux de travail des scénarios de prévision.
Limitations et conseils finaux
- Les dates sont explicites : Modifier une date d'achat ne décale pas silencieusement la première libération. Dans ce script, la première libération est égale à la date de paiement ; adaptez le début séparément si le service commence plus tard.
- L'arrondi se fait une fois : Le script arrondit le montant mensuel régulier au centime, puis place le reste dans la libération finale. Conservez le calendrier complet généré pour préserver cet ajustement.
- Les écritures ordinaires persistent : Ces libérations sont enregistrées dans le fichier généré. Examinez-les et enregistrez-les une fois. N'activez pas également l'amortissement automatique pour le même coût, sinon la charge serait comptabilisée deux fois.
- Choisissez le calendrier comptable : Ce sont des exemples de gestion, pas des règles fiscales spécifiques à une juridiction. Pour des avantages irréguliers ou une proratisation quotidienne, calculez et enregistrez les montants et dates réels à la place.