Skip to content

Commit

Permalink
http://luc.lino-framework.org/blog/2019/1210.html
Browse files Browse the repository at this point in the history
  • Loading branch information
lsaffre committed Dec 10, 2019
1 parent 024d193 commit f3f4c54
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 119 deletions.
23 changes: 14 additions & 9 deletions lino_xl/lib/bevat/choicelists.py
Expand Up @@ -33,18 +33,24 @@
add('71', _("Luxemburg"), 'lu')


VAT_CLASSES_AND_RATES = [("services", "0.21"), ("goods", "0.21"), ("reduced", "0.07")]
VatRules.clear()
add = VatRules.add_item
add('normal', '0.21', NAT, 'purchases', None, CommonAccounts.vat_deductible)
add('reduced', '0.07', NAT, 'purchases', None, CommonAccounts.vat_deductible)
add('normal', '0.21', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
add('reduced', '0.07', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
for vat_class, rate in VAT_CLASSES_AND_RATES:
add(vat_class, rate, NAT, 'purchases', None, CommonAccounts.vat_deductible)
add(vat_class, rate, EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
add(vat_class, rate, None, 'sales', None, CommonAccounts.vat_due)

# add('normal', '0.21', NAT, 'purchases', None, CommonAccounts.vat_deductible)
# add('reduced', '0.07', NAT, 'purchases', None, CommonAccounts.vat_deductible)
# add('normal', '0.21', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
# add('reduced', '0.07', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
# add('normal', '0.21', EU, 'sales', 'intracom', CommonAccounts.vat_due, CommonAccounts.vat_returnable)
# add('reduced', '0.07', EU, 'sales', 'intracom', CommonAccounts.vat_due, CommonAccounts.vat_returnable)
add('normal', '0.00', EU, 'sales', 'intracom')
add('reduced', '0.00', EU, 'sales', 'intracom')
add('normal', '0.21', None, 'sales', None, CommonAccounts.vat_due)
add('reduced', '0.07', None, 'sales', None, CommonAccounts.vat_due)
# add('normal', '0.00', EU, 'sales', 'intracom')
# add('reduced', '0.00', EU, 'sales', 'intracom')
# add('normal', '0.21', None, 'sales', None, CommonAccounts.vat_due)
# add('reduced', '0.07', None, 'sales', None, CommonAccounts.vat_due)
add()


Expand All @@ -63,7 +69,6 @@




class DeclarationFields(DeclarationFieldsBase):
pass

Expand Down
18 changes: 6 additions & 12 deletions lino_xl/lib/bevats/choicelists.py
Expand Up @@ -29,20 +29,14 @@
add('30', _("Intracom services"), 'intracom', EU, needs_vat_id=True)
add('35', _("Intracom supplies"), 'intracom_supp', EU, needs_vat_id=True)


VAT_CLASSES_AND_RATES = [("services", "0.21"), ("goods", "0.21"), ("reduced", "0.07")]
VatRules.clear()
add = VatRules.add_item
add('normal', '0.21', NAT, 'purchases', 'subject', CommonAccounts.vat_deductible)
add('reduced', '0.07', NAT, 'purchases', 'subject', CommonAccounts.vat_deductible)
# add('normal', '0.21', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
# add('reduced', '0.07', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
# add('normal', '0.21', EU, 'purchases', 'intracom_supp', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
# add('reduced', '0.07', EU, 'purchases', 'intracom_supp', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
add('normal', '0.21', EU, 'purchases', 'intracom', CommonAccounts.vat_due, vat_returnable=True)
add('reduced', '0.07', EU, 'purchases', 'intracom', CommonAccounts.vat_due, vat_returnable=True)
add('normal', '0.21', EU, 'purchases', 'intracom_supp', CommonAccounts.vat_due, vat_returnable=True)
add('reduced', '0.07', EU, 'purchases', 'intracom_supp', CommonAccounts.vat_due, vat_returnable=True)
add()
for vat_class, rate in VAT_CLASSES_AND_RATES:
add(vat_class, rate, NAT, 'purchases', 'subject', CommonAccounts.vat_deductible)
add(vat_class, rate, EU, 'purchases', 'intracom', CommonAccounts.vat_due, vat_returnable=True)
add(vat_class, rate, EU, 'purchases', 'intracom_supp', CommonAccounts.vat_due, vat_returnable=True)
add() # allow any other combination with rate 0

# print('\n'.join(["{}:{}".format(i.vat_area, i.vat_regime) for i in VatRules.get_list_items()]))
# for va in VatAreas.get_list_items():
Expand Down
142 changes: 90 additions & 52 deletions lino_xl/lib/eevat/choicelists.py
Expand Up @@ -13,6 +13,7 @@
from lino_xl.lib.vat.choicelists import VatRegimes, VatAreas, VatRules
from lino_xl.lib.ledger.choicelists import CommonAccounts


NAT = VatAreas.national
EU = VatAreas.eu
INT = VatAreas.international
Expand All @@ -26,41 +27,48 @@
add('30', _("Intra-community"), 'intracom', EU, needs_vat_id=True)
# add('31', _("Delay in collection"), 'delayed', EU) # report de perception
# add('40', _("Inside EU"), 'inside', EU)
add('40', _("Tax-free"), 'tax_free')
add('50', _("Outside EU"), 'outside', INT)
add('60', _("Exempt"), 'exempt', item_vat=False)
add('60', _("Exempt"), 'exempt', item_vat=False) # army, ...
if False: # tim2lino can need it
add('70', _("Germany"), 'de')
add('71', _("Luxemburg"), 'lu')

VAT_CLASSES_AND_RATES = [
("services", "0.20"), ("goods", "0.20"),
("real_estate", "0.20"), ("vehicles", "0.20"),
("reduced", "0.09")]
VatRules.clear()
add = VatRules.add_item
add('normal', '0.20', NAT, 'purchases', None, CommonAccounts.vat_deductible)
add('reduced', '0.09', NAT, 'purchases', None, CommonAccounts.vat_deductible)
add('normal', '0.20', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
add('reduced', '0.09', EU, 'purchases', 'intracom', CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
# add('normal', '0.20', EU, 'sales', 'intracom', CommonAccounts.vat_due, CommonAccounts.vat_returnable)
# add('reduced', '0.09', EU, 'sales', 'intracom', CommonAccounts.vat_due, CommonAccounts.vat_returnable)
add('normal', '0.00', EU, 'sales', 'intracom')
add('reduced', '0.00', EU, 'sales', 'intracom')
add('reduced', '0.09', None, 'sales', None, CommonAccounts.vat_due)
add('normal', '0.20', None, 'sales', None, CommonAccounts.vat_due)
add()
# vat_class rate vat_area trade_type vat_regime vat_account vat_returnable_account vat_returnable
add(None, '0', None, None, "exempt")


for vat_class, rate in VAT_CLASSES_AND_RATES:
for vat_regime, area in [('intracom', EU), ('cocontractor', NAT)]:
add(vat_class, rate, area, 'purchases', vat_regime, CommonAccounts.vat_deductible, CommonAccounts.vat_returnable)
add(vat_class, rate, area, 'sales', vat_regime, CommonAccounts.vat_due, CommonAccounts.vat_returnable)

for vat_class, rate in VAT_CLASSES_AND_RATES:
add(vat_class, rate, NAT, 'purchases', None, CommonAccounts.vat_deductible)
add(vat_class, rate, None, 'sales', None, CommonAccounts.vat_due)

add() # allow any other combination with rate 0


VatColumns.clear()
add = VatColumns.add_item
add('00', _("Sales with 20% VAT"), CommonAccounts.sales)
add('01', _("Sales with 9% VAT"), CommonAccounts.sales)
add('02', _("Sales with 0% VAT"), CommonAccounts.sales)
add('10', _("Sales turnover"), CommonAccounts.sales)
# add('01', _("Sales with 20% VAT"), CommonAccounts.sales)
# add('02', _("Sales with 9% VAT"), CommonAccounts.sales)
# add('03', _("Sales with 0% VAT"), CommonAccounts.sales)
add('40', _("VAT due"), CommonAccounts.vat_due)
add('41', _("VAT returnable"), CommonAccounts.vat_returnable)
add('50', _("VAT deductible"), CommonAccounts.vat_deductible)
add('51', _("VAT deductible import"), CommonAccounts.vat_deductible)
add('52', _("VAT deductible real estate"), CommonAccounts.vat_deductible)
add('53', _("VAT deductible vehicles 100%"), CommonAccounts.vat_deductible)
add('54', _("VAT deductible vehicles"), CommonAccounts.vat_deductible)
add('81', _("Purchase of goods"), CommonAccounts.purchase_of_goods)
add('82', _("Purchase of services"), CommonAccounts.purchase_of_services)
add('83', _("Purchase of investments"), CommonAccounts.purchase_of_investments)
add('60', _("Purchase of goods"), CommonAccounts.purchase_of_goods)
add('61', _("Other purchases"), CommonAccounts.purchase_of_services)
# add('62', _("Purchase of services"), CommonAccounts.purchase_of_services)
# add('63', _("Purchase of investments"), CommonAccounts.purchase_of_investments)


class DeclarationFields(DeclarationFieldsBase):
Expand All @@ -73,48 +81,78 @@ class DeclarationFields(DeclarationFieldsBase):

# https://www.riigiteataja.ee/aktilisa/1060/1201/7010/Lisa%201.pdf#

# value, dc, vat_columns, text
# value dc vat_columns text // fieldnames both_dc vat_regimes vat_classes

mfld("1", CREDIT, '10', "20% määraga maksustatavad toimingud ja tehingud",
vat_classes="goods services", vat_regimes="!exempt !tax_free !intracom !cocontractor")
mfld("2", CREDIT, '10', "9% määraga maksustatavad toimingud ja tehingud",
vat_classes="reduced", vat_regimes="!exempt !tax_free !intracom !cocontractor")

mfld("3", CREDIT, '10', "0% määraga maksustatavad toimingud ja tehingud, sh",
vat_regimes="exempt tax_free intracom cocontractor")

mfld("1", CREDIT, '00', "20% määraga maksustatavad toimingud ja tehingud")
mfld("2", CREDIT, '01', "9% määraga maksustatavad toimingud ja tehingud")
mfld("3", CREDIT, '02', "0% määraga maksustatavad toimingud ja tehingud, sh")
mfld("31", CREDIT, '02',
mfld("31", CREDIT, '10',
"1) kauba ühendusesisene käive ja teise liikmesriigi maksukohustuslasele / "
"piiratud maksukohustuslasele osutatud teenuste käive kokku, sh",
vat_regimes="intracom cocontractor")
mfld("311", CREDIT, '10', "1) kauba ühendusesisene käive",
vat_regimes="intracom")
mfld("311", CREDIT, '02', "kauba ühendusesisene käive", vat_regimes="intracom")
mfld("32", CREDIT, '02', "2) kauba eksport, sh", vat_regimes="!intracom")
mfld("321", CREDIT, '02', "käibemaksutagastusega müük reisijale", vat_regimes="!intracom")
mfld("4", CREDIT, '40', "Käibemaks kokku (20% lahtrist 1 + 9% lahtrist 2)")
mfld("41", CREDIT, '41', "Impordilt tasumisele kuuluv käibemaks")
mfld("5", CREDIT, '50', "Kokku sisendkäibemaksusumma, mis on seadusega lubatud maha arvata, sh")
mfld("51", CREDIT, '51', "1) impordilt tasutud või tasumisele kuuluv käibemaks")
mfld("52", CREDIT, '52', "2) põhivara soetamiselt tasutud või tasumisele kuuluv käibemaks")
mfld("53", CREDIT, '53',

mfld("32", CREDIT, '10', "2) kauba eksport, sh",
vat_regimes="tax_free exempt")
mfld("321", CREDIT, '10', "1) käibemaksutagastusega müük reisijale",
vat_regimes="tax_free")

mfld("4", CREDIT, '40',
"Käibemaks kokku (20% lahtrist 1 + 9% lahtrist 2)")
mfld("41", CREDIT, '41',
"Impordilt tasumisele kuuluv käibemaks")

mfld("5", CREDIT, '50',
"Kokku sisendkäibemaksusumma, mis on seadusega lubatud maha arvata, sh")
mfld("51", CREDIT, '50',
"1) impordilt tasutud või tasumisele kuuluv käibemaks",
vat_regimes="intracom")
mfld("52", CREDIT, '50',
"2) põhivara soetamiselt tasutud või tasumisele kuuluv käibemaks",
vat_classes="real_estate")
mfld("53", CREDIT, '50',
"3) ettevõtluses (100%) kasutatava sõiduauto soetamiselt ja sellise"
"sõiduauto tarbeks kaupade soetamiselt ja teenuste saamiselt"
"tasutud või tasumisele kuuluv käibemaks")
mfld("54", CREDIT, '54',
"tasutud või tasumisele kuuluv käibemaks",
vat_classes="vehicles")
mfld("54", CREDIT, '50',
"4) osaliselt ettevõtluses kasutatava sõiduauto soetamiselt ja sellise"
"sõiduauto tarbeks kaupade soetamiselt ja teenuste saamiselt"
"tasutud või tasumisele kuuluv käibemaks")

mfld("6", CREDIT, '52', "Kauba ühendusesisene soetamine ja teise liikmesriigi maksukohustuslaselt saadud teenused kokku, sh")
mfld("61", CREDIT, '52', "1) kauba ühendusesisene soetamine")
mfld("7", CREDIT, '52', "Muu kauba soetamine ja teenuse saamine, mida maksustatakse käibemaksuga, sh")
mfld("71", CREDIT, '52', "1) erikorra alusel maksustatava kinnisasja, metallijäätmete, väärismetallija metalltoodete soetamine (KMS § 41¹)")

mfld("8", CREDIT, '52', "Maksuvaba käive")
mfld("9", CREDIT, '52',
"tasutud või tasumisele kuuluv käibemaks",
vat_classes="vehicles")

mfld("6", DEBIT, '60',
"Kauba ühendusesisene soetamine ja teise liikmesriigi "
"maksukohustuslaselt saadud teenused kokku, sh")
mfld("61", DEBIT, '60', "1) kauba ühendusesisene soetamine",
vat_regimes="intracom", vat_classes="goods")

mfld("7", DEBIT, '60',
"Muu kauba soetamine ja teenuse saamine, mida maksustatakse käibemaksuga, sh",
vat_regimes="!intracom", vat_classes="!goods")
mfld("71", DEBIT, '60',
"1) erikorra alusel maksustatava kinnisasja, metallijäätmete, väärismetalli "
"ja metalltoodete soetamine (KMS § 41¹)",
vat_regimes="!intracom", vat_classes="!goods") # not yet handled

mfld("8", DEBIT, '60', "Maksuvaba käive", vat_classes="exempt")
mfld("9", DEBIT, '61',
"Erikorra alusel maksustatava kinnisasja, metallijäätmete, väärismetalli ja "
"metalltoodetekäive (KMS § 411) ning teises liikmesriigis paigaldatava või "
"metalltoodete käive (KMS § 411) ning teises liikmesriigis paigaldatava või "
"kokkupandava kauba maksustatav väärtus")

wfld("10", CREDIT, None, "Täpsustused -", is_payable=True)
wfld("11", DEBIT, None, "Täpsustused +", is_payable=True)
wfld("10", CREDIT, None, "Täpsustused -", editable=True)
wfld("11", DEBIT, None, "Täpsustused +", editable=True)

sfld("12", DEBIT, None,
"Tasumisele kuuluv käibemaks (lahter 4 + lahter 41 - lahter 5 + "
"lahter 10 - lahter 11)", is_payable=True)
"lahter 10 - lahter 11)", is_payable=True, fieldnames="4 41 5 10 11", both_dc=False)
sfld("13", CREDIT, None,
"Enammakstud käibemaks (lahter 4 + lahter 41 - lahter 5 + "
"lahter 10 - lahter 11)", is_payable=True)
"lahter 10 - lahter 11)", is_payable=True, fieldnames="4 41 5 10 11", both_dc=False)
2 changes: 1 addition & 1 deletion lino_xl/lib/eevat/desktop.py
Expand Up @@ -25,7 +25,7 @@ class VouchersByDeclaration(ledger.Vouchers):
# required_roles = set([1])

class DeclarationDetail(dd.DetailLayout):
main = "info values"
main = "info values vat.MovementsByDeclaration"

info = dd.Panel("""
start_period end_period entry_date accounting_period
Expand Down
13 changes: 7 additions & 6 deletions lino_xl/lib/ledger/choicelists.py
Expand Up @@ -127,18 +127,19 @@ def clearable(cls, choice, ar):
add = CommonAccounts.add_item

add('1000', _("Net income (loss)"), 'net_income_loss', True)

add('4000', _("Customers"), 'customers', True)
add('4100', _("Suppliers"), 'suppliers', True)
add('4200', _("Employees"), 'employees', True)
add('4300', _("Pending Payment Orders"), 'pending_po', True)
add('4400', _("Suppliers"), 'suppliers', True)
add('4500', _("Employees"), 'employees', True)
add('4550', _("Internal clearings"), 'clearings', True)
add('4600', _("Tax Offices"), 'tax_offices', True)
add('4500', _("Tax Offices"), 'tax_offices', True)

add('4510', _("VAT due"), 'vat_due', False)
add('4511', _("VAT returnable"), 'vat_returnable', False)
add('4512', _("VAT deductible"), 'vat_deductible', False)
add('4520', _("VAT deductible"), 'vat_deductible', False)
add('4530', _("VAT returnable"), 'vat_returnable', False)
add('4513', _("VAT declared"), 'due_taxes', False)

add('4800', _("Internal clearings"), 'clearings', True)
add('4900', _("Waiting account"), 'waiting', True)

add('5500', _("BestBank"), 'best_bank', False)
Expand Down
4 changes: 3 additions & 1 deletion lino_xl/lib/ledger/fixtures/demo_bookings.py
Expand Up @@ -20,7 +20,7 @@
REQUEST = settings.SITE.login() # BaseRequest()
MORE_THAN_A_MONTH = datetime.timedelta(days=40)

from lino_xl.lib.vat.choicelists import VatAreas, VatRules
from lino_xl.lib.vat.choicelists import VatAreas, VatRules, VatClasses
from lino_xl.lib.ledger.choicelists import TradeTypes

def objects():
Expand Down Expand Up @@ -89,6 +89,7 @@ def func():
# print(20151216, START_YEAR, settings.SITE.demo_date(), end_date - date)

PAYMENT_TERMS = Cycler(PaymentTerm.objects.all())
VAT_CLASSES = Cycler(VatClasses.get_list_items())
if len(PAYMENT_TERMS) == 0:
raise Exception("No PAYMENT_TERMS.")

Expand Down Expand Up @@ -120,6 +121,7 @@ def func():
(amount * INFLATION_RATE * (date.year - START_YEAR))
item = model(voucher=invoice,
account=account,
vat_class=VAT_CLASSES.pop(),
total_incl=myround(amount) +
AMOUNT_DELTAS.pop(), **kwargs)
try:
Expand Down
2 changes: 1 addition & 1 deletion lino_xl/lib/ledger/ui.py
Expand Up @@ -1007,7 +1007,7 @@ class MovementsByVoucher(Movements):
See also :class:`lino_xl.lib.ledger.models.Movement`.
"""
master_key = 'voucher'
column_names = 'account project partner debit credit match_link cleared *'
column_names = 'account project partner debit credit vat_class match_link cleared *'
sum_text_column = 3
# auto_fit_column_widths = True
display_mode = "html"
Expand Down
18 changes: 11 additions & 7 deletions lino_xl/lib/products/fixtures/furniture.py
@@ -1,13 +1,11 @@
# -*- coding: UTF-8 -*-
# Copyright 2009-2014 Rumma & Ko Ltd
#
# Copyright 2009-2019 Rumma & Ko Ltd
# License: BSD (see file COPYING for details)

from __future__ import unicode_literals

from lino.utils.instantiator import Instantiator
from lino_xl.lib.products.choicelists import ProductTypes

from lino.api import dd
from lino.api import dd, _


def objects():
Expand All @@ -16,20 +14,23 @@ def objects():
product = Instantiator('products.Product', "sales_price cat").build

furniture = productcat(
id=1, **dd.babel_values(
id=1, product_type=ProductTypes.default, **dd.babel_values(
'name',
en="Furniture", et="Mööbel", de="Möbel", fr="Meubles"))
yield furniture
# print "foo", furniture.id, furniture
hosting = productcat(
id=2, **dd.babel_values(
id=2, product_type=ProductTypes.default, **dd.babel_values(
'name',
en="Website Hosting",
et="Veebimajutus",
de="Website-Hosting",
fr="Hébergement de sites Internet"))
yield hosting

other = productcat(id=3, **dd.str2kw('name', _("Other")))
yield other

kw = dd.babel_values('name',
en="Wooden table",
et=u"Laud puidust",
Expand Down Expand Up @@ -107,3 +108,6 @@ def objects():
et="Pilditöötlus ja kodulehtede sisuhaldustööd",
de="Bildbearbeitung und Unterhalt Website",
fr="Traitement d'images et maintenance site existant"))

yield product("29.90", 3, **dd.str2kw('name', _("Book"), vat_class="reduced"))
yield product("1.40", 3, **dd.str2kw('name', _("Stamp"), vat_class="exempt"))
2 changes: 1 addition & 1 deletion lino_xl/lib/products/models.py
Expand Up @@ -59,7 +59,6 @@ class Meta:

delivery_unit = DeliveryUnits.field(default='piece')
product_type = ProductTypes.field()

vat_class = VatClasses.field(blank=True)

@dd.chooser()
Expand Down Expand Up @@ -109,6 +108,7 @@ def get_rule_fee(cls, partner, event_type):
return rule.fee

def full_clean(self):
# print("20191210", self.name, self.vat_class)
if self.product_type is None:
if self.cat_id:
self.product_type = self.cat.product_type or ProductTypes.default
Expand Down

0 comments on commit f3f4c54

Please sign in to comment.