Bad debts: write-offs and the allowance for doubtful receivables
Two tools deal with customer invoices that will not be paid:
- a write-off takes all or part of what is open on one invoice off the books, when it is known that the money will not come;
- the allowance (Delkredere, Wertberichtigung auf Forderungen, ducroire, fondo svalutazione crediti, loss allowance) covers the risk that some of the open invoices will not be paid, at a period end, before anyone knows which.
Accounts
Every chart template has three accounts for this, each with a role:
| Chart | Allowance (receivable_allowance) |
Bad debts (bad_debt_expense) |
Change of the allowance (allowance_expense) |
|---|---|---|---|
| Swiss KMU | 1109 Delkredere | 3805 Verluste aus Forderungen, Veränderung Delkredere | (3805) |
| German HGB | 2190 Wertberichtigungen auf Forderungen aus LuL | 6930 Forderungsverluste | 6920 Einstellungen in Wertberichtigungen auf Forderungen |
| Spanish PGC | 490000 Deterioro de valor de créditos por operaciones comerciales | 650000 Pérdidas de créditos comerciales incobrables | 694000 Pérdidas por deterioro de créditos por operaciones comerciales |
| French PCG | 491000 Dépréciations des comptes de clients | 654000 Pertes sur créances irrécouvrables | 681700 Dotations aux dépréciations des actifs circulants |
| Italian | 2190 Fondo svalutazione crediti | 6850 Perdite su crediti | 6430 Svalutazione dei crediti dell'attivo circolante |
| IFRS, US GAAP, UK FRS 102, Canada | 1290 (loss allowance, allowance or provision for doubtful debts) | 6600 Bad debts | 6610 (change in the allowance) |
The allowance account is a contra account of the receivables (an asset with a credit balance) and a control account: only the allowance run posts to it, a manual entry is refused. The Swiss KMU chart books both the loss and the change of the allowance to 3805, as the KMU publications do; the other charts keep them apart, and the run falls back to the bad-debt account where a chart has no allowance-expense account.
Writing off an invoice
On a posted customer invoice that still has something open, Write off asks for:
- the amount, with VAT, in the invoice's currency (default: all that is open);
- what happens to the VAT:
- the loss is final (the bankruptcy is closed, a certificate of loss was issued): the output VAT on the amount is corrected now (CH MWSTG Art. 41, DE UStG § 17 Abs. 2);
- the loss is not final yet: the VAT stays owed and the whole amount goes to bad debts.
Its VAT can be corrected later, once the loss is final (see below). A company that reports
VAT when paid (the cash basis) is not offered this: no VAT is owed on money that never came
in (CH MWSTG Art. 40 Abs. 2, DE UStG § 13 Abs. 1 Nr. 1 b), so there a write-off always
corrects the VAT, and the server refuses
keep(write_off_keep_cash_basis);
- the reason, which is required and kept with the write-off;
- the date: on or after the invoice and its latest payment, not after today.
It is an internal entry, not a credit note: nothing is sent to the customer, and the customer still
owes the money in law. It always waits for a second person (four eyes, ADR-0036). The request
carries the reason "A write-off removes a receivable; a second person approves it." and is decided
on Approvals, never by an agent. While it waits it reserves its amount on the invoice. A rejection
releases that amount. Once posted it gets its number (WO-2026-000001).
The entry
A CHF invoice of 540.50 (500.00 + 8.1 % VAT), written off in full:
| the loss is final | the loss is not final | |
|---|---|---|
| Dr 3805 bad debts | 500.00 | 540.50 |
| Dr 2200 output VAT | 40.50 | |
| Cr 1100 receivables | 540.50 | 540.50 |
With the VAT corrected, the invoice's posting is taken back in proportion, as for a cash discount
(cash_discount.proportional_lines). Its revenue lines go to the bad-debt account. Its VAT lines
go back to the VAT accounts with their tax tags, so the VAT return shows the reduction where it
shows a cash discount's. The Swiss return of the quarter keeps Ziffer 200 as declared, shows the
loss of 500.00 in Ziffer 235 (Entgeltsminderungen wie Skonti, Rabatte, Verluste) and −500.00 /
−40.50 at 8.1 % in Ziffer 303, so 299 and 379 agree. The German UStVA nets the base in Kz 81 or
86 (§17 Abs. 2 UStG), Spain uses its correction boxes (LIVA art. 80) and Italy nets the base of
the rate. On the French CA3 the base stays as declared (A1 and the rate lines) and the VAT is
deducted on line 21 "Autre TVA à déduire" as a positive amount (CGI art. 272-1): the return shows
it as box 21R, the sub-line "dont régularisation sur de la TVA collectée", which is part of line 21
and of the total on line 23; box 21 itself stays open for amounts entered by hand, so line 21 on
the form is 21 plus 21R. A partial
write-off of 100.00 corrects 7.49 VAT (100 × 40.50 / 540.50) and books 92.51 to bad debts.
A foreign-currency invoice is written off at the rate the books carry it at, like a credit note. Every line of the entry uses that one rate, so the receivable is relieved by exactly what the books hold for the part written off, and no exchange difference is booked.
On the cash basis
On the cash basis a write-off settles the invoice like a payment, so the return of its period reports what it settles, and its VAT correction takes exactly that back: nothing is due on an invoice that was never paid. Where the law converts what is paid at the official rate of the day it is paid (Germany, UStG § 16 Abs. 6 Satz 2; Spain, art. 79.Once LIVA), the correction is converted at the official rate of the write-off's day too, not at the invoice's. Example: an unpaid invoice of USD 1,190.00 dated 20 August (BMF August 1.1593) written off in full on 10 September (BMF September 1.25): the September UStVA shows Kz 81 800 / 152.00 settled and −800 / −152.00 corrected, so 0 / 0.
Where it shows
- the invoice's card: the status is written off (or partially written off, or write-off awaiting approval), and the payments tab lists the write-off with its number, its VAT treatment and its reason;
- the customer's account activity (screen, PDF and CSV): a line of the kind
write_off; - the aging: the written-off amount is no longer open.
A posted write-off is not reversed as a journal entry. What happens to it later has actions of its own on the invoice's card, under the write-off:
Money received after a write-off
If the customer pays after all (a dividend from the bankruptcy, a late payment), Money received after write-off asks for the amount, the day and the bank account. The invoice stays written off. The entry debits the bank account and credits the bad-debt account (a recovery). If the write-off corrected the VAT, the VAT is owed again on what came in (CH MWSTG Art. 41, DE UStG § 17 Abs. 2 Satz 2): the write-off's correction lines are taken back in proportion to the amount received, so the VAT return of the period of the receipt shows it like a sale (Swiss Ziffer 200 and the rate box, German Kz 81, Spanish correction boxes). If the write-off kept the VAT, nothing is owed again and the whole amount goes to the bad-debt account. It goes through the approval policy like any other entry, and it is audited.
The 540.50 invoice above, written off with the VAT corrected, then 200.00 received and later the remaining 340.50:
| 200.00 received | 340.50 received | |
|---|---|---|
| Dr 1020 bank | 200.00 | 340.50 |
| Cr 3805 bad debts | 185.01 | 314.99 |
| Cr 2200 output VAT | 14.99 | 25.51 |
Each part takes its share of the VAT the write-off corrected (200 × 40.50 / 540.50 = 14.99), and
the last one the rest, so the VAT owed again adds up to the 40.50 corrected. At most what was
written off is received this way (recovery_more_than_written_off).
Correcting the VAT later
A write-off that kept the VAT can have it corrected once the loss is final: Correct the VAT now asks for the day the loss became final. The VAT is corrected on what was written off and not received since, as a write-off that corrects it at once would have: the invoice's posting taken back in proportion, its VAT lines to the VAT accounts with their tax tags, and the bad-debt account relieved by the VAT it held. With 100.00 of the 540.50 received first, 440.50 is left and 440.50 × 40.50 / 540.50 = 33.01 VAT is corrected: Dr 3805 407.49, Dr 2200 33.01, Cr 3805 440.50. Money received after that makes this VAT due again, as above. It also goes through the approval policy. One action of a write-off waits for approval at a time.
The allowance run
On the allowance settings each bucket says what its percent means, the Include VAT switch says what off means, and Suggest with AI proposes a percent per aging bucket for the company's country and industry, each with its reason; nothing changes until you save. Marking an invoice doubtful offers 25, 50, 75 and 100 %.
At a period end, Doubtful receivables (Period close, or the close checklist's link) works out the allowance invoice by invoice:
- specific: an invoice marked doubtful is covered by its own percent (50 % for a dispute, 100 % for a customer in bankruptcy);
- general: every other open invoice is covered by the percent of its aging bucket at the period end. The percents are set per company. The suggested ones are 0 % for invoices not yet due and 5 % for overdue ones.
The percent is taken on what the books carry for the invoice: its carrying amount in the functional currency. Only posted entries count: a write-off or a receipt still waiting for approval has not relieved anything yet. A foreign-currency invoice counts at what is open on it at the closing rate of the period end, as the FX revaluation values it, so the allowance covers the revalued receivable (EUR 1,000.00 open at a closing rate of 0.90 is CHF 900.00, whatever it was booked at). The company chooses whether that amount includes VAT. Swiss and Liechtenstein companies take it with VAT by default, as the Swiss del credere is usually a percent of the receivables as invoiced; others take it without VAT. Invoices of group companies are left out.
The run posts the difference between that target and what the allowance account holds at the period end: Dr allowance expense / Cr allowance to raise it, or the reverse to release part of it. The entry is dated at the period end and goes through the approval policy like the other period-end runs. One run stands per period, and a rejected one can be made again. It is not reversed: the next period's run adjusts the allowance again.
Example: at 30 September an invoice of 1,081.00 not yet due (0 %), one of 540.50 61 days overdue (5 %: 27.03) and one of 216.20 marked 50 % doubtful (108.10) call for 135.13. The run posts Dr 3805 135.13 / Cr 1109 135.13.
The close checklist warns (it does not block) while a run would post something; many companies adjust the allowance only at the year end.
API
| Operation | What it does |
|---|---|
POST /v1/documents/{document_id}/write-off |
Write off all or part of what is open (waits for a second person). |
GET /v1/documents/{document_id}/write-offs |
The write-offs of an invoice, with what was received after each and its later VAT correction. |
POST /v1/documents/{document_id}/write-off/recovery |
Book money received after a write-off (the VAT owed again). |
POST /v1/documents/{document_id}/write-off/vat-correction |
Correct the VAT a write-off kept, now that the loss is final. |
GET, PUT /v1/entities/{entity}/receivable-allowance/settings |
The general allowance percents. |
PUT, DELETE /v1/documents/{document_id}/doubtful |
Mark an invoice doubtful, or unmark it. |
GET /v1/periods/{period_id}/receivable-allowance |
The calculation at the period end. |
POST /v1/periods/{period_id}/receivable-allowance |
Post the allowance. |
Where the code is
src/erp/features/invoicing/write_offs.py: the write-off, its entry and its approval hooks;src/erp/features/invoicing/write_off_follow_ups.py: money received after a write-off and the VAT corrected later;src/erp/modules/cash_discount.py: the proportional VAT correction both use;src/erp/features/invoicing/receivable_allowance.py: settings, doubtful invoices, the calculation and the run;src/erp/features/invoicing/receivable_allowance_check.py: the close check;src/erp/features/invoicing/api/receivables.py: the API;ui/src/features/invoicing/pages/WriteOff.tsx,ReceivableAllowance.tsx: the screens.