Wednesday, August 2, 2017

Working on #1933. Lydia doesn’t need a normal Belgian VAT declaration but a special one. With the new infrastructure this is simply a new plugin lino_xl.lib.bevats which starts as a copy of lino_xl.lib.bevat.

Before duplicating the plugin, I fixed a design flaw: it is not necessary to specify both the model and a table when declaring a new voucher type. The table is enough because it points to the model. With a little subtlety though: the table’s model is not always resolvable when the table is being defined. To fix this, I added a new method add_item_lazy to all choicelists and have it used by all voucher type definitions.

For example, instead of saying:

from .models import ClientVoucher
VoucherTypes.add_item(ClientVoucher, ClientVouchersByJournal)

we can now say:


And I saw the optimization confirmed because at some places, until now, we had to write:

def pre_analyze(sender, **kw):
    VoucherTypes.add_item('sales.VatProductInvoice', InvoicesByJournal)

which we can now write as well by a simple one-liner:


New specs pages bevat : Belgian VAT declarations and and bevats : Simplified Belgian VAT declarations

Clearing the declared movements

It would be nice if a VAT declaration would also “clear” the movements which it declares. But for this we would need a second match field, which seems to be overkill. Here is how I realized this.

The “match” is a string which links a series of ledger movements together. When all movements of a given match have the sum of their debit equal to the sum of their credit, then all movements of the match are said to be “cleared”. The match of an invoice is automatically generated using “journal + voucher number”. The match of a financial voucher (bank statement, payment order, journal entry,…) is generated using “journal + voucher number + item number”. A VAT declaration is like an invoice : its match is generated by “journal + voucher number”.

But a VAT declaration also does something new. It does not only generate a debth towards the tax office (an amount with a match which is to be cleared e.g. by a payment order) but it also clears all the movements into the due or deductible VAT accounts which had been created by the individual invoices. These movements do not have the match of that invoice, their match is empty (because an invoice’s match is used only for the partner movement of an invoice). When registering a VAT declaration, all these movements would get the VAT declaration’s match. And when deregistering the declaration their match would become blank again. I tried this. But the problem is that we would still need separate match and cleared fields for clearing per (general) account.


The following test case in Miscellaneous was failing:

rv =

That was because InstanceAction.run_from_session() calls InstanceAction.request_from() which no longer uses InstanceAction.setup_from(). But InstanceAction.request_from() didn’t inherit _confirm_answer to the child session. Now it does.