Salta al contenuto principale

Ammortamento

Scopri come gestire efficacemente l'ammortamento in Beancount, distribuendo i costi nel tempo per una maggiore chiarezza e una migliore gestione finanziaria.

Registra i costi pagati anticipatamente tra le attività, poi imputa la quota di ciascun mese ai costi con normali transazioni Beancount. Lo script seguente genera libri contabili completi e riproducibili per un'assicurazione, una licenza software, un compenso professionale anticipato e l'ammortamento di attrezzature. Richiede Python 3 e nessuna libreria di terze parti.

Per esempio, una polizza auto semestrale costa $600 da pagare anticipatamente. Sei imputazioni mensili di $100 separano il pagamento dall'imputazione del costo e ti aiutano a pianificare il budget in modo efficace.

Che cos'è l'ammortamento?

L'ammortamento distribuisce il costo di un'attività immateriale o di un costo pagato anticipatamente tra i periodi che ne beneficiano. Questi esempi adottano una semplice convenzione mensile per la contabilità gestionale. Non determinano una deduzione fiscale né un metodo di ammortamento previsto dalla normativa.

La soluzione Beancount: fava.plugins.amortize_over

Compatibilità verificata il 2026-09-07: fava.plugins.amortize_over non è presente nella directory dei plugin della versione standard di Fava 1.30.16. Aggiungere la relativa direttiva plugin a quell'installazione standard produce un errore di importazione. Gli esempi portabili qui presentati sono stati verificati con Beancount 3.2.3, beanquery 0.2.0 e Fava 1.30.16.

Il codice sorgente personalizzato di Beancount.io contiene effettivamente un'implementazione di amortize_over. Questa richiede un pagamento separato e una transazione che definisca il piano, con esattamente due scritture e i metadati amortize_months. Le date mensili mantengono il giorno originario del piano, mentre le copie future vengono omesse al caricamento. La regola di arrotondamento distribuisce i centesimi tra i periodi rimanenti. Queste evidenze nel codice sorgente non stabiliscono quale versione sia attualmente in esecuzione sul servizio ospitato. I piani espliciti seguenti hanno date dichiarate e una propria regola di arrotondamento per l'ultimo periodo.

Passo 1: Abilitare il plugin

Per questa procedura non occorre abilitare alcun plugin. Salva il blocco Python del passo 3 come amortize.py. Installa uv per eseguire i comandi di verifica e interrogazione con le versioni utilizzate qui. Fava serve soltanto se desideri consultare i report via web.

Lo script scrive normali transazioni sullo standard output. Reindirizza l'output in un nuovo file di esempio, esaminalo e convalidalo prima di incorporare le registrazioni nei tuoi libri contabili. Una nuova esecuzione con > sostituisce il file di esempio generato; aggiungere l'output con >> duplicherebbe le transazioni.

Passo 2: Strutturare i conti

Ogni file generato è un libro contabile di esempio autonomo. L'esempio dell'assicurazione apre i conti seguenti e registra un saldo bancario iniziale dimostrativo di $600 prima di pagare il premio:

ContoFunzione
Assets:Bank:CheckingDisponibilità utilizzata per il pagamento
Assets:Prepaid:InsurancePremio in attesa di essere imputato ai costi
Expenses:Insurance:AutoCosto mensile dell'assicurazione auto
Equity:Opening-BalancesContropartita della disponibilità iniziale dell'esempio

Quando adatti le transazioni generate a un libro contabile esistente, usa le aperture dei conti e il saldo bancario effettivi. Non aggiungere la disponibilità iniziale dell'esempio a un conto già finanziato e non registrare nuovamente un acquisto già presente nei tuoi libri contabili.

Passo 3: Registrare la transazione da ripartire

Salva questo programma completo come amortize.py. Ogni scenario specifica la data del pagamento, il numero di imputazioni mensili, l'attività acquistata, il conto di costo e il conto accreditato dalle imputazioni. La prima imputazione avviene alla data del pagamento; le successive cadono nello stesso giorno dei mesi seguenti, anticipato all'ultimo giorno del mese se necessario.

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)

Esegui questo blocco di comandi dalla directory che contiene amortize.py:

python3 amortize.py insurance > insurance.beancount
uvx --from beancount-io==0.1.0 bea --file insurance.beancount check

Il pagamento accredita il conto corrente per 600.00 USD e addebita il conto dell'assicurazione pagata anticipatamente per lo stesso importo. Ogni imputazione addebita il conto di costo e accredita il conto dell'assicurazione pagata anticipatamente per 100.00 USD. Le imputazioni sono sei: il 1 giugno, il 1 luglio, il 1 agosto, il 1 settembre, il 1 ottobre e il 1 novembre 2024. Il saldo del costo anticipato è 500.00 USD dopo l'imputazione di giugno, 400.00 USD dopo quella di luglio e zero dopo quella di novembre.

Esempi pratici

Licenza software annuale

Usa lo stesso script salvato per generare un esempio software separato e autonomo:

python3 amortize.py software > software.beancount
uvx --from beancount-io==0.1.0 bea --file software.beancount check

Il pagamento della licenza di $1,200 avviene il 15 gennaio 2024. Dodici imputazioni di 100.00 USD vanno dal 15 gennaio al 15 dicembre 2024. Questo esempio imputa un mese intero all'inizio di ogni periodo mensile; non calcola una quota proporzionale per gennaio. Dopo l'ultima imputazione, Assets:Prepaid:Software è pari a zero e Expenses:Software:Adobe ammonta complessivamente a 1200.00 USD.

Compenso anticipato per servizi professionali

Questo esempio separato tratta il pagamento di $4,500 del 5 gennaio come un compenso anticipato consumato in parti uguali durante gennaio, febbraio e marzo:

python3 amortize.py retainer > retainer.beancount
uvx --from beancount-io==0.1.0 bea --file retainer.beancount check

Tre imputazioni di 1500.00 USD, datate 5 gennaio, 5 febbraio e 5 marzo 2024, portano Assets:Prepaid:Professional a zero e Expenses:Professional:Legal a 4500.00 USD. Per un compenso maturato con l'effettiva prestazione dei servizi, sostituisci questa ipotesi con il calendario reale delle prestazioni.

Ammortamento delle attrezzature (immobilizzazioni materiali)

L'ammortamento delle immobilizzazioni materiali utilizza un conto di rettifica dell'attivo per mantenere visibile il costo d'acquisto. Questo esempio ipotizza una vita utile di tre anni, un valore residuo pari a zero e l'imputazione di quote mensili intere a partire dal 20 gennaio 2024:

python3 amortize.py equipment > equipment.beancount
uvx --from beancount-io==0.1.0 bea --file equipment.beancount check

L'acquisto addebita Assets:Equipment:Computers:Cost per 3000.00 USD una sola volta. Le 36 quote addebitano Expenses:Depreciation:Computers e accreditano Assets:Equipment:Computers:AccumDep. Le quote 1–35 sono di 83.33 USD; la quota 36 del 20 dicembre 2026 è di 83.45 USD. Quindi 35 × 83.33 + 83.45 = 3000.00. Usare 83.33 USD per tutte e 36 le quote lascerebbe 0.12 USD da ammortizzare.

Al termine, il costo rimane 3000.00 USD, il fondo ammortamento è -3000.00 USD e il loro valore contabile netto è zero. Il conto di rettifica dell'attivo non torna a zero finché l'attrezzatura rimane registrata.

Report e verifica

1. Controllare i saldi dei costi anticipati con le asserzioni

Beancount controlla un saldo all'inizio della data indicata, prima delle transazioni di quel giorno. Aggiungi questo blocco di asserzioni contestuali al file insurance.beancount generato, poi esegui nuovamente il relativo comando 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 USD

Il 2 luglio segue due imputazioni, quelle del 1 giugno e del 1 luglio. Un'asserzione di 500.00 USD al 2 luglio è errata. Queste asserzioni richiedono il libro contabile dell'assicurazione generato; non sono transazioni autonome.

2. Verifica avanzata con bea query

Con il file dell'assicurazione generato, questo comando eseguibile restituisce i saldi cumulativi fino al 1 luglio, usando il 2 luglio come limite esclusivo:

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"

Il risultato atteso è Assets:Prepaid:Insurance a 400.00 USD e Expenses:Insurance:Auto a 200.00 USD. Raggruppare invece per data mostrerebbe i movimenti di ogni giorno, anziché un saldo cumulativo.

Per visualizzare un file generato nella versione locale di Fava verificata, usa:

uv run --no-project --with beancount==3.2.3 --with beanquery==0.2.0 --with fava==1.30.16 fava insurance.beancount

Apri l'URL locale mostrato da Fava. Consulta il riferimento delle opzioni di Fava per la configurazione. Seleziona esplicitamente il periodo del report: il generatore produce l'intero piano, comprese le date future, quindi un totale senza limiti temporali include le imputazioni future. Per i file di pianificazione separati, consulta la procedura per gli scenari previsionali.

Limiti e suggerimenti finali

  • Le date sono esplicite: Cambiare una data di acquisto non rinvia implicitamente la prima imputazione. In questo script la prima imputazione coincide con la data del pagamento; modifica separatamente l'inizio se il servizio comincia più tardi.
  • L'arrotondamento avviene una sola volta: Lo script arrotonda ai centesimi l'importo mensile ordinario, poi attribuisce il residuo all'ultima imputazione. Conserva l'intero piano generato per mantenere questa rettifica.
  • Le registrazioni ordinarie rimangono salvate: Queste imputazioni vengono salvate nel file generato. Esaminale e registrale una sola volta. Non abilitare anche l'ammortamento automatico per lo stesso costo, altrimenti il costo verrebbe imputato due volte.
  • Scegli il piano contabile: Questi sono esempi di contabilità gestionale, non regole fiscali specifiche di una giurisdizione. Per benefici irregolari o una ripartizione giornaliera, calcola e registra gli importi e le date effettivi.

Fonte: https://beancount.io/it/docs/Tips/amortize