[FIX] l10n_ke_edi_tremol: allow multiple taxes per line
The existing implementation for the fiscal device applies a number of limitations to the content of the invoice in order to ensure the invoice can be regularised and serialised in such a way as to make it transmissible to the device. One of these checks was ensuring that only one tax can be applied per line. This check was implemented as the device itself only accepts one tax per line. This check isn't entirely accurate, since the user should be able to add taxes such as levies, service charges etc (non-vat taxes) to the the line, and have them skipped when transmitting the invoice data to the device. As such, this commit adapts the code to alter the checks (allowing for only one 'VAT' tax, and any number of other taxes). The way the price total is determined is altered to use only the "VAT" tax and base amount to get the price_total for the line from the corresponding line's tax details. This commit also adds a test. closes odoo/odoo#148397 Task-id: None X-original-commit: bb3a32c7f45ac5adb3dddf560f6af33f9bca3780 Signed-off-by: Josse Colpaert <jco@odoo.com> Signed-off-by: Daniel Kosky (dako) <dako@odoo.com>
This commit is contained in:
@@ -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([
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user