From 7c54283632e343455377466180dfbd367d3a0eec Mon Sep 17 00:00:00 2001 From: Paul Stroobant Date: Fri, 8 Mar 2024 14:15:26 +0100 Subject: [PATCH] [FIX] onboarding: unlink progress when company_id is unlinked Steps to reproduce issue: 1. Download Accounting (or Sales or just Invoices) 2. Open Accounting 3. Create Company 2 and switch to it 4. Open Accounting again 5. Remove Company 2 6. Open Accounting 7. You receive an error: > ValueError: Expected singleton: onboarding.progress(1, 2) Explanation: In `_compute_current_progress`, the filter to get `current_progress_id` accepts `onboarding.progress` with both the company in which the user is at the moment or no company at all. https://github.com/odoo/odoo/blob/77f9ff50db3cdb88397d0b1cc7042c772d0d417b/addons/onboarding/models/onboarding_onboarding.py#L55-L69 This is due to the fact that some onboardings are not related to a company while others are. After that, getting the `onboarding_state` will trigger an `ensure_one` check. In the current case, an `onboarding.progress` with a `company_id` is not deleted once the company is deleted. Therefore the value becomes `False`. The `ensure_one` that comes after will throw an error because of it. Suggested fix: `ondelete` decorator requires the module to be upgraded. For this issue, it is preferable to have a fix that is automatically applied. The added method simulates the `cascade` effect of `ondelete` and does not require the module upgrade. opw-3762382 closes odoo/odoo#157142 X-original-commit: 8e3283aabfd93a78eb4d72c4fd97f6a20ad08ef4 Signed-off-by: Thibault Delavallee (tde) --- addons/onboarding/models/__init__.py | 1 + .../onboarding/models/onboarding_progress.py | 2 +- addons/onboarding/models/res_company.py | 13 +++++++++++++ addons/onboarding/tests/test_onboarding.py | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 addons/onboarding/models/res_company.py diff --git a/addons/onboarding/models/__init__.py b/addons/onboarding/models/__init__.py index 0e27595dad9..75e4113d850 100644 --- a/addons/onboarding/models/__init__.py +++ b/addons/onboarding/models/__init__.py @@ -5,3 +5,4 @@ from . import onboarding_onboarding from . import onboarding_onboarding_step from . import onboarding_progress from . import onboarding_progress_step +from . import res_company diff --git a/addons/onboarding/models/onboarding_progress.py b/addons/onboarding/models/onboarding_progress.py index 3bb15560b7e..8a11d4db1e3 100644 --- a/addons/onboarding/models/onboarding_progress.py +++ b/addons/onboarding/models/onboarding_progress.py @@ -19,7 +19,7 @@ class OnboardingProgress(models.Model): onboarding_state = fields.Selection( ONBOARDING_PROGRESS_STATES, string='Onboarding progress', compute='_compute_onboarding_state', store=True) is_onboarding_closed = fields.Boolean('Was panel closed?') - company_id = fields.Many2one('res.company') + company_id = fields.Many2one('res.company', ondelete='cascade') onboarding_id = fields.Many2one( 'onboarding.onboarding', 'Related onboarding tracked', required=True, ondelete='cascade') progress_step_ids = fields.Many2many('onboarding.progress.step', string='Progress Steps Trackers') diff --git a/addons/onboarding/models/res_company.py b/addons/onboarding/models/res_company.py new file mode 100644 index 00000000000..cca976d3e9d --- /dev/null +++ b/addons/onboarding/models/res_company.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models + + +class Company(models.Model): + _inherit = 'res.company' + + @api.ondelete(at_uninstall=False) + def _unlink_onboarding_progress(self): + progress = self.env['onboarding.progress'].sudo().search([('company_id', 'in', self.ids)]) + progress.unlink() diff --git a/addons/onboarding/tests/test_onboarding.py b/addons/onboarding/tests/test_onboarding.py index f5dab985eca..40bf8055e72 100644 --- a/addons/onboarding/tests/test_onboarding.py +++ b/addons/onboarding/tests/test_onboarding.py @@ -4,6 +4,7 @@ from psycopg2 import IntegrityError from odoo import Command +from odoo.addons.mail.tests.common import mail_new_test_user from odoo.addons.onboarding.tests.common import TestOnboardingCommon from odoo.exceptions import ValidationError from odoo.tools import mute_logger @@ -215,3 +216,20 @@ class TestOnboarding(TestOnboardingCommon): # But it can self.step_initially_w_o_onboarding.with_company(self.company_2).action_set_just_done() self.assert_onboarding_is_done(self.onboarding_3.with_company(self.company_2)) + + def test_remove_company_with_progress(self): + user = mail_new_test_user( + self.env, + login='erp_manager', + groups="base.group_erp_manager", + ) + self.onboarding_1_step_1.is_per_company = True + + self.onboarding_1._search_or_create_progress() + self.onboarding_1.with_company(self.company_2)._search_or_create_progress() + self.assertEqual(len(self.onboarding_1.progress_ids), 2) + + # group_erp_manager has no access to onboardng, compute_current_progress is the focus of this test + self.company_2.with_user(user).unlink() + self.onboarding_1._compute_current_progress() + self.assertEqual(len(self.onboarding_1.progress_ids), 1)