Accounting and DATEV
billing:datev:export writes a period of issued invoices as a DATEV EXTF "Buchungsstapel" (the booking batch
a German tax advisor imports). With no --from/--to it exports the previous calendar month, so a monthly
cron hands last month's bookings to the Steuerberater:
php artisan billing:datev:export # a period of invoices as a DATEV EXTF booking batch (defaults to last month)
The account numbers come from config('billing.datev') and must be confirmed with the advisor — left unset
the file is structurally valid with blank account fields. Each business transaction resolves to the account
that carries its own tax logic through a DatevAccountResolver, so a fan-revenue rate, an OSS country or a
§13b input each land on their own account rather than one revenue account for everything. With no chart
selected the export is the single-seller revenue account, byte-for-byte unchanged.
A sale to a business across a border
A service sold to a business in another member state, whose tax the recipient owes, books to its own revenue
account: 8336 in SKR03, 4336 in SKR04. The booking also carries the recipient's VAT id in field 40
(EU-Land u. UStID), which is where DATEV reads the recapitulative statement from. Without DATEV,
billing:recapitulative-statement:export writes the statement as a file (see Taxes). A service to a business
outside the union is not taxable here and books to 8338 or 4338. Neither may land on the standard revenue
account: that is an automatic account, and it would derive domestic tax from a posting that carries none.
Only a selected chart routes these sales, and a chart without the two accounts refuses the booking rather than book the sale as domestic. A published configuration needs them added; the upgrading guide shows the two lines.
Goods the platform supplies itself
Where the platform is treated as supplying goods itself, as the deemed supplier of goods another seller offers through it, a selected chart books its sale to the buyer by where that sale is taxed:
| The sale | Transaction | SKR03 | SKR04 |
|---|---|---|---|
| taxed at home, standard rate | goods_revenue_standard | 8400 | 4400 |
| taxed at home, reduced rate | goods_revenue_reduced | 8300 | 4300 |
| declared in the Union scheme | oss_goods_revenue, one account per destination | from 8320 to 8329 | from 4320 to 4329 |
| declared in the import scheme | import_scheme_goods_revenue, one account per destination | — | — |
The home accounts are the Automatikkonten every other sale at that rate books to; the transactions are
separate so goods and services can be kept apart. The Union scheme's accounts are a block per destination
country, as the services' are, because DATEV keeps one country and rate per account in that range: no
default ships. The seller's supply of the goods to the platform, exempt under § 4 Nr. 4c UStG, books to
deemed_supply_input_exempt against the seller's payable.
No account could be confirmed for the import scheme's sales or for the exempt supply, so both ship unmapped, and a booking for either is refused by name until you configure an account agreed with your accountant.
From the admin console, without a shell
The same batch is downloadable from the admin console, for whoever holds the billing.admin.ability Gate.
Pick a period, get the file. It is the same assembly the command runs, deliberately: this export has
twice shipped a batch that was structurally valid, imported cleanly, and was missing an entire category of
bookings, so a second implementation is the one thing not on offer.
Two things behave differently from a download you might expect:
- Nothing is written to the server. The file is streamed straight to the browser. A booking batch is your complete revenue history for the period in one file, and a copy left in storage is a second place it has to be protected, retained and erased from.
- A refusal downloads nothing at all. Where the writer refuses — a document reference the format cannot carry, a period spanning two posting months — the screen shows you which, and no partial file is produced. That asymmetry is the point: the import does not argue, so a truncated batch surfaces months later as a reconciliation that does not close, with nothing to point at.
The EXTF header's field 21 (Festschreibekennzeichen) is emitted as 1, marking each booking batch as
locked against alteration after import, as GoBD requires. A correction is booked as a Haben (credit) against
the invoice it corrects; see Invoices and e-invoicing for the document side.