Migrating from QuickBooks to Beancount: A Step-by-Step Guide
Fase 1: Gegevens Exporteren uit QuickBooks
Het migreren van vijf jaar aan gegevens begint met het exporteren van alle QuickBooks-records in een bruikbaar formaat. QuickBooks Desktop en QuickBooks Online hebben verschillende exportopties:
1.1 QuickBooks Desktop – Exportopties
IIF (Intuit Interchange Format): QuickBooks Desktop kan lijsten (zoals het rekeningschema, klanten, leveranciers) exporteren naar .IIF
-tekstbestanden. Ga in QuickBooks Desktop naar File → Utilities → Export → Lists to IIF, en selecteer vervolgens de lijsten die u nodig heeft (bijv. Rekeningschema, Klanten, Leveranciers). Dit levert een tekstbestand op dat rekeningnamen, -types en lijstgegevens bevat. IIF is een eigen, maar platte-tekstformaat dat relatief eenvoudig te parsen is. Gebruik dit om uw Rekeningschema en contactlijsten vast te leggen ter referentie in Beancount.
Grootboek/Journaal via CSV: Voor transactiegegevens biedt QuickBooks Desktop geen volledige export met één klik, maar u kunt rapporten gebruiken. De aanbevolen methode is om het Algemeen Journaal (alle transacties) over de gewenste datumperiode te exporteren. Open in QuickBooks Desktop Reports → Accountant & Taxes → Journal, stel de datums in van de vroegste transactie tot vandaag, en klik op Export → Excel. Sla het resultaat op als CSV na het verwijderen van eventuele rapportkop- en voetteksten en lege kolommen. Zorg ervoor dat de numerieke gegevens schoon zijn: inclusief centen (bijv. 3.00
niet 3
), geen extra aanhalingstekens en geen valutasymbolen of dubbele mintekens in de CSV. De CSV moet kolommen hebben zoals Date, Trans #, Name, Account, Memo, Debit, Credit, Balance (of een enkele kolom Amount, afhankelijk van het rapportformaat).
Tip: QuickBooks Desktop 2015+ kan ook transacties exporteren via het Find-dialoogvenster. Gebruik Edit → Find → Advanced, stel het datumbereik in op vijf jaar en exporteer de resultaten naar CSV. Waarschuwing: Sommige versies beperken de export tot 32.768 regels. Als u zeer grote datasets heeft, exporteer dan jaar na jaar (of in kleinere stukken) om afkapping te voorkomen, en voeg ze later samen. Zorg ervoor dat de datumbereiken niet overlappen om duplicaten te voorkomen.
Andere Formaten (QBO/QFX/QIF): QuickBooks Desktop kan banktransacties importeren via .QBO
(Web Connect) of .QFX/.OFX
-bestanden, maar voor het exporteren vanuit QuickBooks zijn dit geen gebruikelijke opties. Als uw doel is om alleen banktransacties te extraheren, heeft u deze mogelijk al in QBO/OFX van uw bank. Voor een volledige grootboekexport kunt u zich echter beter houden aan IIF en CSV. QuickBooks Desktop kan niet rechtstreeks naar QIF (Quicken Interchange Format) exporteren zonder tools van derden. Als u toch een manier vindt om QIF te verkrijgen, merk dan op dat sommige oudere grootboektools (Ledger 2.x) QIF konden lezen, maar het is beter om met CSV te werken in onze pijplijn.
1.2 QuickBooks Online – Exportopties
Ingebouwde Excel/CSV Export: QuickBooks Online (QBO) biedt een Export Data-tool. Ga naar Settings ⚙ → Tools → Export Data. Gebruik in het exportdialoogvenster het tabblad Reports om gegevens te selecteren (bijv. General Ledger of Transaction List) en het tabblad Lists voor lijsten (rekeningschema, etc.), kies All dates, en exporteer naar Excel. QuickBooks Online zal een ZIP-bestand downloaden met meerdere Excel-bestanden voor de geselecteerde rapporten en lijsten (bijvoorbeeld Winst & Verlies, Balans, Grootboek, Klanten, Leveranciers, Rekeningschema, etc.). U kunt deze Excel-bestanden vervolgens converteren naar CSV voor verwerking.
Transaction Detail Report: Als de standaardexport van QBO geen enkel Grootboek-bestand bevat, kunt u handmatig een gedetailleerd rapport genereren:
- Navigeer naar Reports en zoek Transaction Detail by Account (of General Ledger in sommige QBO-versies).
- Stel Report period in op het volledige bereik van vijf jaar.
- Onder Rapportopties, stel Group by = None in (om individuele transacties zonder subtotalen te tonen).
- Pas de kolommen aan om ten minste op te nemen: Date, Transaction Type, Number, Name (Payee/Customer), Memo/Description, Account, Debit, Credit (of een enkele Amount-kolom), en Balance. Neem ook eventuele klassen of locaties op als u die gebruikt.
- Genereer het rapport en Export to Excel.
Dit levert een gedetailleerd grootboek op van alle transacties. Sla het op als CSV. Elke regel vertegenwoordigt één splitsing (boeking) van een transactie. U zult later de regels per transactie moeten groeperen voor de conversie.
Rekeningschema en Andere Lijsten: QuickBooks Online kan het rekeningschema exporteren via Accounting → Chart of Accounts → Batch Actions → Export to Excel. Doe dit om de rekeningnamen en -types te verkrijgen. Exporteer op dezelfde manier Klanten, Leveranciers, etc., als u de namen wilt overnemen voor metadata.
QuickBooks Online API (Optioneel): Voor een programmatische aanpak biedt Intuit een REST API voor QBO-gegevens. Gevorderde gebruikers kunnen een QuickBooks Online-app maken (vereist een ontwikkelaarsaccount) en de API gebruiken om gegevens in JSON op te halen. U kunt bijvoorbeeld de Account
-endpoint opvragen voor het rekeningschema en de JournalEntry
- of GeneralLedger
-rapportendpoints voor transacties. Er zijn Python SDK's zoals python-quickbooks
die de API wrappen. Het gebruik van de API omvat echter OAuth-authenticatie en is overdreven voor een eenmalige migratie, tenzij u de voorkeur geeft aan automatisering. In de meeste gevallen is de handmatige export naar CSV/Excel eenvoudiger en minder foutgevoelig.
Fase 2: Gegevens Transformeren en Opschonen
Zodra u de QuickBooks-gegevens in CSV (en/of IIF) hebt, is de volgende stap het omzetten naar Beancount's platte-tekst grootboekformaat. Dit omvat het parsen van de exports, het mappen van QuickBooks-rekeningen naar een Beancount-rekeningschema en het formatteren van transacties in Beancount-syntaxis.
2.1 QuickBooks Exports Parsen met Python
Het gebruik van Python zorgt voor nauwkeurigheid en reproduceerbaarheid van de transformatie. We zullen scripts schetsen voor twee belangrijke taken: het importeren van het rekeningschema en het converteren van transacties.
Rekeningen Importeren en Mappen: Het is cruciaal om uw rekeningen in Beancount op te zetten voordat u transacties toevoegt. QuickBooks-rekeningen hebben types (Bank, Accounts Receivable, Expense, etc.) die we zullen mappen naar de hiërarchie van Beancount (Assets, Liabilities, Income, Expenses, etc.). We kunnen bijvoorbeeld een mapping gebruiken zoals:
# QuickBooks-rekeningtype naar Beancount-hoofdcategorie
AccountTypeMap = {
'BANK': 'Assets',
'CCARD': 'Liabilities',
'AR': 'Assets', # Accounts Receivable (Debiteuren) als activa
'AP': 'Liabilities', # Accounts Payable (Crediteuren) als passiva
'FIXASSET': 'Assets',
'OASSET': 'Assets', # Other Asset (Overige activa)
'OCASSET': 'Assets', # Other Current Asset (Overige vlottende activa)
'LTLIAB': 'Liabilities', # Long Term Liability (Langlopende verplichting)
'OCLIAB': 'Liabilities', # Other Current Liability (Overige kortlopende verplichting)
'EQUITY': 'Equity',
'INC': 'Income',
'EXP': 'Expenses',
'EXINC': 'Income', # Other Income (Overige inkomsten)
'EXEXP': 'Expenses', # Other Expense (Overige uitgaven)
}
Met behulp van de QuickBooks Desktop IIF-export of de CSV met de rekeningenlijst van QBO, halen we de naam en het type van elke rekening op. Dan:
-
Beancount-rekeningnamen aanmaken: QuickBooks gebruikt soms dubbele punten (
:
) in rekeningnamen om subrekeningen aan te duiden (bijv. “Current Assets:Checking”). Beancount gebruikt dezelfde dubbele-puntnotatie voor hiërarchie. U kunt de naam vaak direct hergebruiken. Als de QuickBooks-rekeningnamen niet met een categorie beginnen, voeg dan de gemapte categorie toe. Bijvoorbeeld, een QuickBooks-rekening van het typeBANK
genaamd "Checking" wordtAssets:Checking
in Beancount. EenEXP
(expense)-rekening "Meals" wordtExpenses:Meals
, enz. -
Zorg voor geldige naamgeving: Verwijder of vervang alle tekens die Beancount kunnen verwarren. QuickBooks staat tekens zoals
&
of/
in namen toe. Het is verstandig om speciale tekens te verwijderen of te vervangen (bijv.&
vervangen doorand
, schuine strepen of spaties verwijderen). Zorg er ook voor dat alle rekeningnamen uniek zijn na transformatie – QuickBooks staat mogelijk dezelfde subrekeningnaam onder verschillende ouders toe, wat prima is, maar in Beancount moet de volledige naam (met ouders) uniek zijn. Hernoem indien nodig of voeg een kwalificator toe om ze te onderscheiden. -
Rekeningopeningen uitvoeren: In Beancount moet elke gebruikte rekening worden geopend met een
open
-directive. U kunt een datum kiezen vóór uw eerste transactie (bijv. als u gegevens van 2019–2023 migreert, gebruik dan2018-12-31
of een nog eerdere datum voor alle openingen). Het script schrijft dan regels zoals:2018-12-31 open Assets:Checking USD
2018-12-31 open Expenses:Meals USD
voor elke rekening (ervan uitgaande dat USD de hoofdvaluta is). Gebruik de juiste valuta voor elke rekening (zie notities over meerdere valuta's hieronder).
Transactieconversie: De belangrijkste uitdaging is het converteren van de QuickBooks-transactie-export (CSV) naar Beancount-boekingen. Elke QuickBooks-transactie (factuur, rekening, cheque, journaalpost, etc.) kan meerdere splitsingen (regels) hebben die moeten worden samengevoegd tot één Beancount-transactie.
We gebruiken de CSV-lezer van Python om door de geëxporteerde regels te itereren en splitsingen te verzamelen:
import csv
from collections import defaultdict
# Lees alle regels uit de QuickBooks Journaal CSV
rows = []
with open('quickbooks_geexporteerd_journaal.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for line in reader:
rows.append(line)
# Groepeer regels per transactie (ervan uitgaande dat 'Trans #' transacties identificeert)
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)
Nu is transactions
een dictionary waarbij elke sleutel een transactie-ID/nummer is en de waarde de lijst met splitsingen voor die transactie is. Vervolgens converteren we elke groep naar Beancount:
def format_date(qb_date):
# QuickBooks-datums kunnen eruitzien als "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():
# Sorteer splitsingen op regelvolgorde indien nodig (ze komen meestal in de juiste volgorde)
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()
# Transactiekop
output_lines.append(f'{date} * "{payee}" "{memo}"')
if first.get('Num'): # voeg referentienummer toe indien beschikbaar
output_lines.append(f' number: "{first["Num"]}"')
# Loop door elke splitsing/boeking
for split in splits:
acct_name = split['Account'].strip()
# Map QuickBooks-rekeningnaam naar Beancount-rekening (met eerdere mapping)
beancount_acct = account_map.get(acct_name, acct_name)
# Bepaal bedrag met teken:
amount = split.get('Amount') or ""
debit = split.get('Debit') or ""
credit = split.get('Credit') or ""
if amount:
# Sommige exports hebben een enkele Amount-kolom (negatief voor credits)
amt_str = amount
else:
# Indien aparte Debit/Credit-kolommen
amt_str = debit if debit else f"-{credit}"
# Verwijder eventuele komma's in getallen voor de zekerheid
amt_str = amt_str.replace(",", "")
# Voeg valuta toe
currency = split.get('Currency') or "USD"
amt_str = f"{amt_str} {currency}"
# Memo/omschrijving voor de splitsing
line_memo = split.get('Memo', "").strip()
comment = f" ; {line_memo}" if line_memo else ""
output_lines.append(f" {beancount_acct:<40} {amt_str}{comment}")
# Einde van transactie – lege regel
output_lines.append("")
Deze scriptlogica doet het volgende:
-
Formatteert de datum naar JJJJ-MM-DD voor Beancount.
-
Gebruikt de begunstigde (Name) en memo voor de transactieomschrijving. Bijvoorbeeld:
2020-05-01 * "ACME Corp" "Factuurbetaling"
(Als er geen begunstigde is, kunt u het QuickBooks-transactietype gebruiken of de begunstigde leeg laten). -
Voegt
number
-metadata toe als er een referentienummer is (cheque #, factuur #, etc.). -
Itereert door elke splitsingsregel:
- Mapt de QuickBooks-rekeningnaam naar de Beancount-rekening met behulp van een dictionary
account_map
(gevuld vanuit de stap van het rekeningschema). - Bepaalt het bedrag. Afhankelijk van uw export, heeft u mogelijk een enkele Amount-kolom (met positieve/negatieve waarden) of afzonderlijke Debit- en Credit-kolommen. De bovenstaande code behandelt beide gevallen. Het zorgt ervoor dat credits worden weergegeven als negatieve bedragen voor Beancount (aangezien in Beancount een enkel getal met een teken per boeking wordt gebruikt).
- Voegt de valuta toe (uitgaande van USD, tenzij er een andere valutakolom aanwezig is).
- Schrijft de Beancount-boekingsregel met de rekening, het bedrag en een opmerking met de regelmemo. Bijvoorbeeld:
Assets:Checking 500.00 USD ; Storting
Income:Sales -500.00 USD ; Storting
Dit weerspiegelt een storting van $500 (van Income naar Checking).
- Mapt de QuickBooks-rekeningnaam naar de Beancount-rekening met behulp van een dictionary
-
Na het opsommen van alle splitsingen, scheidt een lege regel de transactie.
Omgaan met meerdere valuta's: Als uw QuickBooks-gegevens meerdere valuta's bevatten, neem dan de valutacode op bij elke boeking (zoals hierboven getoond). Zorg ervoor dat rekeningen in vreemde valuta's worden geopend met die valuta. Als u bijvoorbeeld een bankrekening in EUR heeft, zou u open Assets:Bank:Checking EUR
uitvoeren en de transacties op die rekening gebruiken EUR. Beancount ondersteunt grootboeken met meerdere valuta's en houdt impliciete conversies bij, maar u moet mogelijk prijsboekingen voor wisselkoersen toevoegen als u conversie naar een basisvaluta in rapporten wilt. Het wordt ook aanbevolen om uw belangrijkste operationele valuta bovenaan het Beancount-bestand te declareren (bijv. option "operating_currency" "USD"
).
De conversie uitvoeren: Sla het Python-script op (bijvoorbeeld als qb_naar_beancount.py
) en voer het uit op uw geëxporteerde bestanden. Het zou een .beancount
-bestand moeten produceren dat alle rekeningen en transacties bevat.
2.2 Omgaan met Randgevallen en Gegevensopschoning
Houd tijdens de transformatie rekening met deze veelvoorkomende valkuilen en hoe u ze kunt aanpakken:
-
Mismatch in Rekeningnamen: QuickBooks kan rekeningnamen hebben die botsen met de hiërarchische namen van Beancount. QuickBooks kan bijvoorbeeld twee verschillende bovenliggende rekeningen hebben met elk een subrekening genaamd "Insurance". In Beancount moet
Expenses:Insurance
uniek zijn. Los dit op door er een te hernoemen (bijv. "Insurance-Vehicle" vs "Insurance-Health") vóór de export of map ze naar unieke Beancount-rekeningen in uw script. Consistente naamgevingsconventies (geen speciale tekens en gebruik van hiërarchie) zullen hoofdpijn besparen. Gebruik de remapping-bestandsbenadering indien nodig: onderhoud een CSV of dictionary van oude naam → nieuwe Beancount-naam en pas deze toe tijdens de conversie (ons voorbeeldcode gebruikt eenaccount_map
en kan overschrijvingen uit een bestand laden). -
Datums en Formaten: Zorg ervoor dat alle datums consistent zijn geformatteerd. Het bovenstaande script normaliseert M/D/J naar ISO-formaat. Pas ook op voor problemen met fiscaal jaar vs kalenderjaar als uw periode van vijf jaar een jaareinde overschrijdt. Beancount geeft niet om grenzen van fiscale jaren, maar u wilt misschien later bestanden per jaar splitsen voor het gemak.
-
Numerieke Precisie: QuickBooks behandelt valuta met centen, dus werken in centen is meestal prima. Alle bedragen moeten idealiter twee decimalen hebben in de CSV. Als bedragen zijn omgezet in gehele getallen (geen decimaal) of komma's/haakjes hebben (voor negatieven), schoon die dan op in het script (verwijder komma's, converteer
(100.00)
naar-100.00
, etc.). De CSV-export, indien correct uitgevoerd (volgens de instructies), zou die opmaakproblemen al moeten vermijden. -
Negatieve Bedragen en Tekens: QuickBooks-rapporten tonen negatieven soms als
-100.00
of als(100.00)
of zelfs--100.00
in bepaalde Excel-exports. De opschoningsstap moet hiermee omgaan. Zorg ervoor dat de debet- en creditbedragen van elke transactie op nul uitkomen. Beancount zal dit afdwingen (indien niet in evenwicht, zal het een fout geven bij het importeren). -
Dubbele Transacties: Als u transacties in batches moest exporteren (bijv. jaar na jaar of rekening per rekening), wees dan voorzichtig met het samenvoegen zonder overlap. Controleer of de eerste transactie van een jaar niet ook de laatste is van de vorige batch, enz. Het is gemakkelijk om per ongeluk een paar transacties op de grenzen te dupliceren. Als u duplicaten vermoedt, kunt u de uiteindelijke Beancount-boekingen op datum sorteren en zoeken naar identieke boekingen, of Beancount's unieke transactietags gebruiken om ze te vangen. Een strategie is om QuickBooks-transactienummers op te nemen als metadata (bijv. gebruik de
Trans #
of factuurnummer als eentxn
-tag ofquickbooks_id
-metadata) en dan te zorgen dat er geen duplicaten van die ID's bestaan. -
Ongebalanceerde Splitsingen / Tussenrekeningen: QuickBooks kan vreemde gevallen hebben zoals een transactie met een onbalans die QuickBooks automatisch heeft aangepast naar een "Opening Balance Equity" of "Retained Earnings". Bij het instellen van de beginbalansen van rekeningen boekt QuickBooks bijvoorbeeld vaak verschillen naar een Eigen Vermogen-rekening. Deze zullen verschijnen in de geëxporteerde transacties. Beancount vereist expliciet evenwicht. Mogelijk moet u een Eigen Vermogen-rekening voor beginbalansen introduceren (meestal
Equity:Opening-Balances
) om QuickBooks te spiegelen. Het is een goede gewoonte om een beginbalansboeking te hebben op de eerste dag van uw grootboek die de startsaldi van alle rekeningen vaststelt (zie Fase 5). -
Randgevallen met Meerdere Valuta's: Als u meerdere valuta's gebruikt, kan de export van QuickBooks alle bedragen in de thuisvaluta of in hun oorspronkelijke valuta vermelden. Idealiter krijgt u de gegevens in de oorspronkelijke valuta voor elke rekening (de rapporten van QuickBooks Online doen dit meestal). In Beancount heeft elke boeking een valuta. Als QuickBooks wisselkoersen of een thuisvaluta-conversie heeft geleverd, kunt u die negeren en vertrouwen op de prijsboekingen van Beancount. Als QuickBooks geen wisselkoersen heeft geëxporteerd, wilt u misschien handmatig prijsrecords toevoegen (bijv. met de
price
-directive van Beancount) voor belangrijke datums om de waardering te evenaren. Voor de basisintegriteit van het grootboek is het echter voldoende dat transacties in hun oorspronkelijke valuta's in evenwicht zijn – ongerealiseerde winsten/verliezen hoeven niet expliciet te worden geregistreerd, tenzij u dezelfde rapporten wilt. -
Debiteuren / Crediteuren: QuickBooks houdt factuur- en rekeningdetails bij (vervaldata, betaalstatus, etc.) die niet volledig zullen worden overgedragen in een plat grootboek. U krijgt de A/R- en A/P-transacties (facturen die A/R verhogen, betalingen die A/R verlagen, etc.), maar niet de factuurdocumenten of klantensaldi per factuur. Als gevolg hiervan moet u na de migratie controleren of uw A/R- en A/P-rekeningsaldi in Beancount gelijk zijn aan de openstaande saldi van klanten/leveranciers in QuickBooks. Als u facturen moet volgen, kunt u de metadata van Beancount gebruiken (bijv. een
invoice
-tag of link opnemen). De QuickBooks-factuurnummers zouden via deNum
- ofMemo
-velden moeten zijn meegekomen – ons script bewaart deNum
alsnumber: "..."
in de transactiemetadata. -
Inactieve of Gesloten Rekeningen: De IIF-export kan inactieve rekeningen bevatten (als u ervoor koos deze op te nemen). Het is prima om ze te importeren (ze zullen gewoon geen transacties en een nulsaldo hebben als ze echt inactief zijn). U kunt ze in Beancount als gesloten markeren na de laatste transactiedatum met een
close
-directive. Dit houdt uw grootboek opgeruimd. Bijvoorbeeld:2023-12-31 close Expenses:OldAccount ; gesloten na migratie
Dit is optioneel en voornamelijk voor de netheid.
Door de gegevens zorgvuldig op te schonen en te mappen zoals hierboven beschreven, krijgt u een Beancount-grootboekbestand dat structureel uw QuickBooks-gegevens weerspiegelt. De volgende stap is om te verifiëren dat het ook numeriek QuickBooks weerspiegelt.
Fase 3: Gegevensvalidatie en Afstemming
Validatie is een kritieke fase in een migratie van boekhoudgegevens. We moeten ervoor zorgen dat het Beancount-grootboek tot op de cent nauwkeurig overeenkomt met de QuickBooks-boekhouding. Er kunnen verschillende strategieën en hulpmiddelen worden gebruikt:
3.1 Afstemming van de Proefbalans
Een proefbalans-rapport toont de eindsaldi van alle rekeningen (met debet- en creditbedragen of positief/negatief aangegeven) en zou op nul moeten uitkomen. Het draaien van een proefbalans in beide systemen voor dezelfde datum is de snelste manier om de algehele nauwkeurigheid te bevestigen.
-
In QuickBooks: Genereer een Trial Balance-rapport voor de laatste dag van het laatste jaar (bijv. 31 december 2023). Dit rapport toont het saldo van elke rekening. Exporteer het of noteer de belangrijkste cijfers.
-
In Beancount: Gebruik de rapportage van Beancount om een proefbalans te genereren. Een eenvoudige methode is via de opdrachtregel:
bean-report gemigreerd.beancount balances
Het
balances
-rapport is een proefbalans die alle rekeningen en hun saldi vermeldt. U kunt het bestand ook openen in Fava (de web-UI van Beancount) en kijken naar de sectie Balances of Balance Sheet. Elk rekeningsaldo in Beancount moet overeenkomen met de proefbalans van QuickBooks. Als QuickBooks bijvoorbeeld Accounts Receivable =