هزینههای پیشپرداختشده را بهعنوان دارایی ثبت کنید، سپس سهم هر ماه را با تراکنشهای معمولی Beancount به هزینه آزاد کنید. اسکریپت زیر دفترهای کامل و قابلتکرار را برای بیمه، نرمافزار، حق مشاوره و استهلاک تجهیزات چاپ میکند. این اسکریپت به پایتون ۳ نیاز دارد و هیچ کتابخانهی شخص ثالثی لازم نیست.
بهعنوان مثال، یک بیمهنامهی شش ماههی خودرو ۶۰۰ دلار بهصورت یکجا هزینه دارد. شش قسط ماهانهی ۱۰۰ دلاری، پرداخت نقدی را از شناسایی هزینه جدا میکند و به شما کمک میکند بودجهی مؤثر داشته باشید.
مستهلکسازی چیست؟
مستهلکسازی هزینهی یک دارایی نامشهود یا قلم پیشپرداختی را در طول دورههایی که سود میرساند، توزیع میکند. این مثالها از یک قرارداد سادهی ماهانه برای گزارشگیری مدیریتی استفاده میکنند. آنها مبنای کسر مالیاتی یا روش استهلاک قانونی را تعیین نمیکنند.
راهحل Beancount: fava.plugins.amortize_over
سازگاری در تاریخ 2026-09-07 بررسی شد: fava.plugins.amortize_over در فهرست پلاگینهای Fava استاندارد 1.30.16 وجود ندارد. افزودن دستور plugin آن به نصب استاندارد فوق، خطای import ایجاد میکند. مثالهای قابلحمل در اینجا با Beancount 3.2.3، beanquery 0.2.0 و Fava 1.30.16 آزمایش شدهاند.
منبع سفارشی Beancount.io حاوی یک پیادهسازی amortize_over است. این پیادهسازی انتظار یک پرداخت جداگانه و یک تراکنش زمانبندی با دقیقاً دو قید و متادیتای amortize_months دارد. تاریخهای ماهانهی آن از روز اصلی زمانبندی پیروی میکنند و در زمان بارگذاری، رونوشتهای آینده را حذف میکند. قانون گرد کردن آن سنتها را در دورههای باقیمانده توزیع میکند. این شواهد منبع مشخص نمیکند که کدام نسخه در حال اجرا است. زمانبندیهای صریح زیر دارای تاریخهای اعلامشده و قانون گرد کردن دورهی پایانی خود هستند.
مرحله ۱: فعالسازی پلاگین
هیچ پلاگینی برای فعالسازی در این گردشکار وجود ندارد. بلوک پایتون در مرحله ۳ را بهعنوان amortize.py ذخیره کنید. uv را برای اجرای دستورات اعتبارسنجی و پرسوجو با نسخههای استفادهشده در اینجا نصب کنید. Fava فقط در صورت نیاز به گزارشهای وب لازم است.
اسکریپت تراکنشهای معمولی را به خروجی استاندارد مینویسد. آن خروجی را به یک فایل مثال جدید هدایت کنید، آن را بررسی کنید و قبل از گنجاندن اقلام در دفتر خود، اعتبارسنجی کنید. اجرای مجدد با > آن فایل مثال تولیدشده را جایگزین میکند؛ افزودن با >> تراکنشها را تکراری میکند.
مرحله ۲: ساختار حسابهای خود
هر فایل تولیدشده یک دفتر مثال مستقل است. مثال بیمه این حسابها را باز میکند و موجودی اولیهی بانکی ۶۰۰ دلاری را قبل از پرداخت حق بیمه فراهم میکند:
| حساب | هدف |
|---|---|
Assets:Bank:Checking | نقدی که برای پرداخت استفاده میشود |
Assets:Prepaid:Insurance | حق بیمهی در انتظار شناسایی هزینه |
Expenses:Insurance:Auto | هزینهی ماهانهی بیمه |
Equity:Opening-Balances | طرف مقابل موجودی نقدی اولیهی مثال |
هنگام تطبیق تراکنشهای تولیدشده با دفتر موجود، از باز شدن حسابها و موجودی بانک واقعی خود استفاده کنید. موجودی نقدی اولیهی مثال را به حسابی که قبلاً تأمین شده اضافه نکنید، یا اگر خریدی قبلاً در دفتر شما ثبت شده، دوباره آن را ثبت نکنید.
مرحله ۳: ثبت تراکنش مستهلکسازیشده
این برنامهی کامل را بهعنوان amortize.py ذخیره کنید. هر سناریو تاریخ پرداخت، تعداد قسطهای ماهانه، دارایی خرید، حساب هزینه و حسابی که قسطها به آن بستانکار میشوند را مشخص میکند. اولین قسط در تاریخ پرداخت است؛ قسطهای بعدی در همان روز ماههای بعدی قرار میگیرند و در صورت لزوم به آخر ماه محدود میشوند.
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)این بلوک دستور را از دایرکتوری حاوی amortize.py اجرا کنید:
python3 amortize.py insurance > insurance.beancount
uvx --from beancount-io==0.1.0 bea --file insurance.beancount checkپرداخت با 600.00 USD به چکینگ بستانکار و با همان مبلغ به بیمهی پیشپرداختی بدهکار میشود. هر قسط هزینه را بدهکار و بیمهی پیشپرداختی را با 100.00 USD بستانکار میکند. شش قسط وجود دارد: در تاریخ ۱ ژوئن، ۱ ژوئیه، ۱ اوت، ۱ سپتامبر، ۱ اکتبر و ۱ نوامبر ۲۰۲۴. موجودی پیشپرداختی پس از قسط ژوئن 500.00 USD، پس از قسط ژوئیه 400.00 USD و پس از قسط نوامبر صفر است.
مثالهای عملی
مجوز نرمافزار سالانه
از همان اسکریپت ذخیرهشده استفاده کنید تا یک مثال نرمافزاری مستقل جداگانه تولید کنید:
python3 amortize.py software > software.beancount
uvx --from beancount-io==0.1.0 bea --file software.beancount checkپرداخت مجوز ۱٬۲۰۰ دلاری در تاریخ ۱۵ ژانویهی ۲۰۲۴ است. دوازده قسط 100.00 USD از ۱۵ ژانویه تا ۱۵ دسامبر ۲۰۲۴ اجرا میشوند. این مثال یک ماه کامل را در ابتدای هر ماه شناسایی میکند؛ ژانویه را بر اساس روز محاسبه نمیکند. پس از آخرین قسط، Assets:Prepaid:Software صفر و Expenses:Software:Adobe مجموعاً 1200.00 USD است.
حق مشاورهی خدمات حرفهای
این مثال جداگانه، پرداخت ۴٬۵۰۰ دلاری ۵ ژانویه را بهعنوان هزینهی پیشپرداختی در نظر میگیرد که بهطور مساوی در ژانویه، فوریه و مارس مصرف میشود:
python3 amortize.py retainer > retainer.beancount
uvx --from beancount-io==0.1.0 bea --file retainer.beancount checkسه قسط 1500.00 USD با تاریخهای ۵ ژانویه، ۵ فوریه و ۵ مارس ۲۰۲۴، Assets:Prepaid:Professional را صفر و Expenses:Professional:Legal را 4500.00 USD میگذارند. برای حق مشاورهای که با ارائهی خدمات کسب میشود، این فرض را با زمانبندی خدمات واقعی جایگزین کنید.
استهلاک تجهیزات (داراییهای ثابت)
استهلاک داراییهای ثابت از یک حساب ضد دارایی برای حفظ هزینهی خرید استفاده میکند. این مثال یک عمر مفید سهساله، ارزش باقیماندهی صفر و شناسایی کامل ماهانه از ۲۰ ژانویهی ۲۰۲۴ را فرض میکند:
python3 amortize.py equipment > equipment.beancount
uvx --from beancount-io==0.1.0 bea --file equipment.beancount checkخرید یک بار Assets:Equipment:Computers:Cost را با 3000.00 USD بدهکار میکند. ۳۶ قسط Expenses:Depreciation:Computers را بدهکار و Assets:Equipment:Computers:AccumDep را بستانکار میکنند. قسطهای ۱ تا ۳۵ هر کدام 83.33 USD هستند؛ قسط ۳۶ در تاریخ ۲۰ دسامبر ۲۰۲۶ 83.45 USD است. بنابراین 35 × 83.33 + 83.45 = 3000.00. استفاده از 83.33 USD برای هر ۳۶ قسط، 0.12 USD را بدون استهلاک باقی میگذارد.
پس از اتمام، هزینهی خرید همچنان 3000.00 USD، استهلاک انباشته -3000.00 USD و ارزش دفتری خالص صفر است. حساب ضد دارایی خودش تا زمانی که تجهیزات ثبت شدهاند، به صفر بازنمیگردد.
گزارشگیری و اعتبارسنجی
۱. نظارت بر موجودی پیشپرداختی با تأییدیهها
Beancount موجودی را در ابتدا تاریخ خود، قبل از تراکنشهای آن روز بررسی میکند. این بلوک تأییدیهای زمینهای را به insurance.beancount تولیدشده اضافه کنید و سپس دستور 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۲ ژوئیه پس از دو قسط، یعنی ۱ ژوئن و ۱ ژوئیه، میآید. تأییدیهی 500.00 USD در تاریخ ۲ ژوئیه نادرست است. این تأییدیهها به دفتر بیمهی تولیدشده نیاز دارند؛ آنها تراکنشهای مستقل نیستند.
۲. اعتبارسنجی پیشرفته با bea query
با فایل بیمهی تولیدشده، این دستور اجرایی موجودیهای تجمعی تا ۱ ژوئیه را با استفاده از یک برش انحصاری در ۲ ژوئیه برمیگرداند:
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"انتظار Assets:Prepaid:Insurance در 400.00 USD و Expenses:Insurance:Auto در 200.00 USD را داشته باشید. گروهبندی بر اساس تاریخ بهجای آن، حرکت روزانه را نشان میدهد نه موجودی تجمعی را.
برای مشاهدهی هر فایل تولیدشده در نسخهی محلی آزمایششدهی Fava، از موارد زیر استفاده کنید:
uv run --no-project --with beancount==3.2.3 --with beanquery==0.2.0 --with fava==1.30.16 fava insurance.beancountURL محلی که Fava چاپ میکند را باز کنید. برای پیکربندی، به مرجع گزینههای Fava مراجعه کنید. دورهی گزارشگیری را بهطور صریح انتخاب کنید: تولیدکننده کل زمانبندی، از جمله تاریخهای آینده را منتشر میکند، بنابراین مجموع بدون محدودیت شامل قسطهای آینده میشود. برای فایلهای برنامهریزی جداگانه، به گردشکار سناریوی پیشبینی مراجعه کنید.
محدودیتها و نکات نهایی
- تاریخها صریح هستند: تغییر تاریخ خرید، قسط اول را بیسرصدا به تعویق نمیاندازد. در این اسکریپت، قسط اول برابر با تاریخ پرداخت است؛ اگر خدمات دیرتر شروع شد، شروع را جداگانه تنظیم کنید.
- گرد کردن یک بار انجام میشود: اسکریپت مبلغ ماهانهی عادی را به سنت گرد میکند، سپس باقیمانده را در قسط پایانی قرار میدهد. کل زمانبندی تولیدشده را حفظ کنید تا آن تنظیم حفظ شود.
- اقلام معمولی باقی میمانند: این قسطها در فایل تولیدشده ذخیره میشوند. آنها را یک بار بررسی و ثبت کنید. برای همان هزینه، مستهلکسازی خودکار را نیز فعال نکنید، در غیر این صورت هزینه دو بار شناسایی میشود.
- زمانبندی حسابداری را انتخاب کنید: اینها مثالهای مدیریتی هستند، نه قوانین مالیاتی مختص حوزهی قضایی. برای مزایای نامنظم یا محاسبهی روزانه، مبالغ و تاریخهای واقعی را محاسبه و ثبت کنید.