From 405483cb06b389a6fe3f9e0c6d9fc9546bb8cfcb Mon Sep 17 00:00:00 2001 From: "Thomas Becquevort (thbe)" Date: Wed, 6 Dec 2023 15:23:07 +0100 Subject: [PATCH] [IMP] hr_expense:warn user on expense category price update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description of the issue/feature this commit addresses: Currently, if the price of an expense category which has expenses posted is modified, the total amount of those expenses is modified too. This is a wanted behavior but this might surprise the user and so it would be preferable to tell him that those amount will be modified when he is editing the category's price. Desired behavior after the commit is merged: Adding this commit, when a user modifies the standard_price on a expense category, if this category has posted or draft expenses linked, a warning message will appear to tell the tell the user of what is going to happen. task-3506770 closes odoo/odoo#144983 X-original-commit: 5aabb58 Signed-off-by: de Wouters de Bouchout Jean-BenoƮt (jbw) Signed-off-by: Thomas Becquevort (thbe) --- addons/hr_expense/i18n/hr_expense.pot | 9 +++ addons/hr_expense/models/__init__.py | 1 + addons/hr_expense/models/product_product.py | 26 +++++++++ addons/hr_expense/tests/__init__.py | 1 + ..._expenses_standard_price_update_warning.py | 56 +++++++++++++++++++ addons/hr_expense/views/hr_expense_views.xml | 3 + 6 files changed, 96 insertions(+) create mode 100644 addons/hr_expense/models/product_product.py create mode 100644 addons/hr_expense/tests/test_expenses_standard_price_update_warning.py diff --git a/addons/hr_expense/i18n/hr_expense.pot b/addons/hr_expense/i18n/hr_expense.pot index e4a7a5add31..47ef63fda3b 100644 --- a/addons/hr_expense/i18n/hr_expense.pot +++ b/addons/hr_expense/i18n/hr_expense.pot @@ -2015,6 +2015,15 @@ msgstr "" msgid "The sum of after split shut remain the same" msgstr "" +#. module: hr_expense +#. odoo-python +#: code:addons/hr_expense/models/product_product.py:0 +#, python-format +msgid "" +"There are unposted expenses linked to this category. Updating the category " +"cost will change expense amounts. Make sure it is what you want to do." +msgstr "" + #. module: hr_expense #. odoo-python #: code:addons/hr_expense/models/hr_expense_sheet.py:0 diff --git a/addons/hr_expense/models/__init__.py b/addons/hr_expense/models/__init__.py index 85fd0506c63..00625929f9f 100644 --- a/addons/hr_expense/models/__init__.py +++ b/addons/hr_expense/models/__init__.py @@ -8,6 +8,7 @@ from . import account_tax from . import hr_department from . import hr_expense from . import hr_expense_sheet +from . import product_product from . import product_template from . import res_config_settings from . import account_journal_dashboard diff --git a/addons/hr_expense/models/product_product.py b/addons/hr_expense/models/product_product.py new file mode 100644 index 00000000000..fe628d03520 --- /dev/null +++ b/addons/hr_expense/models/product_product.py @@ -0,0 +1,26 @@ +from odoo import api, fields, models, _ + + +class ProductProduct(models.Model): + _inherit = "product.product" + + standard_price_update_warning = fields.Char(compute="_compute_standard_price_update_warning") + + @api.onchange('standard_price') + def _compute_standard_price_update_warning(self): + undone_expenses = self.env['hr.expense']._read_group( + domain=[('state', 'in', ['draft', 'reported', 'approved']), ('product_id', 'in', self.ids)], + groupby=['price_unit'], + ) + # The following list is composed of all the unit_amounts of expenses that use this product and should NOT trigger a warning. + # Those are the amounts of any undone expense using this product and 0.0 which is the default unit_amount. + unit_amounts_no_warning = [self.env.company.currency_id.round(row[0]) for row in undone_expenses] + for product in self: + product.standard_price_update_warning = False + if undone_expenses: + rounded_price = self.env.company.currency_id.round(product.standard_price) + if rounded_price and (len(unit_amounts_no_warning) > 1 or (len(unit_amounts_no_warning) == 1 and rounded_price not in unit_amounts_no_warning)): + product.standard_price_update_warning = _( + "There are unposted expenses linked to this category. Updating the category cost will change expense amounts. " + "Make sure it is what you want to do." + ) diff --git a/addons/hr_expense/tests/__init__.py b/addons/hr_expense/tests/__init__.py index 699673b16c3..01f8b5dcd31 100644 --- a/addons/hr_expense/tests/__init__.py +++ b/addons/hr_expense/tests/__init__.py @@ -7,3 +7,4 @@ from . import test_expenses_access_rights from . import test_expenses_mail_import from . import test_expenses_multi_company from . import test_expenses_tax +from . import test_expenses_standard_price_update_warning diff --git a/addons/hr_expense/tests/test_expenses_standard_price_update_warning.py b/addons/hr_expense/tests/test_expenses_standard_price_update_warning.py new file mode 100644 index 00000000000..0d08293dc35 --- /dev/null +++ b/addons/hr_expense/tests/test_expenses_standard_price_update_warning.py @@ -0,0 +1,56 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.hr_expense.tests.common import TestExpenseCommon +from odoo.tests import tagged, Form + + +@tagged('post_install', '-at_install') +class TestExpenseStandardPriceUpdateWarning(TestExpenseCommon): + def test_expense_standard_price_update_warning(self): + self.expense_cat_A = self.env['product.product'].create({ + 'name': 'Category A', + 'default_code': 'CA', + 'standard_price': 0.0, + }) + self.expense_cat_B = self.env['product.product'].create({ + 'name': 'Category B', + 'default_code': 'CB', + 'standard_price': 0.0, + }) + self.expense_cat_C = self.env['product.product'].create({ + 'name': 'Category C', + 'default_code': 'CC', + 'standard_price': 0.0, + }) + self.expense_1 = self.env['hr.expense'].create({ + 'employee_id': self.expense_employee.id, + 'name': 'Expense 1', + 'product_id': self.expense_cat_A.id, + 'total_amount': 1, + }) + self.expense_2 = self.env['hr.expense'].create({ + 'employee_id': self.expense_employee.id, + 'name': 'Expense 2', + 'product_id': self.expense_cat_B.id, + 'total_amount': 5, + }) + + # At first, there is no warning message on the categories because their prices are 0 + self.assertFalse(self.expense_cat_A.standard_price_update_warning) + self.assertFalse(self.expense_cat_B.standard_price_update_warning) + self.assertFalse(self.expense_cat_C.standard_price_update_warning) + + # When modifying the price of the first category, a message should appear as a an expense will be modified. + with Form(self.expense_cat_A, view="hr_expense.product_product_expense_form_view") as form: + form.standard_price = 5 + self.assertTrue(form.standard_price_update_warning) + + # When modifying the price of the second category, no message should appear as the price of the linked + # expense is the price of the category that is going to be saved. + with Form(self.expense_cat_B, view="hr_expense.product_product_expense_form_view") as form: + form.standard_price = 5 + self.assertFalse(form.standard_price_update_warning) + + # When modifying the price of the thirs category, no message should appear as no expense is linked to it. + with Form(self.expense_cat_C, view="hr_expense.product_product_expense_form_view") as form: + form.standard_price = 5 + self.assertFalse(form.standard_price_update_warning) diff --git a/addons/hr_expense/views/hr_expense_views.xml b/addons/hr_expense/views/hr_expense_views.xml index 2430fe85dbf..08834baf26e 100644 --- a/addons/hr_expense/views/hr_expense_views.xml +++ b/addons/hr_expense/views/hr_expense_views.xml @@ -550,6 +550,9 @@ product.product
+