Buchen Sie vorausbezahlte Kosten als Vermögenswerte und geben Sie dann jeden Monatsanteil mit gewöhnlichen Beancount-Transaktionen als Aufwand frei. Das folgende Skript erstellt vollständige, reproduzierbare Hauptbücher für Versicherungen, Software, einen Vorschuss (Retainer) und Geräteabschreibung. Es benötigt Python 3 und keine Drittanbieter-Bibliotheken.
Beispielsweise kostet eine sechsmonatige Kfz-Versicherungspolice 600 $ im Voraus. Sechs monatliche Freigaben von jeweils 100 $ trennen die Barzahlung von der Aufwandserfassung und helfen Ihnen, effektiv zu budgetieren.
Was ist Amortisierung?
Amortisierung verteilt die Kosten eines immateriellen Vermögenswerts oder vorausbezahlten Postens über die Zeiträume, in denen er genutzt wird. Diese Beispiele verwenden eine einfache monatliche Konvention für das Management-Reporting. Sie bestimmen weder einen Steuerabzug noch eine gesetzliche Abschreibungsmethode.
Die Beancount-Lösung: fava.plugins.amortize_over
Kompatibilität geprüft am 2026-09-07: fava.plugins.amortize_over ist im Plugin-Verzeichnis des Standard-Fava 1.30.16 nicht vorhanden. Das Hinzufügen seiner plugin-Direktive zu dieser Standardinstallation führt zu einem Importfehler. Die hier portablen Beispiele wurden mit Beancount 3.2.3, beanquery 0.2.0 und Fava 1.30.16 getestet.
Die benutzerdefinierte Quelle von Beancount.io enthält jedoch eine amortize_over-Implementierung. Sie erwartet eine separate Zahlung und eine Plan-Transaktion mit genau zwei Buchungsposten und amortize_months-Metadaten. Ihre monatlichen Daten folgen dem ursprünglichen Tag des Plans, und sie lässt zukünftige Kopien zum Ladezeitpunkt aus. Ihre Rundungsregel verteilt die Cents auf die verbleibenden Zeiträume. Diese Quellenangabe belegt nicht, welche Version eine gehostete Bereitstellung derzeit ausführt. Die unten aufgeführten expliziten Pläne haben ihre eigenen angegebenen Daten und eine Rundungsregel für die Endperiode.
Schritt 1: Plugin aktivieren
Für diesen Arbeitsablauf ist kein Plugin zu aktivieren. Speichern Sie den Python-Block aus Schritt 3 als amortize.py. Installieren Sie uv, um die Validierungs- und Abfragebefehle mit den hier verwendeten Versionen auszuführen. Fava wird nur benötigt, wenn Sie die Web-Berichte wünschen.
Das Skript schreibt gewöhnliche Transaktionen auf die Standardausgabe. Leiten Sie diese Ausgabe in eine neue Beispieldatei um, prüfen Sie sie und validieren Sie sie, bevor Sie Einträge in Ihre Bücher übernehmen. Ein erneutes Ausführen mit > ersetzt diese generierte Beispieldatei; ein Anhängen mit >> würde Transaktionen duplizieren.
Schritt 2: Kontenstruktur
Jede generierte Datei ist ein eigenständiges Beispielhauptbuch. Das Versicherungsbeispiel eröffnet diese Konten und stellt einen illustrativen Kontostand von 600 $ auf dem Bankkonto vor der Prämienzahlung bereit:
| Konto | Zweck |
|---|---|
Assets:Bank:Checking | Bargeld für die Zahlung |
Assets:Prepaid:Insurance | Prämie, die auf Aufwandserfassung wartet |
Expenses:Insurance:Auto | Monatliche Versicherungsausgabe |
Equity:Opening-Balances | Gegenkonto des Beispiels-Startguthabens |
Wenn Sie die generierten Transaktionen an ein bestehendes Hauptbuch anpassen, verwenden Sie Ihre tatsächlichen Kontenöffnungen und Ihren Bankkontostand. Fügen Sie das Startguthaben des Beispiels nicht zu einem bereits finanzierten Konto hinzu und buchen Sie einen Kauf nicht erneut, wenn er bereits in Ihren Büchern vorhanden ist.
Schritt 3: Die amortisierte Transaktion erfassen
Speichern Sie dieses vollständige Programm als amortize.py. Jedes Szenario gibt das Zahlungsdatum, die Anzahl der monatlichen Freigaben, den gekauften Vermögenswert, das Aufwandskonto und das Konto an, das durch die Freigaben gutgeschrieben wird. Die erste Freigabe erfolgt am Zahlungsdatum; spätere Freigaben fallen auf denselben Tag der Folgemonate, bei Bedarf auf Monatsende geklemmt.
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)Führen Sie diesen Befehlsblock aus dem Verzeichnis aus, das amortize.py enthält:
python3 amortize.py insurance > insurance.beancount
uvx --from beancount-io==0.1.0 bea --file insurance.beancount checkDie Zahlung schreibt das Girokonto mit 600.00 USD gut und belastet die vorausbezahlte Versicherung mit demselben Betrag. Jede Freigabe belastet das Aufwandskonto und schreibt der vorausbezahlten Versicherung 100.00 USD gut. Es gibt sechs Freigaben am 1. Juni, 1. Juli, 1. August, 1. September, 1. Oktober und 1. November 2024. Das vorausbezahlte Guthaben beträgt nach der Freigabe im Juni 500.00 USD, nach der im Juli 400.00 USD und nach der im November null.
Praktische Beispiele
Jährliche Softwarelizenz
Verwenden Sie dasselbe gespeicherte Skript, um ein separates eigenständiges Software-Beispiel zu generieren:
python3 amortize.py software > software.beancount
uvx --from beancount-io==0.1.0 bea --file software.beancount checkDie Lizenzzahlung von 1.200 $ erfolgt am 15. Januar 2024. Zwölf Freigaben von 100.00 USD laufen vom 15. Januar bis 15. Dezember 2024. Dieses Beispiel erfasst jeweils einen vollen Monat zu jedem Monatsbeginn; es rechnet den Januar nicht anteilig. Nach der letzten Freigabe ist Assets:Prepaid:Software null und Expenses:Software:Adobe summiert sich auf 1200.00 USD.
Vorschuss für professionelle Dienstleistungen
Dieses separate Beispiel behandelt die Zahlung von 4.500 $ am 5. Januar als vorausbezahlte Gebühr, die gleichmäßig über Januar, Februar und März verbraucht wird:
python3 amortize.py retainer > retainer.beancount
uvx --from beancount-io==0.1.0 bea --file retainer.beancount checkDrei Freigaben von 1500.00 USD, datiert auf den 5. Januar, 5. Februar und 5. März 2024, lassen Assets:Prepaid:Professional auf null und Expenses:Professional:Legal auf 4500.00 USD zurück. Für einen Vorschuss, der verdient wird, wenn Dienstleistungen erbracht werden, ersetzen Sie diese Annahme durch den tatsächlichen Dienstleistungsplan.
Geräteabschreibung (Anlagevermögen)
Abschreibung für Anlagevermögen verwendet ein Gegenkonto, um die Anschaffungskosten zu erhalten. Dieses Beispiel geht von einer dreijährigen Nutzungsdauer, einem Restwert von null und voller monatlicher Erfassung ab dem 20. Januar 2024 aus:
python3 amortize.py equipment > equipment.beancount
uvx --from beancount-io==0.1.0 bea --file equipment.beancount checkDer Kauf belastet Assets:Equipment:Computers:Cost einmalig mit 3000.00 USD. Die 36 Freigaben belasten Expenses:Depreciation:Computers und schreiben Assets:Equipment:Computers:AccumDep gut. Freigaben 1–35 betragen 83.33 USD; Freigabe 36 am 20. Dezember 2026 beträgt 83.45 USD. Somit ergibt 35 × 83.33 + 83.45 = 3000.00. Würde man für alle 36 Freigaben 83.33 USD verwenden, blieben 0.12 USD nicht abgeschrieben.
Bei Abschluss bleiben die Kosten bei 3000.00 USD, die kumulierte Abschreibung beträgt -3000.00 USD, und ihr Netto-Buchwert ist null. Das Gegenkonto selbst kehrt nicht auf null zurück, solange das Gerät noch erfasst ist.
Berichterstattung und Verifikation
1. Überwachen vorausbezahlter Salden mit Assertions
Beancount prüft einen Saldo zu Beginn seines Datums, vor den Transaktionen dieses Tages. Fügen Sie diesen kontextuellen Assertions-Block an die generierte insurance.beancount an und führen Sie dann ihren bea check-Befehl erneut aus:
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 USDDer 2. Juli folgt auf zwei Freigaben, den 1. Juni und den 1. Juli. Eine Assertion von 500.00 USD am 2. Juli ist falsch. Diese Assertions benötigen das generierte Versicherungshauptbuch; sie sind keine eigenständigen Transaktionen.
2. Fortgeschrittene Verifikation mit bea query
Mit der generierten Versicherungsdatei liefert dieser ausführbare Befehl kumulative Salden bis zum 1. Juli, mit einem exklusiven Stichtag 2. Juli:
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"Erwarten Sie Assets:Prepaid:Insurance bei 400.00 USD und Expenses:Insurance:Auto bei 200.00 USD. Eine Gruppierung nach Datum würde stattdessen die Bewegungen jedes Tages zeigen, nicht einen kumulativen Saldo.
Um eine generierte Datei in der getesteten lokalen Fava-Version anzuzeigen, verwenden Sie:
uv run --no-project --with beancount==3.2.3 --with beanquery==0.2.0 --with fava==1.30.16 fava insurance.beancountÖffnen Sie die lokale URL, die Fava ausgibt. Weitere Konfigurationsoptionen finden Sie in der Fava-Optionen-Referenz. Wählen Sie den Berichtszeitraum explizit aus: Der Generator erzeugt den gesamten Zeitplan, einschließlich zukünftiger Daten, sodass ein unbegrenzter Gesamtbetrag zukünftige Freigaben enthält. Für separate Planungsdateien siehe den Forecast-Szenario-Workflow.
Einschränkungen und abschließende Tipps
- Daten sind explizit: Eine Änderung des Kaufdatums verschiebt die erste Freigabe nicht stillschweigend. In diesem Skript entspricht die erste Freigabe dem Zahlungsdatum; passen Sie den Start separat an, wenn die Dienstleistung später beginnt.
- Rundung erfolgt einmalig: Das Skript rundet den regulären monatlichen Betrag auf Cents und legt den Rest in die letzte Freigabe. Behalten Sie den vollständigen generierten Zeitplan bei, um diese Anpassung zu erhalten.
- Gewöhnliche Einträge bleiben bestehen: Diese Freigaben sind in der generierten Datei gespeichert. Prüfen und erfassen Sie sie einmalig. Aktivieren Sie nicht zusätzlich automatische Amortisierung für dieselben Kosten, da die Aufwendungen sonst doppelt erfasst würden.
- Wählen Sie den Buchungszeitplan: Dies sind Management-Beispiele, keine rechtsgebietspezifischen Steuerregeln. Für unregelmäßige Leistungen oder tagesgenaue Abgrenzung berechnen und erfassen Sie die tatsächlichen Beträge und Daten.