diff --git a/addons/hr_expense/i18n/hr_expense.pot b/addons/hr_expense/i18n/hr_expense.pot index 40230b67901..493f34f27c0 100644 --- a/addons/hr_expense/i18n/hr_expense.pot +++ b/addons/hr_expense/i18n/hr_expense.pot @@ -2151,6 +2151,13 @@ msgstr "" msgid "You cannot delete a posted or paid expense." msgstr "" +#. module: hr_expense +#. odoo-python +#: code:addons/hr_expense/models/analytic.py:0 +#, python-format +msgid "You cannot delete an analytic account that is used in an expense." +msgstr "" + #. module: hr_expense #: code:addons/hr_expense/models/hr_expense.py:0 #, python-format diff --git a/addons/hr_expense/models/analytic.py b/addons/hr_expense/models/analytic.py index 8c0f769b912..e3a21b8a98b 100644 --- a/addons/hr_expense/models/analytic.py +++ b/addons/hr_expense/models/analytic.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models, api +from odoo import api, fields, models, _ +from odoo.exceptions import UserError class AccountAnalyticApplicability(models.Model): @@ -20,3 +21,18 @@ class AccountAnalyticApplicability(models.Model): super()._compute_display_account_prefix() for applicability in self.filtered(lambda rec: rec.business_domain == 'expense'): applicability.display_account_prefix = True + + +class AccountAnalyticAccount(models.Model): + _inherit = 'account.analytic.account' + + @api.ondelete(at_uninstall=False) + def _unlink_except_account_in_analytic_distribution(self): + self.env.cr.execute(""" + SELECT id FROM hr_expense + WHERE analytic_distribution::jsonb ?| array[%s] + LIMIT 1 + """, ([str(id) for id in self.ids],)) + expense_ids = self.env.cr.fetchall() + if expense_ids: + raise UserError(_("You cannot delete an analytic account that is used in an expense.")) diff --git a/addons/hr_expense/tests/test_expenses.py b/addons/hr_expense/tests/test_expenses.py index 25385602e05..b2b041f37c4 100644 --- a/addons/hr_expense/tests/test_expenses.py +++ b/addons/hr_expense/tests/test_expenses.py @@ -4,6 +4,7 @@ from odoo.addons.hr_expense.tests.common import TestExpenseCommon from odoo.tests import tagged, Form from odoo.tools.misc import formatLang from odoo import fields, Command +from odoo.exceptions import UserError @tagged('-at_install', 'post_install') @@ -742,3 +743,28 @@ class TestExpenses(TestExpenseCommon): 'analytic_distribution': {str(self.analytic_account_2.id): 100}, } ]) + + def test_analytic_account_deleted(self): + """ Test that an analytic account cannot be deleted if it is used in an expense """ + + expense = self.env['hr.expense.sheet'].create({ + 'name': 'Expense for Dick Tracy', + 'employee_id': self.expense_employee.id, + }) + expense = self.env['hr.expense'].create({ + 'name': 'Choucroute Saucisse', + 'employee_id': self.expense_employee.id, + 'product_id': self.product_a.id, + 'unit_amount': 700.00, + 'sheet_id': expense.id, + 'analytic_distribution': { + self.analytic_account_1.id: 50, + self.analytic_account_2.id: 50, + }, + }) + + with self.assertRaises(UserError): + (self.analytic_account_1 | self.analytic_account_2).unlink() + + expense.unlink() + self.analytic_account_1.unlink()