diff --git a/CHANGELOG b/CHANGELOG
index a26e8fb14e..b543ba1dec 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,4 @@
+* Allow to export tax reports as file
* Remove support for Python 2.7
Version 4.8.0 - 2018-05-21
diff --git a/__init__.py b/__init__.py
index 4effdfa4a2..61a7b99e32 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,2 +1,21 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from trytond.pool import Pool
+from . import account
+from . import reporting_tax
+
+
+def register():
+ Pool.register(
+ reporting_tax.PrintAEATStart,
+ account.TaxCodeTemplate,
+ account.TaxCode,
+ module='account_es', type_='model')
+ Pool.register(
+ reporting_tax.AEAT111,
+ reporting_tax.AEAT115,
+ reporting_tax.AEAT303,
+ module='account_es', type_='report')
+ Pool.register(
+ reporting_tax.PrintAEAT,
+ module='account_es', type_='wizard')
diff --git a/account.py b/account.py
new file mode 100644
index 0000000000..c217d76ba3
--- /dev/null
+++ b/account.py
@@ -0,0 +1,39 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import fields
+from trytond.pool import PoolMeta
+from trytond.pyson import Bool, Eval
+
+__all__ = ['TaxCodeTemplate', 'TaxCode']
+
+
+class TaxCodeTemplate(metaclass=PoolMeta):
+ __name__ = 'account.tax.code.template'
+
+ aeat_report = fields.Selection([
+ (None, ''),
+ ('111', "Model 111"),
+ ('115', "Model 115"),
+ ('303', "Model 303"),
+ ], "AEAT Report")
+
+ def _get_tax_code_value(self, code=None):
+ value = super(TaxCodeTemplate, self)._get_tax_code_value(code=code)
+ value['aeat_report'] = self.aeat_report
+ return value
+
+
+class TaxCode(metaclass=PoolMeta):
+ __name__ = 'account.tax.code'
+
+ aeat_report = fields.Selection([
+ (None, ''),
+ ('111', "Model 111"),
+ ('115', "Model 115"),
+ ('303', "Model 303"),
+ ], "AEAT Report",
+ states={
+ 'readonly': (Bool(Eval('template', -1))
+ & ~Eval('template_override', False)),
+ },
+ depends=['template', 'template_override'])
diff --git a/aeat111.txt b/aeat111.txt
new file mode 100644
index 0000000000..7829ceab21
--- /dev/null
+++ b/aeat111.txt
@@ -0,0 +1 @@
+${justify('', 300)} I${company.party.tax_identifier.code[2:]}${justify(company.rec_name.upper(), 80)}${year}${period}${format_integer(parties['02'])}${format_decimal(amounts['02'])}${format_decimal(amounts['03'])}${format_integer(parties['05'])}${format_decimal(amounts['05'])}${format_decimal(amounts['06'])}${format_integer(parties['08'])}${format_decimal(amounts['08'])}${format_decimal(amounts['09'])}${format_integer(parties['11'])}${format_decimal(amounts['11'])}${format_decimal(amounts['12'])}${format_integer(parties['14'])}${format_decimal(amounts['14'])}${format_decimal(amounts['15'])}${format_integer(parties['17'])}${format_decimal(amounts['17'])}${format_decimal(amounts['18'])}${format_integer(parties['20'])}${format_decimal(amounts['20'])}${format_decimal(amounts['21'])}${format_integer(parties['23'])}${format_decimal(amounts['23'])}${format_decimal(amounts['24'])}${format_integer(parties['26'])}${format_decimal(amounts['26'])}${format_decimal(amounts['27'])}${format_decimal(amounts['28'])}${format_decimal(amounts['29'])}${format_decimal(amounts['30'])}${justify('', 451)}
diff --git a/aeat115.txt b/aeat115.txt
new file mode 100644
index 0000000000..4c0be980b2
--- /dev/null
+++ b/aeat115.txt
@@ -0,0 +1 @@
+${justify('', 300)} I${company.party.tax_identifier.code[2:]}${justify(company.rec_name.upper(), 80)}${year}${period}${format_integer(parties['03'], 15)}${format_decimal(amounts['02'])}${format_decimal(amounts['03'])}${format_decimal(amounts['04'])}${format_decimal(amounts['05'])}${justify('', 297)}
diff --git a/aeat303.txt b/aeat303.txt
new file mode 100644
index 0000000000..42dcd3824d
--- /dev/null
+++ b/aeat303.txt
@@ -0,0 +1 @@
+${justify('', 300)} ${declaration_type}${company.party.tax_identifier.code[2:]}${justify(company.rec_name.upper(), 80)}${year}${period}2322 2222${format_decimal(amounts['01'])}${format_percentage(amounts['02'])}${format_decimal(amounts['03'])}${format_decimal(amounts['04'])}${format_percentage(amounts['05'])}${format_decimal(amounts['06'])}${format_decimal(amounts['07'])}${format_percentage(amounts['08'])}${format_decimal(amounts['09'])}${format_decimal(amounts['10'])}${format_decimal(amounts['11'])}${format_decimal(amounts['12'])}${format_decimal(amounts['13'])}${format_decimal(amounts['14'])}${format_decimal(amounts['15'])}${format_decimal(amounts['16'])}${format_percentage(amounts['017'])}${format_decimal(amounts['18'])}${format_decimal(amounts['19'])}${format_percentage(amounts['20'])}${format_decimal(amounts['21'])}${format_decimal(amounts['22'])}${format_percentage(amounts['23'])}${format_decimal(amounts['24'])}${format_decimal(amounts['25'], True)}${format_decimal(amounts['26'], True)}${format_decimal(amounts['27'], True)}${format_decimal(amounts['28'])}${format_decimal(amounts['29'])}${format_decimal(amounts['30'])}${format_decimal(amounts['31'])}${format_decimal(amounts['32'])}${format_decimal(amounts['33'])}${format_decimal(amounts['34'])}${format_decimal(amounts['35'])}${format_decimal(amounts['36'])}${format_decimal(amounts['37'])}${format_decimal(amounts['38'])}${format_decimal(amounts['39'])}${format_decimal(amounts['40'], True)}${format_decimal(amounts['41'], True)}${format_decimal(amounts['42'], True)}${format_decimal(amounts['43'], True)}${format_decimal(amounts['44'], True)}${format_decimal(amounts['45'], True)}${format_decimal(amounts['46'], True)}022${justify('', 592)}${format_decimal(amounts['59'])}${format_decimal(amounts['60'])}${format_decimal(amounts['61'])}${format_decimal(amounts['62'])}${format_decimal(amounts['63'])}${format_decimal(amounts['74'])}${format_decimal(amounts['75'])}${format_decimal(amounts['76'])}${format_decimal(amounts['64'], True)}${format_percentage(amounts['65'])}0000${format_decimal(amounts['66'], True)}${format_decimal(amounts['77'])}${format_decimal(amounts['67'])}${format_decimal(amounts['68'], True)}${format_decimal(amounts['69'], True)}${format_decimal(amounts['70'], True)}${format_decimal(amounts['71'], True)}${justify('', 60)}0 0 0 0 0 0 ${format_decimal(amounts['80'])}${format_decimal(amounts['81'])}${format_decimal(amounts['93'])}${format_decimal(amounts['83'])}${format_decimal(amounts['84'])}${format_decimal(amounts['85'])}${format_decimal(amounts['86'])}${format_decimal(amounts['79'])}${format_decimal(amounts['88'])}0${format_percentage(amounts['89'])}${format_percentage(amounts['90'])}${format_percentage(amounts['91'])}${format_percentage(amounts['92'])}${format_decimal(amounts['94'])}${format_decimal(amounts['95'])}${format_decimal(amounts['96'])}${format_decimal(amounts['97'])}${format_decimal(amounts['98'])}${format_decimal(amounts['99'])}${justify('', 468)}
diff --git a/doc/index.rst b/doc/index.rst
index eb980f3c5a..a86104816b 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -9,3 +9,9 @@ The Spanish account module defines the following charts of account:
The chart was published as `REAL DECRETO 1514/2007
https://www.boe.es/boe/dias/2007/11/20/pdfs/C00001-00152.pdf`_ on 20th November
2007.
+
+A wizard allows to generate the following AEAT files:
+
+* Modelo 111
+* Modelo 115
+* Modelo 303
diff --git a/reporting_tax.py b/reporting_tax.py
new file mode 100644
index 0000000000..93f72e753c
--- /dev/null
+++ b/reporting_tax.py
@@ -0,0 +1,317 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+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.conditionals import Case
+from sql.functions import Substring, Position
+
+from trytond.model import ModelView, fields
+from trytond.model.modelsql import convert_from
+from trytond.pool import Pool
+from trytond.report import Report
+from trytond.transaction import Transaction
+from trytond.wizard import Wizard, StateView, StateTransition, StateReport, \
+ Button
+
+__all__ = ['AEAT111', 'AEAT115', 'AEAT303', 'PrintAEATStart', 'PrintAEAT']
+
+
+def justify(string, size):
+ return string[:size].ljust(size)
+
+
+def format_decimal(n, include_sign=False):
+ if not isinstance(n, Decimal):
+ n = Decimal(n)
+ sign = ''
+ if include_sign:
+ sign = 'N' if n < 0 else ''
+ return sign + ('{0:.2f}'.format(abs(n))).replace('.', '').rjust(
+ 17 - len(sign), '0')
+
+
+def format_integer(n, size=8):
+ return ('%d' % n).rjust(size, '0')
+
+
+def format_percentage(n, size=5):
+ return ('{0:.2f}'.format(n)).replace('.', '').rjust(size, '0')
+
+
+class AEATReport(Report):
+
+ @classmethod
+ def get_context(cls, records, data):
+ pool = Pool()
+ Period = pool.get('account.period')
+ context = super().get_context(records, data)
+
+ periods = sorted(
+ Period.browse(data['periods']), key=attrgetter('start_date'))
+
+ context['year'] = str(periods[0].start_date.year)
+ context['company'] = periods[0].fiscalyear.company
+
+ start_month = periods[0].start_date.month
+ end_month = periods[-1].end_date.month
+ if end_month - start_month > 0:
+ context['period'] = str(end_month // 3) + 'T'
+ else:
+ context['period'] = str(start_month).rjust(2, '0')
+
+ context['justify'] = justify
+ context['format_decimal'] = format_decimal
+ context['format_integer'] = format_integer
+ context['format_percentage'] = format_percentage
+
+ with Transaction().set_context(periods=data['periods']):
+ context['amounts'] = cls.compute_amounts()
+
+ return context
+
+ @classmethod
+ def compute_amounts(cls):
+ amounts = defaultdict(lambda: Decimal(0))
+ for tax_code in cls.tax_codes():
+ amounts[tax_code.code] += tax_code.amount
+ return amounts
+
+ @classmethod
+ def tax_codes(cls):
+ pool = Pool()
+ TaxCode = pool.get('account.tax.code')
+ return TaxCode.search([('aeat_report', '=', cls._aeat_report)])
+
+
+class AEATPartyReport(AEATReport):
+
+ @classmethod
+ def aeat_party_expression(cls, tables):
+ '''
+ Returns a couple of sql expression and tables used by sql query to
+ compute the aeat party.
+ '''
+ pool = Pool()
+ Invoice = pool.get('account.invoice')
+
+ table, _ = tables[None]
+ is_invoice = table.origin.like(Invoice.__name__ + ',%')
+
+ if 'invoice' in tables:
+ invoice, _ = tables['invoice']
+ else:
+ invoice = Invoice.__table__()
+ tables['invoice'] = {
+ None: (invoice, (is_invoice
+ & (invoice.id == Cast(
+ Substring(table.origin,
+ Position(',', table.origin) + Literal(1)),
+ Invoice.id.sql_type().base)))),
+ }
+
+ return Case((is_invoice, invoice.party), else_=Null), tables
+
+ @classmethod
+ def get_context(cls, records, data):
+ pool = Pool()
+ Move = pool.get('account.move')
+ Line = pool.get('account.move.line')
+ TaxLine = pool.get('account.tax.line')
+ Tax = pool.get('account.tax')
+
+ context = super().get_context(records, data)
+ cursor = Transaction().connection.cursor()
+
+ move = Move.__table__()
+ move_line = Line.__table__()
+ tax_line = TaxLine.__table__()
+
+ tables = {
+ None: (move, None),
+ 'lines': {
+ None: (move_line, move_line.move == move.id),
+ 'tax_lines': {
+ None: (tax_line, tax_line.move_line == move_line.id),
+ },
+ },
+ }
+
+ expression, tables = cls.aeat_party_expression(tables)
+
+ parties = defaultdict(int)
+ for tax_code in cls.tax_codes():
+ domain = ['OR']
+ for line in tax_code.lines:
+ domain.append(line._line_domain)
+
+ with Transaction().set_context(periods=data['periods']):
+ tax_line_domain = [Tax._amount_domain(), domain]
+ _, where = Move.search_domain([
+ ('lines', 'where', [
+ ('tax_lines', 'where', tax_line_domain),
+ ]),
+ ], tables=tables)
+
+ from_ = convert_from(None, tables)
+ cursor.execute(*from_.select(
+ expression, where=where, group_by=(expression,)).select(
+ Count(Literal('*'))))
+ row = cursor.fetchone()
+ if row:
+ parties[tax_code.code] += row[0]
+ context['parties'] = parties
+ return context
+
+
+class AEAT111(AEATPartyReport):
+ __name__ = 'account.reporting.aeat111'
+ _aeat_report = '111'
+
+ @classmethod
+ def get_context(cls, records, data):
+ context = super().get_context(records, data)
+ amounts = context['amounts']
+ for code in ['28', '30']:
+ assert code not in amounts, (
+ "computed code %s already defined" % code)
+ amounts['28'] = (amounts['03'] + amounts['06'] + amounts['09']
+ + amounts['12'] + amounts['15'] + amounts['18'] + amounts['21']
+ + amounts['24'] + amounts['27'])
+ amounts['30'] = amounts['28'] - amounts['29']
+ return context
+
+
+class AEAT115(AEATPartyReport):
+ __name__ = 'account.reporting.aeat115'
+ _aeat_report = '115'
+
+ @classmethod
+ def get_context(cls, records, data):
+ context = super().get_context(records, data)
+ amounts = context['amounts']
+ assert '05' not in amounts, (
+ "computed code 05 already defined")
+ amounts['05'] = amounts['03'] - amounts['04']
+ return context
+
+
+class AEAT303(AEATReport):
+ __name__ = 'account.reporting.aeat303'
+ _aeat_report = '303'
+
+ @classmethod
+ def compute_amounts(cls):
+ amounts = super().compute_amounts()
+ amounts['65'] = 100.0
+ return amounts
+
+ @classmethod
+ def get_context(cls, records, data):
+ pool = Pool()
+ Period = pool.get('account.period')
+ TaxCodeLine = pool.get('account.tax.code.line')
+ context = super().get_context(records, data)
+ amounts = context['amounts']
+
+ periods = Period.browse(data['periods'])
+ start_date = periods[0].start_date
+ end_date = periods[-1].end_date
+
+ lines = TaxCodeLine.search([
+ ('code', 'in', cls.tax_codes()),
+ ('code.code', 'in', ['03', '06', '09', '18', '21', '24']),
+ ('tax', 'where', [
+ ('type', '=', 'percentage'),
+ ['OR',
+ ('start_date', '=', None),
+ ('start_date', '<=', end_date),
+ ],
+ ['OR',
+ ('end_date', '=', None),
+ ('end_date', '>=', start_date),
+ ],
+ ]),
+ ])
+ for line in lines:
+ code = str(int(line.code.code) - 1).rjust(2, '0')
+ amounts[code] = float(line.tax.rate * Decimal(100))
+
+ for code in ['46', '64', '66', '69', '71', '88']:
+ assert code not in amounts, (
+ "computed code %s already defined" % code)
+ amounts['46'] = amounts['27'] - amounts['45']
+ amounts['64'] = amounts['46'] + amounts['58'] + amounts['76']
+ amounts['66'] = amounts['64'] * Decimal(amounts['65']) / Decimal(100.0)
+ amounts['69'] = (amounts['66'] + amounts['77'] - amounts['67']
+ + amounts['68'])
+ amounts['71'] = (amounts['69'] - amounts['70'])
+ amounts['88'] = (amounts['80'] + amounts['81'] - amounts['93']
+ + amounts['94'] + amounts['83'] + amounts['84'] + amounts['85']
+ + amounts['86'] + amounts['95'] + amounts['96'] + amounts['97']
+ + amounts['98'] - amounts['79'] - amounts['99'])
+
+ last_period = [p for p in periods[0].fiscalyear.periods
+ if p.type == 'standard'][-1]
+ declaration_type = 'N'
+ if amounts['69'] > 0:
+ declaration_type = 'I'
+ elif amounts['69'] < 0:
+ declaration_type = 'D' if last_period in periods else 'C'
+ context['declaration_type'] = declaration_type
+ return context
+
+
+class PrintAEATStart(ModelView):
+ 'Print AEAT Start'
+ __name__ = 'account.reporting.aeat.start'
+
+ report = fields.Selection([
+ ('111', "Model 111"),
+ ('115', "Model 115"),
+ ('303', "Model 303"),
+ ], "Report", required=True)
+ periods = fields.Many2Many('account.period', None, None, 'Periods',
+ required=True)
+
+
+class PrintAEAT(Wizard):
+ 'Print AEAT'
+ __name__ = 'account.reporting.aeat'
+ start = StateView('account.reporting.aeat.start',
+ 'account_es.print_aeat_start_view_form', [
+ Button('Cancel', 'end', 'tryton-cancel'),
+ Button('Print', 'choice', 'tryton-ok', default=True),
+ ])
+ choice = StateTransition()
+ model_111 = StateReport('account.reporting.aeat111')
+ model_115 = StateReport('account.reporting.aeat115')
+ model_303 = StateReport('account.reporting.aeat303')
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._error_messages.update({
+ 'same_fiscalyear': ("Periods should be of the same fiscalyear "
+ "to generate the report."),
+ })
+
+ def transition_choice(self):
+ validate = getattr(self, 'validate_%s' % self.start.report, None)
+ if validate:
+ validate()
+ return 'model_%s' % self.start.report
+
+ def open_report(self, action):
+ return action, {'periods': [p.id for p in self.start.periods]}
+
+ do_model_111 = open_report
+ do_model_115 = open_report
+ do_model_303 = open_report
+
+ def validate_303(self):
+ if len(set(p.fiscalyear for p in self.start.periods)) > 1:
+ self.raise_user_error('same_fiscalyear')
diff --git a/reporting_tax.xml b/reporting_tax.xml
new file mode 100644
index 0000000000..125f2e0706
--- /dev/null
+++ b/reporting_tax.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+ AEAT Model 111
+ account.reporting.aeat111
+ account_es/aeat111.txt
+ txt
+
+
+
+
+
+
+
+
+
+
+
+ AEAT Model 115
+ account.reporting.aeat115
+ account_es/aeat115.txt
+ txt
+
+
+
+
+
+
+
+
+
+
+
+ AEAT Model 303
+ account.reporting.aeat303
+ account_es/aeat303.txt
+ txt
+
+
+
+
+
+
+
+
+
+
+
+ account.reporting.aeat.start
+ form
+ print_aeat_start_form
+
+
+ Print AEAT
+ account.reporting.aeat
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/setup.py b/setup.py
index a54c6c2190..f59eb6dad1 100644
--- a/setup.py
+++ b/setup.py
@@ -72,7 +72,8 @@ setup(name=name,
],
package_data={
'trytond.modules.account_es': (info.get('xml', [])
- + ['tryton.cfg']),
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.text',
+ 'icons/*.svg', 'tests/*.rst', 'tests/*.txt']),
},
classifiers=[
'Development Status :: 5 - Production/Stable',
diff --git a/tax.xml b/tax.xml
index 388c635281..cfd43bd87a 100644
--- a/tax.xml
+++ b/tax.xml
@@ -375,6 +375,7 @@ this repository contains the full copyright notices and license terms. -->
IVA superreducido
01
+ 303
@@ -395,6 +396,7 @@ this repository contains the full copyright notices and license terms. -->
IVA reducido
04
+ 303
@@ -415,6 +417,7 @@ this repository contains the full copyright notices and license terms. -->
IVA normal
07
+ 303
@@ -435,6 +438,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarias de bienes y servicios
10
+ 303
@@ -469,18 +473,21 @@ this repository contains the full copyright notices and license terms. -->
Otras operaciones con inversión del sujeto pasivo
12
+ 303
Modificación bases
14
+ 303
Recargo equivalencia normal
16
+ 303
@@ -501,6 +508,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia reducido
19
+ 303
@@ -521,6 +529,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia superreducido
22
+ 303
@@ -542,6 +551,7 @@ this repository contains the full copyright notices and license terms. -->
Modificación bases del recargo de equivalencia
25
+ 303
@@ -549,12 +559,14 @@ this repository contains the full copyright notices and license terms. -->
Total cuota devengada
27
+ 303
IVA superreducido
03
+ 303
@@ -575,6 +587,7 @@ this repository contains the full copyright notices and license terms. -->
IVA reducido
06
+ 303
@@ -595,6 +608,7 @@ this repository contains the full copyright notices and license terms. -->
IVA normal
09
+ 303
@@ -615,6 +629,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarias de bienes y servicios
11
+ 303
@@ -649,18 +664,21 @@ this repository contains the full copyright notices and license terms. -->
Otras operaciones con inversión del sujeto pasivo
13
+ 303
Modificación cuotas
15
+ 303
Recargo equivalencia normal
18
+ 303
@@ -681,6 +699,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia reducido
21
+ 303
@@ -701,6 +720,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia superreducido
24
+ 303
@@ -722,6 +742,7 @@ this repository contains the full copyright notices and license terms. -->
Modificación cuotas del recargo equivalencia
26
+ 303
@@ -741,6 +762,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones interiores corrientes
28
+ 303
@@ -804,6 +826,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones interiores con bienes inversión
30
+ 303
@@ -853,6 +876,7 @@ this repository contains the full copyright notices and license terms. -->
Importaciones de bienes corrientes
32
+ 303
@@ -873,6 +897,7 @@ this repository contains the full copyright notices and license terms. -->
Importaciones de bienes de inversión
34
+ 303
@@ -893,6 +918,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarios de bienes y servicios corrientes
36
+ 303
@@ -913,6 +939,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitario de bienes de inversión
38
+ 303
@@ -933,6 +960,7 @@ this repository contains the full copyright notices and license terms. -->
Rectificación de deducciones
40
+ 303
@@ -940,12 +968,14 @@ this repository contains the full copyright notices and license terms. -->
Total a deducir
45
+ 303
Por cuotas soportadas en operaciones interiores corrientes
29
+ 303
@@ -995,6 +1025,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en operaciones interiores con bienes inversión
31
+ 303
@@ -1057,6 +1088,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en las importaciones de bienes corrientes
33
+ 303
@@ -1077,6 +1109,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en las importaciones de bienes de inversión
35
+ 303
@@ -1097,6 +1130,7 @@ this repository contains the full copyright notices and license terms. -->
En adquisiciones intracomunitarios de bienes y servicios corrientes
37
+ 303
@@ -1117,6 +1151,7 @@ this repository contains the full copyright notices and license terms. -->
En adquisiciones intracomunitario de bienes de inversión
39
+ 303
@@ -1137,24 +1172,28 @@ this repository contains the full copyright notices and license terms. -->
Rectificación de deducciones
41
+ 303
Compensaciones Reǵimen Especial A.G y P.
42
+ 303
Regularización bienes de inversión
43
+ 303
Regularización por aplicación del porcentaje definitio de prorrata
44
+ 303
@@ -1162,6 +1201,7 @@ this repository contains the full copyright notices and license terms. -->
Entregas intracomunitarias de bienes y servicios
59
+ 303
@@ -1198,6 +1238,7 @@ this repository contains the full copyright notices and license terms. -->
Exportaciones y operaciones asimiladas
60
+ 303
@@ -1218,6 +1259,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones no sujetas o con inversión del sujeto pasivo que originn derecho a deducción
61
+ 303
@@ -1231,6 +1273,7 @@ this repository contains the full copyright notices and license terms. -->
Importe percepeciones actividades economicas
08
+ 111
@@ -1293,6 +1336,7 @@ this repository contains the full copyright notices and license terms. -->
Importe retenciones actividades economicas
09
+ 111
@@ -1362,6 +1406,7 @@ this repository contains the full copyright notices and license terms. -->
Base de las retenciones e ingresos a cuenta
02
+ 115
@@ -1382,6 +1427,7 @@ this repository contains the full copyright notices and license terms. -->
Retenciones e ingresos a cuenta
03
+ 115
diff --git a/tax_normal.xml b/tax_normal.xml
index 59ff67879a..a90ad181bc 100644
--- a/tax_normal.xml
+++ b/tax_normal.xml
@@ -375,6 +375,7 @@ this repository contains the full copyright notices and license terms. -->
IVA superreducido
01
+ 303
@@ -395,6 +396,7 @@ this repository contains the full copyright notices and license terms. -->
IVA reducido
04
+ 303
@@ -415,6 +417,7 @@ this repository contains the full copyright notices and license terms. -->
IVA normal
07
+ 303
@@ -435,6 +438,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarias de bienes y servicios
10
+ 303
@@ -469,18 +473,21 @@ this repository contains the full copyright notices and license terms. -->
Otras operaciones con inversión del sujeto pasivo
12
+ 303
Modificación bases
14
+ 303
Recargo equivalencia normal
16
+ 303
@@ -501,6 +508,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia reducido
19
+ 303
@@ -521,6 +529,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia superreducido
22
+ 303
@@ -542,6 +551,7 @@ this repository contains the full copyright notices and license terms. -->
Modificación bases del recargo de equivalencia
25
+ 303
@@ -549,12 +559,14 @@ this repository contains the full copyright notices and license terms. -->
Total cuota devengada
27
+ 303
IVA superreducido
03
+ 303
@@ -575,6 +587,7 @@ this repository contains the full copyright notices and license terms. -->
IVA reducido
06
+ 303
@@ -595,6 +608,7 @@ this repository contains the full copyright notices and license terms. -->
IVA normal
09
+ 303
@@ -615,6 +629,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarias de bienes y servicios
11
+ 303
@@ -649,18 +664,21 @@ this repository contains the full copyright notices and license terms. -->
Otras operaciones con inversión del sujeto pasivo
13
+ 303
Modificación cuotas
15
+ 303
Recargo equivalencia normal
18
+ 303
@@ -681,6 +699,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia reducido
21
+ 303
@@ -701,6 +720,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia superreducido
24
+ 303
@@ -722,6 +742,7 @@ this repository contains the full copyright notices and license terms. -->
Modificación cuotas del recargo equivalencia
26
+ 303
@@ -741,6 +762,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones interiores corrientes
28
+ 303
@@ -804,6 +826,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones interiores con bienes inversión
30
+ 303
@@ -853,6 +876,7 @@ this repository contains the full copyright notices and license terms. -->
Importaciones de bienes corrientes
32
+ 303
@@ -873,6 +897,7 @@ this repository contains the full copyright notices and license terms. -->
Importaciones de bienes de inversión
34
+ 303
@@ -893,6 +918,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarios de bienes y servicios corrientes
36
+ 303
@@ -913,6 +939,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitario de bienes de inversión
38
+ 303
@@ -933,6 +960,7 @@ this repository contains the full copyright notices and license terms. -->
Rectificación de deducciones
40
+ 303
@@ -940,12 +968,14 @@ this repository contains the full copyright notices and license terms. -->
Total a deducir
45
+ 303
Por cuotas soportadas en operaciones interiores corrientes
29
+ 303
@@ -995,6 +1025,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en operaciones interiores con bienes inversión
31
+ 303
@@ -1057,6 +1088,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en las importaciones de bienes corrientes
33
+ 303
@@ -1077,6 +1109,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en las importaciones de bienes de inversión
35
+ 303
@@ -1097,6 +1130,7 @@ this repository contains the full copyright notices and license terms. -->
En adquisiciones intracomunitarios de bienes y servicios corrientes
37
+ 303
@@ -1117,6 +1151,7 @@ this repository contains the full copyright notices and license terms. -->
En adquisiciones intracomunitario de bienes de inversión
39
+ 303
@@ -1137,24 +1172,28 @@ this repository contains the full copyright notices and license terms. -->
Rectificación de deducciones
41
+ 303
Compensaciones Reǵimen Especial A.G y P.
42
+ 303
Regularización bienes de inversión
43
+ 303
Regularización por aplicación del porcentaje definitio de prorrata
44
+ 303
@@ -1162,6 +1201,7 @@ this repository contains the full copyright notices and license terms. -->
Entregas intracomunitarias de bienes y servicios
59
+ 303
@@ -1198,6 +1238,7 @@ this repository contains the full copyright notices and license terms. -->
Exportaciones y operaciones asimiladas
60
+ 303
@@ -1218,6 +1259,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones no sujetas o con inversión del sujeto pasivo que originn derecho a deducción
61
+ 303
@@ -1231,6 +1273,7 @@ this repository contains the full copyright notices and license terms. -->
Importe percepeciones actividades economicas
08
+ 111
@@ -1293,6 +1336,7 @@ this repository contains the full copyright notices and license terms. -->
Importe retenciones actividades economicas
09
+ 111
@@ -1362,6 +1406,7 @@ this repository contains the full copyright notices and license terms. -->
Base de las retenciones e ingresos a cuenta
02
+ 115
@@ -1382,6 +1427,7 @@ this repository contains the full copyright notices and license terms. -->
Retenciones e ingresos a cuenta
03
+ 115
diff --git a/tax_pyme.xml b/tax_pyme.xml
index a477ba0a5b..3948cf060c 100644
--- a/tax_pyme.xml
+++ b/tax_pyme.xml
@@ -375,6 +375,7 @@ this repository contains the full copyright notices and license terms. -->
IVA superreducido
01
+ 303
@@ -395,6 +396,7 @@ this repository contains the full copyright notices and license terms. -->
IVA reducido
04
+ 303
@@ -415,6 +417,7 @@ this repository contains the full copyright notices and license terms. -->
IVA normal
07
+ 303
@@ -435,6 +438,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarias de bienes y servicios
10
+ 303
@@ -469,18 +473,21 @@ this repository contains the full copyright notices and license terms. -->
Otras operaciones con inversión del sujeto pasivo
12
+ 303
Modificación bases
14
+ 303
Recargo equivalencia normal
16
+ 303
@@ -501,6 +508,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia reducido
19
+ 303
@@ -521,6 +529,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia superreducido
22
+ 303
@@ -542,6 +551,7 @@ this repository contains the full copyright notices and license terms. -->
Modificación bases del recargo de equivalencia
25
+ 303
@@ -549,12 +559,14 @@ this repository contains the full copyright notices and license terms. -->
Total cuota devengada
27
+ 303
IVA superreducido
03
+ 303
@@ -575,6 +587,7 @@ this repository contains the full copyright notices and license terms. -->
IVA reducido
06
+ 303
@@ -595,6 +608,7 @@ this repository contains the full copyright notices and license terms. -->
IVA normal
09
+ 303
@@ -615,6 +629,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarias de bienes y servicios
11
+ 303
@@ -649,18 +664,21 @@ this repository contains the full copyright notices and license terms. -->
Otras operaciones con inversión del sujeto pasivo
13
+ 303
Modificación cuotas
15
+ 303
Recargo equivalencia normal
18
+ 303
@@ -681,6 +699,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia reducido
21
+ 303
@@ -701,6 +720,7 @@ this repository contains the full copyright notices and license terms. -->
Recargo equivalencia superreducido
24
+ 303
@@ -722,6 +742,7 @@ this repository contains the full copyright notices and license terms. -->
Modificación cuotas del recargo equivalencia
26
+ 303
@@ -741,6 +762,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones interiores corrientes
28
+ 303
@@ -804,6 +826,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones interiores con bienes inversión
30
+ 303
@@ -853,6 +876,7 @@ this repository contains the full copyright notices and license terms. -->
Importaciones de bienes corrientes
32
+ 303
@@ -873,6 +897,7 @@ this repository contains the full copyright notices and license terms. -->
Importaciones de bienes de inversión
34
+ 303
@@ -893,6 +918,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitarios de bienes y servicios corrientes
36
+ 303
@@ -913,6 +939,7 @@ this repository contains the full copyright notices and license terms. -->
Adquisiciones intracomunitario de bienes de inversión
38
+ 303
@@ -933,6 +960,7 @@ this repository contains the full copyright notices and license terms. -->
Rectificación de deducciones
40
+ 303
@@ -940,12 +968,14 @@ this repository contains the full copyright notices and license terms. -->
Total a deducir
45
+ 303
Por cuotas soportadas en operaciones interiores corrientes
29
+ 303
@@ -995,6 +1025,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en operaciones interiores con bienes inversión
31
+ 303
@@ -1057,6 +1088,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en las importaciones de bienes corrientes
33
+ 303
@@ -1077,6 +1109,7 @@ this repository contains the full copyright notices and license terms. -->
Por cuotas soportadas en las importaciones de bienes de inversión
35
+ 303
@@ -1097,6 +1130,7 @@ this repository contains the full copyright notices and license terms. -->
En adquisiciones intracomunitarios de bienes y servicios corrientes
37
+ 303
@@ -1117,6 +1151,7 @@ this repository contains the full copyright notices and license terms. -->
En adquisiciones intracomunitario de bienes de inversión
39
+ 303
@@ -1137,24 +1172,28 @@ this repository contains the full copyright notices and license terms. -->
Rectificación de deducciones
41
+ 303
Compensaciones Reǵimen Especial A.G y P.
42
+ 303
Regularización bienes de inversión
43
+ 303
Regularización por aplicación del porcentaje definitio de prorrata
44
+ 303
@@ -1162,6 +1201,7 @@ this repository contains the full copyright notices and license terms. -->
Entregas intracomunitarias de bienes y servicios
59
+ 303
@@ -1198,6 +1238,7 @@ this repository contains the full copyright notices and license terms. -->
Exportaciones y operaciones asimiladas
60
+ 303
@@ -1218,6 +1259,7 @@ this repository contains the full copyright notices and license terms. -->
Operaciones no sujetas o con inversión del sujeto pasivo que originn derecho a deducción
61
+ 303
@@ -1231,6 +1273,7 @@ this repository contains the full copyright notices and license terms. -->
Importe percepeciones actividades economicas
08
+ 111
@@ -1293,6 +1336,7 @@ this repository contains the full copyright notices and license terms. -->
Importe retenciones actividades economicas
09
+ 111
@@ -1362,6 +1406,7 @@ this repository contains the full copyright notices and license terms. -->
Base de las retenciones e ingresos a cuenta
02
+ 115
@@ -1382,6 +1427,7 @@ this repository contains the full copyright notices and license terms. -->
Retenciones e ingresos a cuenta
03
+ 115
diff --git a/tests/111.txt b/tests/111.txt
new file mode 100644
index 0000000000..7c4f50a7b6
--- /dev/null
+++ b/tests/111.txt
@@ -0,0 +1 @@
+ IB01000009DUNDER MIFFLIN 201801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000001000000000000000001500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000001500
diff --git a/tests/115.txt b/tests/115.txt
new file mode 100644
index 0000000000..71ac67adb2
--- /dev/null
+++ b/tests/115.txt
@@ -0,0 +1 @@
+ IB01000009DUNDER MIFFLIN 20180100000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/tests/303.txt b/tests/303.txt
new file mode 100644
index 0000000000..03ba10e37f
--- /dev/null
+++ b/tests/303.txt
@@ -0,0 +1 @@
+ IB01000009DUNDER MIFFLIN 2018012322 222200000000000000000004000000000000000000000000000000000000010000000000000000000000000000000020000021000000000000000420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000420000000000000010000000000000000021000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210000000000000002100022 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210010000000000000000000002100000000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000002100 0 0 0 0 0 0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/tests/scenario_reporting.rst b/tests/scenario_reporting.rst
new file mode 100644
index 0000000000..1f0c4ce5a5
--- /dev/null
+++ b/tests/scenario_reporting.rst
@@ -0,0 +1,181 @@
+=============================
+Account ES Reporting Scenario
+=============================
+
+Imports::
+
+ >>> import datetime
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.tools import file_open
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import create_fiscalyear
+ >>> from trytond.modules.account_invoice.tests.tools import \
+ ... set_fiscalyear_invoice_sequences
+ >>> today = datetime.date.today()
+
+Install account_es::
+
+ >>> config = activate_modules('account_es')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+ >>> tax_identifier = company.party.identifiers.new()
+ >>> tax_identifier.type = 'eu_vat'
+ >>> tax_identifier.code = 'ESB01000009'
+ >>> company.party.save()
+
+Create fiscal year::
+
+ >>> fiscalyear = set_fiscalyear_invoice_sequences(
+ ... create_fiscalyear(company, datetime.date(2018, 1, 1)))
+ >>> fiscalyear.click('create_period')
+ >>> period = fiscalyear.periods[0]
+
+Create chart of accounts::
+
+ >>> AccountTemplate = Model.get('account.account.template')
+ >>> Account = Model.get('account.account')
+ >>> ModelData = Model.get('ir.model.data')
+ >>> data, = ModelData.find([
+ ... ('module', '=', 'account_es'),
+ ... ('fs_id', '=', 'pgc_0_pyme'),
+ ... ], limit=1)
+ >>> account_template = AccountTemplate(data.db_id)
+ >>> create_chart = Wizard('account.create_chart')
+ >>> create_chart.execute('account')
+ >>> create_chart.form.account_template = account_template
+ >>> create_chart.form.company = company
+ >>> create_chart.execute('create_account')
+ >>> accounts = {}
+ >>> for kind in ['receivable', 'payable', 'revenue', 'expense']:
+ ... accounts[kind], = Account.find([
+ ... ('kind', '=', kind),
+ ... ('company', '=', company.id),
+ ... ], limit=1)
+ >>> expense = accounts['expense']
+ >>> revenue = accounts['revenue']
+ >>> create_chart.form.account_receivable = accounts['receivable']
+ >>> create_chart.form.account_payable = accounts['payable']
+ >>> create_chart.execute('create_properties')
+
+Create parties::
+
+ >>> Party = Model.get('party.party')
+ >>> TaxRule = Model.get('account.tax.rule')
+ >>> party = Party(name='Party')
+ >>> party.save()
+ >>> tax_rule, = TaxRule.find([
+ ... ('company', '=', company.id),
+ ... ('kind', '=', 'purchase'),
+ ... ('name', '=', 'Retención IRPF 15%'),
+ ... ])
+ >>> supplier = Party(name='Supplier')
+ >>> supplier.supplier_tax_rule = tax_rule
+ >>> supplier.save()
+
+Create account category::
+
+ >>> Tax = Model.get('account.tax')
+ >>> customer_tax, = Tax.find([
+ ... ('company', '=', company.id),
+ ... ('name', '=', 'IVA 21%'),
+ ... ])
+ >>> supplier_tax, = Tax.find([
+ ... ('company', '=', company.id),
+ ... ('name', '=', 'IVA 21% (operaciones corrientes)'),
+ ... ])
+ >>> ProductCategory = Model.get('product.category')
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = expense
+ >>> account_category.account_revenue = revenue
+ >>> account_category.customer_taxes.append(customer_tax)
+ >>> account_category.supplier_taxes.append(supplier_tax)
+ >>> account_category.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'service'
+ >>> template.list_price = Decimal('40')
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Create invoices::
+
+ >>> Invoice = Model.get('account.invoice')
+ >>> invoice = Invoice()
+ >>> invoice.party = party
+ >>> invoice.invoice_date = period.start_date
+ >>> line = invoice.lines.new()
+ >>> line.product = product
+ >>> line.quantity = 5
+ >>> line.unit_price = Decimal('40')
+ >>> invoice.click('post')
+ >>> invoice.total_amount
+ Decimal('242.00')
+ >>> invoice = Invoice()
+ >>> invoice.type = 'in'
+ >>> invoice.party = 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('106.00')
+
+Generate aeat reports::
+
+ >>> Period = Model.get('account.period')
+ >>> aeat = Wizard('account.reporting.aeat')
+ >>> aeat.form.report = '111'
+ >>> aeat.form.periods.append(Period(period.id))
+ >>> aeat.execute('choice')
+ >>> extension, content, _, name = aeat.actions[0]
+ >>> extension
+ 'txt'
+ >>> with file_open('account_es/tests/111.txt') as f:
+ ... content == f.read()
+ True
+ >>> name
+ 'AEAT Model 111'
+
+ >>> aeat = Wizard('account.reporting.aeat')
+ >>> aeat.form.report = '115'
+ >>> period = Period(period.id)
+ >>> aeat.form.periods.append(Period(period.id))
+ >>> aeat.execute('choice')
+ >>> extension, content, _, name = aeat.actions[0]
+ >>> extension
+ 'txt'
+ >>> with file_open('account_es/tests/115.txt') as f:
+ ... content == f.read()
+ True
+ >>> name
+ 'AEAT Model 115'
+
+ >>> aeat = Wizard('account.reporting.aeat')
+ >>> aeat.form.report = '303'
+ >>> aeat.form.periods.append(Period(period.id))
+ >>> aeat.execute('choice')
+ >>> extension, content, _, name = aeat.actions[0]
+ >>> extension
+ 'txt'
+ >>> with file_open('account_es/tests/303.txt') as f:
+ ... content == f.read()
+ True
+ >>> name
+ 'AEAT Model 303'
diff --git a/tests/test_account_es.py b/tests/test_account_es.py
index cadbdb6637..9103632753 100644
--- a/tests/test_account_es.py
+++ b/tests/test_account_es.py
@@ -1,8 +1,12 @@
# 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 unittest
+import doctest
+
import trytond.tests.test_tryton
from trytond.tests.test_tryton import ModuleTestCase
+from trytond.tests.test_tryton import doctest_teardown
+from trytond.tests.test_tryton import doctest_checker
class AccountTestCase(ModuleTestCase):
@@ -14,4 +18,8 @@ def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(
AccountTestCase))
+ suite.addTests(doctest.DocFileSuite('scenario_reporting.rst',
+ tearDown=doctest_teardown, encoding='utf-8',
+ checker=doctest_checker,
+ optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
return suite
diff --git a/tryton.cfg b/tryton.cfg
index 59db24c7bd..24e14c56c5 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -10,3 +10,5 @@ xml:
tax_normal.xml
account_pyme.xml
tax_pyme.xml
+ view.xml
+ reporting_tax.xml
diff --git a/view.xml b/view.xml
new file mode 100644
index 0000000000..9ec9fb4736
--- /dev/null
+++ b/view.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ account.tax.code.template
+
+ tax_code_template_form
+
+
+
+ account.tax.code
+
+ tax_code_form
+
+
+
diff --git a/view/print_aeat_start_form.xml b/view/print_aeat_start_form.xml
new file mode 100644
index 0000000000..a46dc6a7ca
--- /dev/null
+++ b/view/print_aeat_start_form.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/view/tax_code_form.xml b/view/tax_code_form.xml
new file mode 100644
index 0000000000..1326334045
--- /dev/null
+++ b/view/tax_code_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/view/tax_code_template_form.xml b/view/tax_code_template_form.xml
new file mode 100644
index 0000000000..1326334045
--- /dev/null
+++ b/view/tax_code_template_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+