Salta al contingut principal

Amortització

Apreneu a gestionar eficaçment l'amortització a Beancount, cosa que us permet distribuir les despeses al llarg del temps per a una millor claredat i gestió financera.

Registreu els costos prepagats com a actius i després allibereu la part mensual a despeses amb transaccions ordinàries de Beancount. El script següent imprimeix llibres majors complets i reproduïbles per a assegurances, programari, un honorari i depreciació d'equipament. Necessita Python 3 i cap biblioteca de tercers.

Per exemple, una pòlissa d'assegurança d'automòbil de sis mesos costa $600 per avançat. Sis alliberaments mensuals de $100 separen el pagament en efectiu del reconeixement de la despesa i us ajuden a pressupostar eficaçment.

Què és l'Amortització?

L'amortització distribueix el cost d'un actiu intangible o element prepagat al llarg dels períodes que en beneficia. Aquests exemples utilitzen una convenció mensual senzilla per a informes de gestió. No determinen una deducció fiscal ni un mètode de depreciació legal.

La Solució de Beancount: fava.plugins.amortize_over

Compatibilitat comprovada el 07-09-2026: fava.plugins.amortize_over és absent del directori de complements de Fava estàndard 1.30.16. Afegir la seva directiva plugin a aquesta instal·lació estàndard produeix un error d'importació. Els exemples portàtils aquí es van provar amb Beancount 3.2.3, beanquery 0.2.0 i Fava 1.30.16.

El codi font personalitzat de Beancount.io sí que conté una implementació d'amortize_over. Espera un pagament separat i una transacció de calendari amb exactament dos assentaments i les metadades amortize_months. Les seves dates mensuals segueixen el dia original del calendari i omet les còpies futures en el moment de la càrrega. La seva regla d'arrodoniment distribueix els cèntims entre els períodes restants. Aquesta evidència del codi font no estableix quina versió executa actualment una implementació allotjada. Els calendaris explícits a continuació tenen les seves pròpies dates declarades i la regla d'arrodoniment del període final.

Pas 1: Activeu el Complement

No hi ha cap complement a activar per a aquest flux de treball. Deseu el bloc de Python del pas 3 com a amortize.py. Instal·leu uv per executar les ordres de validació i consulta amb les versions utilitzades aquí. Només cal Fava si voleu els informes web.

El script escriu transaccions ordinàries a la sortida estàndard. Redirigiu aquesta sortida a un nou fitxer d'exemple, inspeccioneu-lo i valideu-lo abans d'incorporar les anotacions als vostres llibres. Tornar a executar amb > substitueix aquest fitxer d'exemple generat; afegir amb >> duplicaria les transaccions.

Pas 2: Estructureu els Vostres Comptes

Cada fitxer generat és un llibre major d'exemple independent. L'exemple d'assegurança obre aquests comptes i proporciona un saldo bancari inicial il·lustratiu de $600 abans de pagar la prima:

ComptePropòsit
Assets:Bank:CheckingEfectiu utilitzat per al pagament
Assets:Prepaid:InsurancePrima pendent de reconeixement de despesa
Expenses:Insurance:AutoDespesa mensual d'assegurança
Equity:Opening-BalancesContrapartida de l'efectiu inicial de l'exemple

Quan adapteu les transaccions generades a un llibre major existent, utilitzeu les vostres obertures de comptes i el vostre saldo bancari reals. No afegiu l'efectiu inicial de l'exemple a un compte ja finançat, ni registreu una compra de nou si ja és als vostres llibres.

Pas 3: Registreu la Transacció Amortitzada

Deseu aquest programa complet com a amortize.py. Cada escenari especifica la data de pagament, el nombre d'alliberaments mensuals, l'actiu de compra, el compte de despeses i el compte acreditat pels alliberaments. El primer alliberament és a la data de pagament; els alliberaments posteriors cauen el mateix dia dels mesos següents, ajustats a final de mes si cal.

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)

Executeu aquest bloc d'ordres des del directori que conté amortize.py:

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

El pagament acredita el compte corrent amb 600.00 USD i carrega l'assegurança prepagada amb la mateixa quantitat. Cada alliberament carrega la despesa i acredita l'assegurança prepagada amb 100.00 USD. Hi ha sis alliberaments, l'1 de juny, l'1 de juliol, l'1 d'agost, l'1 de setembre, l'1 d'octubre i l'1 de novembre de 2024. El saldo prepagat és de 500.00 USD després de l'alliberament de juny, 400.00 USD després del de juliol i zero després del de novembre.

Exemples Pràctics

Llicència de Programari Anual

Utilitzeu el mateix script desat per generar un exemple de programari independent separat:

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

El pagament de la llicència de $1,200 és el 15 de gener de 2024. Dotze alliberaments de 100.00 USD van del 15 de gener al 15 de desembre de 2024. Aquest exemple reconeix un mes complet a cada inici mensual; no fa prorrateig de gener. Després de l'últim alliberament, Assets:Prepaid:Software és zero i Expenses:Software:Adobe suma 1200.00 USD.

Honorari de Serveis Professionals

Aquest exemple separat tracta el pagament de $4,500 del 5 de gener com una tarifa prepagada consumida equitativament durant gener, febrer i març:

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

Tres alliberaments de 1500.00 USD, amb dates del 5 de gener, 5 de febrer i 5 de març de 2024, deixen Assets:Prepaid:Professional a zero i Expenses:Professional:Legal a 4500.00 USD. Per a un honorari guanyat a mesura que es presten els serveis, substituïu aquesta hipòtesi pel calendari de serveis real.

Depreciació d'Equipament (Actius Fixos)

La depreciació d'actius fixos utilitza un compte de contra-actiu per preservar el cost de compra. Aquest exemple assumeix una vida útil de tres anys, valor residual zero i reconeixement mensual complet a partir del 20 de gener de 2024:

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

La compra carrega Assets:Equipment:Computers:Cost amb 3000.00 USD una sola vegada. Els 36 alliberaments carreguen Expenses:Depreciation:Computers i acrediten Assets:Equipment:Computers:AccumDep. Els alliberaments 1–35 són de 83.33 USD; l'alliberament 36 del 20 de desembre de 2026 és de 83.45 USD. Així, 35 × 83.33 + 83.45 = 3000.00. Utilitzar 83.33 USD per a tots 36 deixaria 0.12 USD sense depreciar.

En finalitzar, el cost roman en 3000.00 USD, la depreciació acumulada és de -3000.00 USD i el seu valor net comptable és zero. El compte de contra-actiu en si no torna a zero mentre l'equipament encara estigui registrat.

Informes i Verificació

1. Superviseu els Saldos Prepagats amb Assertions

Beancount comprova un saldo a l'inici de la seva data, abans de les transaccions d'aquest dia. Afegiu aquest bloc d'assertions contextuals al fitxer insurance.beancount generat i torneu a executar la seva ordre 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

El 2 de juliol segueix dos alliberaments, l'1 de juny i l'1 de juliol. Una assertió de 500.00 USD el 2 de juliol és incorrecta. Aquestes assertions necessiten el llibre major d'assegurança generat; no són transaccions independents.

2. Verificació Avançada amb bea query

Amb el fitxer d'assegurança generat, aquesta ordre executable retorna els saldos acumulats fins a l'1 de juliol, utilitzant un tall exclusiu el 2 de juliol:

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"

Espereu Assets:Prepaid:Insurance a 400.00 USD i Expenses:Insurance:Auto a 200.00 USD. Agrupar per data en lloc d'això mostraria el moviment de cada dia en lloc d'un saldo acumulat.

Per visualitzar qualsevol fitxer generat a la versió local de Fava provada, utilitzeu:

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

Obriu l'URL local que imprimeix Fava. Consulteu la referència d'opcions de Fava per a la configuració. Seleccioneu el període d'informe explícitament: el generador emet el calendari complet, incloses les dates futures, de manera que un total sense restriccions inclou els alliberaments futurs. Per a fitxers de planificació separats, vegeu el flux de treball d'escenaris de previsió.

Limitacions i Consells Finals

  • Les dates són explícites: Canviar una data de compra no ajorna silenciosament el primer alliberament. En aquest script, el primer alliberament és igual a la data de pagament; adapteu l'inici per separat si el servei comença més tard.
  • L'arrodoniment passa una vegada: El script arrodoneix la quantitat mensual regular a cèntims i després posa la resta a l'alliberament final. Conserveu el calendari complet generat per preservar aquest ajust.
  • Les anotacions ordinàries persisteixen: Aquests alliberaments es desen al fitxer generat. Reviseu-los i registreu-los una vegada. No habiliteu també l'amortització automàtica per al mateix cost, o la despesa es reconeixeria dues vegades.
  • Trieu el calendari comptable: Aquests són exemples de gestió, no regles fiscals específiques de jurisdicció. Per a beneficis irregulars o prorrateig diari, calculeu i registreu les quantitats i dates reals en lloc d'això.

Font: https://beancount.io/ca/docs/Tips/amortize