vat
: Adding VAT (Value-added tax) functionality¶
The lino_xl.lib.vat
plug-in adds functionality for handling sales and
purchase invoices in a context where the site operator is subject to
value-added tax (VAT). It provides a framework for handling VAT declarations.
When using this plugin, you will probably also install one of the national VAT
implementations.
A tested document¶
This is a tested document. The following instructions are used for initialization:
>>> from lino import startup
>>> startup('lino_book.projects.pierre.settings.doctests')
>>> from lino.api.doctest import *
Overview¶
The VAT plug in defines the following concepts:
- VAT rate
The percentage to apply to a base amount in order to compute the amount of VAT.
- VAT regime
Specifies how the VAT for this voucher is being handled, e.g. which VAT rates are available and whether and how and when VAT is to be declared and paid to the national VAT office. See VAT regimes.
- VAT class
The nature of a trade object to be differentiated in the VAT declaration.
For example most countries differentiate between "goods" and "services". Other common VAT classes are "investments" or "vehicles".
The list of available VAT classes is defined by your national VAT plugin. For example in Estonia the VAT office wants to know, in one field of your declaration, how much money you spend for buying "vehicles" and in another field how much you spent for "real estate" objects, while in Belgium both vehicles and real estate objects are considered together as "investments".
- VAT rules
A set of rules that defines which VAT rate to apply and which account to use for a given combination of regime, class and trade type. The available VAT rules vary depending on which VAT declaration plugin is installed.
- VAT declaration
A ledger voucher that expresses the fact that the site operator submitted a VAT declaration to their tax office.
- VAT area
A group of countries having same VAT rules in the country of the site operator. See VAT areas.
- national declaration module
The module that implements a given national VAT configuration.
Every Lino site has at most one national declaration module, which corresponds to the country where the site operator is registered.
Specified by
lino_xl.lib.vat.Plugin.declaration_plugin
.
National VAT implementations¶
Applications using this plug-in must specify the national implementations
for their VAT declarations by setting the declaration_plugin
plugin attribute.
Currently we have three declaration plug-ins:
Accounting applications to be used by site operators who don't care about VAT
might use lino_xl.lib.vatless
instead (though this plug-in might become
deprecated). The modules lino_xl.lib.vatless
and lino_xl.lib.vat
can theoretically both be installed though obviously this wouldn't make sense.
VAT regimes¶
A VAT regime must be assigned to each voucher and may optionally be assigned to each partner.
The VAT regime of a partner is used as the default value for all vouchers with this partner. When you define a default VAT regime per partner, any new voucher created for this partner will have this VAT regime. Existing vouchers are not changed when you change this field.
The available VAT regimes vary depending on which VAT declaration plugin is installed. See also Available VAT regimes. When no declaration module is installed, we have only one default regime.
>>> rt.show(vat.VatRegimes, language="en")
...
======= ======== ======== ========== ==============
value name text VAT area Needs VAT id
------- -------- -------- ---------- --------------
10 normal Normal No
======= ======== ======== ========== ==============
Note that the VAT regime has nothing to do with the trade type. For example, when a partner has the regime "Intra-community", this regime is used for both sales and purchase invoices with this partner. The difference between sales and purchases is defined by the VAT rules, not by the regime.
-
class
lino_xl.lib.vat.
VatRegime
¶ Base class for the items of
VatRegimes
. Each VAT regime is an instance of this and has two properties:-
item_vat
¶ Whether unit prices are VAT included or not. No longer used. See
Plugin.item_vat
instead.
-
needs_vat_id
¶ Whether this VAT regime requires that partner to have a
vat_id
.
-
VAT classes¶
A VAT class is a direct or indirect property of a trade object (e.g. a Product) that influences the VAT rate to be used. Here is the list of VAT classes used unless you have some local change.
>>> rt.show(vat.VatClasses, language="en")
======= ============= ===========================
value name text
------- ------------- ---------------------------
010 goods Goods at normal VAT rate
020 reduced Goods at reduced VAT rate
030 exempt Goods exempt from VAT
100 services Services
200 investments Investments
210 real_estate Real estate
220 vehicles Vehicles
300 vatless Operations without VAT
======= ============= ===========================
The list of VAT classes does not contain the actual VAT rates because this still varies by country, and within a same country it can vary, e.g. depending on the date of the operation or other factors.
A VAT class is assigned to each item of an invoice. The VAT class can influence the available VAT rates. You can sell or purchase a same product to different partners using different VAT regimes.
VAT rules¶
When no national declaration module is installed, we have only one default VAT rule with no condition and zero rate.
>>> rt.show(vat.VatRules, language="en")
...
+-------+------------------+
| value | Description |
+=======+==================+
| 1 | VAT rule 1: |
| | apply 0 % |
| | and book to None |
+-------+------------------+
-
class
lino_xl.lib.vat.
VatRule
¶ A rule which defines how VAT is to be handled for a given invoice item.
Example data see
lino_xl.lib.vat.fixtures.euvatrates
.Database fields:
-
seqno
¶ The sequence number.
-
country
¶
-
vat_class
¶
-
vat_regime
¶ The regime for which this rule applies.
Pointer to
VatRegimes
.
-
rate
¶ The VAT rate to be applied. Note that a VAT rate of 20 percent is stored as 0.20 (not 20).
-
vat_account
¶ The general account where VAT is to be booked.
-
vat_returnable
¶ Whether VAT is returnable. Returnable VAT does not increase the total amount of the voucher, it causes an additional movement into the
vat_returnable_account
. See About returnable VAT.
-
vat_returnable_account
¶ Where to book returnable VAT. If this field is empty and
vat_returnable
is True, then VAT will be added to the base account. See About returnable VAT.
-
get_vat_rule(cls, trade_type, vat_regime,
-
vat_class=None, country=None, date=None)
Return the VAT rule to be applied for the given criteria.
Lino loops through all rules (ordered by their
seqno
) and returns the first object which matches.
-
VAT areas¶
When your business is located, e.g. in Belgium and you buy goods or services from France, Germany and the Netherlands, then these countries are called "intra community". Certain VAT rules apply for all intra-community countries. We don't want to repeat them for each country. That's why we have VAT areas.
A VAT area is a group of countries for which same VAT rules apply in the country of the site operator.
VAT areas are used to group countries into groups where similar VAT regimes are available.
The VatAreas
choice list contains the list of available VAT areas.
>>> rt.show(vat.VatAreas, language="en")
======= =============== ===============
value name text
------- --------------- ---------------
10 national National
20 eu EU
30 international International
======= =============== ===============
The plugin property eu_country_codes
defines which countries are
considered part of the EU.
So the country
field of a
partner influences which VAT regimes are available for this partner.
Available VAT regimes¶
The declaration plugin controls which VAT regimes are available for selection on a partner or on a voucher.
The list of available VAT regimes for a partner depends on the VAT area and on whether the partner has a VAT id or not.
-
get_vat_regime_choices(country=None, vat_id=None):
Used for the choosers of the
vat_regime
field of a partner and a voucher.
Why differentiate between VAT regimes and VAT classes?¶
You might ask why we use two sets of categories for specifying the VAT rate. Some other accounting programs do not have two different categories for the subtle difference between "exempt from VAT" and "VAT 0%", they have just a category "VAT rate" which you can set per invoice item (and a default value per provider).
The problem with this simplified vision is that at least for Belgian VAT declarations there is a big difference between having 0% of VAT because the provider is a private person and having 0% of VAT because you are buying post stamps or flight tickets (which are exempt from VAT).
Another thing to consider is that in Lino we want to be able to have partners who are both a provider and a customer. Their VAT regime remains the same for both trade types (sales and purchase) while the default VAT class to use in invoice items depends on the account or the product.
Account invoices¶
An account invoice is an invoice for which the user enters just the bare
accounts and amounts. The lino_xl.lib.vat
plugin defines a VAT-capable
implementation of account invoices. They are typically
used to store incoming purchase invoices, and they do no not usually produce a
printable document.
If you also need products, quantities and discounts, use a journal having
VatProductInvoice
as voucher type
instead.
Account invoices are typically used to store incoming purchase invoices, but
exceptions in both directions are possible: (1) purchase invoices can be stored
using VatProductInvoice
if stock
management is important, or (2) outgoing sales invoice can be stored as
VatAccountInvoice
because they have been created using some external
tool and are entered into Lino just for the general ledger.
It is one of the most basic voucher types, which can be used even in accounting
applications that don't have lino_xl.lib.sales
.
There are two database models:
-
class
lino_xl.lib.vat.
VatAccountInvoice
¶ Django model for storing account invoices.
-
class
lino_xl.lib.vat.
InvoiceItem
¶ Django model for representing items of an account invoice.
There are several views:
-
class
lino_xl.lib.vat.
Invoices
¶ The table of all
VatAccountInvoice
objects.
-
class
lino_xl.lib.vat.
InvoicesByJournal
¶ Shows all invoices of a given journal (whose
voucher_type
must beVatAccountInvoice
)
-
class
lino_xl.lib.vat.
PrintableInvoicesByJournal
¶ Purchase journal
-
class
lino_xl.lib.vat.
ItemsByInvoice
¶
-
class
lino_xl.lib.vat.
VouchersByPartner
¶
Utilites¶
The lino_xl.lib.vat.utils
module contains some utility functions.
>>> from lino_xl.lib.vat.utils import add_vat, remove_vat
>>> add_vat(100, 21)
121.0
>>> remove_vat(121, 21)
100.0
>>> add_vat(10, 21)
12.1
>>> add_vat(1, 21)
1.21
Showing the invoices covered by a VAT declaration¶
The plugin defines two tables that show the invoices covered by a VAT declaration, IOW the invoices that have contributed to the numbers in the declaration.
-
class
lino_xl.lib.vat.
SalesByDeclaration
¶ Show a list of all sales invoices whose VAT regime is Intra-Community.
-
class
lino_xl.lib.vat.
PurchasesByDeclaration
¶ Show a list of all purchase invoices whose VAT regime is Intra-Community.
-
class
lino_xl.lib.vat.
VatInvoices
¶ Common base class for
SalesByDeclaration
andPurchasesByDeclaration
Intracom sales and purchases¶
The plugin defines two reports accessible via the
menu and integrated in the printout of a VAT declaration:-
class
lino_xl.lib.vat.
IntracomSales
¶ Show a list of all sales invoices whose VAT regime is Intra-Community.
-
class
lino_xl.lib.vat.
IntracomPurchases
¶ Show a list of all purchase invoices whose VAT regime is Intra-Community.
-
class
lino_xl.lib.vat.
IntracomInvoices
¶ Common base class for
IntracomSales
andIntracomPurchases
These reports are empty when you have no national declaration plugin installed:
>>> rt.show(vat.IntracomSales, language='en')
...
No data to display
>>> rt.show(vat.IntracomPurchases, language='en')
...
No data to display
Model mixins¶
-
class
lino_xl.lib.vat.
VatTotal
¶ Model mixin which defines the database fields
total_incl
,total_base
andtotal_vat
and some related behaviour.Used for both the voucher (
VatDocument
) and for each item (VatItemBase
).-
total_incl
¶ The amount VAT included.
-
total_base
¶ The amount VAT excluded.
-
total_vat
¶ The amount of VAT.
All three total fields are
lino.core.fields.PriceField
instances.The fields are editable by default, but implementing models can call
lino.core.fields.update_field()
to change this behaviour. A model that sets all fields to non-editable should also setedit_totals
to False.-
get_trade_type
()¶ Subclasses of VatTotal must implement this method.
-
get_vat_rule
()¶ Return the VAT rule for this voucher or voucher item. Called when user edits a total field in the document header when
edit_totals
is True.
-
total_base_changed
()¶ Called when user has edited the
total_base
field. If total_base has been set to blank, then Lino fills it usingreset_totals()
. If user has entered a value, computetotal_vat
andtotal_incl
from this value using the vat rate. If there is no VatRule,total_incl
andtotal_vat
are set to None.If there are rounding differences,
total_vat
will get them.
-
total_vat_changed
()¶ Called when user has edited the total_vat field. If it has been set to blank, then Lino fills it using
reset_totals()
. If user has entered a value, computetotal_incl
. If there is no VatRule, total_incl is set to None.
-
total_incl_changed
()¶ Called when user has edited the total_incl field. If total_incl has been set to blank, then Lino fills it using
reset_totals()
. If user enters a value, computetotal_base
andtotal_vat
from this value using the vat rate. If there is no VatRule, total_incl should be disabled, so this method will never be called.If there are rounding differences, total_vat will get them.
-
-
class
lino_xl.lib.vat.
VatDocument
¶ Abstract base class for invoices, offers and other vouchers.
Inherited by
VatAccountInvoice
as well as in other plugins (e.g.lino_xl.lib.sales.VatProductInvoice
andlino_xl.lib.ana.AnaAccountInvoice
).Models that inherit this mixin can set the following class attribute:
-
edit_totals
¶ Whether the user usually wants to edit the total amount or not.
The total fields of an invoice are not automatically updated each time an item is modified. Users must click the Σ ("Compute sums") button (or Save or the Register button) to see the invoice's totals.
Inherits the following database fields from
VatTotal
:-
total_base
¶
-
total_vat
¶
-
total_incl
¶
Adds the following database fields:
-
project
¶ Pointer to a
lino_xl.lib.ledger.Plugin.project_model
.
-
partner
¶ Mandatory field to be defined in the implementing class.
-
items_edited
¶ An automatically managed boolean field which says whether the user has manually edited the items of this document. If this is False and
edit_totals
is True, Lino will automatically update the only invoice item according topartner
andvat_regime
andtotal_incl
.
-
vat_regime
¶ The VAT regime to be used in this document.
A pointer to
VatRegimes
.
Adds an action:
-
compute_sums
¶ Calls
ComputeSums
for this document.
-
-
class
lino_xl.lib.vat.
ComputeSums
¶ Compute the sum fields of a
VatDocument
based on its items.Represented by a "Σ" button.
-
class
lino_xl.lib.vat.
VatItemBase
¶ Model mixin for items of a
VatDocument
.Abstract Base class for
lino_xl.lib.ledger.InvoiceItem
, i.e. the lines of invoices without unit prices and quantities.Subclasses must define a field called "voucher" which must be a ForeignKey with related_name="items" to the "owning document", which in turn must be a subclass of
VatDocument
).-
vat_class
¶ The VAT class to be applied for this item. A pointer to
VatClasses
.
-
get_vat_rule
(self, tt)¶ Return the VatRule which applies for this item.
tt is the trade type (which is the same for each item of a voucher, that's why we expect the caller to provide it).
This basically calls the class method
VatRule.get_vat_rule()
with appropriate arguments.When selling certain products ("automated digital services") in the EU, you have to pay VAT in the buyer's country at that country's VAT rate. See e.g. How can I comply with VAT obligations?.
TODO: Add a new attribute VatClass.buyers_country or a checkbox Product.buyers_country or some other way to specify this.
-
-
class
lino_xl.lib.vat.
QtyVatItemBase
¶ Model mixin for items of a
VatTotal
. ExtendsVatItemBase
by addingunit_price
andqty
.Abstract Base class for
lino_xl.lib.sales.InvoiceItem
andlino_xl.lib.sales.OrderItem
, i.e. invoice items with unit prices and quantities.-
unit_price
¶ The unit price for this item.
-
qty
¶
Changing the
unit_price
ot theqty
will automatically reset the total amount of this item: the value unit_price * qty will be stored intotal_incl
ifVatRegime.item_vat
is True, otherwise intotal_base
.-
VAT columns¶
-
class
lino_xl.lib.vat.
VatColumns
¶ The global list of VAT columns.
The VAT column of a ledger account indicates where the movements on this account are to be collected in VAT declarations.
VAT declarations¶
A VAT declaration is a voucher that expresses that a corporation declares to its government how much sales and purchases they've done during a given period.
A VAT declaration is a computed summary of ledger movements in an observed period or range of periods. The voucher itself is a ledger voucher that generates new movements in its own period of declration, which is different from the observed period range.
-
class
lino_xl.lib.vat.
VatDeclaration
¶ Abstract base class for VAT declarations.
Inherits from
lino_xl.lib.sepa.Payable
lino_xl.lib.ledger.Voucher
lino_xl.lib.excerpts.Certifiable
lino_xl.lib.ledger.PeriodRange
-
accounting_period
¶
-
get_payable_sums_dict
()¶ Implements
lino_xl.lib.sepa.Payable.get_payable_sums_dict()
.As a side effect this updates values in the computed fields of this declaration.
-
Declaration fields¶
Defining the declaration fields is responsibility of each national implementation plugin. But every individual field in every VAT declaration of every country is an instance of one of the following three classes:
-
class
lino_xl.lib.vat.
MvtDeclarationField
¶ A declaration field to be computed by analyzing the ledger movements.
-
class
lino_xl.lib.vat.
WritableDeclarationField
¶ A declaration field to be entered manually by the end user.
-
class
lino_xl.lib.vat.
SumDeclarationField
¶ A declaration field that computes the sum of its observed fields.
All these three declaration field classes have a common ancestor
DeclarationField
.
-
class
lino_xl.lib.vat.
DeclarationField
¶ Base class for all declaration fields.
It is not instantiated directly but by using one of its subclasses
-
editable
¶ Whether the value of this field is to be manually entered by the end user.
Most fields are not editable, i.e. computed.
-
both_dc
¶ Whether the value of this field is to be manually entered by the end user.
-
fieldnames
¶ An optional space-separated list of names of observed fields, i.e. other declaration fields to be observed by this field. If a field name is prefixed by a "-", the observed field will additionally be inverted.
This is used only by sum fields. The values of all observed fields will be added, except inverted fields whose value will be subtracted.
Note that the booking direction (D or C) of the observed fields is ignored when computing the sum.
-
vat_regimes
¶
-
vat_classes
¶
-
vat_columns
¶
-
exclude_vat_regimes
¶
-
exclude_vat_classes
¶
-
exclude_vat_columns
¶
-
is_payable
¶ Whether the value of this field represents an amount to be paid to the tax office.
-
Configuration¶
See also lino_xl.lib.vat.Plugin
for configuration options.
Fill invoice items based on voucher's total¶
In a VatAccountInvoice, end users may edit the total amount of the invoice in order to have Lino assist them for filling invoice items based on this amount.
Manually editing the VAT amount of invoice items¶
End users can manually edit any amount of an invoice item.
When you enter a total_incl
, Lino automatically
computes the total_base
and total_vat
. But when entering data from a legacy system, you may
want to manually specify a different VAT amount.
Example¶
An electricity invoice of 94,88 €. Only 35% of the total amount is deductible.
Manually enter 94.88 in
VatProductInvoice.total_incl
. Lino fills one invoice item. The general account of this item is either the provider'spurchase_account
or (if that field is empty)lino_xl.lib.ledger.CommonAccounts.waiting
.Change the amount of the invoice item (
total_incl
) from 94.88 to 33.22 (94.88 * 0.35). Lino automatically setstotal_base
to 27.68 € (33.22 / 1.20) andtotal_vat
to 5.54 (33.22 - 27.68).Add a second line and manually set
InvoiceItem.account
to600020
(Non deducible costs). Lino automatically fills the remaining amount (94.88 - 33.22 = 61.66) into theInvoiceItem.total_incl
field and computes the other amounts of that line. Since account600020
hasvat_class
set toexempt
, the other amounts are set to blank.
About returnable VAT¶
- returnable VAT
A VAT amount in an invoice that is not to be paid to (or by) the partner but must be declared in the VAT declaration.
Returnable VAT, unlike normal VAT, does not increase the total amount of the voucher but causes an additional movement into the account configured as "VAT returnable" (a common account).
See also
vat_returnable_account
.
The VAT columns checker¶
-
class
lino_xl.lib.vat.
VatColumnsChecker
¶ Check VAT columns configuration.
This is an unbound data checker
(lino.modlib.checkdata.Checker.model
is None), i.e. the messages aren't bound to a particular
database object.