Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] l10n_it_fatturapa_out: Configurazione in azienda per numero massimo fatture per fattura elettronica #3800

Merged
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
6 changes: 5 additions & 1 deletion l10n_it_fatturapa_out/models/partner.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2019 Roberto Fichera <[email protected]>
# Copyright 2023 Simone Rubino - Aion Tech
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from odoo import _, api, fields, models
Expand All @@ -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")
Expand Down
15 changes: 13 additions & 2 deletions l10n_it_fatturapa_out/tests/fatturapa_common.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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
Expand Down
70 changes: 69 additions & 1 deletion l10n_it_fatturapa_out/tests/test_fatturapa_xml_validation.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -1113,3 +1113,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)
11 changes: 7 additions & 4 deletions l10n_it_fatturapa_out/wizard/wizard_export_fatturapa.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading