diff --git a/l10n_it_edi_related_document/models/account_move.py b/l10n_it_edi_related_document/models/account_move.py index 05dca65981e1..ac23358789eb 100644 --- a/l10n_it_edi_related_document/models/account_move.py +++ b/l10n_it_edi_related_document/models/account_move.py @@ -1,4 +1,5 @@ from odoo import api, fields, models +from odoo.exceptions import UserError from odoo.addons.l10n_it_edi.models.account_move import get_text @@ -58,7 +59,55 @@ def create(self, vals_list): ) if line: vals["invoice_line_id"] = line.id - return super().create(vals_list) + ret = super().create(vals_list) + # after creating documents, check if one should is eligible + # to become the standard_related_document_id + for record in ret.filtered( + lambda r: r.type == "order" + and r.invoice_id + and not r.invoice_id.standard_related_document_id + ): + invoice = record.invoice_id.with_context( + l10n_it_edi_related_loop_avoid=True + ) + invoice.standard_related_document_id = record + invoice.l10n_it_origin_document_type = "purchase_order" + invoice.l10n_it_origin_document_name = record.name + invoice.l10n_it_origin_document_date = record.date + invoice.l10n_it_cig = record.cig + record.invoice_id.l10n_it_cup = record.cup + + return ret + + def _l10n_it_sync_related_document(self): + for record in self: + if record == record.invoice_id.standard_related_document_id: + document_type = record.type + if document_type == "order": + document_type = "purchase_order" + elif document_type == "reception": + # unsupported type + record.invoice_id.standard_related_document_id = False + continue + elif document_type == "invoice": + # unsupported type + record.invoice_id.standard_related_document_id = False + continue + record.invoice_id.l10n_it_origin_document_type = document_type + record.invoice_id.l10n_it_origin_document_name = record.name + record.invoice_id.l10n_it_origin_document_date = record.date + record.invoice_id.l10n_it_cig = record.cig + record.invoice_id.l10n_it_cup = record.cup + + def write(self, vals): + ret = super().write(vals) + if self._context.get("l10n_it_edi_related_loop_avoid"): + return ret + if vals.keys() & {"type", "name", "date", "cig", "cup"}: + self.with_context( + l10n_it_edi_related_loop_avoid=True + )._l10n_it_sync_related_document() + return ret class AccountMove(models.Model): @@ -68,6 +117,80 @@ class AccountMove(models.Model): "account.move.related_document", "invoice_id", copy=False ) + standard_related_document_id = fields.Many2one( + comodel_name="account.move.related_document", + string="Standard Related Document", + help="Technical field to store the document corresponding to standard fields", + ) + + # override + l10n_it_origin_document_type = fields.Selection( + inverse="_inverse_original_related_document_fields" + ) + l10n_it_origin_document_name = fields.Char( + inverse="_inverse_original_related_document_fields" + ) + l10n_it_origin_document_date = fields.Date( + inverse="_inverse_original_related_document_fields" + ) + l10n_it_cig = fields.Char(inverse="_inverse_original_related_document_fields") + l10n_it_cup = fields.Char(inverse="_inverse_original_related_document_fields") + + def _inverse_original_related_document_fields(self): + for record in self: + if record._context.get("l10n_it_edi_related_loop_avoid"): + continue + if ( + not record.l10n_it_origin_document_type + or not record.l10n_it_origin_document_name + ): + if record.standard_related_document_id: + # deleted reference + record.related_document_ids = [ + fields.Command.unlink(record.standard_related_document_id.id) + ] + record.standard_related_document_id.unlink() + record.standard_related_document_id = False + continue + # type map + # purchase_order -> order + # contract -> contract + # agreement -> agreement + # ? -> reception + # ? -> invoice + document_type = record.l10n_it_origin_document_type + if document_type == "purchase_order": + document_type = "order" + + if ( + document_type + not in dict( + self.env["account.move.related_document"]._fields["type"].selection + ).keys() + ): + raise UserError( + self.env._("Unknown document type %s") % (document_type,) + ) + + vals = { + "type": document_type, + "name": self.l10n_it_origin_document_name, + "date": self.l10n_it_origin_document_date, + "cig": self.l10n_it_cig, + "cup": self.l10n_it_cup, + } + if not record.standard_related_document_id: + self.standard_related_document_id = self.env[ + "account.move.related_document" + ].create(vals) + self.related_document_ids = [ + fields.Command.link(self.standard_related_document_id.id) + ] + else: + self.standard_related_document_id.with_context( + l10n_it_edi_related_loop_avoid=True + ).update(vals) + def _l10n_it_edi_get_values(self, pdf_values=None): res = super()._l10n_it_edi_get_values(pdf_values=pdf_values) updated_values = self.remove_redundant_values(res) diff --git a/l10n_it_edi_related_document/tests/test_import_xml.py b/l10n_it_edi_related_document/tests/test_import_xml.py index e5bf78721834..d8a59708e140 100644 --- a/l10n_it_edi_related_document/tests/test_import_xml.py +++ b/l10n_it_edi_related_document/tests/test_import_xml.py @@ -31,3 +31,64 @@ def test_receive_vendor_bill(self): self.assertTrue( invoice.line_ids.filtered(lambda x: rcp_doc_type in x.related_document_ids) ) + + def test_standard_fields(self): + euro = self.setup_other_currency("EUR") + invoice = self.env["account.move"].create( + { + "move_type": "out_invoice", + "partner_id": self.partner_a.id, + "invoice_date": fields.Date.from_string("2016-01-01"), + "currency_id": euro.id, + "invoice_line_ids": [ + ( + 0, + None, + { + "product_id": self.product_a.id, + "quantity": 3, + "price_unit": 750, + }, + ), + ], + } + ) + + # add a document, via standard fields + # note: this must be an atomic write(), as both name and type are required + # fields and can't be assigned one a time + invoice.write( + { + "l10n_it_origin_document_name": "S00001", + "l10n_it_origin_document_type": "purchase_order", + "l10n_it_origin_document_date": invoice.invoice_date, + "l10n_it_cig": "CIG", + "l10n_it_cup": "CUP", + } + ) + self.assertEqual( + invoice.standard_related_document_id, invoice.related_document_ids[0] + ) + self.assertEqual(invoice.standard_related_document_id.type, "order") + self.assertEqual(invoice.standard_related_document_id.name, "S00001") + self.assertEqual( + invoice.standard_related_document_id.date, invoice.invoice_date + ) + self.assertEqual(invoice.standard_related_document_id.cig, "CIG") + self.assertEqual(invoice.standard_related_document_id.cup, "CUP") + + # alter the document + invoice.standard_related_document_id.name = "S00002" + invoice.standard_related_document_id.date = fields.Date.from_string( + "2016-01-02" + ) + invoice.standard_related_document_id.cig = "CIG2" + invoice.standard_related_document_id.cup = "CUP2" + + # check if standard fields changed accordingly + self.assertEqual(invoice.l10n_it_origin_document_name, "S00002") + self.assertEqual( + invoice.l10n_it_origin_document_date, fields.Date.from_string("2016-01-02") + ) + self.assertEqual(invoice.l10n_it_cig, "CIG2") + self.assertEqual(invoice.l10n_it_cup, "CUP2")