[FIX] l10n_es_edi_facturae: handle ZeroDivisionError when discount value is 100

This traceback raises when user tries to 'Send & Print' the invoice of sale
order having a discount of 100%.

Steps to reproduce:
1) Install "l10n_es_edi_facturae" & "sale_management" and switch to "ES Company".
2) Open "Sales" >  "Configuration" > "Settings" and click on
   "Discounts" checkbox > "Save" button to activate it.
3) Now click on "Orders" > "Quotations" button and then "New" button .
4) Select any "Customer" and in "Order Lines" select a "product" with
  "Invoicing Policy" as 'Ordered quantities' (ex. 'Chair floor protection').
5) Now, in that 'Sale order line' enter the value of 'Disc.%' as '100' .
6) Click on "Confirm" button and then "Create Invoice" button.
7) In "Create Invoice" Wizard, select "Regular Invoice" if not >
  "Create Draft Invoice" button.
8) In "Customer Invoice", click on "Confirm" button > "Send & Print" button.
9) In "Configure your document layout" wizard, click on "Save" > "Send & Print".

Error: ZeroDivisionError: float division by zero, is generated from
"_l10n_es_edi_facturae_inv_lines_to_items"  method.

See: https://github.com/odoo/odoo/blob/b5c19d368339f9d2b7af6e61e88a918d6ba318ee/addons/l10n_es_edi_facturae/models/account_move.py#L195

It gets the value of "line.discount" as 100, so the overall value of
"(1 - line.discount / 100.0)" becomes Zero and it tries to  divide
"line.price_subtotal" by 'Zero', that's why this error is coming.

sentry-4325625223

closes odoo/odoo#131029

X-original-commit: 363e679601920f1a5a1fd6e1021521dae2a76714
Signed-off-by: de Wouters de Bouchout Jean-Benoît (jbw) <jbw@odoo.com>
Signed-off-by: Mohit Beniwal (mobe) <mobe@odoo.com>
This commit is contained in:
Mohit Beniwal
2023-08-16 16:05:06 +02:00
parent 0b3d9a0360
commit a2b41824df
2 changed files with 27 additions and 2 deletions
@@ -192,10 +192,18 @@ class AccountMove(models.Model):
continue
invoice_line_values = {}
price_before_discount = line.currency_id.round(line.price_subtotal / (1 - line.discount / 100.0))
tax_base_before_discount = self.env['account.tax']._convert_to_tax_base_line_dict(
base_line=line,
currency=line.currency_id,
taxes=line.tax_ids,
price_unit=line.price_unit,
quantity=line.quantity,
)
tax_before_discount = self.env['account.tax']._compute_taxes([tax_base_before_discount])
price_before_discount = sum(to_update['price_subtotal'] for _dummy, to_update in tax_before_discount['base_lines_to_update'])
discount = max(0., (price_before_discount - line.price_subtotal))
surcharge = abs(min(0., (price_before_discount - line.price_subtotal)))
totals['total_gross_amount'] += line.price_subtotal
totals['total_gross_amount'] += price_before_discount
totals['total_general_discounts'] += discount
totals['total_general_surcharges'] += surcharge
base_line = self.env['account.tax']._convert_to_tax_base_line_dict(
@@ -234,3 +234,20 @@ class TestEdiFacturaeXmls(AccountEdiTestCommon):
with file_open("l10n_es_edi_facturae/tests/data/expected_refund_document.xml", "rt") as f:
expected_xml = lxml.etree.fromstring(f.read().encode())
self.assertXmlTreeEqual(lxml.etree.fromstring(generated_file), expected_xml)
def test_discount_100_percent(self):
""" Create an invoice with a 100% discount """
with freeze_time(self.frozen_today), \
patch(f"{self.certificate_module}.fields.datetime.now", lambda x=None: self.frozen_today), \
patch(f"{self.certificate_module}.sha1", lambda x: sha1()):
invoice = self.create_invoice(
partner_id=self.partner_a.id,
move_type='out_invoice',
invoice_line_ids=[{'product_id': self.product_a.id, 'price_unit': 1000.0, 'discount': 100.0, 'quantity': 2}],
)
invoice.action_post()
wizard = self.create_send_and_print(invoice)
result = wizard.action_send_and_print()
self.assertEqual(result['type'], 'ir.actions.act_url')
self.assertEqual(invoice.invoice_line_ids[0].price_subtotal, 0.0)