accounted-multicase-intgr
Example integration that sends vouchers (bilag) from a Multicase "buntfil" export to Accounted through its v1 REST API.
It reads the .xls export, groups the posting lines into vouchers, maps them to
Accounted journal entries and creates them as drafts, optionally posting them.
Install
go install simenandre.no/accounted-multicase-intgr@latest
Usage
cp config.example.json config.json # then adjust the mapping
# Parse and map every voucher, no network access
accounted-multicase-intgr check "MC Buntfil 01102026-12102026.xls"
accounted-multicase-intgr check -v "MC Buntfil 01102026-12102026.xls" # print each entry
export ACCOUNTED_API_KEY=gnubok_sk_... # scope bookkeeping:write
export ACCOUNTED_COMPANY_ID=<company uuid>
# export ACCOUNTED_URL=https://app.accounted.se
accounted-multicase-intgr push -dry-run export.xls # server validates, nothing is saved
accounted-multicase-intgr push export.xls # create drafts
accounted-multicase-intgr push -commit export.xls # create and post, assigning voucher numbers
push validates everything before it writes anything: if any voucher has an
unmapped account or VAT code, or a date outside an open fiscal period, nothing
is sent.
How vouchers are mapped
- Grouping. Lines are grouped by
BilagsArtandBilagsnummer. Inventory corrections (Lagerkorrigering) carry Bilagsnummer 0 and are grouped per batch (BuntHodeID) instead. - Amounts.
Belopis used, in the Multicase company's base currency. Positive is debit, negative is credit. Amounts are rounded to two decimals; Multicase writes currency conversions with three, so a voucher can end up a few öre off. That difference, up tomax_rounding_ore, is posted torounding_account. Zero-amount lines are dropped. - Accounts. A line whose
Kontoequals the customer number (Faktura kundenr) or supplier number (LevNr.) is a subledger line and is posted tocustomer_ledger_account/supplier_ledger_account. Every other account must be listed inaccounts. - VAT. Multicase posts revenue and cost lines gross with an MVA code and
leaves the split to the receiving ledger. For codes with a
rate, the net amount stays on the mapped account and the VAT goes to the code'saccount. Codes with rate 0 pass through untouched. - Dimensions.
AvdNr.andProsjektare sent as the SIE dimensions named indimensions(by default 1, kostnadsställe, and 6, projekt).
config.example.json maps the accounts found in one Print Supplies AS export
to BAS 2026 accounts. It is a starting point only: have the mapping, and in
particular the VAT codes, checked by whoever keeps the books.
Not booking twice
Each voucher is sent with source_id multicase:<BilagsArt>:<Bilagsnummer>
and a deterministic Idempotency-Key, so retries after a timeout are replayed
by the server rather than repeated. Accounted keeps idempotency keys for 24
hours, so push also records every draft and posted voucher in
multicase-state.json. Re-running an overlapping export skips what was sent.
A voucher that changed in Multicase after it was sent is reported and skipped. Posted vouchers cannot be edited; correct them in Accounted (storno or rättelse).
Limitations
- Accounted keeps its ledger in SEK. Amounts are sent as they appear in Multicase, so the export's base currency must match the Accounted company's.
- Only the first worksheet of the export is read, and only Excel 97-2003
(
.xls) files are supported. The bundled BIFF8 reader exists because the available Go libraries decode negative whole-number cells as large positive numbers. - Requests are throttled to stay under the default limit of 100 requests per minute per API key; 429 and 5xx responses are retried.
