From fe6782c6bc9ede3015321bec41fd7584cd8ad83b Mon Sep 17 00:00:00 2001 From: nni-odoo Date: Tue, 21 Jun 2022 03:15:15 +0000 Subject: [PATCH] [FIX] l10n_id_efaktur: fix price when tax is not included MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Columns involving price within the downloaded e-faktur document is supposed to report prices that does not include tax. When taxes are configured to not be included in price (account.tax field: price_include), result would be correct. However, if the tax configurations is "Included in Price", the price columns will not respect the official e-faktur guideline. Consequently, it will also result to the discount column to be incorrect due to the calculation. 2889400 closes odoo/odoo#97049 X-original-commit: 633c89bcc00cea674f2582c25dadafb2792d9945 Signed-off-by: William André (wan) --- addons/l10n_id_efaktur/models/account_move.py | 7 +- addons/l10n_id_efaktur/tests/__init__.py | 1 + .../tests/test_l10n_id_efaktur.py | 89 +++++++++++++++++++ 3 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 addons/l10n_id_efaktur/tests/__init__.py create mode 100644 addons/l10n_id_efaktur/tests/test_l10n_id_efaktur.py diff --git a/addons/l10n_id_efaktur/models/account_move.py b/addons/l10n_id_efaktur/models/account_move.py index 3b3e3d98fad..0d49cc90175 100644 --- a/addons/l10n_id_efaktur/models/account_move.py +++ b/addons/l10n_id_efaktur/models/account_move.py @@ -203,9 +203,10 @@ class AccountMove(models.Model): if tax.amount > 0: tax_line += line.price_subtotal * (tax.amount / 100.0) - invoice_line_unit_price = line.price_unit - - invoice_line_total_price = invoice_line_unit_price * line.quantity + discount = 1 - (line.discount / 100) + # guarantees price to be tax-excluded + invoice_line_total_price = line.price_subtotal / discount if discount else 0 + invoice_line_unit_price = invoice_line_total_price / line.quantity if line.quantity else 0 line_dict = { 'KODE_OBJEK': line.product_id.default_code or '', diff --git a/addons/l10n_id_efaktur/tests/__init__.py b/addons/l10n_id_efaktur/tests/__init__.py new file mode 100644 index 00000000000..7e82df58992 --- /dev/null +++ b/addons/l10n_id_efaktur/tests/__init__.py @@ -0,0 +1 @@ +from . import test_l10n_id_efaktur diff --git a/addons/l10n_id_efaktur/tests/test_l10n_id_efaktur.py b/addons/l10n_id_efaktur/tests/test_l10n_id_efaktur.py new file mode 100644 index 00000000000..ed7b9b87ea3 --- /dev/null +++ b/addons/l10n_id_efaktur/tests/test_l10n_id_efaktur.py @@ -0,0 +1,89 @@ +from odoo.tests import tagged, common +from odoo.addons.l10n_id_efaktur.models.account_move import FK_HEAD_LIST, LT_HEAD_LIST, OF_HEAD_LIST, _csv_row + +@tagged('post_install', '-at_install', 'post_install_l10n') +class TestIndonesianEfaktur(common.TransactionCase): + def setUp(self): + """ + 1) contact with l10n_id_pkp=True, l10n_id_kode_transaksi="01" + 2) tax: amount=10, type_tax_use=sale, price_include=True + 3) invoice with partner_id=contact, journal=customer invoices, + """ + super().setUp() + + self.maxDiff = 1500 + # change company info for csv detai later + self.env.company.country_id = self.env.ref('base.id') + self.env.company.street = "test" + self.env.company.phone = "12345" + + self.partner_id = self.env['res.partner'].create({"name": "l10ntest", "l10n_id_pkp": True, "l10n_id_kode_transaksi": "01", "l10n_id_nik": "12345"}) + self.tax_id = self.env['account.tax'].create({"name": "test tax", "type_tax_use": "sale", "amount": 10.0, "price_include": True}) + + self.efaktur = self.env['l10n_id_efaktur.efaktur.range'].create({'min': '0000000000001', 'max': '0000000000010'}) + self.out_invoice_1 = self.env['account.move'].create({ + 'move_type': 'out_invoice', + 'partner_id': self.partner_id.id, + 'invoice_date': '2019-05-01', + 'date': '2019-05-01', + 'invoice_line_ids': [ + (0, 0, {'name': 'line1', 'price_unit': 110.0, 'tax_ids': self.tax_id.ids}), + ], + 'l10n_id_kode_transaksi': "01", + }) + self.out_invoice_1.action_post() + + self.out_invoice_2 = self.env['account.move'].create({ + 'move_type': 'out_invoice', + 'partner_id': self.partner_id.id, + 'invoice_date': '2019-05-01', + 'date': '2019-05-01', + 'invoice_line_ids': [ + (0, 0, {'name': 'line1', 'price_unit': 110.11, 'quantity': 400, 'tax_ids': self.tax_id.ids}) + ], + 'l10n_id_kode_transaksi': '01' + }) + self.out_invoice_2.action_post() + + def test_efaktur_csv_output_1(self): + """ + Test to ensure that the output csv data contains tax-excluded prices regardless of whether the tax configuration is tax-included or tax-excluded. + Current test is using price of 110 which is tax-included with tax of amount 10%. So the unit price listed has to be 100 whereas the original result would have 110 instead. + """ + # to check the diff when test fails + + efaktur_csv_output = self.out_invoice_1._generate_efaktur_invoice(',') + output_head = '%s%s%s' % ( + _csv_row(FK_HEAD_LIST, ','), + _csv_row(LT_HEAD_LIST, ','), + _csv_row(OF_HEAD_LIST, ','), + ) + # remaining lines + line_4 = '"FK","01","0","0000000000001","5","2019","1/5/2019","12345","l10ntest","","100","10","0","","0","110","0","0","INV/2019/00001 12345","0"\n' + line_5 = '"OF","","","100","1.0","100","0","100","10","0","0"\n' + + efaktur_csv_expected = output_head + line_4 + line_5 + + self.assertEqual(efaktur_csv_expected, efaktur_csv_output) + + def test_efaktur_csv_output_decimal_place(self): + """ + Test to ensure that decimal place conversion is only done when inputting to csv + This is to test original calculation of invoice_line_total_price: invoice_line_total_price = invoice_line_unit_price * line.quantity + as invoice_line_unit_price is already converted to be tax-excluded and set to the decimal place as configured on the currency, the calculation of total could be flawed. + + In this test case, the tax-included price unit is 110.11, hence tax-excluded is 100.1, + invoice_line_unit_price will be 100, if we continue with the calculation of total price, it will be 100*400 = 40000 + eventhough the total is supposed to be 100.1*400 = 40040, there is a 40 discrepancy + """ + efaktur_csv_output = self.out_invoice_2._generate_efaktur_invoice(',') + output_head = '%s%s%s' % ( + _csv_row(FK_HEAD_LIST, ','), + _csv_row(LT_HEAD_LIST, ','), + _csv_row(OF_HEAD_LIST, ','), + ) + line_4 = '"FK","01","0","0000000000002","5","2019","1/5/2019","12345","l10ntest","","40040","4004","0","","0","44044","0","0","INV/2019/00002 12345","0"\n' + line_5 = '"OF","","","100","400.0","40040","0","40040","4004","0","0"\n' + + efaktur_csv_expected = output_head + line_4 + line_5 + self.assertEqual(efaktur_csv_expected, efaktur_csv_output)