diff --git a/l10n_it_fatturapa_out/models/partner.py b/l10n_it_fatturapa_out/models/partner.py index 19cb4f972fef..bca0175481b3 100644 --- a/l10n_it_fatturapa_out/models/partner.py +++ b/l10n_it_fatturapa_out/models/partner.py @@ -1,4 +1,5 @@ # Copyright 2019 Roberto Fichera +# Copyright 2023 Simone Rubino - Aion Tech # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). from odoo import _, api, fields, models @@ -11,7 +12,10 @@ class ResPartner(models.Model): max_invoice_in_xml = fields.Integer( string="Max Invoice # in XML", default=lambda self: self.env.company.max_invoice_in_xml, - help="Maximum number of invoices to group in a single " "XML file. 0=Unlimited", + help="Maximum number of invoices to group in a single " + "XML file.\n" + "If this is 0, then the number configured " + "in the account settings is considered.", ) @api.constrains("max_invoice_in_xml") diff --git a/l10n_it_fatturapa_out/tests/fatturapa_common.py b/l10n_it_fatturapa_out/tests/fatturapa_common.py index 7bd084cabb72..d547713a79e1 100644 --- a/l10n_it_fatturapa_out/tests/fatturapa_common.py +++ b/l10n_it_fatturapa_out/tests/fatturapa_common.py @@ -1,3 +1,6 @@ +# Copyright 2023 Simone Rubino - Aion Tech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + import base64 import tempfile @@ -228,9 +231,17 @@ def set_sequences( seq_date = inv_seq._create_date_range_seq(dt) seq_date.number_next_actual = invoice_number - def run_wizard(self, invoice_id): + def run_wizard(self, invoice_ids): + """ + Execute the export wizard on the invoices having ID `invoice_ids`. + + :param invoice_ids: integer or list of integers + :return: result of export wizard + """ + if not isinstance(invoice_ids, list): + invoice_ids = [invoice_ids] wizard = self.wizard_model.create({}) - return wizard.with_context(active_ids=invoice_id).exportFatturaPA() + return wizard.with_context(active_ids=invoice_ids).exportFatturaPA() def set_e_invoice_file_id(self, e_invoice, file_name): # We need this because file name is random and we can't predict it diff --git a/l10n_it_fatturapa_out/tests/test_fatturapa_xml_validation.py b/l10n_it_fatturapa_out/tests/test_fatturapa_xml_validation.py index 325b82e5072c..8171c0ecd73a 100644 --- a/l10n_it_fatturapa_out/tests/test_fatturapa_xml_validation.py +++ b/l10n_it_fatturapa_out/tests/test_fatturapa_xml_validation.py @@ -1,7 +1,7 @@ # Copyright 2014 Davide Corio # Copyright 2015-2016 Lorenzo Battistini - Agile Business Group # Copyright 2018-2019 Alex Comba - Agile Business Group -# Copyright 2024 Simone Rubino - Aion Tech +# Copyright 2023 Simone Rubino - Aion Tech # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import base64 @@ -1118,3 +1118,71 @@ def test_18_xml_export(self): # XML doc to be validated xml_content = base64.decodebytes(attachment.datas) self.check_content(xml_content, "IT06363391001_00018.xml") + + def _get_multiple_invoices(self, partner, invoices_number=2): + """Create `invoices_number` invoices for `partner`.""" + invoices = self.invoice_model.browse() + for _ in range(invoices_number): + invoices |= self.init_invoice( + "out_invoice", + partner=partner, + amounts=[ + 100, + ], + ) + invoices.action_post() + return invoices + + def test_max_invoice_number_unlimited(self): + """Check that when both partner and company do not have any max value, + only one attachment is created.""" + + # pre-condition: partner and company do not have any max value + company = self.company + self.assertEqual(company.max_invoice_in_xml, 0) + partner = self.res_partner_fatturapa_0 + self.assertEqual(partner.max_invoice_in_xml, 0) + + # Create two invoices + invoices = self._get_multiple_invoices(partner) + self.run_wizard(invoices.ids) + + # Check that only one attachment is created + attachments_nbr = len(invoices.mapped("fatturapa_attachment_out_id")) + self.assertEqual(attachments_nbr, 1) + + def test_max_invoice_number_partner(self): + """Check that when partner has a max value, company value is ignored and + many attachments are created.""" + + # pre-condition: partner has a value + company = self.company + self.assertEqual(company.max_invoice_in_xml, 0) + partner = self.res_partner_fatturapa_0 + partner.max_invoice_in_xml = 1 + + # Create two invoices + invoices = self._get_multiple_invoices(partner) + self.run_wizard(invoices.ids) + + # Check that two attachments are created + attachments_nbr = len(invoices.mapped("fatturapa_attachment_out_id")) + self.assertEqual(attachments_nbr, 2) + + def test_max_invoice_number_company(self): + """Check that when company has a max value and partner does not, + many attachments are created.""" + + # pre-condition: only company has a value + company = self.company + company.max_invoice_in_xml = 1 + partner = self.res_partner_fatturapa_0 + self.assertEqual(partner.max_invoice_in_xml, 0) + + # Create two invoices + invoices = self._get_multiple_invoices(partner) + self.run_wizard(invoices.ids) + + # Check that two attachments are created + attachments_nbr = len(invoices.mapped("fatturapa_attachment_out_id")) + self.assertEqual(attachments_nbr, 2) diff --git a/l10n_it_fatturapa_out/wizard/wizard_export_fatturapa.py b/l10n_it_fatturapa_out/wizard/wizard_export_fatturapa.py index d232ee8e0d3e..dc73818baade 100644 --- a/l10n_it_fatturapa_out/wizard/wizard_export_fatturapa.py +++ b/l10n_it_fatturapa_out/wizard/wizard_export_fatturapa.py @@ -3,6 +3,7 @@ # Copyright 2018 Simone Rubino - Agile Business Group # Copyright 2018 Sergio Corato # Copyright 2019 Alex Comba - Agile Business Group +# Copyright 2023 Simone Rubino - Aion Tech # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import base64 @@ -217,11 +218,13 @@ def split_list(my_list, size): if invoice.partner_id not in res: res[invoice.partner_id] = [] res[invoice.partner_id].append(invoice.id) + + company = self.env.company + company_max_invoice = company.max_invoice_in_xml for partner_id in res.keys(): - if partner_id.max_invoice_in_xml: - res[partner_id] = list( - split_list(res[partner_id], partner_id.max_invoice_in_xml) - ) + max_invoice = partner_id.max_invoice_in_xml or company_max_invoice + if max_invoice: + res[partner_id] = list(split_list(res[partner_id], max_invoice)) else: res[partner_id] = [res[partner_id]] # The returned dictionary contains a plain res.partner object as key