Financial Accounting
Export bookings and debtor/creditor master data to an accounting system.
A financial accounting app exports the ERP's bookings and debtor/creditor master data to an accounting system. DATEV is the reference implementation.
Registering the finance backend
await methods.createFinanceBackend('DATEV');Registering it makes your app appear as an export target in the ERP's finance export.
The export is two-phase
Do not collapse these. The ERP model separates producing the files from transmitting them:
1. Build ERP data ──► formatted files ──► DMS
2. Transmit DMS files ──► accounting system ──► job statusPhase 1 is triggered by the user, reads the booking run, and writes finished files into the DMS. Phase 2 picks those files up and uploads them. Keeping them apart means a transmission can be retried without regenerating, and the exported files stay auditable.
Both phases are long-running. The reference app answers the HTTP request immediately and continues in the background, writing progress into a status record the UI polls.
If you do that, remember a 200 then means "accepted", not "finished". Clients that treat it as completion will read stale files. Give them a status endpoint.
Reading the data
Bookings come from computed queries — the booking run, its bookings, and the individual records:
Within a booking, the first record is the header and the remaining records are the lines. A booking with only one record therefore produces no output.
The accounts come straight from the data — there is no mapping table in the app:
Account (Konto)
the header record's ledger
Contra account (Gegenkonto)
the line record's ledger
Tax key (BU-Schlüssel)
the line record's transaction key
Skip lines whose amount is zero or whose booking state is not OK.
Always sort a paged query by a unique column. Offset paging over an unsorted result set is undefined: pages overlap, some rows arrive twice and others never arrive at all — differently on every run. The backend adds no default order. Sort by id, and deduplicate afterwards as a safety net.
Format details are unforgiving
Accounting formats are validated strictly on import. The things that actually break exports:
Encoding. Write UTF-8 with a byte-order mark. Strip it again when reading your own files back.
Numbers. German decimal comma, exactly two decimals, no thousands separator, and the absolute value — the sign is carried by the debit/credit indicator. If that indicator is lost, the booking silently inverts.
Dates are partial. In the DATEV booking format the document date is only day and month; the year comes from the file header. That is precisely why the export must be split per business year — a booking outside the header's year would be filed under the wrong one. Walk backwards and forwards from the main business year and write additional files as needed.
Field widths and quoting. Fields have maximum lengths and per-field quoting rules. Truncation is silent, and an embedded quote character is usually removed rather than escaped — so validate values before writing rather than trusting the writer.
Timezones. Date formatters typically use local time while a date-only configuration value parses as UTC midnight. On a server west of UTC that shifts the business year by a day. Normalise before comparing.
Configuration
An accounting integration needs client identification — for DATEV the consultant number and client number, which combine into the client id used on every API call. Along with the business-year start and the ledger account length, these are required before an export can run: gate the export button on them rather than failing mid-run.
Store them where both your export code and your API layer can read them, and remember that values round-trip as strings.
What to watch out for
Make re-exports distinguishable. A regenerated file must not silently overwrite the previous one — add a suffix. Auditors need to see what was sent and when.
Deduplicate transmissions. Track which files and documents already succeeded and skip them on a re-run, or you create duplicate jobs in the accounting system. Treat the accounting system's own "duplicate" response as success, not as an error.
Guard against concurrent runs, with a staleness timeout so a crashed run doesn't block the export forever.
Respect rate limits and retry properly. Honour Retry-After on 429/503, then back off exponentially with a cap. Distinguish fatal errors (missing rights, expired authorisation) — which should abort the whole run — from per-document failures, which should be logged and skipped.
Check the export rights explicitly. An authorised session is not the same as an authorised service. Verify the required services are enabled for the client and surface a clear message; otherwise a missing entitlement looks like a generic authorisation failure.
Attachments have size limits. Document upload limits are enforced on both sides — check the size before uploading and report oversized documents as warnings rather than aborting the run.
Long-lived authorisation expires. Refresh tokens for accounting APIs can last months or years, but they do expire; handle the expiry as a normal state with a re-authorisation prompt.
Last updated
Was this helpful?