Update to 4.7
This commit is contained in:
parent
d06f9affa6
commit
325df0acd8
|
@ -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
|
13
account.py
13
account.py
|
@ -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
112
aeat.py
|
@ -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
|
||||||
|
|
20
invoice.py
20
invoice.py
|
@ -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():
|
||||||
|
|
44
setup.py
44
setup.py
|
@ -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',
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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')
|
||||||
|
|
10
tools.py
10
tools.py
|
@ -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)):
|
||||||
|
|
|
@ -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}
|
|
@ -1,5 +1,5 @@
|
||||||
[tryton]
|
[tryton]
|
||||||
version=4.3.0
|
version=4.7.0
|
||||||
depends:
|
depends:
|
||||||
account_invoice
|
account_invoice
|
||||||
extras_depend:
|
extras_depend:
|
||||||
|
|
Loading…
Reference in New Issue