Delete issued invoices from SII
This commit is contained in:
parent
c1ac4ed2f1
commit
16d275f83b
75
aeat.py
75
aeat.py
|
@ -10,6 +10,7 @@ __all__ = [
|
|||
import unicodedata
|
||||
from logging import getLogger
|
||||
from decimal import Decimal
|
||||
from operator import attrgetter
|
||||
|
||||
from trytond.model import ModelSQL, ModelView, fields, Workflow
|
||||
from trytond.pyson import Eval
|
||||
|
@ -124,6 +125,7 @@ AEAT_INVOICE_STATE = [
|
|||
('Correcto', 'Accepted'),
|
||||
('AceptadoConErrores', 'Accepted with Errors'),
|
||||
('AceptadaConErrores', 'Accepted with Errors'), # Shame on AEAT
|
||||
('Anulada', 'Deleted'),
|
||||
('Incorrecto', 'Rejected')
|
||||
]
|
||||
|
||||
|
@ -356,6 +358,8 @@ class SIIReport(Workflow, ModelSQL, ModelView):
|
|||
report.submit_issued_invoices()
|
||||
elif report.operation_type == 'C0': # query invoices
|
||||
report.query_issued_invoices()
|
||||
elif report.operation_type == 'D0': # delete invoices
|
||||
report.delete_issued_invoices()
|
||||
else:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
|
@ -398,15 +402,13 @@ class SIIReport(Workflow, ModelSQL, ModelView):
|
|||
|
||||
def submit_issued_invoices(self):
|
||||
_logger.info('Sending report %s to AEAT SII', self.id)
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
Invoice = pool.get('account.invoice')
|
||||
company = Company(Transaction().context.get('company'))
|
||||
headers = mapping.get_headers(
|
||||
name=company.party.name, vat=company.party.vat_number,
|
||||
name=self.company.party.name,
|
||||
vat=self.company.party.vat_number,
|
||||
comm_kind=self.operation_type)
|
||||
invoices = Invoice.map_to_aeat_sii(
|
||||
line.invoice for line in self.lines)
|
||||
invoices = map(
|
||||
IssuedTrytonInvoiceMapper.build_submit_request,
|
||||
(line.invoice for line in self.lines))
|
||||
res = None
|
||||
with self.company.tmp_ssl_credentials() as (crt, key):
|
||||
srv = service.bind_SuministroFactEmitidas(crt, key, test=True)
|
||||
|
@ -415,12 +417,34 @@ class SIIReport(Workflow, ModelSQL, ModelView):
|
|||
for (report_line, response_line) in zip(
|
||||
self.lines, res.RespuestaLinea):
|
||||
report_line.write([report_line], {
|
||||
'state':
|
||||
response_line.EstadoRegistro,
|
||||
'communication_code':
|
||||
response_line.CodigoErrorRegistro,
|
||||
'communication_msg':
|
||||
response_line.DescripcionErrorRegistro,
|
||||
'state': response_line.EstadoRegistro,
|
||||
'communication_code': response_line.CodigoErrorRegistro,
|
||||
'communication_msg': response_line.DescripcionErrorRegistro,
|
||||
})
|
||||
self.write([self], {
|
||||
'communication_state': res.EstadoEnvio,
|
||||
'csv': res.CSV,
|
||||
})
|
||||
|
||||
def delete_issued_invoices(self):
|
||||
headers = mapping.get_headers(
|
||||
name=self.company.party.name,
|
||||
vat=self.company.party.vat_number,
|
||||
comm_kind=self.operation_type)
|
||||
invoices = map(
|
||||
IssuedTrytonInvoiceMapper.build_delete_request,
|
||||
(line.invoice for line in self.lines))
|
||||
res = None
|
||||
with self.company.tmp_ssl_credentials() as (crt, key):
|
||||
srv = service.bind_SuministroFactEmitidas(crt, key, test=True)
|
||||
res = srv.AnulacionLRFacturasEmitidas(headers, invoices)
|
||||
# TODO: assert response order matches report order
|
||||
for (report_line, response_line) in zip(
|
||||
self.lines, res.RespuestaLinea):
|
||||
report_line.write([report_line], {
|
||||
'state': response_line.EstadoRegistro,
|
||||
'communication_code': response_line.CodigoErrorRegistro,
|
||||
'communication_msg': response_line.DescripcionErrorRegistro,
|
||||
})
|
||||
self.write([self], {
|
||||
'communication_state': res.EstadoEnvio,
|
||||
|
@ -430,11 +454,10 @@ class SIIReport(Workflow, ModelSQL, ModelView):
|
|||
def query_issued_invoices(self):
|
||||
res = None
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
Invoice = pool.get('account.invoice')
|
||||
company = Company(Transaction().context.get('company'))
|
||||
headers = mapping.get_headers(
|
||||
name=company.party.name, vat=company.party.vat_number,
|
||||
name=self.company.party.name,
|
||||
vat=self.company.party.vat_number,
|
||||
comm_kind=self.operation_type)
|
||||
filter_ = {
|
||||
'PeriodoImpositivo': {
|
||||
|
@ -484,6 +507,26 @@ class SIIReport(Workflow, ModelSQL, ModelView):
|
|||
})
|
||||
|
||||
|
||||
class IssuedTrytonInvoiceMapper(mapping.OutInvoiceMapper):
|
||||
year = attrgetter('move.period.fiscalyear.name')
|
||||
period = attrgetter('move.period.start_date.month')
|
||||
nif = attrgetter('company.party.vat_number')
|
||||
serial_number = attrgetter('number')
|
||||
issue_date = attrgetter('invoice_date')
|
||||
invoice_kind = attrgetter('sii_operation_key')
|
||||
specialkey_or_trascendence = attrgetter('sii_issued_key')
|
||||
description = attrgetter('description')
|
||||
not_exempt_kind = attrgetter('sii_subjected')
|
||||
counterpart_name = attrgetter('party.name')
|
||||
counterpart_nif = attrgetter('party.vat_number')
|
||||
counterpart_id_type = attrgetter('party.identifier_type')
|
||||
counterpart_country = attrgetter('party.vat_country')
|
||||
taxes = attrgetter('taxes')
|
||||
tax_rate = attrgetter('tax.rate')
|
||||
tax_base = attrgetter('base')
|
||||
tax_amount = attrgetter('amount')
|
||||
|
||||
|
||||
class SIIReportLine(ModelSQL, ModelView):
|
||||
'''
|
||||
AEAT SII Issued
|
||||
|
|
47
invoice.py
47
invoice.py
|
@ -1,24 +1,22 @@
|
|||
# The COPYRIGHT file at the top level of this repository contains the full
|
||||
# copyright notices and license terms.
|
||||
|
||||
from operator import attrgetter
|
||||
|
||||
from trytond import backend
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from trytond.model import ModelView, fields
|
||||
from trytond.wizard import Wizard, StateView, StateTransition, Button
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval, And, Bool
|
||||
from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
from sql.operators import In
|
||||
from sql.aggregate import Max
|
||||
from .aeat import (OPERATION_KEY, BOOK_KEY, SEND_SPECIAL_REGIME_KEY,
|
||||
RECEIVE_SPECIAL_REGIME_KEY, AEAT_INVOICE_STATE, IVA_SUBJECTED,
|
||||
EXCEMPTION_CAUSE, 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)
|
||||
|
||||
from .pyAEATsii import mapping
|
||||
|
||||
__all__ = ['Invoice', 'ReasignSIIRecord', 'ReasignSIIRecordStart',
|
||||
'ReasignSIIRecordEnd']
|
||||
__all__ = [
|
||||
'Invoice', 'ReasignSIIRecord', 'ReasignSIIRecordStart',
|
||||
'ReasignSIIRecordEnd'
|
||||
]
|
||||
|
||||
|
||||
class Invoice:
|
||||
|
@ -112,31 +110,6 @@ class Invoice:
|
|||
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def map_to_aeat_sii(cls, invoices):
|
||||
mapper = IssuedTrytonInvoiceMapper()
|
||||
return map(mapper.build_request, invoices)
|
||||
|
||||
|
||||
class IssuedTrytonInvoiceMapper(mapping.OutInvoiceMapper):
|
||||
year = attrgetter('move.period.fiscalyear.name')
|
||||
period = attrgetter('move.period.start_date.month')
|
||||
nif = attrgetter('company.party.vat_number')
|
||||
serial_number = attrgetter('number')
|
||||
issue_date = attrgetter('invoice_date')
|
||||
invoice_kind = attrgetter('sii_operation_key')
|
||||
specialkey_or_trascendence = attrgetter('sii_issued_key')
|
||||
description = attrgetter('description')
|
||||
not_exempt_kind = attrgetter('sii_subjected')
|
||||
counterpart_name = attrgetter('party.name')
|
||||
counterpart_nif = attrgetter('party.vat_number')
|
||||
counterpart_id_type = attrgetter('party.identifier_type')
|
||||
counterpart_country = attrgetter('party.vat_country')
|
||||
taxes = attrgetter('taxes')
|
||||
tax_rate = attrgetter('tax.rate')
|
||||
tax_base = attrgetter('base')
|
||||
tax_amount = attrgetter('amount')
|
||||
|
||||
|
||||
class ReasignSIIRecordStart(ModelView):
|
||||
"""
|
||||
|
|
|
@ -19,13 +19,18 @@ def get_headers(name=None, vat=None, comm_kind=None, version='0.7'):
|
|||
class OutInvoiceMapper(object):
|
||||
|
||||
@classmethod
|
||||
def build_request(cls, invoice):
|
||||
def build_delete_request(cls, invoice):
|
||||
return {
|
||||
'PeriodoImpositivo': cls.build_period(invoice),
|
||||
'IDFactura': cls.build_invoice_id(invoice),
|
||||
'FacturaExpedida': cls.build_issued_invoice(invoice),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def build_submit_request(cls, invoice):
|
||||
request = cls.build_delete_request(invoice)
|
||||
request['FacturaExpedida'] = cls.build_issued_invoice(invoice)
|
||||
return request
|
||||
|
||||
@classmethod
|
||||
def build_period(cls, invoice):
|
||||
return {
|
||||
|
|
Loading…
Reference in New Issue