[FIX] l10n_es_edi_tbai: fix unit price, discount in multicurrency export

Currently there are the following bugs when XML-exporting invoices
that are not in company currency and use discounts:
  * The discount is computed and exported in document currency.
    But it should be exported in company currency.
  * The unit price value (excl. discount) is computed wrongly
    since it uses the wrong discount value.

This commit corrects the discount and unit price computation / export.

closes odoo/odoo#148566

X-original-commit: 1cc846e8a53fd7c4298b7324d9c4f272592f0497
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Sven Führ (svfu) <svfu@odoo.com>
This commit is contained in:
Sven Fuehr
2024-01-10 07:26:54 +00:00
parent cce80f4c73
commit 46a8cda75f
2 changed files with 79 additions and 3 deletions
@@ -330,10 +330,11 @@ class AccountEdiFormat(models.Model):
invoice_lines = []
for line in invoice.invoice_line_ids.filtered(lambda line: line.display_type not in ('line_section', 'line_note')):
if line.discount == 100.0:
gross_price_subtotal = line.price_unit * line.quantity
inverse_currency_rate = abs(line.move_id.amount_total_signed / line.move_id.amount_total) if line.move_id.amount_total else 1
balance_before_discount = - line.price_unit * line.quantity * inverse_currency_rate
else:
gross_price_subtotal = line.price_subtotal / (1 - line.discount / 100.0)
discount = (gross_price_subtotal - line.price_subtotal) * refund_sign
balance_before_discount = line.balance / (1 - line.discount / 100)
discount = (balance_before_discount - line.balance)
if not any([t.l10n_es_type == 'sujeto_isp' for t in line.tax_ids]):
total = line.price_total * abs(line.balance / line.amount_currency if line.amount_currency != 0 else 1) * -refund_sign
@@ -43,6 +43,81 @@ class TestEdiTbaiXmls(TestEsEdiTbaiCommon):
xml_expected = etree.fromstring(super().L10N_ES_TBAI_SAMPLE_XML_POST)
self.assertXmlTreeEqual(xml_doc, xml_expected)
def test_xml_tree_post_multicurrency(self):
"""Test of Customer Invoice XML. The invoice is not in company currency and has a line with a 100% discount"""
currency_usd = self.env.ref('base.USD')
currency_usd.active = True
date = str(self.out_invoice.invoice_date)
self.env['res.currency.rate'].create({
'name': date,
'company_id': self.company_data['company'].id,
'currency_id': currency_usd.id,
'rate': 0.5})
invoice = self.env['account.move'].create({
'name': 'INV/01',
'move_type': 'out_invoice',
'invoice_date': date,
'partner_id': self.partner_a.id,
'currency_id': currency_usd.id,
'invoice_line_ids': [
(0, 0, {
'product_id': self.product_a.id,
'price_unit': 123.00,
'quantity': 5,
'discount': 20.0,
'tax_ids': [(6, 0, self._get_tax_by_xml_id('s_iva21b').ids)],
}),
(0, 0, {
'product_id': self.product_a.id,
'price_unit': 123.00,
'quantity': 5,
'discount': 100.0,
'tax_ids': [(6, 0, self._get_tax_by_xml_id('s_iva21b').ids)],
}),
],
})
with freeze_time(self.frozen_today):
xml_doc = self.edi_format._get_l10n_es_tbai_invoice_xml(invoice, cancel=False)[invoice]['xml_file']
xml_doc.remove(xml_doc.find("Signature", namespaces=NS_MAP))
xml_expected_base = etree.fromstring(super().L10N_ES_TBAI_SAMPLE_XML_POST)
xpath = """
<xpath expr="//DetallesFactura" position="replace">
<DetallesFactura>
<IDDetalleFactura>
<DescripcionDetalle>producta</DescripcionDetalle>
<Cantidad>5.00</Cantidad>
<ImporteUnitario>246.00</ImporteUnitario>
<Descuento>246.00</Descuento>
<ImporteTotal>1190.64</ImporteTotal>
</IDDetalleFactura>
<IDDetalleFactura>
<DescripcionDetalle>producta</DescripcionDetalle>
<Cantidad>5.00</Cantidad>
<ImporteUnitario>246.00</ImporteUnitario>
<Descuento>1230.00</Descuento>
<ImporteTotal>0.00</ImporteTotal>
</IDDetalleFactura>
</DetallesFactura>
</xpath>
<xpath expr="//ImporteTotalFactura" position="replace">
<ImporteTotalFactura>1190.64</ImporteTotalFactura>
</xpath>
<xpath expr="//DesgloseIVA" position="replace">
<DesgloseIVA>
<DetalleIVA>
<BaseImponible>984.00</BaseImponible>
<TipoImpositivo>21.00</TipoImpositivo>
<CuotaImpuesto>206.64</CuotaImpuesto>
<OperacionEnRecargoDeEquivalenciaORegimenSimplificado>N</OperacionEnRecargoDeEquivalenciaORegimenSimplificado>
</DetalleIVA>
</DesgloseIVA>
</xpath>
"""
xml_expected = self.with_applied_xpath(xml_expected_base, xpath)
self.assertXmlTreeEqual(xml_doc, xml_expected)
def test_xml_tree_in_post(self):
"""Test XML of vendor bill for LROE Batuz"""
with freeze_time(self.frozen_today):