Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 6 additions & 43 deletions l10n_es_verifactu/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ def _get_verifactu_invoice_dict_out(self, cancel=False):
"Huella": self.verifactu_hash,
}
)
if self.verifactu_send_state in ["incorrect", "accepted_with_errors"]:
if self.aeat_state == "sent_w_errors":
# en caso de subsanación, debe generar un nuevo hash en la factura
inv_dict.update(
{
"Subsanacion": "S",
Expand Down Expand Up @@ -526,7 +527,7 @@ def _get_verifactu_qr_values(self):
def _post(self, soft=True):
res = super()._post(soft=soft)
for record in self:
if record.verifactu_enabled and record.verifactu_send_state == "not_sent":
if record.verifactu_enabled and record.aeat_state == "not_sent":
record._check_verifactu_configuration()
record.verifactu_registration_date = datetime.now()
record._generate_verifactu_chaining()
Expand Down Expand Up @@ -636,7 +637,7 @@ def cancel_verifactu(self):

def write(self, vals):
for invoice in self.filtered(
lambda x: x.is_invoice() and x.verifactu_send_state != "not_sent"
lambda x: x.is_invoice() and x.aeat_state != "not_sent"
):
if invoice.move_type in ["out_invoice", "out_refund"]:
if "invoice_date" in vals:
Expand All @@ -647,60 +648,22 @@ def write(self, vals):
self._raise_exception_verifactu(_("invoice number"))
return super().write(vals)

def _compute_verifactu_send_state(self):
for rec in self:
rec.verifactu_send_state = "not_sent"
# Check the state from the last
send_queue = (
rec.verifactu_send_queue_ids
and rec.verifactu_send_queue_ids[0]
or False
)
if send_queue:
rec.verifactu_send_state = send_queue.send_state

def button_cancel(self):
invoices_sent = self.filtered(
lambda inv: inv.verifactu_enabled and inv.verifactu_send_state != "not_sent"
lambda inv: inv.verifactu_enabled and inv.aeat_state != "not_sent"
)
if invoices_sent:
raise UserError(_("You can not cancel invoices sent to verifactu"))
return super().button_cancel()

def button_draft(self):
invoices_sent = self.filtered(
lambda inv: inv.verifactu_enabled and inv.verifactu_send_state != "not_sent"
lambda inv: inv.verifactu_enabled and inv.aeat_state != "not_sent"
)
if invoices_sent:
raise UserError(_("You can not set to draft invoices sent to verifactu"))
return super().button_draft()

def _compute_verifactu_csv(self):
for rec in self:
rec.verifactu_csv = ""
# Check the state from the last
send_queue = (
rec.verifactu_send_queue_ids
and rec.verifactu_send_queue_ids[0]
or False
)
if send_queue:
last_response = send_queue.response_ids and send_queue.response_ids[0]
rec.verifactu_csv = last_response.verifactu_csv

def _search_verifactu_send_state(self, operator, value):
queue_recs = self.env["verifactu.send.queue"].search(
[
("send_state", operator, value),
("move_id", "!=", False),
]
)
if (operator == "=" and value) or (operator == "!=" and not value):
new_operator = "in"
else:
new_operator = "not in"
return [("id", new_operator, queue_recs.mapped("move_id").ids)]

def resend_verifactu(self):
for rec in self:
rec.verifactu_send_queue_ids.write({"correction": True})
67 changes: 2 additions & 65 deletions l10n_es_verifactu/models/verifactu_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@
qrcode = None
_logger.error(err)

VERIFACTU_SEND_STATES = [
("not_sent", "Not sent"),
("correct", "Sent and Correct"),
("incorrect", "Sent and Incorrect"),
("accepted_with_errors", "Sent and accepted with errors"),
]

###########################################
# revisar los imports que no hagan falta
# cuando funcione bien el _connect_aeat sin tener que poner
Expand All @@ -44,6 +37,7 @@

class VerifactuMixin(models.AbstractModel):
_name = "verifactu.mixin"
_inherit = "aeat.mixin"
_description = "Verifactu Mixin"

verifactu_enabled = fields.Boolean(
Expand Down Expand Up @@ -71,6 +65,7 @@ class VerifactuMixin(models.AbstractModel):
"greater o equal to 100 000 000,00 euros.",
compute="_compute_verifactu_macrodata",
)
verifactu_csv = fields.Char(copy=False, readonly=True)
verifactu_return = fields.Text(copy=False, readonly=True)
verifactu_registration_date = fields.Datetime(copy=False)
verifactu_registration_key = fields.Many2one(
Expand Down Expand Up @@ -98,32 +93,6 @@ class VerifactuMixin(models.AbstractModel):
copy=False,
)
verifactu_send_date = fields.Datetime(index=True, copy=False)
verifactu_send_state = fields.Selection(
selection=VERIFACTU_SEND_STATES,
string="Verifactu send state",
compute="_compute_verifactu_send_state",
search="_search_verifactu_send_state",
readonly=True,
copy=False,
help="Indicates the state of this document in relation with the "
"presentation to Verifactu.",
)
verifactu_csv = fields.Char(
string="Verifactu CSV",
compute="_compute_verifactu_csv",
readonly=True,
copy=False,
help="Indicates the CSV of the latest verifactu response.",
)

def _compute_verifactu_send_state(self):
raise NotImplementedError

def _search_verifactu_send_state(self, operator, value):
raise NotImplementedError

def _compute_verifactu_csv(self):
raise NotImplementedError

@api.model
def _selection_verifactu_reference_models(self):
Expand Down Expand Up @@ -219,38 +188,6 @@ def _connect_verifactu_params_aeat(self, mapping_key):
agency = self.env.ref("l10n_es_aeat.aeat_tax_agency_spain")
return agency._connect_params_verifactu(self.company_id)

def _get_verifactu_aeat_header(self, tipo_comunicacion=False, cancellation=False):
"""Builds VERIFACTU send header

:param tipo_comunicacion String 'A0': new reg, 'A1': modification
:param cancellation Bool True when the communitacion es for document
cancellation
:return Dict with header data depending on cancellation
"""
self.ensure_one()
if not self.company_id.vat:
raise UserError(
_("No VAT configured for the company '{}'").format(self.company_id.name)
)
header = {
"ObligadoEmision": {
"NombreRazon": self.company_id.name[0:120],
"NIF": self.company_id.partner_id._parse_aeat_vat_info()[2],
},
}
registration_date = self.verifactu_registration_date
# Si han pasado más de 120 segundos de la fecha y hora de emisión de la factura
# devuelve error 2004: El valor del campo FechaHoraHusoGenRegistro debe ser
# la fecha actual del sistema de la AEAT.
# Debe enviarse como incidencia
if (
self.verifactu_send_state == "incorrect"
and registration_date < fields.Datetime.now()
and self.aeat_send_error[:4] == "2004"
):
header.update({"RemisionVoluntaria": {"Incidencia": "S"}})
return header

def _get_verifactu_invoice_dict(self):
self.ensure_one()
inv_dict = {}
Expand Down
34 changes: 32 additions & 2 deletions l10n_es_verifactu/models/verifactu_send_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,48 @@ def _send_documents_to_verifactu(self):
[("move_id", "=", invoice.id)], limit=1
)
send_queue.correction = False
estadoregistro = linea["EstadoRegistro"]
estado_registro = linea["EstadoRegistro"]
self.env["verifactu.send.response.line"].sudo().create(
{
"send_queue_id": send_queue.id,
"response": linea,
"send_response_id": response.id,
"send_state": VERIFACTU_STATE_MAPPING[estadoregistro],
"send_state": VERIFACTU_STATE_MAPPING[estado_registro],
"error_code": "CodigoErrorRegistro" in linea
and str(linea["CodigoErrorRegistro"])
or "",
}
)
doc_vals = {
"aeat_header_sent": json.dumps(header, indent=4),
}
if estado_registro == "Correcto":
doc_vals.update(
{
"aeat_state": "sent",
"verifactu_csv": res["CSV"],
"aeat_send_failed": False,
}
)
elif estado_registro == "AceptadoConErrores":
doc_vals.update(
{
"aeat_state": "sent_w_errors",
"verifactu_csv": res["CSV"],
"aeat_send_failed": True,
}
)
else:
doc_vals["aeat_send_failed"] = True
doc_vals["verifactu_return"] = linea
send_error = False
if linea["CodigoErrorRegistro"]:
send_error = "{} | {}".format(
str(linea["CodigoErrorRegistro"]),
str(linea["DescripcionErrorRegistro"]),
)
doc_vals["aeat_send_error"] = send_error
send_queue.move_id.write(doc_vals)
return True

@api.depends("response_ids", "response_ids.send_state")
Expand Down
68 changes: 50 additions & 18 deletions l10n_es_verifactu/views/account_move_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
string="Re-send to Verifactu"
name="resend_verifactu"
groups="l10n_es_aeat.group_account_aeat"
attrs="{'invisible': ['|','|',('verifactu_enabled', '=', False), ('state', 'not in', ['posted']), ('verifactu_send_state','not in',['incorrect','accepted_with_errors'])]}"
attrs="{'invisible': ['|','|',('verifactu_enabled', '=', False), ('state', 'not in', ['posted']), ('aeat_state','not in',['sent','sent_w_errors'])]}"
/>
</button>
<notebook position="inside">
Expand All @@ -28,7 +28,7 @@
name="group_aeat_information"
>
<field name="verifactu_enabled" invisible="0" readonly="1" />
<field name="verifactu_send_state" invisible="1" />
<field name="aeat_state" invisible="1" />
<field name="verifactu_description" />
<field
name="verifactu_refund_type"
Expand All @@ -41,11 +41,11 @@
/>
<field
name="verifactu_tax_key"
attrs="{'required': [('verifactu_enabled', '=', True)], 'readonly': [('verifactu_send_state', 'in', ['correct', 'accepted_with_errors'])]}"
attrs="{'required': [('verifactu_enabled', '=', True)], 'readonly': [('aeat_state', '=', 'sent')]}"
/>
<field
name="verifactu_registration_key"
attrs="{'required': [('verifactu_enabled', '=', True)], 'readonly': [('verifactu_send_state', '=', ['correct', 'accepted_with_errors'])]}"
attrs="{'required': [('verifactu_enabled', '=', True)], 'readonly': [('aeat_state', '=', 'sent')]}"
/>
<field
name="verifactu_hash_string"
Expand Down Expand Up @@ -75,15 +75,31 @@
<notebook colspan="2">
<page name="page_aeat_result_general" string="General">
<group>
<field name="verifactu_send_state" />
<field name="aeat_state" />
<field name="verifactu_csv" />
<field
name="aeat_send_failed"
attrs="{'invisible': [('aeat_send_failed', '=', False)]}"
/>
<field
name="aeat_send_error"
attrs="{'invisible': [('aeat_send_failed', '=', False)]}"
/>
</group>
</page>
<page
name="page_aeat_result_technical"
string="Technical"
groups="base.group_no_one"
>
<group>
<label for="aeat_header_sent" />
</group>
<field name="aeat_header_sent" />
<group>
<label for="aeat_content_sent" />
</group>
<field name="aeat_content_sent" />
<group>
<label for="verifactu_send_response_ids" />
</group>
Expand Down Expand Up @@ -113,30 +129,46 @@
<filter
name="verifactu_not_sent"
string="Verifactu not sent"
domain="[('verifactu_send_state', '=', 'not_sent'), ('verifactu_enabled', '=', True)]"
domain="[('aeat_state', '=', 'not_sent'), ('verifactu_enabled', '=', True)]"
help="Never sent to Verifactu"
/>
<filter
name="verifactu_accepted"
string="Verifactu accepted"
domain="[('verifactu_send_state', '=', 'correct')]"
help="Already sent to Verifactu and accepted"
name="verifactu_pending"
string="With modifications not sent to Verifactu"
domain="[('aeat_state', 'in', ['sent_modified','cancelled_modified'])]"
help="Already sent but with local changes not sent yet"
/>
<filter
name="aeat_send_incorrect"
string="Verifactu Incorrect"
domain="[('verifactu_send_state', '=', 'incorrect')]"
help="The document was sent to Verifactu but it has been rejected"
name="verifactu_sent"
string="Verifactu sent"
domain="[('aeat_state', 'not in', ['not_sent'])]"
help="Already sent to Verifactu. It includes cancelled invoices"
/>
<filter
name="aeat_send_accepted_with_errors"
string="Verifactu Accepted with errors"
domain="[('verifactu_send_state', '=', 'accepted_with_errors')]"
help="The document was sent to Verifactu, it has been accepted but it has some errors"
name="aeat_send_failed"
string="Verifactu failed"
domain="[('aeat_send_failed', '=', True)]"
help="The last attemp to sent to Verifactu has failed"
/>
<separator />
<filter
name="verifactu_cancelled"
string="Verifactu cancelled"
domain="[('aeat_state', 'in', ['cancelled','cancelled_modified'])]"
help="Cancelled invoices at Verifactu"
/>
<separator />
</group>
</filter>
<xpath expr="//group" position="inside">
<separator />
<filter
string="Verifactu error"
name="verifactu_error"
domain="[('aeat_send_failed', '=', True)]"
context="{'group_by':'aeat_send_error'}"
/>
</xpath>
</field>
</record>
</odoo>
Loading