راهنمای جامع مهاجرت از QuickBooks به Beancount
مرحله ۱: استخراج دادهها از QuickBooks
مهاجرت دادههای پنج ساله با خارج کردن تمام سوابق QuickBooks در یک فرمت قابل استفاده آغاز میشود. QuickBooks Desktop و QuickBooks Online گزینههای خروجیگیری متفاوتی دارند:
۱.۱ QuickBooks Desktop – گزینههای خروجیگیری
IIF (Intuit Interchange Format): نرمافزار QuickBooks Desktop میتواند لیستها (مانند سرفصل حسابها، مشتریان، فروشندگان) را به فایلهای متنی .IIF
خروجی بگیرد. در QuickBooks Desktop، به مسیر File → Utilities → Export → Lists to IIF بروید، سپس لیستهای مورد نیاز خود (مانند Chart of Accounts، Customers، Vendors) را انتخاب کنید. این کار یک فایل متنی تولید میکند که شامل نام حسابها، انواع آنها و دادههای لیست است. IIF یک فرمت اختصاصی اما مبتنی بر متن ساده است که تجزیه (parse) آن نسبتاً آسان است. از آن برای استخراج سرفصل حسابها (Chart of Accounts) و لیست مخاطبین خود برای ارجاع در Beancount استفاده کنید.
دفتر کل/دفتر روزنامه از طریق CSV: برای دادههای تراکنش، QuickBooks Desktop یک خروجی کامل با یک کلیک ارائه نمیدهد، اما میتوانید از گزارشها استفاده کنید. روش پیشنهادی، خروجی گرفتن از دفتر روزنامه عمومی (General Journal) (شامل تمام تراکنشها) در بازه زمانی مورد نظر است. در QuickBooks Desktop، به مسیر Reports → Accountant & Taxes → Journal بروید، تاریخها را از اولین تراکنش تا امروز تنظیم کنید و روی Export → Excel کلیک کنید. پس از حذف هرگونه سرصفحه/پاصفحه گزارش و ستونهای خالی، نتیجه را به صورت CSV ذخیره کنید. اطمینان حاصل کنید که دادههای عددی تمیز هستند: شامل سنت (مثلاً 3.00
نه 3
)، بدون علامت نقل قول اضافی، و بدون نماد ارز یا منفیهای دوگانه در CSV باشند. فایل CSV باید ستونهایی مانند Date, Trans #, Name, Account, Memo, Debit, Credit, Balance (یا یک ستون Amount واحد بسته به فرمت گزارش) داشته باشد.
نکته: QuickBooks Desktop 2015 به بعد همچنین میتواند تراکنشها را از طریق کادر محاورهای Find خروجی بگیرد. از مسیر Edit → Find → Advanced استفاده کنید، بازه زمانی را برای پنج سال تنظیم کنید، سپس نتایج را به CSV خروجی بگیرید. هشدار: برخی نسخهها خروجی را به 32,768 خط محدود میکنند. اگر دادههای بسیار بزرگی دارید، برای جلوگیری از بریده شدن دادهها، سال به سال (یا در بخشهای کوچکتر) خروجی بگیرید و بعداً آنها را ترکیب کنید. اطمینان حاصل کنید که بازههای زمانی برای جلوگیری از تکرار، همپوشانی نداشته باشند.
فرمتهای دیگر (QBO/QFX/QIF): نرمافزار QuickBooks Desktop میتواند تراکنشهای بانکی را از طریق فایلهای .QBO
(Web Connect) یا .QFX/.OFX
وارد کند، اما برای خروجی گرفتن از QuickBooks، این فرمتها معمول نیستند. اگر هدف شما فقط استخراج تراکنشهای بانکی است، ممکن است قبلاً آنها را در فرمت QBO/OFX از بانک خود داشته باشید. با این حال، برای خروجی کامل دفتر کل، به IIF و CSV پایبند باشید. QuickBooks Desktop نمیتواند مستقیماً بدون ابزارهای شخص ثالث به فرمت QIF (Quicken Interchange Format) خروجی بگیرد. اگر راهی برای دریافت QIF پیدا کردید، توجه داشته باشید که برخی از ابزارهای دفتر کل (مانند Ledger 2.x قدیمی) میتوانستند QIF را بخوانند، اما بهتر است در این فرآیند با CSV کار کنیم.
۱.۲ QuickBooks Online – گزینههای خروجیگیری
خروجی داخلی Excel/CSV: نسخه آنلاین QuickBooks (QBO) ابزاری به نام Export Data ارائه میدهد. به Settings ⚙ → Tools → Export Data بروید. در کادر محاورهای خروجی، از تب Reports برای انتخاب دادهها (مانند General Ledger یا Transaction List) و از تب Lists برای لیستها (سرفصل حسابها و غیره) استفاده کنید، All dates را انتخاب کرده و به Excel خروجی بگیرید. QuickBooks Online یک فایل ZIP حاوی چندین فایل Excel برای گزارشها و لیستهای انتخاب شده (به عنوان مثال، سود و زیان، ترازنامه، دفتر کل، مشتریان، فروشندگان، سرفصل حسابها و غیره) دانلود میکند. سپس میتوانید این فایلهای Excel را برای پردازش به CSV تبدیل کنید.
گزارش جزئیات تراکنش: اگر خروجی پیشفرض QBO شامل یک فایل دفتر کل واحد نباشد، میتوانید به صورت دستی یک گزارش دقیق تهیه کنید:
- به Reports بروید و Transaction Detail by Account (یا General Ledger در برخی نسخههای QBO) را پیدا کنید.
- Report period را روی بازه کامل پنج ساله تنظیم کنید.
- زیر گزینههای گزارش، Group by = None را تنظیم کنید (تا تراکنشهای فردی بدون جمعهای فرعی لیست شوند).
- ستونها را سفارشی کنید تا حداقل شامل این موارد باشند: Date، Transaction Type، Number، Name (Payee/Customer)، Memo/Description، Account، Debit، Credit (یا یک ستون Amount واحد) و Balance. در صورت استفاده، هرگونه class یا location را نیز شامل کنید.
- گزارش را اجرا کرده و سپس Export to Excel را بزنید.
این کار یک دفتر کل دقیق از تمام تراکنشها را به دست میدهد. آن را به صورت CSV ذخیره کنید. هر خط نشاندهنده یک آرتیکل (پستینگ) از یک تراکنش است. بعداً برای تبدیل، باید خطوط را بر اساس تراکنش گروهبندی کنید.
سرفصل حسابها و لیستهای دیگر: در QuickBooks Online میتوانید سرفصل حسابها را از طریق Accounting → Chart of Accounts → Batch Actions → Export to Excel خروجی بگیرید. این کار را برای دریافت نامها و انواع حسابها انجام دهید. به همین ترتیب، اگر میخواهید نامها را برای فراداده (metadata) حفظ کنید، لیست مشتریان، فروشندگان و غیره را نیز خروجی بگیرید.
API QuickBooks Online (اختیاری): برای یک رویکرد برنامهنویسی، Intuit یک REST API برای دادههای QBO ارائه میدهد. کاربران پیشرفته میتوانند یک اپلیکیشن QuickBooks Online ایجاد کنند (نیاز به حساب توسعهدهنده دارد) و از API برای دریافت دادهها در فرمت JSON استفاده کنند. به عنوان مثال، میتوانید از نقطه پایانی (endpoint) Account
برای سرفصل حسابها و از نقاط پایانی گزارش JournalEntry
یا GeneralLedger
برای تراکنشها کوئری بگیرید. SDKهای پایتون مانند python-quickbooks
وجود دارند که API را در خود جای دادهاند. با این حال، استفاده از API شامل احراز هویت OAuth است و برای یک مهاجرت یکباره، مگر اینکه اتوماسیون را ترجیح دهید، بیش از حد پیچیده است. برای اکثر موارد، خروجی دستی به CSV/Excel سادهتر و کمتر مستعد خطا است.
مرحله ۲: تبدیل و پاکسازی دادهها
هنگامی که دادههای QuickBooks را در فرمت CSV (و/یا IIF) در اختیار دارید، مرحله بعدی تبدیل آن به فرمت دفتر کل متنی ساده Beancount است. این شامل تجزیه خروجیها، نگاشت حسابهای QuickBooks به سرفصل حسابهای Beancount و فرمتبندی تراکنشها با سینتکس Beancount است.
۲.۱ تجزیه خروجیهای QuickBooks با پایتون
استفاده از پایتون دقت و تکرارپذیری را برای تبدیل تضمین میکند. ما اسکریپتهایی را برای دو وظیفه کلیدی تشریح میکنیم: وارد کردن سرفصل حسابها و تبدیل تراکنشها.
واردات و نگاشت حسابها: بسیار مهم است که قبل از افزودن تراکنشها، حسابهای خود را در Beancount تنظیم کنید. حسابهای QuickBooks دارای انواع (بانک، حسابهای دریافتنی، هزینه و غیره) هستند که ما آنها را به سلسله مراتب Beancount (داراییها، بدهیها، درآمد، هزینهها و غیره) نگاشت خواهیم کرد. به عنوان مثال، میتوانیم از نگاشتی مانند این استفاده کنیم:
# نگاشت نوع حساب کوییکبوکس به دستهبندی ریشه در بینکانت
AccountTypeMap = {
'BANK': 'Assets',
'CCARD': 'Liabilities',
'AR': 'Assets', # حسابهای دریافتنی به عنوان دارایی
'AP': 'Liabilities', # حسابهای پرداختنی به عنوان بدهی
'FIXASSET': 'Assets',
'OASSET': 'Assets', # سایر داراییها
'OCASSET': 'Assets', # سایر داراییهای جاری
'LTLIAB': 'Liabilities', # بدهیهای بلندمدت
'OCLIAB': 'Liabilities', # سایر بدهیهای جاری
'EQUITY': 'Equity',
'INC': 'Income',
'EXP': 'Expenses',
'EXINC': 'Income', # سایر درآمدها
'EXEXP': 'Expenses', # سایر هزینهها
}
با استفاده از خروجی IIF کوییکبوکس دسکتاپ یا CSV لیست حسابهای QBO، نام و نوع هر حساب را بازیابی میکنیم. سپس:
-
ایجاد نام حسابهای Beancount: کوییکبوکس گاهی از علامت دو نقطه (
:
) در نام حسابها برای نشان دادن حسابهای فرعی استفاده میکند (مثلاً “Current Assets:Checking”). Beancount از همین علامت دو نقطه برای سلسله مراتب استفاده میکند. اغلب میتوانید نام را مستقیماً استفاده کنید. اگر نام حسابهای کوییکبوکس با یک دستهبندی شروع نمیشود، دستهبندی نگاشت شده را به ابتدای آن اضافه کنید. برای مثال، یک حساب کوییکبوکس از نوعBANK
به نام "Checking" در Beancount بهAssets:Checking
تبدیل میشود. یک حسابEXP
(هزینه) به نام "Meals" بهExpenses:Meals
تبدیل میشود و غیره. -
اطمینان از نامگذاری معتبر: کاراکترهایی که ممکن است Beancount را گیج کنند حذف یا جایگزین کنید. کوییکبوکس کاراکترهایی مانند
&
یا/
را در نام ها مجاز میداند. عاقلانه است که کاراکترهای خاص را حذف یا جایگزین کنید (مثلاً&
را باand
جایگزین کنید، اسلشها یا فاصلهها را حذف کنید). همچنین، اطمینان حاصل کنید که تمام نامهای حساب پس از تبدیل منحصر به فرد هستند – ممکن است کوییکبوکس اجازه دهد نام حساب فرعی یکسانی زیر والدین مختلف وجود داشته باشد که مشکلی ندارد، اما در Beancount نام کامل (با والدین) باید منحصر به فرد باشد. در صورت لزوم، برای تمایز، نام را تغییر دهید یا یک شناسه به آن اضافه کنید. -
خروجی گرفتن افتتاح حسابها: در Beancount، هر حسابی که استفاده میشود باید با دستور
open
افتتاح شود. میتوانید تاریخی قبل از اولین تراکنش خود انتخاب کنید (مثلاً اگر دادههای ۲۰۱۹-۲۰۲۳ را منتقل میکنید، از2018-12-31
یا تاریخی حتی زودتر برای همه افتتاحها استفاده کنید). اسکریپت خطوطی مانند این را خواهد نوشت:2018-12-31 open Assets:Checking USD
2018-12-31 open Expenses:Meals USD
برای هر حساب (با فرض اینکه USD ارز اصلی است). از ارز مناسب برای هر حساب استفاده کنید (به یادداشتهای چند ارزی در ادامه مراجعه کنید).
تبدیل تراکنش: چالش اصلی تبدیل خروجی تراکنشهای QuickBooks (CSV) به ورودیهای Beancount است. هر تراکنش QuickBooks (فاکتور، قبض، چک، سند روزنامه و غیره) میتواند چندین آرتیکل (خط) داشته باشد که باید در یک تراکنش Beancount جمعآوری شوند.
ما از خواننده CSV پایتون برای پیمایش خطوط خروجی گرفته شده و جمعآوری آرتیکلها استفاده خواهیم کرد:
import csv
from collections import defaultdict
# خواندن تمام خطوط از فایل CSV دفتر روزنامه کوییکبوکس
rows = []
with open('quickbooks_exported_journal.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for line in reader:
rows.append(line)
# گروهبندی خطوط بر اساس تراکنش (با فرض اینکه 'Trans #' تراکنشها را مشخص میکند)
transactions = defaultdict(list)
for line in rows:
trans_id = line.get('Trans #') or line.get('Transaction ID') or line.get('Num')
transactions[trans_id].append(line)
اکنون transactions
یک دیکشنری است که هر کلید آن یک شناسه/شماره تراکنش است و مقدار آن لیستی از آرتیکلهای آن تراکنش است. در ادامه، هر گروه را به فرمت Beancount تبدیل میکنیم:
def format_date(qb_date):
# تاریخهای کوییکبوکس ممکن است مانند "12/31/2019" باشند
m, d, y = qb_date.split('/')
return f"{y}-{int(m):02d}-{int(d):02d}"
output_lines = []
for trans_id, splits in transactions.items():
# مرتبسازی آرتیکلها بر اساس ترتیب خط در صورت نیاز (معمولاً به ترتیب میآیند)
splits = sorted(splits, key=lambda x: x.get('Line') or 0)
first = splits[0]
date = format_date(first['Date'])
payee = first.get('Name', "").strip()
memo = first.get('Memo', "").strip()
# سربرگ تراکنش
output_lines.append(f"{date} * \"{payee}\" \"{memo}\"")
if first.get('Num'): # اضافه کردن شماره مرجع در صورت وجود
output_lines.append(f" number: \"{first['Num']}\"")
# حلقه روی هر آرتیکل/پستینگ
for split in splits:
acct_name = split['Account'].strip()
# نگاشت نام حساب کوییکبوکس به حساب بینکانت (با استفاده از نگاشت قبلی)
beancount_acct = account_map.get(acct_name, acct_name)
# تعیین مبلغ با علامت:
amount = split.get('Amount') or ""
debit = split.get('Debit') or ""
credit = split.get('Credit') or ""
if amount:
# برخی خروجیها یک ستون Amount واحد دارند (منفی برای بستانکار)
amt_str = amount
else:
# اگر ستونهای بدهکار/بستانکار جدا باشند
amt_str = debit if debit else f"-{credit}"
# برای اطمینان، هرگونه کاما را در اعداد حذف کنید
amt_str = amt_str.replace(",", "")
# اضافه کردن ارز
currency = split.get('Currency') or "USD"
amt_str = f"{amt_str} {currency}"
# شرح/یادداشت برای آرتیکل
line_memo = split.get('Memo', "").strip()
comment = f" ; {line_memo}" if line_memo else ""
output_lines.append(f" {beancount_acct:<40} {amt_str}{comment}")
# پایان تراکنش – خط خالی
output_lines.append("")
منطق این اسکریپت کارهای زیر را انجام میدهد:
- تاریخ را برای Beancount به فرمت YYYY-MM-DD تبدیل میکند.
- از طرف حساب (Name) و شرح (Memo) برای روایت تراکنش استفاده میکند. به عنوان مثال:
2020-05-01 * "ACME Corp" "Invoice payment"
(اگر طرف حسابی وجود نداشته باشد، میتوانید از نوع تراکنش کوییکبوکس استفاده کنید یا طرف حساب را خالی بگذارید). - اگر شماره مرجعی وجود داشته باشد (شماره چک، شماره فاکتور و غیره)، یک فراداده
number
اضافه میکند. - روی هر خط آرتیکل تکرار میکند:
- نام حساب QuickBooks را با استفاده از یک دیکشنری
account_map
(که از مرحله سرفصل حسابها پر شده) به حساب Beancount نگاشت میکند. - مبلغ را تعیین میکند. بسته به خروجی شما، ممکن است یک ستون Amount واحد (با مقادیر مثبت/منفی) یا ستونهای Debit و Credit جداگانه داشته باشید. کد بالا هر دو حالت را مدیریت میکند. این کد تضمین میکند که مبالغ بستانکار به عنوان مقادیر منفی نمایش داده شوند (زیرا در Beancount، برای هر پستینگ از یک عدد با علامت استفاده میشود).
- ارز را ضمیمه میکند (با فرض USD مگر اینکه ستون ارز دیگری وجود داشته باشد).
- خط پستینگ Beancount را با حساب، مبلغ و یک کامنت با شرح خط مینویسد. به عنوان مثال:
Assets:Checking 500.00 USD ; Deposit
Income:Sales -500.00 USD ; Deposit
این نشاندهنده یک واریز ۵۰۰ دلاری است (از درآمد به حساب جاری).
- نام حساب QuickBooks را با استفاده از یک دیکشنری
- پس از لیست کردن تمام آرتیکلها، یک خط خالی تراکنش را جدا میکند.
مدیریت چند ارزی: اگر دادههای QuickBooks شما شامل چندین ارز باشد، کد ارز را در هر پستینگ (همانطور که در بالا نشان داده شد) درج کنید. اطمینان حاصل کنید که حسابهایی که به ارزهای خارجی هستند با همان ارز افتتاح شوند. به عنوان مثال، اگر یک حساب بانکی به یورو (EUR) دارید، باید open Assets:Bank:Checking EUR
را خروجی بگیرید و تراکنشهای آن حساب از EUR استفاده خواهند کرد. Beancount از دفترهای کل چند ارزی پشتیبانی میکند و تبدیلهای ضمنی را ردیابی خواهد کرد، اما اگر میخواهید در گزارشها تبدیل به یک ارز پایه داشته باشید، ممکن است نیاز به اضافه کردن ورودیهای قیمت برای نرخهای ارز داشته باشید. همچنین توصیه میشود که ارز عملیاتی اصلی خود را در بالای فایل Beancount اعلام کنید (مثلاً option "operating_currency" "USD"
).
اجرای تبدیل: اسکریپت پایتون را (به عنوان مثال، با نام qb_to_beancount.py
) ذخیره کرده و آن را بر روی فایلهای خروجی گرفته شده خود اجرا کنید. این باید یک فایل .beancount
حاوی تمام حسابها و تراکنشها تولید کند.
۲.۲ مدیریت موارد خاص و پاکسازی دادهها
در طول تبدیل، به این مشکلات رایج و نحوه رسیدگی به آنها توجه داشته باشید:
-
عدم تطابق نام حسابها: ممکن است نام حسابهای QuickBooks با نامهای سلسلهمراتبی Beancount تداخل داشته باشد. به عنوان مثال، QuickBooks میتواند دو حساب والد مختلف داشته باشد که هر کدام یک حساب فرعی به نام "Insurance" دارند. در Beancount،
Expenses:Insurance
باید منحصر به فرد باشد. این مشکل را با تغییر نام یکی از آنها (مثلاً "Insurance-Vehicle" در مقابل "Insurance-Health") قبل از خروجیگیری یا نگاشت آنها به حسابهای منحصر به فرد Beancount در اسکریپت خود حل کنید. قراردادهای نامگذاری سازگار (بدون کاراکترهای خاص و استفاده از سلسله مراتب) از سردردهای بعدی جلوگیری میکند. در صورت لزوم از رویکرد فایل نگاشت مجدد استفاده کنید: یک CSV یا دیکشنری از نام قدیمی → نام جدید Beancount نگهداری کنید و آن را در طول تبدیل اعمال کنید (کد نمونه ما ازaccount_map
استفاده میکند و میتواند موارد جایگزین را از یک فایل بارگیری کند). -
تاریخها و فرمتها: اطمینان حاصل کنید که تمام تاریخها به طور یکنواخت فرمتبندی شدهاند. اسکریپت بالا فرمت M/D/Y را به فرمت ISO نرمال میکند. همچنین، مراقب مسائل مربوط به سال مالی در مقابل سال تقویمی باشید اگر بازه پنج ساله شما از پایان سال عبور میکند. Beancount به مرزهای سال مالی اهمیتی نمیدهد، اما ممکن است بعداً بخواهید برای راحتی کار، فایلها را بر اساس سال تقسیم کنید.
-
دقت عددی: QuickBooks ارز را با سنت مدیریت میکند، بنابراین کار با سنت معمولاً مشکلی ایجاد نمیکند. همه مبالغ باید در CSV ایدهآل دو رقم اعشار داشته باشند. اگر هر مبلغی به عدد صحیح (بدون اعشار) تبدیل شده یا دارای کاما/پرانتز (برای مقادیر منفی) است، آنها را در اسکریپت پاک کنید (کاماها را حذف کنید،
(100.00)
را به-100.00
تبدیل کنید و غیره). خروجی CSV اگر به درستی انجام شود (طبق دستورالعمل) باید از این مشکلات فرمتبندی جلوگیری کند. -
مبالغ منفی و علائم: گزارشهای QuickBooks گاهی مقادیر منفی را به صورت
-100.00
یا(100.00)
یا حتی--100.00
در برخی خروجیهای Excel نشان میدهند. مرحله پاکسازی باید این موارد را مدیریت کند. اطمینان حاصل کنید که بدهکار و بستانکار هر تراکنش به صفر میرسد. Beancount این را اعمال خواهد کرد (اگر تراز نباشد، در هنگام وارد کردن خطا میدهد). -
تراکنشهای تکراری: اگر مجبور شدید تراکنشها را به صورت دستهای خروجی بگیرید (مثلاً سال به سال یا حساب به حساب)، مراقب باشید که آنها را بدون همپوشانی ادغام کنید. بررسی کنید که اولین تراکنش یک سال، آخرین تراکنش دسته قبلی نباشد. به راحتی ممکن است چند تراکنش در مرزها به طور تصادفی تکرار شوند. اگر به تکراری بودن شک دارید، میتوانید ورودیهای نهایی Beancount را بر اساس تاریخ مرتب کرده و به دنبال ورودیهای یکسان بگردید، یا از تگهای تراکنش منحصر به فرد Beancount برای شناسایی آنها استفاده کنید. یک استراتژی این است که شماره تراکنش QuickBooks را به عنوان فراداده (metadata) اضافه کنید (مثلاً از
Trans #
یا شماره فاکتور به عنوان تگtxn
یا فرادادهquickbooks_id
استفاده کنید) و سپس اطمینان حاصل کنید که هیچ شناسه تکراری وجود ندارد. -
آرتیکلهای نامتوازن / حسابهای معلق: ممکن است QuickBooks موارد عجیبی مانند یک تراکنش با عدم توازن داشته باشد که QuickBooks به طور خودکار آن را به "Opening Balance Equity" یا "Retained Earnings" منتقل کرده است. به عنوان مثال، هنگام تنظیم ماندههای اولیه حساب، QuickBooks اغلب تفاوتها را به یک حساب حقوق صاحبان سهام پست میکند. این موارد در تراکنشهای خروجی گرفته شده ظاهر میشوند. Beancount نیاز به تراز کردن صریح دارد. ممکن است لازم باشد یک حساب حقوق صاحبان سهام برای ماندههای افتتاحیه (معمولاً
Equity:Opening-Balances
) معرفی کنید تا رفتار QuickBooks را تقلید کند. این یک رویه خوب است که یک ورودی مانده افتتاحیه در روز اول دفتر کل خود داشته باشید که ماندههای اولیه همه حسابها را ایجاد میکند (به مرحله ۵ مراجعه کنید). -
موارد خاص چند ارزی: اگر از چند ارز استفاده میکنید، خروجی QuickBooks ممکن است تمام مبالغ را به ارز اصلی یا به ارز بومی خودشان لیست کند. ایدهآل این است که دادهها را به ارز بومی برای هر حساب دریافت کنید (گزارشهای QuickBooks Online معمولاً این کار را انجام میدهند). در Beancount، هر پستینگ یک ارز دارد. اگر QuickBooks نرخهای ارز یا تبدیل به ارز اصلی را ارائه داده باشد، ممکن است آنها را نادیده بگیرید و به ورودیهای قیمت Beancount تکیه کنید. اگر QuickBooks نرخهای ارز را خروجی نگرفته باشد، ممکن است بخواهید به صورت دستی سوابق قیمت را (مثلاً ب ا استفاده از دستور
price
در Beancount) برای تاریخهای کلیدی اضافه کنید تا ارزیابی مطابقت داشته باشد. با این حال، برای یکپارچگی اولیه دفتر کل، کافی است که تراکنشها در ارزهای اصلی خود تراز شوند – سود/زیانهای تحقق نیافته نیازی به ثبت صریح ندارند مگر اینکه بخواهید گزارشهای یکسانی داشته باشید. -
حسابهای دریافتنی / حسابهای پرداختنی: کوییکبوکس جزئیات فاکتورها و قبوض (تاریخ سررسید، وضعیت پرداخت و غیره) را ردیابی میکند که در یک دفتر کل ساده به طور کامل منتقل نمیشوند. شما تراکنشهای A/R (حسابهای دریافتنی) و A/P (حسابهای پرداختنی) را دریافت خواهید کرد (فاکتورها A/R را افزایش میدهند، پرداختها A/R را کاهش میدهند و غیره)، اما نه اسناد فاکتور یا مانده مشتریان به ازای هر فاکتور. در نتیجه، پس از مهاجرت، باید تأیید کنید که مانده حسابهای A/R و A/P شما در Beancount با ماندههای باز مشتریان/فروشندگان در QuickBooks برابر است. اگر نیاز به ردیابی فاکتورها دارید، میتوانید از فراداده Beancount استفاده کنید (مثلاً یک تگ
invoice
یا لینک اضافه کنید). شماره فاکتورهای QuickBooks باید در فیلدهایNum
یاMemo
آمده باشد – اسکریپت ماNum
را به عنوانnumber: "..."
در فراداده تراکنش حفظ میکند. -
حساب های غیرفعال یا بسته شده: خروجی IIF ممکن است شامل حسابهای غیرفعال باشد (اگر انتخاب کرده باشید که آنها را شامل شود). وارد کردن آنها مشکلی ندارد (آنها فقط هیچ تراکنشی نخواهند داشت و اگر واقعاً غیرفعال باشند مانده صفر خواهند داشت). میتوانید پس از تاریخ آخرین تراکنش، آنها را با دستور
close
در Beancount به عنوان بسته شده علامتگذاری کنید. این کار دفتر کل شما را مرتب نگه میدارد. به عنوان مثال:2023-12-31 close Expenses:OldAccount ; closed after migration
این کار اختیاری است و بیشتر برای تمیزی است.
با پاکسازی و نگاشت دقیق دادهها به روش بالا، یک فایل دفتر کل Beancount خواهید داشت که از نظر ساختاری دادههای QuickBooks شما را منعکس میکند. مرحله بعدی تأیید این است که از نظر عددی نیز QuickBooks را منعکس میکند.
مرحله ۳: اعتبارسنجی و مغایرتگیری دادهها
اعتبارسنجی یک مرحله حیاتی در مهاجرت دادههای حسابداری است. ما باید اطمینان حاصل کنیم که دفتر کل Beancount با دفاتر QuickBooks تا آخرین ریال مطابقت دارد. چندین استراتژی و ابزار میتوانند مورد استفاده قرار گیرند:
۳.۱ مغایرتگیری تراز آزمایشی
گزارش تراز آزمایشی (trial balance) مانده پایانی همه حسابها را (با بدهکار و بستانکار یا مثبت/منفی مشخص شده) لیست میکند و جمع آن باید صفر باشد. اجرای یک تراز آزمایشی در هر دو سیستم برای یک تاریخ مشخص، سریعترین راه برای تأیید صحت کلی است.
-
در QuickBooks: یک گزارش Trial Balance برای آخرین روز سال نهایی (مثلاً ۳۱ دسامبر ۲۰۲۳) اجرا کنید. این گزارش مانده هر حساب را نشان میدهد. آن را خروجی بگیرید یا ارقام کلیدی را یادداشت کنید.
-
در Beancount: از گزارشگیری Beancount برای تولید یک تراز آزمایشی استفاده کنید. یک روش آسان از طریق خط فرمان است:
bean-report migrated.beancount balances
گزارش
balances
یک تراز آزمایشی است که تمام حسابها و ماندههای آنها را لیست میکند. همچنین میتوانید فایل را در Fava (رابط کاربری وب Beancount) باز کرده و به بخش Balances یا Balance Sheet نگاه کنید. مانده هر حساب در Beancount باید با تراز آزمایشی QuickBooks مطابقت داشته باشد. به عنوان مثال، اگر QuickBooks نشان دهد Accounts Receivable = $5,000، حساب Assets:Accounts Receivable در Beancount باید در مجموع ۵,۰۰۰ دلار (بدهکار) باشد. اگر Sales Income = $200,000، حساب Income:Sales در Beancount باید ۲۰۰,۰۰۰ دلار (بستانکار، که ممکن است به صورت -200,000 نمایش داده شود اگر از تراز آزمایشی استفاده میکنید که بستانکار را به عنوان منفی نشان میدهد) باشد.
اگر مغایرتی وجود داشت، آنها را مشخص کنید:
- بررسی کنید که آیا یک حساب به طور کامل حذف شده یا اضافی است (آیا یک حساب را فراموش کردهایم یا حسابی را که قبل از دوره مهاجرت بسته شده بود، وارد کردهایم؟).
- اگر ماندهای اشتباه است، جزئیات را بررسی کنید: QuickBooks میتواند یک Account QuickReport یا جزئیات دفتر کل برای آن حساب اجرا کند، و شما میتوانید آن را با رجیستر Beancount برای آن حساب (
bean-report migrated.beancount register -a AccountName
) مقایسه کنید. گاهی اوقات تفاوتها از یک تراکنش گمشده یا تکراری ناشی میشوند.
همچنین تأیید کنید که جمع تمام حسابها در تراز آزمایشی Beancount صفر است (این ابزار یک جمع کل چاپ میکند که باید صفر یا بسیار نزدیک به صفر باشد). Beancount سیستم حسابداری دوطرفه را اعمال میکند، بنابراین اگر هرگونه عدم توازن غیرصفری داشته باشید، به این معنی است که داراییها منهای بدهیها-حقوق صاحبان سهام به صفر نرسیده است، که نشاندهنده یک مشکل است (که QuickBooks معمولاً اجازه آن را نمیدهد، اما اگر برخی دادهها حذف شده باشند ممکن است اتفاق بیفتد).
۳.۲ مقایسه مانده حسابها
علاوه بر تراز آزمایشی، میتوانید صورتهای مالی خاصی را مقایسه کنید:
-
ترازنامه (Balance Sheet): یک ترازنامه QuickBooks برای تاریخ نهایی و یک ترازنامه Beancount (
bean-report migrated.beancount balsheet
) اجرا کنید. این مشابه تراز آزمایشی است اما بر اساس داراییها، بدهیها و حقوق صاحبان سهام سازماندهی شده است. اعداد باید از نظر دستهبندی مطابقت داشته باشند. برای بررسی دقیقتر، مجموع حسابهای اصلی را مقایسه کنید: وجه نقد، حسابهای دریافتنی، داراییهای ثابت، حسابهای پرداختنی، حقوق صاحبان سهام و غیره. -
سود و زیان (صورت درآمد): یک گزارش سود و زیان برای دوره پنج ساله (یا سال به سال) در QuickBooks و در Beancount (
bean-report migrated.beancount income
برای صورت درآمد دوره کامل) اجرا کنید. سود خالص از Beancount باید با QuickBooks برای هر دوره برابر باشد. اگر تمام پنج سال را منتقل کردهاید، سود خالص تجمعی باید مطابقت داشته باشد. همچنین میتوانید مجموع درآمدهای فردی و هزینهها را مقایسه کنید تا اطمینان حاصل کنید که هیچ دستهای جا نیفتاده یا دو بار حساب نشده است. -
نمونهگیری تصادفی تراکنش: چند تراکنش تصادفی (به ویژه از هر سال و هر حساب اصلی) را انتخاب کرده و تأیید کنید که به درستی منتقل شدهاند. به عنوان مثال، یک فاکتور از ۳ سال پیش را در QuickBooks پیدا کنید و سپس مبلغ یا شرح آن را در فایل Beancount جستجو کنید (چون تمام تراکنشها متنی هستند، میتوانید فایل
.beancount
را در یک ویرایشگر متن باز کنید یا از ابزارهای جستجو استفاده کنید). بررسی کنید که تاریخ، مبالغ و حسابها مطابقت دارند. این به شناسایی هرگونه مشکل در فرمتبندی تاریخ یا نگاشت اشتباه حسابها کمک میکند.
۳.۳ بررسیهای یکپارچگی خودکار
از ابزارهای اعتبارسنجی خود Beancount استفاده کنید:
-
bean-check: دستور
bean-check migrated.beancount
را اجرا کنید. این دستور فایل را تجزیه کرده و هرگونه خطای سینتکسی یا عدم تراز را گزارش میدهد. اگر اسکریپت چیزی مانند یک حساب افتتاح نشده یا یک تراکنش نامتوازن را از قلم انداخته باشد،bean-check
آن را علامتگذاری میکند. یک اجرای تمیز (بدون خروجی) به این معنی است که فایل حداقل از نظر داخلی سازگار است. -
تأیید مانده (Balance Assertions): میتوانید به عنوان یک بررسی اضافی، تأییدهای مانده صریح را در دفتر کل برای حسابهای کلیدی اضافه کنید. به عنوان مثال، اگر مانده حساب بانکی را در یک تاریخ خاص میدانید، یک خط اضافه کنید:
2023-12-31 balance Assets:Bank:Checking 10000.00 USD
سپسbean-check
اطمینان حاصل میکند که در دفتر کل، تا آن تاریخ، مانده واقعاً ۱۰,۰۰۰ دلار است. این کار اختیاری است اما میتواند برای حسابهای با اهمیت بالا مفید باشد. میتوانید ماندههای پایانی را از QuickBooks (مثلاً پایان هر سال) بگیرید و آنها را در فایل Beancount تأیید کنید. اگر هر تأییدی شکست بخورد، Beancount تفاوت را گزارش میدهد. -
بررسی دورهای تراز: اگر ترجیح میدهید، میتوانید یک بررسی دورهای انجام دهید. برای هر سال، تغییر خالص را مقایسه کنید. به عنوان مثال، سود خالص در QuickBooks 2020 در مقابل Beancount 2020، و غیره، تا اطمینان حاصل کنید که هر سال به درستی به حقوق صاحبان سهام بسته شده است (QuickBooks به طور خودکار سود خالص را به سود انباشته در هر سال جدید منتقل میکند؛ در Beancount شما فقط حقوق صاحبان سهام تجمعی را خواهید دید). اگر تفاوتهایی مشاهده کردید، ممکن است نشاندهنده مشکلی در دادههای یک سال خاص باشد.
-
تعداد تراکنشها و تکرارها: تعداد تراکنشها را در QuickBooks در مقابل Beancount بشمارید. QuickBooks به راحتی تعداد مستقیم را نشان نمیدهد، اما میتوانید با شمردن خطوط در CSV (هر سربرگ تراکنش در مقابل آرتیکلها) تخمین بزنید. در Beancount، یک راه سریع شمارش رخدادهای
txn
یا* "
در فایل است. آنها باید برابر یا کمی بیشتر از QuickBooks باشند (اگر تراکنشهای مانده افتتاحیه یا تعدیلات اضافه کردهاید). یک عدم تطابق قابل توجه به این معنی است که ممکن است چیزی حذف یا تکرار شده باشد. استفاده ما از شناسههای منحصر به فرد در فراداده میتواند کمک کند: اگر به تکرار شک دارید، فایل Beancount را برای شماره چک یا شماره فاکتور یکسانی که دو بار ظاهر میشود در حالی که نباید، جستجو کنید.
با انجام این اعتبارسنجیها، اطمینان حاصل میکنید که مهاجرت دادهها را حفظ کرده است. برای این مرحله وقت بگذارید – رفع ناهنجاریها اکنون آسانتر از ماهها بعد است که ممکن است به دفاتر حسابداری تکیه شود. مشکلات رایج در صورت شکست اعتبارسنجی: عدم وجود مانده افتتاحیه یک حساب، تاریخگذاری یک تراکنش خارج از محدوده، یا معکوس شدن علامت در یک ورودی. همه اینها پس از شناسایی قابل رفع هستند.
مرحله ۴: نهایی کردن دفتر کل Beancount
پس از پاکسازی و اعتبارسنجی، زمان آن رسیده است که دادهها را در ساختار دفتر کل Beancount خود رسمی کنید. "نهایی کردن" در اینجا هم به معنای نهایی کردن فایلهای دفتر کل و هم به طور بالقوه ثبت آنها در یک سیستم کنترل نسخه برای قابلیت حسابرسی است.
۴.۱ سازماندهی فایلهای دفتر کل و پیکربندی
تصمیم بگیرید که چگونه فایلهای دفتر کل Beancount را ساختار دهید. برای دادههای پنج ساله، میتوانید همه چیز را در یک فایل نگه دارید یا بر اساس سال یا دستهبندی تقسیم کنید. یک ساختار رایج و واضح به این صورت است:
- فایل اصلی دفتر کل: به عنوان مثال،
ledger.beancount
– این نقطه ورود است که میتواند فایلهای دیگر راinclude
کند. ممکن است حاوی گزینههای سراسری باشد و سپس فایلهای سالانه را شامل شود. - فایل حسابها: سرفصل حسابها و ماندههای افتتاحیه را تعریف کنید. به عنوان مثال،
accounts.beancount
با تمام دستوراتopen
(همانطور که توسط اسکریپت تولید شده است). همچنین ممکن است کالاها (ارزها) را در اینجا لیست کنید. - فایلهای تراکنش: یکی برای هر سال، به عنوان مثال،
2019.beancount
،2020.beancount
، و غیره، که حاوی تراکنشهای آن سال است. این کار باعث میشود هر فایل اندازه قابل مدیریتی داشته باشد و به شما امکان میدهد در صورت لزوم روی یک سال تمرکز کنید. به طور متناوب، میتوانید بر اساس نهاد یا حساب تقسیم کنید، اما تقسیم بر اساس زمان برای دادههای مالی ساده است.
مثال فایل اصلی:
option "title" "دفتر کل کسب و کار من"
option "operating_currency" "USD"
include "accounts.beancount"
include "2019.beancount"
include "2020.beancount"
...
include "2023.beancount"
به این ترتیب، تمام دادهها هنگام اجرای گزارشها agregated میشوند، اما شما نظم را حفظ میکنید.
Beancount نیازی به چندین فایل ندارد – میتوانید یک فایل بزرگ داشته باشید – اما ساختار بالا وضوح و کنترل نسخه را بهبود میبخشد. طبق بهترین شیوههای Beancount، خوب است که از سربرگهای بخش واضح استفاده کنید و ورودیهای مرتبط را به طور منطقی گروهبندی کنید.
۴.۲ تنظیم ماندههای افتتاحیه و حقوق صاحبان سهام
اگر مهاجرت شما از یک شروع کاملاً صفر نیست، باید ماندههای افتتاحیه را مدیریت کنید. دو سناریو وجود دارد:
-
دفاتر از ابتدا شروع میشوند: اگر دوره پنج ساله در زمان تأسیس کسب و کار شروع شود (مثلاً شما از ژانویه ۲۰۱۹ با تمام حسابهای صفر شده به جز حقوق صاحبان سهام اولیه شروع به استفاده از QuickBooks کردهاید)، ممکن است به یک تراکنش مانده افتتاحیه جداگانه نیازی نداشته باشید. اولین تراکنشها در سال ۲۰۱۹ (مانند تأمین مالی اولیه به یک حساب بانکی) به طور طبیعی ماندههای اولیه را ایجاد میکنند. فقط اطمینان حاصل کنید که هرگونه سرمایه اولیه یا سود انباشته قبلی از طریق تراکنشهای حقوق صاحبان سهام حساب شده است.
-
دفاتر در میانه راه (تاریخچه جزئی): اگر شما QuickBooks را زودتر شروع کردهاید و ۲۰۱۹ یک نقطه میانی است، پس از ۱ ژانویه ۲۰۱۹ هر حساب یک مانده انتقالی داشته است. QuickBooks آنها را به عنوان مانده افتتاحیه یا سود انباشته داشته است. در Beancount، معمول است که یک ورودی مانده افتتاحیه در روز قبل از تاریخ شروع خود ایجاد کنید:
- از یک حساب حقوق صاحبان سهام به نام
Equity:Opening-Balances
(یا مشابه) برای جبران جمع تمام مبالغ افتتاحیه استفاده کنید. - مثال: اگر در 2018-12-31، وجه نقد ۱۰,۰۰۰ دلار و حسابهای دریافتنی ۵,۰۰۰ دلار و حسابهای پرداختنی ۳,۰۰۰ دلار (بستانکار) بود، یک تراکنش مینوشتید:
2018-12-31 * "Opening Balances"
Assets:Cash 10000.00 USD
Assets:Accounts Receivable 5000.00 USD
Liabilities:Accounts Payable -3000.00 USD
Equity:Opening-Balances -12000.00 USD
این کار باعث میشود ماندهOpening-Balances
با جمع منفی (۱۲,۰۰۰- دلار) باقی بماند که ورودی را تراز میکند. اکنون تمام حسابهای دارایی/بدهی سال ۲۰۱۹ را با ماندههای صحیح شروع میکنند. این باید هرگونه "سود انباشته" یا ماندههای انتقالی QuickBooks را منعکس کند. - به طور متناوب، از دستورات
pad
وbalance
در Beancount استفاده کنید: برای هر حساب، میتوانید آن را ازOpening-Balances
پد (pad) کنید و مانده را تأیید کنید. این یک روش خودکارتر است. به عنوان مثال:2018-12-31 pad Assets:Cash Equity:Opening-Balances
2018-12-31 balance Assets:Cash 10000.00 USD
این به Beancount میگوید که هر ورودی لازم را (بهOpening-Balances
) درج کند تا وجه نقد در آن تاریخ برابر با ۱۰۰۰۰ دلار شود. این کار را برای هر حساب انجام دهید. نتیجه مشابه است، اما نوشتن یک تراکنش صریح مانند روش اول نیز ساده است.
- از یک حساب حقوق صاحبان سهام به نام
-
سود انباشته (Retained Earnings): کوییکبوکس به صراحت یک تراکنش "سود انباشته" را خروجی نمیگیرد - فقط آن را محاسبه میکند. پس از مهاجرت، ممکن است متوجه شوید که اگر آن را ایجاد نکرده باشید،
Equity:Retained Earnings
صفر است. در Beancount، سود انباشته فقط سود سالهای قبل است. میتوانید یک حساب سود انباشته ایجاد کنید و سودهای قبلی را در روز اول هر سال جدید به آن منتقل کنید، یا به سادگی اجازه دهید حقوق صاحبان سهام جمع تمام درآمدها/هزینهها باشد (که در بخش حقوق صاحبان سهام در گزارشها ظاهر میشود). برای شفافیت، برخی از کاربران سالانه ورودیهای بستن حساب را ثبت میکنند. این اختیاری است و عمدتاً برای نمایش است. از آنجا که ما تمام تراکنشها را منتقل کردهایم، سود هر سال به طور طبیعی در صورت اجرای گزارش برای هر سال، جمع میشود. -
بررسیهای مقایسهای: پس از تنظیم ماندههای افتتاحیه، یک ترازنامه در تاریخ شروع اجرا کنید تا اطمینان حاصل کنید که همه چیز درست است (باید آن ماندههای افتتاحیه را در مقابل حقوق صاحبان سهام افتتاحیه که به صفر میرسد، نشان دهد).
۴.۳ نهاییسازی و کنترل نسخه
اکنون که دادهها در فرمت Beancount و ساختار یافته هستند، عاقلانه است که فایلها را به یک مخزن کنترل نسخه (مانند git) کامیت کنید. هر تغییر در دفتر کل قابل ردیابی است و شما یک سابقه حسابرسی از تمام تغییرات دارید. این یک مزیت عمده حسابداری متنی ساده است. به عنوان مثال، در QuickBooks تغییرات ممکن است به راحتی قابل مقایسه (diff) نباشند، اما در Beancount، میتوانید تفاوتها را خط به خط ببینید. همانطور که برخی کاربران اشاره میکنند، با Beancount شما شفافیت و توانایی بازگرداندن تغییرات در صورت لزوم را به دست میآورید - ه ر ورودی میتواند به یک تاریخچه تغییرات مرتبط باشد.
در نظر بگیرید که کامیت این مهاجرت اولیه را به عنوان v1.0
یا مشابه تگگذاری کنید، تا بدانید که وضعیت دفاتر را همانطور که از QuickBooks وارد شده، نشان میدهد. از این به بعد، تراکنشهای جدید را مستقیماً در Beancount وارد خواهید کرد (یا از فیدهای بانکی و غیره وارد میکنید) و میتوانید از شیوههای توسعه نرمافزار معمولی استفاده کنید (کامیت روزانه یا ماهانه، استفاده از شاخهها برای آزمایشها و غیره).
راهاندازی Fava یا ابزارهای دیگر: Fava یک رابط وب برای Beancount است که مشاهده گزارشها را آسان میکند. پس از کامیت، fava ledger.beancount
را اجرا کنید تا صورتهای مالی را مرور کرده و آنها را برای آخرین بار با گزارشهای QuickBooks خود مقایسه کنید. ممکن است تفاوتهای کوچک را در یک رابط کاربری راحتتر تشخیص دهید (به عنوان مثال، حسابی که باید صفر باشد اما مانده کوچکی نشان میدهد، نشاندهنده یک ورودی بستن حساب گمشده یا یک تراکنش سرگردان است).
قراردادهای نامگذاری و ثبات: اکنون کنترل کامل دارید، بنابراین از ثبات اطمینان حاصل کنید:
- همه حسابها باید نامهای واضحی داشته باشند که با نامهای دستهبندی با حروف بزرگ شروع شوند (Assets, Liabilities و غیره). اگر هر کدام عجی ب به نظر میرسد (مثلاً
Assets:assets:SomeAccount
به دلیل عدم تطابق حروف از QuickBooks)، آنها را در فایل حسابها تغییر نام دهید و تراکنشها را بهروز کنید (یک جستجو/جایگزینی سریع در فایل میتواند این کار را انجام دهد، یا ازbean-format
Beancount یا چند مکاننما ویرایشگر استفاده کنید). - نمادهای کالا (کدهای ارز) باید سازگار باشند. برای دلار آمریکا، از
USD
در همه جا استفاده کنید (نه$
یاUS$
). برای دیگران، از کدهای استاندارد (EUR، GBP و غیره) استفاده کنید. این ثبات برای جستجوی قیمت و گزارشهای Beancount مهم است. - هرگونه حساب موقت یا ساختگی که ممکن است ایجاد شده باشد را حذف کنید (به عنوان مثال، اگر از
Expenses:Miscellaneous
برای حسابهای ناشناخته در اسکریپت به عنوان یک راه حل کلی استفاده کردهاید، سعی کنید با نگاشت صحیح همه حسابها آنها را حذف کنید).
بستن QuickBooks: در این مرحله، شما باید دفاتر موازی در Beancount داشته باشید که با QuickBooks مطابقت دارند. برخی انتخاب میکنند که هر دو سیستم را برای مدت کوتاهی به صورت موازی اجرا کنند تا اطمینان حاصل کنند که چیزی از قلم نیفتاده است. اما اگر اعتبارسنجی قوی باشد، میتوانید دفاتر QuickBooks را "ببندید":
- اگر این یک محیط شرکتی است، در نظر بگیرید که تمام اسناد منبع QuickBooks ( فاکتورها، قبوض، رسیدها) را برای سوابق خروجی بگیرید، زیرا اینها در Beancount وجود نخواهند داشت مگر اینکه آنها را به صورت دستی ضمیمه کنید.
- یک نسخه پشتیبان از دادههای QuickBooks (هم فایل شرکت و هم فایلهای خروجی) را نگه دارید.
- از این به بعد، دفتر کل Beancount را به عنوان سیستم اصلی ثبت سوابق نگهداری کنید.
با نهایی کردن دادهها در دفتر کل Beancount، شما خط لوله مهاجرت را تکمیل کردهاید. مرحله نهایی انجام یک حسابرسی و نشان دادن ثبات صورتهای مالی است تا خودتان (و هر ذینفع یا حسابرس) را متقاعد کنید که مهاجرت موفقیتآمیز بوده است.
مرحله ۵: حسابرسی پس از مهاجرت و مثالها
برای نشان دادن موفقیت مهاجرت، یک مقایسه قبل و بعد از صورتهای مالی و احتمالاً یک مقایسه (diff) از تراکنشها تهیه کنید. این شواهدی را ارائه میدهد که دفاتر سازگار هستند.