diff --git a/hr_expense_invoice/models/hr_expense.py b/hr_expense_invoice/models/hr_expense.py index 3dde9b98e..7e3ae69d8 100644 --- a/hr_expense_invoice/models/hr_expense.py +++ b/hr_expense_invoice/models/hr_expense.py @@ -1,11 +1,12 @@ # Copyright 2017 Tecnativa - Vicent Cubells # Copyright 2020 Tecnativa - David Vidal -# Copyright 2021 Tecnativa - Víctor Martínez +# Copyright 2021-2026 Tecnativa - Víctor Martínez # Copyright 2015-2024 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import Command, api, fields, models from odoo.exceptions import UserError +from odoo.tools import float_compare, float_is_zero class HrExpense(models.Model): @@ -57,6 +58,34 @@ def _prepare_invoice_values(self): "invoice_line_ids": invoice_lines, } + def _adjust_invoice_tax_amount(self, invoice): + """If the tax amount does not match due to rounding, we will adjust + it manually, similar to how it is done in the interface using the pencil icon. + Example: Expense 10 (8.7 + 1.30). The invoice generated should also + include 1.30 in taxes. + """ + tax_amount = self.tax_amount_currency + if float_is_zero(tax_amount, precision_rounding=self.currency_id.rounding): + return + if ( + float_compare( + invoice.amount_tax, + tax_amount, + precision_rounding=self.currency_id.rounding, + ) + != 0 + ): + tax_totals = invoice.tax_totals + tax_totals["tax_amount_currency"] = tax_amount + tax_totals["tax_amount"] = tax_amount + subtotals = tax_totals["subtotals"] + subtotals[0]["tax_amount_currency"] = tax_amount + subtotals[0]["tax_amount"] = tax_amount + subtotals[0]["tax_groups"][0]["tax_amount_currency"] = tax_amount + subtotals[0]["tax_groups"][0]["tax_amount"] = tax_amount + tax_totals["subtotals"] = subtotals + invoice.tax_totals = tax_totals + def _prepare_own_account_transfer_move_vals(self): self.ensure_one() self = self.with_company(self.company_id) @@ -102,6 +131,7 @@ def _prepare_own_account_transfer_move_vals(self): def action_expense_create_invoice(self): invoice = self.env["account.move"].create(self._prepare_invoice_values()) + self._adjust_invoice_tax_amount(invoice) attachments = self.env["ir.attachment"].search( [("res_model", "=", self._name), ("res_id", "in", self.ids)] ) diff --git a/hr_expense_invoice/tests/test_hr_expense_invoice.py b/hr_expense_invoice/tests/test_hr_expense_invoice.py index 977dad44a..15855d06b 100644 --- a/hr_expense_invoice/tests/test_hr_expense_invoice.py +++ b/hr_expense_invoice/tests/test_hr_expense_invoice.py @@ -1,12 +1,13 @@ # Copyright 2017 Tecnativa - Vicent Cubells # Copyright 2021 Tecnativa - Pedro M. Baeza -# Copyright 2021-2023 Tecnativa - Víctor Martínez +# Copyright 2021-2026 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). import base64 from odoo import fields from odoo.exceptions import UserError, ValidationError from odoo.tests import Form, tagged +from odoo.tools import mute_logger from odoo.addons.hr_expense.tests.common import TestExpenseCommon @@ -289,3 +290,18 @@ def test_6_hr_expense_mixed_invoice_same_sheet(self): self.assertEqual(self.invoice2.payment_state, "paid") # 2 ap moves and 1 vendor bill self.assertEqual(len(sheet.account_move_ids), 3) + + @mute_logger("odoo.models.unlink") + def test_7_hr_expense_invoice_tax_amount(self): + expense = self.create_expense({"total_amount_currency": 10}) + self.assertEqual(expense.untaxed_amount_currency, 8.7) + self.assertEqual(expense.tax_amount_currency, 1.30) + sheet = self._action_submit_expenses(expense) + self.assertEqual(sheet.total_amount, 10) + sheet.action_submit_sheet() + sheet.action_approve_expense_sheets() + expense.action_expense_create_invoice() + self.assertTrue(expense.invoice_id) + self.assertEqual(expense.invoice_id.amount_untaxed, 8.7) + self.assertEqual(expense.invoice_id.amount_total, 10) + self.assertEqual(sheet.total_amount, 10)