diff --git a/addons/l10n_ke_edi_tremol/models/account_move.py b/addons/l10n_ke_edi_tremol/models/account_move.py index 8282e0a9147..376aab3327a 100644 --- a/addons/l10n_ke_edi_tremol/models/account_move.py +++ b/addons/l10n_ke_edi_tremol/models/account_move.py @@ -68,16 +68,13 @@ class AccountMove(models.Model): move_errors.append(_("This credit note must reference the previous invoice, and this previous invoice must have already been submitted.")) for line in self.invoice_line_ids.filtered(lambda l: l.display_type == 'product'): - if not line.tax_ids or len(line.tax_ids) > 1: - move_errors.append(_("On line %s, you must select one and only one tax.", line.name)) + vat_taxes = line.tax_ids.filtered(lambda tax: tax.amount in (16, 8, 0)) + if not vat_taxes or len(vat_taxes) > 1: + move_errors.append(_("On line %s, you must select one and only one VAT tax.", line.name)) else: - if line.tax_ids.amount == 0 and not line.tax_ids[0].l10n_ke_item_code_id: + if vat_taxes[0].amount == 0 and not line.tax_ids[0].l10n_ke_item_code_id: move_errors.append(_("On line %s, a tax with a KRA item code must be selected, since the tax is 0%% or exempt.", line.name)) - for tax in move.invoice_line_ids.tax_ids: - if tax.amount not in (16, 8, 0): - move_errors.append(_("Tax '%s' is used, but only taxes of 16%%, 8%%, 0%% or Exempt can be sent. Please reconfigure or change the tax.", tax.name)) - if move_errors: errors.append((move.name, move_errors)) @@ -167,12 +164,18 @@ class AccountMove(models.Model): break msgs = [] + tax_details = self._prepare_edi_tax_details() for line in self.invoice_line_ids.filtered(lambda l: l.display_type == 'product' and l.quantity and l.price_total > 0 and not discount_dict.get(l.id) >= 100): # Here we use the original discount of the line, since it the distributed discount has not been applied in the price_total - price = round(line.price_total / abs(line.quantity) * 100 / (100 - line.discount), 2) * currency_rate - percentage = line.tax_ids[0].amount + price_total = 0 + percentage = 0 item_code = line.tax_ids[0].l10n_ke_item_code_id - + for tax in tax_details['invoice_line_tax_details'][line]['tax_details']: + if tax['tax'].amount in (16, 8, 0): # This should only occur once + tax_details = tax_details['invoice_line_tax_details'][line]['tax_details'][tax] + price_total = abs(tax_details['base_amount_currency']) + abs(tax_details['tax_amount_currency']) + percentage = tax['tax'].amount + price = round(price_total / abs(line.quantity) * 100 / (100 - line.discount), 2) * currency_rate uom = line.product_uom_id and line.product_uom_id.name or '' line_data = b';'.join([ diff --git a/addons/l10n_ke_edi_tremol/tests/test_move_export.py b/addons/l10n_ke_edi_tremol/tests/test_move_export.py index 1300b2663f6..3b4612f065f 100644 --- a/addons/l10n_ke_edi_tremol/tests/test_move_export.py +++ b/addons/l10n_ke_edi_tremol/tests/test_move_export.py @@ -187,3 +187,42 @@ class TestKeMoveExport(AccountTestInvoicingCommon): expected_double_negative_header = [b'01; 0;0;1;Sirius Cybernetics Corporation;A000123456F ;Test StreetFurther Test Street;Test StreetFurther Test Street;00500Nairobi ; ;INV202300002 '] expected_messages = expected_double_negative_header + expected_messages[1:] self.assertEqual(generated_messages, expected_messages) + + def test_export_multi_tax_line_invoice(self): + """ When handling invoices with multiple taxes per line, the export should handle the + reported amounts correctly. Using only the VAT taxes in its calculation and not, for + instance, the 2% tourism levy, or the 4% drinks service charge, or the 10% food service + charge. + """ + tourism_levy = self.env['account.tax'].create({ + 'name': 'Tourism levy', + 'amount': 2, + 'company_id': self.company_data['company'].id, + }) + multi_tax_line_invoice = self.env['account.move'].create({ + 'move_type': 'out_invoice', + 'partner_id': self.partner_a.id, + 'invoice_line_ids': [ + (0, 0, { + 'product_id': self.product_a.id, + 'quantity': 10, + 'price_unit': 1000, + 'tax_ids': [ + (6, 0, [ + self.company_data['company'].account_sale_tax_id.id, + tourism_levy.id, + ]), + ], + 'discount': 25, + }), + ], + }) + multi_tax_line_invoice.action_post() + generated_messages = multi_tax_line_invoice._l10n_ke_cu_lines_messages() + expected_sale_line = self.line_dict_to_bytes({ + 'name': b'Infinite Improbability Drive ', + 'price': b'1160.0', # This is the unit price, tax included, but only the 16% VAT + 'quantity': b'10.0', + 'discount': b'-25.0%', + }) + self.assertEqual(generated_messages, [expected_sale_line])