Update to 4.7

This commit is contained in:
Cédric Krier 2018-01-18 17:08:54 +01:00
parent d06f9affa6
commit 325df0acd8
10 changed files with 186 additions and 96 deletions

49
.drone.yml Normal file
View File

@ -0,0 +1,49 @@
clone:
hg:
image: plugins/hg
pipeline:
tox:
image: ${IMAGE}
environment:
- CFLAGS=-O0
- DB_CACHE=/cache
- TOX_TESTENV_PASSENV=CFLAGS DB_CACHE
- POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
commands:
- pip install tox
- tox -e "${TOXENV}-${DATABASE}"
services:
postgresql:
image: postgres
when:
matrix:
DATABASE: postgresql
matrix:
include:
- IMAGE: python:2.7
TOXENV: py27
DATABASE: sqlite
- IMAGE: python:2.7
TOXENV: py27
DATABASE: postgresql
- IMAGE: python:3.4
TOXENV: py34
DATABASE: sqlite
- IMAGE: python:3.4
TOXENV: py34
DATABASE: postgresql
- IMAGE: python:3.5
TOXENV: py35
DATABASE: sqlite
- IMAGE: python:3.5
TOXENV: py35
DATABASE: postgresql
- IMAGE: python:3.6
TOXENV: py36
DATABASE: sqlite
- IMAGE: python:3.6
TOXENV: py36
DATABASE: postgresql

View File

@ -1,13 +1,10 @@
# The COPYRIGHT file at the top level of this repository contains the full # The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms. # copyright notices and license terms.
from trytond.model import ModelSQL, ModelView, fields from trytond.model import fields
from trytond.wizard import Wizard, StateView, StateTransition, Button from trytond.pool import PoolMeta
from trytond.pool import Pool, PoolMeta from .aeat import (BOOK_KEY, SEND_SPECIAL_REGIME_KEY,
from trytond.pyson import Eval, And, Bool RECEIVE_SPECIAL_REGIME_KEY, IVA_SUBJECTED, EXCEMPTION_CAUSE,
from trytond.transaction import Transaction INTRACOMUNITARY_TYPE)
from .aeat import (OPERATION_KEY, BOOK_KEY, SEND_SPECIAL_REGIME_KEY,
RECEIVE_SPECIAL_REGIME_KEY, AEAT_INVOICE_STATE, IVA_SUBJECTED,
EXCEMPTION_CAUSE, INTRACOMUNITARY_TYPE)
__all__ = ['TemplateTax', 'Tax'] __all__ = ['TemplateTax', 'Tax']

112
aeat.py
View File

@ -28,6 +28,7 @@ _ZERO = Decimal('0.0')
# AEAT SII test # AEAT SII test
SII_TEST = config.getboolean('aeat', 'sii_test', default=True) SII_TEST = config.getboolean('aeat', 'sii_test', default=True)
def _decimal(x): def _decimal(x):
return Decimal(x) if x is not None else None return Decimal(x) if x is not None else None
@ -46,7 +47,7 @@ COMMUNICATION_TYPE = [ # L0
# ('A4', 'Amendment of Invoice for Travellers'), # Not suported # ('A4', 'Amendment of Invoice for Travellers'), # Not suported
('C0', 'Query Invoices'), # Not in L0 ('C0', 'Query Invoices'), # Not in L0
('D0', 'Delete Invoices'), # Not In L0 ('D0', 'Delete Invoices'), # Not In L0
] ]
BOOK_KEY = [ BOOK_KEY = [
(None, ''), (None, ''),
@ -54,13 +55,14 @@ BOOK_KEY = [
('I', 'Investment Goods'), ('I', 'Investment Goods'),
('R', 'Received Invoices'), ('R', 'Received Invoices'),
('U', 'Particular Intracommunity Operations'), ('U', 'Particular Intracommunity Operations'),
] ]
OPERATION_KEY = [ # L2_EMI - L2_RECI OPERATION_KEY = [ # L2_EMI - L2_RECI
(None, ''), (None, ''),
('F1', 'Invoice'), ('F1', 'Invoice'),
('F2', 'Simplified Invoice (ticket)'), ('F2', 'Simplified Invoice (ticket)'),
('R1', 'Corrected Invoice (Art 80.1, 80.2 and 80.6 and error grounded in law)'), ('R1', 'Corrected Invoice '
'(Art 80.1, 80.2 and 80.6 and error grounded in law)'),
('R2', 'Corrected Invoice (Art. 80.3)'), ('R2', 'Corrected Invoice (Art. 80.3)'),
('R3', 'Credit Note (Art 80.4)'), ('R3', 'Credit Note (Art 80.4)'),
('R4', 'Corrected Invoice (Other)'), ('R4', 'Corrected Invoice (Other)'),
@ -69,19 +71,18 @@ OPERATION_KEY = [ # L2_EMI - L2_RECI
('F4', 'Invoice summary entry'), ('F4', 'Invoice summary entry'),
('F5', 'Import (DUA)'), ('F5', 'Import (DUA)'),
('F6', 'Other accounting documents'), ('F6', 'Other accounting documents'),
]
]
PARTY_IDENTIFIER_TYPE = [ PARTY_IDENTIFIER_TYPE = [
(None, ''), (None, ''),
('02', 'NIF-VAT'), ('02', 'NIF-VAT'),
('03', 'Passport'), ('03', 'Passport'),
('04', 'Official identification document issued by the country ' ('04', 'Official identification document issued by the country '
'or region of residence'), 'or region of residence'),
('05', 'Residence certificate'), ('05', 'Residence certificate'),
('06', 'Other supporting document'), ('06', 'Other supporting document'),
('07', 'Not registered'), ('07', 'Not registered'),
] ]
SEND_SPECIAL_REGIME_KEY = [ # L3.1 SEND_SPECIAL_REGIME_KEY = [ # L3.1
@ -89,58 +90,58 @@ SEND_SPECIAL_REGIME_KEY = [ # L3.1
('01', 'General tax regime activity'), ('01', 'General tax regime activity'),
('02', 'Export'), ('02', 'Export'),
('03', 'Activities to which the special scheme of used goods, ' ('03', 'Activities to which the special scheme of used goods, '
'works of art, antiquities and collectables (135-139 of the VAT Law)'), 'works of art, antiquities and collectables (135-139 of the VAT Law)'),
('04', 'Special scheme for investment gold'), ('04', 'Special scheme for investment gold'),
('05', 'Special scheme for travel agencies'), ('05', 'Special scheme for travel agencies'),
('06', 'Special scheme applicable to groups of entities, VAT (Advanced)'), ('06', 'Special scheme applicable to groups of entities, VAT (Advanced)'),
('07', 'Special cash basis scheme'), ('07', 'Special cash basis scheme'),
('08', 'Activities subject to Canary Islands General Indirect Tax/Tax on ' ('08', 'Activities subject to Canary Islands General Indirect Tax/Tax on '
'Production, Services and Imports'), 'Production, Services and Imports'),
('09', 'Invoicing of the provision of travel agency services acting as ' ('09', 'Invoicing of the provision of travel agency services acting as '
'intermediaries in the name of and on behalf of other persons ' 'intermediaries in the name of and on behalf of other persons '
'(Additional Provision 4, Royal Decree 1619/2012)'), '(Additional Provision 4, Royal Decree 1619/2012)'),
('10', 'Collections on behalf of third parties of professional fees or ' ('10', 'Collections on behalf of third parties of professional fees or '
'industrial property, copyright or other such rights by partners, ' 'industrial property, copyright or other such rights by partners, '
'associates or members undertaken by companies, associations, ' 'associates or members undertaken by companies, associations, '
'professional organisations or other entities that, amongst their ' 'professional organisations or other entities that, amongst their '
'functions, undertake collections'), 'functions, undertake collections'),
('11', 'Business premises lease activities subject to withholding'), ('11', 'Business premises lease activities subject to withholding'),
('12', 'Business premises lease activities not subject to withholding'), ('12', 'Business premises lease activities not subject to withholding'),
('13', 'Business premises lease activities subject and not subject ' ('13', 'Business premises lease activities subject and not subject '
'to withholding'), 'to withholding'),
('14', 'Invoice with VAT pending accrual (work certifications with Public ' ('14', 'Invoice with VAT pending accrual (work certifications with Public '
'Administration recipients)'), 'Administration recipients)'),
('15', 'Invoice with VAT pending accrual - ' ('15', 'Invoice with VAT pending accrual - '
'operations of successive tract'), 'operations of successive tract'),
('16', 'First semester 2017'), ('16', 'First semester 2017'),
] ]
RECEIVE_SPECIAL_REGIME_KEY = [ RECEIVE_SPECIAL_REGIME_KEY = [
(None, ''), (None, ''),
('01', 'General tax regime activity'), ('01', 'General tax regime activity'),
('02', 'Activities through which businesses pay compensation for special ' ('02', 'Activities through which businesses pay compensation for special '
'VAT arrangements for agriculture and fisheries'), 'VAT arrangements for agriculture and fisheries'),
('03', 'Activities to which the special scheme of used goods, works of art, ' ('03', 'Activities to which the special scheme of used goods, '
'antiquities and collectables (135-139 of the VAT Law)'), 'works of art, antiquities and collectables (135-139 of the VAT Law)'),
('04', 'Special scheme for investment gold'), ('04', 'Special scheme for investment gold'),
('05', 'Special scheme for travel agencies'), ('05', 'Special scheme for travel agencies'),
('06', 'Special scheme applicable to groups of entities, VAT (Advanced)'), ('06', 'Special scheme applicable to groups of entities, VAT (Advanced)'),
('07', 'Special cash basis scheme'), ('07', 'Special cash basis scheme'),
('08', 'Activities subject to Canary Islands General Indirect Tax/Tax ' ('08', 'Activities subject to Canary Islands General Indirect Tax/Tax '
'on Production, Services and Imports'), 'on Production, Services and Imports'),
('09', 'Intra-Community acquisition of assets and provisions of services'), ('09', 'Intra-Community acquisition of assets and provisions of services'),
('12', 'Business premises lease activities'), ('12', 'Business premises lease activities'),
('13', 'Invoice corresponding to an import ' ('13', 'Invoice corresponding to an import '
'(reported without been associated with a DUA)'), '(reported without been associated with a DUA)'),
('14', 'First semester 2017'), ('14', 'First semester 2017'),
] ]
AEAT_COMMUNICATION_STATE = [ AEAT_COMMUNICATION_STATE = [
(None, ''), (None, ''),
('Correcto', 'Accepted'), ('Correcto', 'Accepted'),
('ParcialmenteCorrecto', 'Partially Accepted'), ('ParcialmenteCorrecto', 'Partially Accepted'),
('Incorrecto', 'Rejected') ('Incorrecto', 'Rejected')
] ]
AEAT_INVOICE_STATE = [ AEAT_INVOICE_STATE = [
(None, ''), (None, ''),
@ -156,13 +157,13 @@ AEAT_INVOICE_STATE = [
PROPERTY_STATE = [ # L6 PROPERTY_STATE = [ # L6
('0', ''), ('0', ''),
('1', '1. Property with a land register reference located in any part ' ('1', '1. Property with a land register reference located in any part '
'of Spain, with the exception of the Basque Country and Navarre'), 'of Spain, with the exception of the Basque Country and Navarre'),
('2', '2. Property located in the Autonomous Community of the Basque ' ('2', '2. Property located in the Autonomous Community of the Basque '
'Country or the Chartered Community of Navarre.'), 'Country or the Chartered Community of Navarre.'),
('3', '3. Property in any of the foregoing locations with no land register ' ('3', '3. Property in any of the foregoing locations '
'reference'), 'with no land register reference'),
('4', '4. Property located abroad'), ('4', '4. Property located abroad'),
] ]
# L7 - Iva Subjected # L7 - Iva Subjected
@ -171,8 +172,8 @@ IVA_SUBJECTED = [
('S1', 'Subject - Not exempt. Non VAT reverse charge'), ('S1', 'Subject - Not exempt. Non VAT reverse charge'),
('S2', 'Subject - Not exempt. VAT reverse charge'), ('S2', 'Subject - Not exempt. VAT reverse charge'),
('S3', 'Subject - Not exempt. Both non VAT reverse charge ' ('S3', 'Subject - Not exempt. Both non VAT reverse charge '
'and VAT reverse charge') 'and VAT reverse charge')
] ]
# L9 - Excemption cause # L9 - Excemption cause
EXCEMPTION_CAUSE = [ EXCEMPTION_CAUSE = [
@ -183,26 +184,26 @@ EXCEMPTION_CAUSE = [
('E4', 'Exempt on account of Article 23 and Article 24'), ('E4', 'Exempt on account of Article 23 and Article 24'),
('E5', 'Exempt on account of Article 25'), ('E5', 'Exempt on account of Article 25'),
('E6', 'Exempt on other grounds'), ('E6', 'Exempt on other grounds'),
] ]
# L11 Payment Type # L11 Payment Type
PAYMENT_TYPE = [ PAYMENT_TYPE = [
('01', 'Transfer'), ('01', 'Transfer'),
('02', 'Cheque'), ('02', 'Cheque'),
('03', 'Not to be collected/paid (deadline for accrual/forced accrual ' ('03', 'Not to be collected/paid (deadline for accrual/forced accrual '
'as part of insolvency proceedings)'), 'as part of insolvency proceedings)'),
('04', 'Other methods of collection/payment') ('04', 'Other methods of collection/payment')
] ]
# L12 # L12
INTRACOMUNITARY_TYPE = [ INTRACOMUNITARY_TYPE = [
(None, ''), (None, ''),
('A', 'The transmission or receipt of goods to undertake partial reports ' ('A', 'The transmission or receipt of goods to undertake partial reports '
'or works stipulated in Article 70, section one, Number 7 ' 'or works stipulated in Article 70, section one, Number 7 '
'of the Tax Law (Law 37/1992)'), 'of the Tax Law (Law 37/1992)'),
('B', 'Transfers of goods or intra-Community acquisitions of goods listed ' ('B', 'Transfers of goods or intra-Community acquisitions of goods listed '
'in Article 9.3 and Article 16.2 of the Tax Law (Law 37/1992)'), 'in Article 9.3 and Article 16.2 of the Tax Law (Law 37/1992)'),
] ]
def remove_accents(unicode_string): def remove_accents(unicode_string):
@ -241,10 +242,12 @@ class SIIReport(Workflow, ModelSQL, ModelView):
states={ states={
'readonly': Eval('state') != 'draft', 'readonly': Eval('state') != 'draft',
}, depends=['state']) }, depends=['state'])
company_vat = fields.Char('VAT', size=9, states={ company_vat = fields.Char('VAT', size=9,
states={
'required': Eval('state').in_(['confirmed', 'done']), 'required': Eval('state').in_(['confirmed', 'done']),
'readonly': ~Eval('state').in_(['draft', 'confirmed']), 'readonly': ~Eval('state').in_(['draft', 'confirmed']),
}, depends=['state']) },
depends=['state'])
currency = fields.Function(fields.Many2One('currency.currency', currency = fields.Function(fields.Many2One('currency.currency',
'Currency'), 'on_change_with_currency') 'Currency'), 'on_change_with_currency')
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year', fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
@ -275,21 +278,21 @@ class SIIReport(Workflow, ModelSQL, ModelView):
('done', 'Done'), ('done', 'Done'),
('cancelled', 'Cancelled'), ('cancelled', 'Cancelled'),
('sent', 'Sent'), ('sent', 'Sent'),
], 'State', readonly=True) ], 'State', readonly=True)
communication_state = fields.Selection(AEAT_COMMUNICATION_STATE, communication_state = fields.Selection(AEAT_COMMUNICATION_STATE,
'Communication State', readonly=True) 'Communication State', readonly=True)
csv = fields.Char('CSV', readonly=True) csv = fields.Char('CSV', readonly=True)
version = fields.Selection([ version = fields.Selection([
('0.7', '0.7'), ('0.7', '0.7'),
('1.0', '1.0'), ('1.0', '1.0'),
], 'Version', required=True, ], 'Version', required=True,
states={ states={
'readonly': Eval('state') != 'draft', 'readonly': Eval('state') != 'draft',
}, },
depends=['state']) depends=['state'])
lines = fields.One2Many('aeat.sii.report.lines', 'report', lines = fields.One2Many('aeat.sii.report.lines', 'report',
'Lines', states={ 'Lines', states={
'readonly': Eval('state') != 'draft', 'readonly': Eval('state') != 'draft',
}, depends=['state']) }, depends=['state'])
# TODO crash GTK client 4.x with widget date in XML view and attribute # TODO crash GTK client 4.x with widget date in XML view and attribute
# readonly = True. At the moment, use PYSON to readonly field in XML views. # readonly = True. At the moment, use PYSON to readonly field in XML views.
@ -567,8 +570,10 @@ class SIIReport(Workflow, ModelSQL, ModelView):
base=_decimal(detail.BaseImponible), base=_decimal(detail.BaseImponible),
rate=_decimal(detail.TipoImpositivo), rate=_decimal(detail.TipoImpositivo),
amount=_decimal(detail.CuotaRepercutida), amount=_decimal(detail.CuotaRepercutida),
surcharge_rate=_decimal(detail.TipoRecargoEquivalencia), surcharge_rate=_decimal(
surcharge_amount=_decimal(detail.CuotaRecargoEquivalencia), detail.TipoRecargoEquivalencia),
surcharge_amount=_decimal(
detail.CuotaRecargoEquivalencia),
) )
for detail in reg.DatosFacturaEmitida.TipoDesglose. for detail in reg.DatosFacturaEmitida.TipoDesglose.
DesgloseFactura.Sujeta.NoExenta.DesgloseIVA.DetalleIVA DesgloseFactura.Sujeta.NoExenta.DesgloseIVA.DetalleIVA
@ -706,10 +711,13 @@ class SIIReport(Workflow, ModelSQL, ModelView):
base=_decimal(detail.BaseImponible), base=_decimal(detail.BaseImponible),
rate=_decimal(detail.TipoImpositivo), rate=_decimal(detail.TipoImpositivo),
amount=_decimal(detail.CuotaSoportada), amount=_decimal(detail.CuotaSoportada),
surcharge_rate=_decimal(detail.TipoRecargoEquivalencia), surcharge_rate=_decimal(
surcharge_amount=_decimal(detail.CuotaRecargoEquivalencia), detail.TipoRecargoEquivalencia),
surcharge_amount=_decimal(
detail.CuotaRecargoEquivalencia),
reagyp_rate=_decimal(detail.PorcentCompensacionREAGYP), reagyp_rate=_decimal(detail.PorcentCompensacionREAGYP),
reagyp_amount=_decimal(detail.ImporteCompensacionREAGYP), reagyp_amount=_decimal(
detail.ImporteCompensacionREAGYP),
) )
for detail in reg.DatosFacturaRecibida. for detail in reg.DatosFacturaRecibida.
DesgloseFactura.DesgloseIVA.DetalleIVA DesgloseFactura.DesgloseIVA.DetalleIVA

View File

@ -3,9 +3,10 @@
from decimal import Decimal from decimal import Decimal
from trytond.model import ModelView, fields from trytond.model import ModelView, fields
from trytond.pool import Pool, PoolMeta from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval from trytond.pyson import Eval, Bool
from trytond.transaction import Transaction from trytond.transaction import Transaction
from sql import Null
from sql.aggregate import Max from sql.aggregate import Max
from .aeat import ( from .aeat import (
@ -35,7 +36,7 @@ class Invoice:
sii_received_key = fields.Selection(RECEIVE_SPECIAL_REGIME_KEY, sii_received_key = fields.Selection(RECEIVE_SPECIAL_REGIME_KEY,
'SII Recived Key', 'SII Recived Key',
states={ states={
'invisible': ~Eval('sii_book_key').in_(['R']), 'invisible': ~Eval('sii_book_key').in_(['R']),
}, depends=['sii_book_key']) }, depends=['sii_book_key'])
sii_subjected_key = fields.Selection(IVA_SUBJECTED, 'Subjected') sii_subjected_key = fields.Selection(IVA_SUBJECTED, 'Subjected')
sii_excemption_key = fields.Selection(EXCEMPTION_CAUSE, sii_excemption_key = fields.Selection(EXCEMPTION_CAUSE,
@ -62,7 +63,7 @@ class Invoice:
cls._check_modify_exclude += sii_fields cls._check_modify_exclude += sii_fields
cls._buttons.update({ cls._buttons.update({
'reset_sii_keys': { 'reset_sii_keys': {
'invisible': Eval('sii_state', None) != None, 'invisible': Bool(Eval('sii_state', None)),
'icon': 'tryton-executable'} 'icon': 'tryton-executable'}
}) })
if hasattr(cls, '_intercompany_excluded_fields'): if hasattr(cls, '_intercompany_excluded_fields'):
@ -101,16 +102,17 @@ class Invoice:
c.remove(None) c.remove(None)
c0 = [] c0 = []
if clause[-1] == None or is_none: if clause[-1] is None or is_none:
c0 = [('id', 'not in', invoices)] c0 = [('id', 'not in', invoices)]
clause2 = [tuple(('state',)) + tuple(clause[1:])] + \ clause2 = [tuple(('state',)) + tuple(clause[1:]),
[('id', 'in', lines)] ('id', 'in', lines)]
res_lines = SIILines.search(clause2) res_lines = SIILines.search(clause2)
if is_none: if is_none:
return ['OR', c0, [('id', 'in', [x.invoice.id for x in res_lines])]] return ['OR', c0, [
('id', 'in', [x.invoice.id for x in res_lines])]]
else: else:
return [('id', 'in', [x.invoice.id for x in res_lines])] return [('id', 'in', [x.invoice.id for x in res_lines])]
@ -132,7 +134,7 @@ class Invoice:
cursor.execute(*table.select(Max(table.id), table.invoice, cursor.execute(*table.select(Max(table.id), table.invoice,
where=(table.invoice.in_([x.id for x in invoices]) & where=(table.invoice.in_([x.id for x in invoices]) &
(table.state != None)), (table.state != Null)),
group_by=table.invoice)) group_by=table.invoice))
lines = [a[0] for a in cursor.fetchall()] lines = [a[0] for a in cursor.fetchall()]
@ -140,7 +142,7 @@ class Invoice:
if lines: if lines:
cursor.execute(*join.select(table.state, report.operation_type, cursor.execute(*join.select(table.state, report.operation_type,
table.invoice, table.invoice,
where=((table.id.in_(lines)) & (table.state != None) & where=((table.id.in_(lines)) & (table.state != Null) &
(table.company == report.company)))) (table.company == report.company))))
for state, op, inv in cursor.fetchall(): for state, op, inv in cursor.fetchall():

View File

@ -4,17 +4,21 @@
from setuptools import setup from setuptools import setup
import re import re
import os import os
import ConfigParser import io
try:
from configparser import ConfigParser
except ImportError:
from ConfigParser import ConfigParser
MODULE = 'aeat_sii' MODULE = 'aeat_sii'
PREFIX = 'trytonspain' PREFIX = 'trytonspain'
MODULE2PREFIX = { MODULE2PREFIX = {}
'account_es': 'trytonspain'
}
def read(fname): def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read() return io.open(
os.path.join(os.path.dirname(__file__), fname),
'r', encoding='utf-8').read()
def get_require_version(name): def get_require_version(name):
@ -26,7 +30,7 @@ def get_require_version(name):
major_version, minor_version + 1) major_version, minor_version + 1)
return require return require
config = ConfigParser.ConfigParser() config = ConfigParser()
config.readfp(open('tryton.cfg')) config.readfp(open('tryton.cfg'))
info = dict(config.items('tryton')) info = dict(config.items('tryton'))
for key in ('depends', 'extras_depend', 'xml'): for key in ('depends', 'extras_depend', 'xml'):
@ -41,17 +45,20 @@ minor_version = int(minor_version)
requires = [ requires = [
'cryptography', 'cryptography',
'pyOpenSSL', 'pyOpenSSL',
'pyAEATsii>=0.2.4' 'pyAEATsii>=0.2.4',
] 'python-sql',
]
for dep in info.get('depends', []): for dep in info.get('depends', []):
if not re.match(r'(ir|res|webdav)(\W|$)', dep): if not re.match(r'(ir|res)(\W|$)', dep):
prefix = MODULE2PREFIX.get(dep, 'trytond') prefix = MODULE2PREFIX.get(dep, 'trytond')
requires.append('%s_%s >= %s.%s, < %s.%s' % requires.append(get_require_version('%s_%s' % (prefix, dep)))
(prefix, dep, major_version, minor_version,
major_version, minor_version + 1))
requires.append(get_require_version('trytond')) requires.append(get_require_version('trytond'))
tests_require = [get_require_version('proteus')] tests_require = [get_require_version('proteus')]
dependency_links = []
if minor_version % 2:
# Add development index for testing with proteus
dependency_links.append('https://trydevpi.tryton.org/')
setup(name='%s_%s' % (PREFIX, MODULE), setup(name='%s_%s' % (PREFIX, MODULE),
version=version, version=version,
@ -68,7 +75,7 @@ setup(name='%s_%s' % (PREFIX, MODULE),
], ],
package_data={ package_data={
'trytond.modules.%s' % MODULE: (info.get('xml', []) 'trytond.modules.%s' % MODULE: (info.get('xml', [])
+ ['tryton.cfg', 'locale/*.po', 'tests/*.rst', 'view/*.xml']), + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst']),
}, },
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
@ -88,12 +95,17 @@ setup(name='%s_%s' % (PREFIX, MODULE),
'Natural Language :: Russian', 'Natural Language :: Russian',
'Natural Language :: Spanish', 'Natural Language :: Spanish',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Office/Business', 'Topic :: Office/Business',
], ],
license='GPL-3', license='GPL-3',
install_requires=requires, install_requires=requires,
dependency_links=dependency_links,
zip_safe=False, zip_safe=False,
entry_points=""" entry_points="""
[trytond.modules] [trytond.modules]
@ -102,4 +114,8 @@ setup(name='%s_%s' % (PREFIX, MODULE),
test_suite='tests', test_suite='tests',
test_loader='trytond.test_loader:Loader', test_loader='trytond.test_loader:Loader',
tests_require=tests_require, tests_require=tests_require,
use_2to3=True,
convert_2to3_doctests=[
'tests/scenario_aeat_sii.rst',
],
) )

View File

@ -1,3 +1,8 @@
# The COPYRIGHT file at the top level of this repository contains the full # The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms. # copyright notices and license terms.
from .test_aeat_sii import suite try:
from trytond.modules.aeat_sii.tests.test_aeat_sii import suite
except ImportError:
from .test_aeat_sii import suite
__all__ = ['suite']

View File

@ -13,15 +13,10 @@ Imports::
... get_company ... get_company
>>> from trytond.modules.account.tests.tools import create_fiscalyear, \ >>> from trytond.modules.account.tests.tools import create_fiscalyear, \
... create_chart, get_accounts, create_tax, set_tax_code ... create_chart, get_accounts, create_tax, set_tax_code
>>> from.trytond.modules.account_invoice.tests.tools import \ >>> from trytond.modules.account_invoice.tests.tools import \
... set_fiscalyear_invoice_sequences ... set_fiscalyear_invoice_sequences
>>> today = datetime.date.today() >>> today = datetime.date.today()
Create database::
>>> config = config.set_trytond()
>>> config.pool.test = True
Install account_sii:: Install account_sii::
>>> config = activate_modules('aeat_sii') >>> config = activate_modules('aeat_sii')

View File

@ -3,18 +3,18 @@
# copyright notices and license terms. # copyright notices and license terms.
import unicodedata import unicodedata
src_chars = """"/*+?¿!$[]{}@#`^:;<>=~%\\""" src_chars = u"/*+?¿!$[]{}@#`^:;<>=~%\\"
src_chars = unicode(src_chars, 'iso-8859-1') dst_chars = u"________________________"
dst_chars = """________________________"""
dst_chars = unicode(dst_chars, 'iso-8859-1')
def normalize(text): def normalize(text):
if isinstance(text, unicode): if isinstance(text, unicode):
text = text.encode('utf-8') text = text.encode('utf-8')
return text return text
def unaccent(text): def unaccent(text):
if isinstance(text, str): if isinstance(text, bytes):
text = unicode(text, 'utf-8') text = unicode(text, 'utf-8')
output = text output = text
for c in xrange(len(src_chars)): for c in xrange(len(src_chars)):

18
tox.ini Normal file
View File

@ -0,0 +1,18 @@
[tox]
envlist = {py27,py34,py35,py36}-{sqlite,postgresql,mysql},pypy-{sqlite,postgresql}
[testenv]
commands = {envpython} setup.py test
deps =
{py27,py34,py35,py36}-postgresql: psycopg2 >= 2.5
pypy-postgresql: psycopg2cffi >= 2.5
mysql: MySQL-python
sqlite: sqlitebck
setenv =
sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
mysql: TRYTOND_DATABASE_URI={env:MYSQL_URI:mysql://}
sqlite: DB_NAME={env:SQLITE_NAME::memory:}
postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
mysql: DB_NAME={env:MYSQL_NAME:test}
install_command = pip install --pre --process-dependency-links {opts} {packages}

View File

@ -1,5 +1,5 @@
[tryton] [tryton]
version=4.3.0 version=4.7.0
depends: depends:
account_invoice account_invoice
extras_depend: extras_depend: