Manuál pre migráciu z QuickBooks do Beancount
Fáza 1: Exportovanie údajov z QuickBooks
Migrácia údajov za päť rokov sa začína exportovaním všetkých záznamov z QuickBooks v použiteľnom formáte. QuickBooks Desktop a QuickBooks Online majú rôzne možnosti exportu:
1.1 QuickBooks Desktop – Možnosti exportu
IIF (Intuit Interchange Format): QuickBooks Desktop dokáže exportovať zoznamy (ako účtovná osnova, zákazníci, dodávatelia) do textových súborov .IIF
. V QuickBooks Desktop prejdite na File → Utilities → Export → Lists to IIF, potom vyberte zoznamy, ktoré potrebujete (napr. Chart of Accounts, Customers, Vendors). Týmto získate textový súbor, ktorý obsahuje názvy účtov, typy a údaje zo zoznamov. IIF je proprietárny, ale jednoduchý textový formát, ktorý sa pomerne ľahko spracováva. Použite ho na zachytenie vašej účtovnej osnovy a zoznamov kontaktov ako referencie v Beancount.
Hlavná kniha/Denník cez CSV: Pre transakčné údaje QuickBooks Desktop neposkytuje export všetkých údajov jedným kliknutím, ale môžete použiť reporty. Odporúčanou metódou je exportovať hlavný denník (všetky transakcie) za požadované časové obdobie. V QuickBooks Desktop otvorte Reports → Accountant & Taxes → Journal, nastavte dátumy od najskoršej transakcie po dnešok a kliknite na Export → Excel. Výsledok uložte ako CSV po odstránení všetkých hlavičiek/pätičiek reportu a prázdnych stĺpcov. Uistite sa, že numerické údaje sú čisté: zahrňte centy (napr. 3.00
, nie 3
), žiadne nadbytočné úvodzovky a žiadne symboly meny alebo dvojité záporné znamienka v CSV. CSV by mal mať stĺpce ako Date, Trans #, Name, Account, Memo, Debit, Credit, Balance (alebo jeden stĺpec Amount v závislosti od formátu reportu).
Tip: QuickBooks Desktop 2015+ môže tiež exportovať transakcie cez dialógové okno Find. Použite Edit → Find → Advanced, nastavte časový rozsah na päť rokov a potom exportujte výsledky do CSV. Upozornenie: Niektoré verzie obmedzujú export na 32 768 riadkov. Ak máte veľmi veľké dáta, exportujte ich rok po roku (alebo v menších častiach), aby ste sa vyhli skráteniu, a neskôr ich spojte. Uistite sa, že sa časové rozsahy neprekrývajú, aby ste predišli duplikátom.
Iné formáty (QBO/QFX/QIF): QuickBooks Desktop môže importovať bankové transakcie cez súbory .QBO
(Web Connect) alebo .QFX/.OFX
, ale pre export z QuickBooks tieto formáty nie sú typické. Ak je vaším cieľom extrahovať iba bankové transakcie, možno ich už máte vo formáte QBO/OFX od vašej banky. Avšak pre úplný export hlavnej knihy sa držte IIF a CSV. QuickBooks Desktop nemôže priamo exportovať do QIF (Quicken Interchange Format) bez nástrojov tretích strán. Ak nájdete spôsob, ako získať QIF, všimnite si, že niektoré nástroje pre hlavnú knihu (starší Ledger 2.x) dokázali čítať QIF, ale v našom postupe je lepšie pracovať s CSV.
1.2 QuickBooks Online – Možnosti exportu
Vstavaný export do Excel/CSV: QuickBooks Online (QBO) poskytuje nástroj Export Data. Prejdite na Settings ⚙ → Tools → Export Data. V dialógovom okne exportu použite kartu Reports na výber údajov (napr. General Ledger alebo Transaction List) a kartu Lists pre zoznamy (účtovná osnova atď.), vyberte All dates a exportujte do Excelu. QuickBooks Online stiahne ZIP súbor obsahujúci viacero Excel súborov pre vybrané reporty a zoznamy (napríklad Profit and Loss, Balance Sheet, General Ledger, Customers, Vendors, Chart of Accounts atď.). Tieto Excel súbory potom môžete previesť na CSV na ďalšie spracovanie.
Report s detailmi transakcií: Ak predvolený export QBO neobsahuje jeden súbor s hlavnou knihou, môžete manuálne spustiť podrobný report:
- Prejdite na Reports a nájdite Transaction Detail by Account (alebo General Ledger v niektorých verziách QBO).
- Nastavte Report period na celý päťročný rozsah.
- V možnostiach reportu nastavte Group by = None (aby sa zobrazili jednotlivé transakcie bez medzisúčtov).
- Prispôsobte stĺpce tak, aby obsahovali aspoň: Date, Transaction Type, Number, Name (Payee/Customer), Memo/Description, Account, Debit, Credit (alebo jeden stĺpec Amount) a Balance. Zahrňte aj triedu alebo lokalitu, ak sa používajú.
- Spustite report a potom Export to Excel.
Týmto získate podrobnú hlavnú knihu všetkých transakcií. Uložte ju ako CSV. Každý riadok bude predstavovať jeden rozpis (zápis) transakcie. Neskôr budete musieť zoskupiť riadky podľa transakcií na konverziu.
Účtovná osnova a ďalšie zoznamy: QuickBooks Online môže exportovať účtovnú osnovu cez Accounting → Chart of Accounts → Batch Actions → Export to Excel. Urobte to, aby ste získali názvy a typy účtov. Podobne exportujte zákazníkov, dodávateľov atď., ak chcete preniesť názvy pre metadáta.
QuickBooks Online API (voliteľné): Pre programátorský prístup Intuit poskytuje REST API pre údaje QBO. Pokročilí používatelia si môžu vytvoriť aplikáciu QuickBooks Online (vyžaduje si vývojársky účet) a použiť API na získanie údajov vo formáte JSON. Napríklad, môžete sa dotazovať na koncový bod Account
pre účtovnú osnovu a na koncové body reportov JournalEntry
alebo GeneralLedger
pre transakcie. Existujú Python SDK ako python-quickbooks
, ktoré obaľujú API. Avšak použitie API zahŕňa OAuth autentifikáciu a je pre jednorazovú migráciu zbytočne zložité, pokiaľ nepreferujete automatizáciu. Pre väčšinu prípadov je manuálny export do CSV/Excelu jednoduchší a menej náchylný na chyby.
Fáza 2: Transformácia a čistenie údajov
Keď máte údaje z QuickBooks vo formáte CSV (a/alebo IIF), ďalším krokom je ich konverzia do formátu textového denníka Beancount. To zahŕňa spracovanie exportov, mapovanie účtov QuickBooks na účtovnú osnovu Beancount a formátovanie transakcií v syntaxi Beancount.
2.1 Spracovanie exportov z QuickBooks pomocou Pythonu
Použitie Pythonu zabezpečí presnosť a reprodukovateľnosť transformácie. Načrtneme skripty pre dve kľúčové úlohy: importovanie účtovnej osnovy a konverziu transakcií.
Import a mapovanie účtov: Je kľúčové nastaviť si účty v Beancount pred pridaním transakcií. Účty v QuickBooks majú typy (Bank, Accounts Receivable, Expense atď.), ktoré zmapujeme na hierarchiu Beancount (Assets, Liabilities, Income, Expenses atď.). Môžeme použiť napríklad takéto mapovanie:
# Mapovanie typu účtu QuickBooks na koreňovú kategóriu Beancount
AccountTypeMap = {
'BANK': 'Assets',
'CCARD': 'Liabilities',
'AR': 'Assets', # Pohľadávky ako aktíva
'AP': 'Liabilities', # Záväzky ako pasíva
'FIXASSET': 'Assets',
'OASSET': 'Assets', # Ostatné aktíva
'OCASSET': 'Assets', # Ostatné bežné aktíva
'LTLIAB': 'Liabilities', # Dlhodobé záväzky
'OCLIAB': 'Liabilities', # Ostatné bežné záväzky
'EQUITY': 'Equity',
'INC': 'Income',
'EXP': 'Expenses',
'EXINC': 'Income', # Ostatné výnosy
'EXEXP': 'Expenses', # Ostatné náklady
}
Použitím exportu IIF z QuickBooks Desktop alebo CSV so zoznamom účtov z QBO získame názov a typ každého účtu. Potom:
-
Vytvorte názvy účtov Beancount: QuickBooks niekedy používa dvojbodky (
:
) v názvoch účtov na označenie podúčtov (napr. „Current Assets:Checking“). Beancount používa rovnakú notáciu s dvojbodkou pre hierarchiu. Často môžete názov použiť priamo. Ak názvy účtov v QuickBooks nezačínajú kategóriou, pridajte na začiatok zmapovanú kategóriu. Napríklad účet QuickBooks typuBANK
s názvom "Checking" sa v Beancount staneAssets:Checking
. ÚčetEXP
(náklady) "Meals" sa staneExpenses:Meals
, atď. -
Zabezpečte platné pomenovanie: Odstráňte alebo nahraďte všetky znaky, ktoré by mohli Beancount zmiasť. QuickBooks povoľuje znaky ako
&
alebo/
v názvoch. Je rozumné odstrániť alebo nahradiť špeciálne znaky (napr. nahradiť&
zaand
, odstrániť lomky alebo medzery). Taktiež zabezpečte, aby boli všetky názvy účtov po transformácii jedinečné – QuickBooks mohol povoliť rovnaký názov podúčtu pod rôznymi nadradenými účtami, čo je v poriadku, ale v Beancount musí byť plný názov (s nadradenými účtami) jedinečný. Ak je to potrebné, premenujte alebo pridajte kvalifikátor na ich rozlíšenie. -
Výstup otvorení účtov: V Beancount musí byť každý použitý účet otvorený pomocou direktívy
open
. Môžete si zvoliť dátum pred prvou transakciou (napr. ak migrujete údaje z rokov 2019–2023, použite2018-12-31
alebo ešte skorší dátum pre všetky otvorenia). Skript zapíše riadky ako:2018-12-31 open Assets:Checking USD
2018-12-31 open Expenses:Meals USD
pre každý účet (za predpokladu, že USD je hlavná mena). Použite príslušnú menu pre každý účet (pozri poznámky o viacerých menách nižšie).
Konverzia transakcií: Hlavnou výzvou je konverzia exportu transakcií z QuickBooks (CSV) na položky Beancount. Každá transakcia v QuickBooks (faktúra, účet, šek, denníkový zápis atď.) môže mať viacero rozpisov (riadkov), ktoré musia byť zoskupené do jednej transakcie Beancount.
Použijeme čítačku CSV v Pythone na iteráciu cez exportované riadky a akumuláciu rozpisov:
import csv
from collections import defaultdict
# Načítanie všetkých riadkov z CSV denníka QuickBooks
rows = []
with open('quickbooks_exported_journal.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for line in reader:
rows.append(line)
# Zoskupenie riadkov podľa transakcie (za predpokladu, že 'Trans #' identifikuje transakcie)
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)
Teraz je transactions
slovník, kde každý kľúč je ID/číslo transakcie a hodnota je zoznam rozpisov pre túto transakciu. Ďalej prevedieme každú skupinu do formátu Beancount:
def format_date(qb_date):
# Dátumy v QuickBooks môžu byť vo formáte "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():
# Zoradenie rozpisov podľa poradia riadkov, ak je to potrebné (zvyčajne sú už v poradí)
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()
# Hlavička transakcie
output_lines.append(f"{date} * \"{payee}\" \"{memo}\"")
if first.get('Num'): # zahrnutie referenčného čísla, ak je dostupné
output_lines.append(f" number: \"{first['Num']}\"")
# Prechádzanie každým rozpisom/zápisom
for split in splits:
acct_name = split['Account'].strip()
# Mapovanie názvu účtu QuickBooks na účet Beancount (pomocou predchádzajúceho mapovania)
beancount_acct = account_map.get(acct_name, acct_name)
# Určenie sumy so znamienkom:
amount = split.get('Amount') or ""
debit = split.get('Debit') or ""
credit = split.get('Credit') or ""
if amount:
# Niektoré exporty majú jeden stĺpec Amount (záporný pre kredity)
amt_str = amount
else:
# Ak sú samostatné stĺpce Debit/Credit
amt_str = debit if debit else f"-{credit}"
# Pre istotu odstránenie čiarok v číslach
amt_str = amt_str.replace(",", "")
# Pridanie meny
currency = split.get('Currency') or "USD"
amt_str = f"{amt_str} {currency}"
# Poznámka/popis pre rozpis
line_memo = split.get('Memo', "").strip()
comment = f" ; {line_memo}" if line_memo else ""
output_lines.append(f" {beancount_acct:<40} {amt_str}{comment}")
# Koniec transakcie – prázdny riadok
output_lines.append("")
Logika tohto skriptu robí nasledovné:
-
Formátuje dátum na YYYY-MM-DD pre Beancount.
-
Používa príjemcu (Name) a poznámku (Memo) pre popis transakcie. Napríklad:
2020-05-01 * "ACME Corp" "Platba faktúry"
(Ak nie je uvedený príjemca, môžete použiť typ transakcie z QuickBooks alebo nechať príjemcu v prázdnych úvodzovkách). -
Pridáva metadáta
number
, ak existuje referenčné číslo (číslo šeku, faktúry atď.). -
Iteruje cez každý riadok rozpisu:
- Mapuje názov účtu QuickBooks na účet Beancount pomocou slovníka
account_map
(naplneného z kroku s účtovnou osnovou). - Určuje sumu. V závislosti od vášho exportu môžete mať jeden stĺpec Amount (s kladnými/zápornými hodnotami) alebo samostatné stĺpce Debit a Credit. Kód vyššie zvláda oba prípady. Zabezpečuje, že kredity (strana Dal) sú reprezentované ako záporné sumy pre Beancount (keďže v Beancount sa pre každý zápis používa jedno číslo so znamienkom).
- Pripojí menu (predpokladá sa USD, pokiaľ nie je prítomný stĺpec s inou menou).
- Zapíše riadok zápisu Beancount s účtom, sumou a komentárom s poznámkou z riadku. Napríklad:
Assets:Checking 500.00 USD ; Deposit
Income:Sales -500.00 USD ; Deposit
Toto odráža vklad 500 USD (z príjmu na bežný účet).
- Mapuje názov účtu QuickBooks na účet Beancount pomocou slovníka
-
Po vymenovaní všetkých rozpisov oddeľuje transakciu prázdny riadok.
Spracovanie viacerých mien: Ak vaše údaje v QuickBooks obsahujú viacero mien, zahrňte kód meny pri každom zápise (ako je uvedené vyššie). Uistite sa, že účty, ktoré sú v cudzích menách, sú otvorené s touto menou. Napríklad, ak máte bankový účet v EUR, mali by ste zadať open Assets:Bank:Checking EUR
a transakcie na tomto účte budú používať EUR. Beancount podporuje denníky s viacerými menami a bude sledovať implicitné konverzie, ale možno budete musieť pridať cenové záznamy pre výmenné kurzy, ak chcete konverziu na základnú menu v reportoch. Odporúča sa tiež deklarovať hlavnú operačnú menu na začiatku súboru Beancount (napr. option "operating_currency" "USD"
).
Spustenie konverzie: Uložte Python skript (napríklad ako qb_to_beancount.py
) a spustite ho na svojich exportovaných súboroch. Mal by vyprodukovať súbor .beancount
obsahujúci všetky účty a transakcie.
2.2 Riešenie okrajových prípadov a čistenie údajov
Počas transformácie dávajte pozor na tieto bežné úskalia a ako ich riešiť:
-
Nesúlad názvov účtov: QuickBooks môže mať názvy účtov, ktoré sú v konflikte s hierarchickými názvami Beancount. Napríklad, QuickBooks môže mať dva rôzne nadradené účty, každý s podúčtom s názvom "Poistenie". V Beancount musí byť
Expenses:Insurance
jedinečný. Vyriešte to premenovaním jedného z nich (napr. "Poistenie-Vozidlo" vs. "Poistenie-Zdravotne") pred exportom alebo ich zmapujte na jedinečné účty Beancount vo vašom skripte. Konzistentné konvencie pomenovania (žiadne špeciálne znaky a použitie hierarchie) vám ušetria bolesti hlavy. V prípade potreby použite prístup s premapovacím súborom: udržiavajte CSV alebo slovník starého názvu → nový názov Beancount a aplikujte ho počas konverzie (náš príkladový kód používaaccount_map
a mohol by načítať prepisy zo súboru). -
Dátumy a formáty: Uistite sa, že všetky dátumy sú konzistentne formátované. Skript vyššie normalizuje M/D/Y na ISO formát. Taktiež dávajte pozor na problémy s fiškálnym vs. kalendárnym rokom, ak váš päťročný rozsah prekračuje koniec roka. Beancount sa nestará o hranice fiškálneho roka, ale neskôr možno budete chcieť rozdeliť súbory podľa rokov pre pohodlie.
-
Numerická presnosť: QuickBooks pracuje s menou na centy, takže práca v centoch je zvyčajne v poriadku. Všetky sumy by ideálne mali mať dve desatinné miesta v CSV. Ak sa nejaké sumy zmenili na celé čísla (bez desatinnej časti) alebo majú čiarky/zátvorky (pre záporné hodnoty), vyčistite ich v skripte (odstráňte čiarky, preveďte
(100.00)
na-100.00
, atď.). Export CSV, ak je vykonaný správne (podľa pokynov), by sa mal týmto problémom s formátovaním vyhnúť. -
Záporné sumy a znamienka: Reporty v QuickBooks niekedy zobrazujú záporné hodnoty ako
-100.00
alebo(100.00)
alebo dokonca--100.00
v niektorých exportoch do Excelu. Krok čistenia by mal tieto prípady zvládnuť. Uistite sa, že strany Má dať (debit) a Dal (credit) každej transakcie sa vynulujú. Beancount to bude vynucovať (ak nie je vyrovnaná, pri importe vyhodí chybu). -
Duplicitné transakcie: Ak ste museli exportovať transakcie v dávkach (napr. rok po roku alebo účet po účte), dávajte pozor, aby ste ich zlúčili bez prekrytia. Skontrolujte, či prvá transakcia jedného roka nie je zároveň poslednou z predchádzajúcej dávky, atď. Je ľahké omylom duplikovať niekoľko transakcií na hraniciach. Ak máte podozrenie na duplikáty, môžete zoradiť výsledné položky Beancount podľa dátumu a hľadať identické položky, alebo použiť jedinečné značky transakcií Beancount na ich odhalenie. Jednou stratégiou je zahrnúť čísla transakcií z QuickBooks ako metadáta (napr. použiť
Trans #
alebo číslo faktúry ako značkutxn
alebo metadátaquickbooks_id
) a potom zabezpečiť, aby neexistovali žiadne duplikáty týchto ID. -
Nevyrovnané rozpisy / Prechodné účty: QuickBooks môže mať zvláštne prípady, ako transakciu s nevyrovnanosťou, ktorú QuickBooks automaticky upravil na účet „Opening Balance Equity“ alebo „Retained Earnings“. Napríklad pri nastavovaní počiatočných zostatkov účtov QuickBooks často zaúčtuje rozdiely na účet vlastného imania. Tieto sa objavia v exportovaných transakciách. Beancount bude vyžadovať explicitné vyrovnanie. Možno budete musieť zaviesť účet vlastného imania pre počiatočné zostatky (bežne
Equity:Opening-Balances
), aby ste zrkadlili QuickBooks. Je dobrým zvykom mať na prvý deň vášho denníka položku počiatočných zostatkov, ktorá stanoví počiatočné zostatky všetkých účtov (pozri Fázu 5). -
Okrajové prípady viacerých mien: Ak používate viacero mien, export z QuickBooks môže uvádzať všetky sumy v domácej mene alebo v ich natívnej mene. Ideálne je získať údaje v natívnej mene pre každý účet (reporty z QuickBooks Online to zvyčajne robia). V Beancount každý zápis nesie menu. Ak QuickBooks poskytol výmenné kurzy alebo konverziu na domácu menu, môžete ich ignorovať a spoľahnúť sa na cenové záznamy Beancount. Ak QuickBooks neexportoval výmenné kurzy, možno budete chcieť manuálne pridať cenové záznamy (napr. pomocou direktívy
price
v Beancount) pre kľúčové dátumy, aby sa zhodovalo ocenenie. Avšak pre základnú integritu denníka stačí, že transakcie sa vyrovnávajú vo svojich pôvodných menách – nerealizované zisky/straty nemusia byť explicitne zaznamenané, pokiaľ nechcete rovnaké reporty. -
Pohľadávky / Záväzky: QuickBooks sleduje detaily faktúr a účtov (dátumy splatnosti, stav platby atď.), ktoré sa v jednoduchom denníku úplne neprenesú. Získate transakcie pohľadávok (A/R) a záväzkov (A/P) (faktúry zvyšujúce A/R, platby znižujúce A/R atď.), ale nie dokumenty faktúr alebo zostatky zákazníkov podľa faktúr. V dôsledku toho by ste po migrácii mali overiť, že zostatky vašich účtov A/R a A/P v Beancount sa rovnajú otvoreným zostatkom zákazníkov/dodávateľov v QuickBooks. Ak potrebujete sledovať faktúry, môžete použiť metadáta Beancount (napr. zahrnúť značku
invoice
alebo odkaz). Čísla faktúr z QuickBooks by sa mali preniesť v poliachNum
aleboMemo
– náš skript zachovávaNum
akonumber: "..."
v metadátach transakcie. -
Neaktívne alebo zrušené účty: Export IIF môže obsahovať neaktívne účty (ak ste sa rozhodli ich zahrnúť). Je v poriadku ich importovať (budú mať len nulový zostatok, ak boli skutočne neaktívne, a žiadne transakcie). Po poslednom dátume transakcie ich môžete v Beancount označiť ako uzavreté pomocou direktívy
close
. To udržuje váš denník uprataný. Napríklad:2023-12-31 close Expenses:OldAccount ; zrušený po migrácii
Toto je voliteľné a slúži hlavne na čistotu.
Dôkladným čistením a mapovaním údajov, ako je uvedené vyššie, získate súbor denníka Beancount, ktorý štrukturálne zrkadlí vaše údaje z QuickBooks. Ďalším krokom je overenie, či aj numericky zrkadlí QuickBooks.