diff --git a/CHANGELOG b/CHANGELOG
index b285ff27d3..8c8c2fbab0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,4 @@
+* Add Spanish VAT list and EC Operation List
* Add amount to compensate from previous periods in 303 report
* Update model 303 to new format
diff --git a/__init__.py b/__init__.py
index 61a7b99e32..3ba6f55df8 100644
--- a/__init__.py
+++ b/__init__.py
@@ -2,6 +2,7 @@
# this repository contains the full copyright notices and license terms.
from trytond.pool import Pool
from . import account
+from . import party
from . import reporting_tax
@@ -10,11 +11,20 @@ def register():
reporting_tax.PrintAEATStart,
account.TaxCodeTemplate,
account.TaxCode,
+ account.TaxTemplate,
+ account.Tax,
+ party.Party,
+ reporting_tax.ESVATList,
+ reporting_tax.ESVATListContext,
+ reporting_tax.ECOperationList,
+ reporting_tax.ECOperationListContext,
module='account_es', type_='model')
Pool.register(
reporting_tax.AEAT111,
reporting_tax.AEAT115,
reporting_tax.AEAT303,
+ reporting_tax.AEAT347,
+ reporting_tax.AEAT349,
module='account_es', type_='report')
Pool.register(
reporting_tax.PrintAEAT,
diff --git a/account.py b/account.py
index c217d76ba3..b756667fe3 100644
--- a/account.py
+++ b/account.py
@@ -4,7 +4,7 @@ from trytond.model import fields
from trytond.pool import PoolMeta
from trytond.pyson import Bool, Eval
-__all__ = ['TaxCodeTemplate', 'TaxCode']
+__all__ = ['TaxCodeTemplate', 'TaxCode', 'TaxTemplate', 'Tax']
class TaxCodeTemplate(metaclass=PoolMeta):
@@ -37,3 +37,34 @@ class TaxCode(metaclass=PoolMeta):
& ~Eval('template_override', False)),
},
depends=['template', 'template_override'])
+
+
+class TaxTemplate(metaclass=PoolMeta):
+ __name__ = 'account.tax.template'
+
+ es_vat_list_code = fields.Char("Spanish VAT List Code")
+ es_ec_purchases_list_code = fields.Char("Spanish EC Purchase List Code")
+
+ def _get_tax_value(self, tax=None):
+ value = super()._get_tax_value(tax=tax)
+ for name in ['es_vat_list_code', 'es_ec_purchases_list_code']:
+ if not tax or getattr(tax, name) != getattr(self, name):
+ value[name] = getattr(self, name)
+ return value
+
+
+class Tax(metaclass=PoolMeta):
+ __name__ = 'account.tax'
+
+ es_vat_list_code = fields.Char("Spanish VAT List Code",
+ states={
+ 'readonly': (Bool(Eval('template', -1))
+ & ~Eval('template_override', False)),
+ },
+ depends=['template', 'template_override'])
+ es_ec_purchases_list_code = fields.Char("Spanish EC Purchases List Code",
+ states={
+ 'readonly': (Bool(Eval('template', -1))
+ & ~Eval('template_override', False)),
+ },
+ depends=['template', 'template_override'])
diff --git a/reporting_tax.py b/reporting_tax.py
index 10e4ff7740..04313aa34d 100644
--- a/reporting_tax.py
+++ b/reporting_tax.py
@@ -1,26 +1,31 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+import unicodedata
from collections import defaultdict
from decimal import Decimal
from operator import attrgetter
from sql import Cast, Null, Literal
-from sql.aggregate import Count
+from sql.aggregate import Count, Max, Min, Sum
from sql.conditionals import Case
-from sql.functions import Substring, Position
+from sql.functions import Substring, Position, Extract
from trytond.i18n import gettext
-from trytond.model import ModelView, fields
+from trytond.model import ModelSQL, ModelView, fields
from trytond.model.modelsql import convert_from
from trytond.pool import Pool
+from trytond.pyson import Eval
from trytond.report import Report
from trytond.transaction import Transaction
from trytond.wizard import Wizard, StateView, StateTransition, StateReport, \
Button
+from trytond.modules.account_eu.account import ECSalesList, ECSalesListContext
from .exceptions import PrintError
-__all__ = ['AEAT111', 'AEAT115', 'AEAT303', 'PrintAEATStart', 'PrintAEAT']
+__all__ = ['AEAT111', 'AEAT115', 'AEAT303', 'PrintAEATStart', 'PrintAEAT',
+ 'ESVATList', 'ESVATListContext', 'AEAT347', 'ECOperationList',
+ 'ECOperationListContext', 'AEAT349']
# XXX fix: https://genshi.edgewall.org/ticket/582
@@ -63,6 +68,26 @@ def format_percentage(n, size=5):
return ('{0:.2f}'.format(n)).replace('.', '').rjust(size, '0')
+def identifier_code(identifier):
+ if identifier:
+ return identifier.code[2:]
+ return ''
+
+
+def country_code(record):
+ code = None
+ if record.party_tax_identifier:
+ code = record.party_tax_identifier.code[:2]
+ if code is None or code == 'ES':
+ return ''
+ return code
+
+
+def strip_accents(s):
+ return ''.join(c for c in unicodedata.normalize('NFD', s)
+ if unicodedata.category(c) != 'Mn')
+
+
class AEATReport(Report):
@classmethod
@@ -348,3 +373,271 @@ class PrintAEAT(Wizard):
if len(set(p.fiscalyear for p in self.start.periods)) > 1:
raise PrintError(
gettext('account_es.msg_report_same_fiscalyear'))
+
+
+class ESVATList(ModelSQL, ModelView):
+ "Spanish VAT List"
+ __name__ = 'account.reporting.vat_list_es'
+
+ company_tax_identifier = fields.Many2One(
+ 'party.identifier', "Company Tax Identifier")
+ party_tax_identifier = fields.Many2One(
+ 'party.identifier', "Party Tax Identifier")
+ party = fields.Many2One('party.party', "Party")
+ province_code = fields.Function(fields.Char("Province Code"),
+ 'get_province_code', searcher='search_province_code')
+ code = fields.Char("Code")
+ amount = fields.Numeric(
+ "Amount", digits=(16, Eval('currency_digits', 2)),
+ depends=['currency_digits'])
+ first_period_amount = fields.Numeric(
+ "First Period Amount", digits=(16, Eval('currency_digits', 2)),
+ depends=['currency_digits'])
+ second_period_amount = fields.Numeric(
+ "Second Period Amount", digits=(16, Eval('currency_digits', 2)),
+ depends=['currency_digits'])
+ third_period_amount = fields.Numeric(
+ "Third Period Amount", digits=(16, Eval('currency_digits', 2)),
+ depends=['currency_digits'])
+ fourth_period_amount = fields.Numeric(
+ "Fourth Period Amount", digits=(16, Eval('currency_digits', 2)),
+ depends=['currency_digits'])
+ currency = fields.Many2One('currency.currency', "Currency")
+ currency_digits = fields.Function(
+ fields.Integer("Currency Digits"), 'get_currency_digits')
+
+ def get_currency_digits(self, name):
+ return self.currency.digits
+
+ @classmethod
+ def get_province_code(cls, records, name):
+ return {r.id: r.party.es_province_code or '' if r.party else ''
+ for r in records}
+
+ @classmethod
+ def search_province_code(cls, name, clause):
+ return [(('party.es_province_code',) + tuple(clause[1:]))]
+
+ @classmethod
+ def table_query(cls):
+ pool = Pool()
+ Invoice = pool.get('account.invoice')
+ InvoiceTax = pool.get('account.invoice.tax')
+ Tax = pool.get('account.tax')
+ Date = pool.get('ir.date')
+ context = Transaction().context
+ invoice = Invoice.__table__()
+ invoice_tax = InvoiceTax.__table__()
+ tax = Tax.__table__()
+
+ amount = invoice_tax.base + invoice_tax.amount
+ month = Extract('MONTH', invoice.invoice_date)
+
+ where = ((invoice.company == context.get('company'))
+ & (invoice.state.in_(['posted', 'paid']))
+ & (tax.es_vat_list_code != Null)
+ & (Extract('year', invoice.invoice_date)
+ == context.get('date', Date.today()).year))
+ return (invoice_tax
+ .join(invoice,
+ condition=invoice_tax.invoice == invoice.id)
+ .join(tax, condition=invoice_tax.tax == tax.id)
+ .select(
+ Max(invoice_tax.id).as_('id'),
+ Literal(0).as_('create_uid'),
+ Min(invoice_tax.create_date).as_('create_date'),
+ Literal(0).as_('write_uid'),
+ Max(invoice_tax.write_date).as_('write_date'),
+ invoice.tax_identifier.as_('company_tax_identifier'),
+ invoice.party.as_('party'),
+ invoice.party_tax_identifier.as_('party_tax_identifier'),
+ tax.es_vat_list_code.as_('code'),
+ Sum(amount).as_('amount'),
+ Sum(amount, filter_=month <= Literal(3)).as_(
+ 'first_period_amount'),
+ Sum(amount, filter_=(
+ (month > Literal(3)) & (month <= Literal(6)))).as_(
+ 'second_period_amount'),
+ Sum(amount, filter_=(
+ (month > Literal(6)) & (month <= Literal(9)))).as_(
+ 'third_period_amount'),
+ Sum(amount, filter_=(
+ (month > Literal(9)) & (month <= Literal(12)))).as_(
+ 'fourth_period_amount'),
+ invoice.currency.as_('currency'),
+ where=where,
+ group_by=[
+ invoice.tax_identifier,
+ invoice.type,
+ invoice.party,
+ invoice.party_tax_identifier,
+ invoice.currency,
+ tax.es_vat_list_code,
+ ]))
+
+
+class ESVATListContext(ModelView):
+ "Spanish VAT List Context"
+ __name__ = 'account.reporting.vat_list_es.context'
+
+ company = fields.Many2One('company.company', "Company", required=True)
+ date = fields.Date("Date", required=True,
+ context={'date_format': '%Y'})
+
+ @classmethod
+ def default_company(cls):
+ return Transaction().context.get('company')
+
+ @classmethod
+ def default_date(cls):
+ pool = Pool()
+ Date = pool.get('ir.date')
+ return Date.today()
+
+
+class AEAT347(Report):
+ __name__ = 'account.reporting.aeat347'
+
+ @classmethod
+ def get_context(cls, records, data):
+ pool = Pool()
+ Company = pool.get('company.company')
+ t_context = Transaction().context
+
+ context = super().get_context(records, data)
+
+ context['year'] = str(t_context['date'].year)
+ context['company'] = Company(t_context['company'])
+ context['records_amount'] = sum(
+ (r.amount for r in records), Decimal(0))
+
+ context['justify'] = justify
+
+ def format_decimal(n):
+ if not isinstance(n, Decimal):
+ n = Decimal(n)
+ sign = 'N' if n < 0 else ' '
+ return sign + ('{0:.2f}'.format(abs(n))).replace('.', '').rjust(
+ 15, '0')
+ context['format_decimal'] = format_decimal
+ context['format_integer'] = format_integer
+ context['identifier_code'] = identifier_code
+ context['country_code'] = country_code
+ context['strip_accents'] = strip_accents
+
+ return context
+
+
+class ECOperationList(ECSalesList):
+ "EC Operation List"
+ __name__ = 'account.reporting.es_ec_operation_list'
+
+ @classmethod
+ def table_query(cls):
+ pool = Pool()
+ Invoice = pool.get('account.invoice')
+ InvoiceTax = pool.get('account.invoice.tax')
+ Move = pool.get('account.move')
+ Period = pool.get('account.period')
+ Tax = pool.get('account.tax')
+ context = Transaction().context
+ invoice = Invoice.__table__()
+ invoice_tax = InvoiceTax.__table__()
+ move = Move.__table__()
+ period = Period.__table__()
+ tax = Tax.__table__()
+
+ sales = super().table_query()
+
+ where = ((invoice.company == context.get('company'))
+ & (period.fiscalyear == context.get('fiscalyear')))
+ if context.get('period'):
+ where &= (period.id == context.get('period'))
+ where &= ((tax.es_ec_purchases_list_code != Null)
+ & (tax.es_ec_purchases_list_code != ''))
+ where &= invoice.type == 'in'
+ purchases = (invoice_tax
+ .join(invoice,
+ condition=invoice_tax.invoice == invoice.id)
+ .join(tax, condition=invoice_tax.tax == tax.id)
+ .join(move, condition=invoice.move == move.id)
+ .join(period, condition=move.period == period.id)
+ .select(
+ Max(invoice_tax.id).as_('id'),
+ Literal(0).as_('create_uid'),
+ Min(invoice_tax.create_date).as_('create_date'),
+ Literal(0).as_('write_uid'),
+ Max(invoice_tax.write_date).as_('write_date'),
+ invoice.tax_identifier.as_('company_tax_identifier'),
+ invoice.party.as_('party'),
+ invoice.party_tax_identifier.as_('party_tax_identifier'),
+ tax.es_ec_purchases_list_code.as_('code'),
+ Sum(invoice_tax.base).as_('amount'),
+ invoice.currency.as_('currency'),
+ where=where,
+ group_by=[
+ invoice.tax_identifier,
+ invoice.party,
+ invoice.party_tax_identifier,
+ tax.es_ec_purchases_list_code,
+ invoice.currency,
+ ]))
+ return sales | purchases
+
+
+class ECOperationListContext(ECSalesListContext):
+ "EC Operation List Context"
+ __name__ = 'account.reporting.es_ec_operation_list.context'
+
+
+class AEAT349(Report):
+ __name__ = 'account.reporting.aeat349'
+
+ @classmethod
+ def get_context(cls, records, data):
+ pool = Pool()
+ Period = pool.get('account.period')
+ Fiscalyear = pool.get('account.fiscalyear')
+ t_context = Transaction().context
+
+ context = super().get_context(records, data)
+
+ fiscalyear = Fiscalyear(t_context['fiscalyear'])
+ context['year'] = str(fiscalyear.start_date.year)
+ context['company'] = fiscalyear.company
+ context['records_amount'] = sum(
+ (r.amount for r in records), Decimal(0))
+
+ period_id = t_context.get('period')
+ if not period_id:
+ # Yearly
+ context['period'] = '0A'
+ context['period_number'] = '99'
+ else:
+ period = Period(period_id)
+ start_month = period.start_date.month
+ end_month = period.end_date.month
+ if end_month - start_month > 0:
+ context['period'] = str(end_month // 3) + 'T'
+ context['period_number'] = str(20 + (end_month // 3))
+ else:
+ context['period'] = str(start_month).rjust(2, '0')
+ context['period_number'] = str(start_month).rjust(2, '0')
+
+ context['justify'] = justify
+ context['format_integer'] = format_integer
+ context['format_percentage'] = format_percentage
+ context['records_amount'] = sum(
+ (r.amount for r in records), Decimal(0))
+
+ context['justify'] = justify
+ context['identifier_code'] = identifier_code
+
+ def format_decimal(n, digits=13):
+ if not isinstance(n, Decimal):
+ n = Decimal(n)
+ return ('{0:.2f}'.format(abs(n))).replace('.', '').rjust(
+ digits, '0')
+ context['format_decimal'] = format_decimal
+
+ return context
diff --git a/reporting_tax.xml b/reporting_tax.xml
index 1e26dd4053..00bbbcbcfc 100644
--- a/reporting_tax.xml
+++ b/reporting_tax.xml
@@ -63,5 +63,114 @@ this repository contains the full copyright notices and license terms. -->
+
+ account.reporting.vat_list_es
+ tree
+ vat_list_list
+
+
+
+ Spanish VAT List
+ account.reporting.vat_list_es
+ account.reporting.vat_list_es.context
+
+
+
+
+
+
+
+
+
+ account.reporting.vat_list_es.context
+ form
+ vat_list_context_form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AEAT Model 347
+ account.reporting.aeat347
+ account_es/aeat347.txt
+ txt
+
+
+
+
+
+
+
+
+
+
+
+ form_print
+ account.reporting.vat_list_es,-1
+
+
+
+
+ account.reporting.es_ec_operation_list
+ tree
+ es_ec_operation_list
+
+
+
+ EC Operation List
+ account.reporting.es_ec_operation_list
+ account.reporting.es_ec_operation_list.context
+
+
+
+
+
+
+
+
+
+ account.reporting.es_ec_operation_list.context
+ form
+ es_ec_operation_list_context_form
+
+
+
+ AEAT Model 349
+ account.reporting.aeat349
+ account_es/aeat349.txt
+ txt
+
+
+
+
+
+
+
+
+
+
+
+ form_print
+ account.reporting.es_ec_operation_list,-1
+
+
diff --git a/setup.py b/setup.py
index c0349321eb..180044a2d5 100755
--- a/setup.py
+++ b/setup.py
@@ -45,7 +45,7 @@ if minor_version % 2:
'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
name[8:], name, version))
-requires = []
+requires = ['python-sql']
for dep in info.get('depends', []):
if not re.match(r'(ir|res)(\W|$)', dep):
requires.append(get_require_version('trytond_%s' % dep))
diff --git a/tax.xml b/tax.xml
index d980fd5c8b..0aabb447d6 100644
--- a/tax.xml
+++ b/tax.xml
@@ -12,6 +12,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA 10%
@@ -22,6 +23,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA 4%
@@ -32,6 +34,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA Exento
@@ -117,6 +120,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 10% (operaciones corrientes)
@@ -127,6 +131,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 4% (operaciones corrientes)
@@ -137,6 +142,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Exento (operaciones corrientes)
@@ -157,6 +163,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 10% (bienes de inversión)
@@ -167,6 +174,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 4% (bienes de inversión)
@@ -177,6 +185,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Exento (bienes de inversión)
@@ -319,6 +328,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Intracomunitario. Operaciones corrientes (2)
@@ -341,6 +351,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Intracomunitario. Bienes inversión (2)
diff --git a/tax_normal.xml b/tax_normal.xml
index d2c77b5485..9c1c0a1f97 100644
--- a/tax_normal.xml
+++ b/tax_normal.xml
@@ -12,6 +12,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA 10%
@@ -22,6 +23,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA 4%
@@ -32,6 +34,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA Exento
@@ -117,6 +120,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 10% (operaciones corrientes)
@@ -127,6 +131,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 4% (operaciones corrientes)
@@ -137,6 +142,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Exento (operaciones corrientes)
@@ -157,6 +163,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 10% (bienes de inversión)
@@ -167,6 +174,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 4% (bienes de inversión)
@@ -177,6 +185,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Exento (bienes de inversión)
@@ -319,6 +328,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Intracomunitario. Operaciones corrientes (2)
@@ -341,6 +351,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Intracomunitario. Bienes inversión (2)
diff --git a/tax_pyme.xml b/tax_pyme.xml
index 4f3874efab..0a63699844 100644
--- a/tax_pyme.xml
+++ b/tax_pyme.xml
@@ -12,6 +12,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA 10%
@@ -22,6 +23,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA 4%
@@ -32,6 +34,7 @@ this repository contains the full copyright notices and license terms. -->
+ B
IVA Exento
@@ -117,6 +120,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 10% (operaciones corrientes)
@@ -127,6 +131,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 4% (operaciones corrientes)
@@ -137,6 +142,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Exento (operaciones corrientes)
@@ -157,6 +163,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 10% (bienes de inversión)
@@ -167,6 +174,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA 4% (bienes de inversión)
@@ -177,6 +185,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Exento (bienes de inversión)
@@ -319,6 +328,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Intracomunitario. Operaciones corrientes (2)
@@ -341,6 +351,7 @@ this repository contains the full copyright notices and license terms. -->
+ A
IVA Intracomunitario. Bienes inversión (2)
diff --git a/tests/303.txt b/tests/303.txt
index 93e2235b04..684374e452 100644
--- a/tests/303.txt
+++ b/tests/303.txt
@@ -1 +1 @@
- IB01000009DUNDER MIFFLIN 2018012322 2222000000000000000000040000000000000000000000000000000000000100000000000000000000000000000000200000210000000000000004200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000004200000000000000100000000000000000210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002100000000000000021000220 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210010000000000000000000002100000000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000002100 0 0 0 0 0 0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ IB01000009DUNDER MIFFLIN 2018012322 2222000000000000000000040000000000000000000000000000000000000100000000000000000000000000000000200000210000000000000004200000000000000100000000000000000210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000006300000000000000100000000000000000210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000021000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004200000000000000021000220 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210010000000000000000000002100000000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000002100 0 0 0 0 0 0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/tests/scenario_reporting.rst b/tests/scenario_reporting.rst
index d60abb1061..4226896836 100644
--- a/tests/scenario_reporting.rst
+++ b/tests/scenario_reporting.rst
@@ -6,7 +6,7 @@ Imports::
>>> import datetime
>>> from decimal import Decimal
- >>> from proteus import Model, Wizard
+ >>> from proteus import Model, Wizard, Report
>>> from trytond.tests.tools import activate_modules
>>> from trytond.tools import file_open
>>> from trytond.modules.company.tests.tools import create_company, \
@@ -65,9 +65,20 @@ Create chart of accounts::
Create parties::
+ >>> Country = Model.get('country.country')
+ >>> spain = Country(name='Spain', code='ES')
+ >>> spain.save()
>>> Party = Model.get('party.party')
>>> TaxRule = Model.get('account.tax.rule')
>>> party = Party(name='Party')
+ >>> tax_identifier = party.identifiers.new()
+ >>> tax_identifier.type = 'eu_vat'
+ >>> tax_identifier.code = 'ES00000000T'
+ >>> address, = party.addresses
+ >>> address.country = spain
+ >>> address.zip = '25001'
+ >>> party.es_province_code
+ '25'
>>> party.save()
>>> tax_rule, = TaxRule.find([
... ('company', '=', company.id),
@@ -76,7 +87,22 @@ Create parties::
... ])
>>> supplier = Party(name='Supplier')
>>> supplier.supplier_tax_rule = tax_rule
+ >>> tax_identifier = supplier.identifiers.new()
+ >>> tax_identifier.type = 'eu_vat'
+ >>> tax_identifier.code = 'ES00000001R'
+ >>> supplier.es_province_code = '08'
>>> supplier.save()
+ >>> tax_rule, = TaxRule.find([
+ ... ('company', '=', company.id),
+ ... ('kind', '=', 'purchase'),
+ ... ('name', '=', 'Compras Intracomunitarias'),
+ ... ])
+ >>> ec_supplier = Party(name='Intracomunitary Supplier')
+ >>> ec_supplier.supplier_tax_rule = tax_rule
+ >>> tax_identifier = ec_supplier.identifiers.new()
+ >>> tax_identifier.type = 'eu_vat'
+ >>> tax_identifier.code = 'BE0897290877'
+ >>> ec_supplier.save()
Create account category::
@@ -136,6 +162,17 @@ Create invoices::
>>> invoice.click('post')
>>> invoice.total_amount
Decimal('106.00')
+ >>> invoice = Invoice()
+ >>> invoice.type = 'in'
+ >>> invoice.party = ec_supplier
+ >>> invoice.invoice_date = period.start_date
+ >>> line = invoice.lines.new()
+ >>> line.product = product
+ >>> line.quantity = 5
+ >>> line.unit_price = Decimal('20')
+ >>> invoice.click('post')
+ >>> invoice.total_amount
+ Decimal('100.00')
Generate aeat reports::
@@ -179,3 +216,37 @@ Generate aeat reports::
True
>>> name
'AEAT Model 303'
+
+ >>> VatList = Model.get('account.reporting.vat_list_es')
+ >>> context = {
+ ... 'company': company.id,
+ ... 'date': period.end_date,
+ ... }
+ >>> with config.set_context(context):
+ ... vat_list_records = VatList.find([])
+ ... report = Report('account.reporting.aeat347')
+ ... extension, content, _, name = report.execute(vat_list_records)
+ >>> extension
+ 'txt'
+ >>> with file_open('account_es/tests/347.txt') as f:
+ ... content == f.read()
+ True
+ >>> name
+ 'AEAT Model 347'
+
+ >>> ECOperationList = Model.get('account.reporting.es_ec_operation_list')
+ >>> context = {
+ ... 'company': company.id,
+ ... 'fiscalyear': fiscalyear.id,
+ ... }
+ >>> with config.set_context(context):
+ ... records = ECOperationList.find([])
+ ... report = Report('account.reporting.aeat349')
+ ... extension, content, _, name = report.execute(records)
+ >>> extension
+ 'txt'
+ >>> with file_open('account_es/tests/349.txt') as f:
+ ... content == f.read()
+ True
+ >>> name
+ 'AEAT Model 349'
diff --git a/tryton.cfg b/tryton.cfg
index 3169a28aa2..1f1d15d36c 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -4,6 +4,8 @@ depends:
ir
account
account_eu
+ account_invoice
+ party
xml:
tax_groups.xml
account_normal.xml
@@ -13,3 +15,4 @@ xml:
view.xml
reporting_tax.xml
message.xml
+ party.xml
diff --git a/view.xml b/view.xml
index 9ec9fb4736..f2771a1835 100644
--- a/view.xml
+++ b/view.xml
@@ -14,5 +14,17 @@ this repository contains the full copyright notices and license terms. -->
tax_code_form
+
+
+ account.tax.template
+
+ tax_template_form
+
+
+
+ account.tax
+
+ tax_form
+