Skip to content

Commit 993ee08

Browse files
committed
[FIX] l10n_it_edi: The imported e-invoice was submitted to the wrong company, and the original XML wasn't attached
- The context used to create the Form used 'with_context' instead of 'with_company'. - An additional message has been posted to the chatter with the original E-invoice XML from the email. - Some code clarification were due where the e-invoice company is determined. opw-2460485 closes odoo#71616 X-original-commit: db25a9d Signed-off-by: Josse Colpaert <[email protected]> Signed-off-by: Paolo Gatti <[email protected]>
1 parent 741a0ee commit 993ee08

File tree

3 files changed

+32
-29
lines changed

3 files changed

+32
-29
lines changed

addons/l10n_it_edi/models/account_edi_format.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ def _import_fattura_pa(self, tree, invoice):
109109
invoice = self.env['account.move']
110110
first_run = False
111111

112+
# Type must be present in the context to get the right behavior of the _default_journal method (account.move).
113+
# journal_id must be present in the context to get the right behavior of the _default_account method (account.move.line).
114+
elements = tree.xpath('//CessionarioCommittente//IdCodice')
115+
company = elements and self.env['res.company'].search([('vat', 'ilike', elements[0].text)], limit=1)
116+
if not company:
117+
elements = tree.xpath('//CessionarioCommittente//CodiceFiscale')
118+
company = elements and self.env['res.company'].search([('l10n_it_codice_fiscale', 'ilike', elements[0].text)], limit=1)
119+
if not company:
120+
# Only invoices with a correct VAT or Codice Fiscale can be imported
121+
_logger.warning('No company found with VAT or Codice Fiscale like %r.', elements[0].text)
122+
continue
123+
112124
# Refund type.
113125
# TD01 == invoice
114126
# TD02 == advance/down payment on invoice
@@ -123,32 +135,14 @@ def _import_fattura_pa(self, tree, invoice):
123135
move_type = 'in_refund'
124136
elif elements and elements[0].text and elements[0].text != 'TD01':
125137
_logger.info('Document type not managed: %s. Invoice type is set by default.', elements[0].text)
126-
invoice_ctx = invoice.with_context(default_move_type=move_type)
127-
128-
# type must be present in the context to get the right behavior of the _default_journal method (account.move).
129-
# journal_id must be present in the context to get the right behavior of the _default_account method (account.move.line).
130-
131-
elements = tree.xpath('//CessionarioCommittente//IdCodice')
132-
company = elements and self.env['res.company'].search([('vat', 'ilike', elements[0].text)], limit=1)
133-
if not company:
134-
elements = tree.xpath('//CessionarioCommittente//CodiceFiscale')
135-
company = elements and self.env['res.company'].search([('l10n_it_codice_fiscale', 'ilike', elements[0].text)], limit=1)
136-
137-
if company:
138-
invoice_ctx = invoice_ctx.with_context(company_id=company.id)
139-
else:
140-
company = self.env.company
141-
if elements:
142-
_logger.info('No company found with codice fiscale: %s. The user\'s company is set by default.', elements[0].text)
143-
else:
144-
_logger.info('Company not found. The user\'s company is set by default.')
145138

146-
if not self.env.is_superuser():
147-
if self.env.company != company:
148-
raise UserError(_("You can only import invoice concern your current company: %s", self.env.company.display_name))
139+
# Setup the context for the Invoice Form
140+
invoice_ctx = invoice.with_company(company) \
141+
.with_context(default_move_type=move_type,
142+
account_predictive_bills_disable_prediction=True)
149143

150144
# move could be a single record (editing) or be empty (new).
151-
with Form(invoice_ctx.with_context(account_predictive_bills_disable_prediction=True)) as invoice_form:
145+
with Form(invoice_ctx) as invoice_form:
152146
message_to_log = []
153147

154148
# Partner (first step to avoid warning 'Warning! You must first select a partner.'). <1.2>

addons/l10n_it_edi/models/ir_mail_server.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,20 +135,22 @@ def _attachment_invoice(self, msg_txt):
135135
# we have a receipt
136136
self._message_receipt_invoice(split_underscore[1], attachment)
137137
else:
138-
match = re.search("([A-Z]{2}[A-Za-z0-9]{2,28}_[A-Za-z0-9]{0,5}.(xml.p7m|xml))", attachment.fname)
138+
att_filename = attachment.fname
139+
match = re.search("([A-Z]{2}[A-Za-z0-9]{2,28}_[A-Za-z0-9]{0,5}.(xml.p7m|xml))", att_filename)
139140
# If match, we have an invoice.
140141
if match:
141142
# If it's signed, the content has a bytes type and we just remove the signature's envelope
142143
if match.groups()[1] == 'xml.p7m':
143144
att_content_data = remove_signature(attachment.content)
144145
# If the envelope cannot be removed, the remove_signature returns None, so we skip
145146
if not att_content_data:
146-
_logger.warning("E-invoice couldn't be read: %s", attachment.fname)
147+
_logger.warning("E-invoice couldn't be read: %s", att_filename)
147148
continue
148-
# Otherwise, it should be an utf-8 encoded XML string
149+
att_filename = att_filename.replace('.xml.p7m', '.xml')
149150
else:
151+
# Otherwise, it should be an utf-8 encoded XML string
150152
att_content_data = attachment.content.encode()
151-
self._create_invoice_from_mail(att_content_data, attachment.fname, from_address)
153+
self._create_invoice_from_mail(att_content_data, att_filename, from_address)
152154
else:
153155
if split_underscore[1] == 'AT':
154156
# Attestazione di avvenuta trasmissione della fattura con impossibilità di recapito
@@ -174,7 +176,7 @@ def _create_invoice_from_mail(self, att_content_data, att_name, from_address):
174176
return invoices
175177

176178
# Create the new attachment for the file
177-
self.env['ir.attachment'].create({
179+
attachment = self.env['ir.attachment'].create({
178180
'name': att_name,
179181
'raw': att_content_data,
180182
'res_model': 'account.move',
@@ -195,6 +197,10 @@ def _create_invoice_from_mail(self, att_content_data, att_name, from_address):
195197

196198
invoices.l10n_it_send_state = 'new'
197199
invoices.invoice_source_email = from_address
200+
for invoice in invoices:
201+
invoice.with_context(no_new_invoice=True, default_res_id=invoice.id) \
202+
.message_post(body=(_("Original E-invoice XML file")), attachment_ids=[attachment.id])
203+
198204
self._cr.commit()
199205

200206
_logger.info('New E-invoices (%s), ids: %s', att_name, [x.id for x in invoices])

addons/l10n_it_edi/tests/test_ir_mail_server.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ def setUpClass(cls):
4444
super().setUpClass(chart_template_ref='l10n_it.l10n_it_chart_template_generic',
4545
edi_format_ref='l10n_it_edi.edi_fatturaPA')
4646

47+
# Use the company_data_2 to test that the e-invoice is imported for the right company
48+
cls.company = cls.company_data_2['company']
49+
4750
# Initialize the company's codice fiscale
48-
cls.company = cls.company_data['company']
4951
cls.company.l10n_it_codice_fiscale = 'IT01234560157'
5052

5153
# Build test data.
@@ -108,6 +110,7 @@ def test_receive_signed_vendor_bill(self):
108110
""" Test a signed (P7M) sample e-invoice file from https://www.fatturapa.gov.it/export/documenti/fatturapa/v1.2/IT01234567890_FPR01.xml """
109111
invoices = self._create_invoice(self.signed_invoice_content, self.signed_invoice_filename)
110112
self.assertRecordValues(invoices, [{
113+
'company_id': self.company.id,
111114
'name': 'BILL/2014/12/0001',
112115
'date': datetime.date(2014, 12, 18),
113116
'ref': '01234567890',

0 commit comments

Comments
 (0)