[FIX] onboarding: prevent crash with multiple progress records

Multiple progress records for the same onboarding and company_id (False)
were allowed to be created in several databases which resulted in crashes.

As simple stable fix, we'll select only the latest `onboarding_progress`
records created per onboarding when trying to compute the current_progress_id
and similarly for progress steps.

This will be cleaned with an upgrade script in master so that this code should
not be necessary for long.

Task-3101666

closes odoo/odoo#109257

X-original-commit: 06f2bd985c8b98e708120226daf66b20832000bc
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
This commit is contained in:
Florian Charlier
2023-01-06 08:09:07 +01:00
parent 0f55e6a773
commit b35af33ffb
3 changed files with 38 additions and 0 deletions
@@ -48,6 +48,8 @@ class Onboarding(models.Model):
current_progress_id = onboarding.progress_ids.filtered(
lambda progress: progress.company_id.id in {False, self.env.company.id})
if current_progress_id:
if len(current_progress_id) > 1:
current_progress_id = current_progress_id.sorted('create_date', reverse=True)[0]
onboarding.current_onboarding_state = current_progress_id.onboarding_state
onboarding.current_progress_id = current_progress_id
onboarding.is_onboarding_closed = current_progress_id.is_onboarding_closed
@@ -49,6 +49,8 @@ class OnboardingStep(models.Model):
if step in existing_progress_steps.step_id:
current_progress_step_id = existing_progress_steps.filtered(
lambda progress_step: progress_step.step_id == step)
if len(current_progress_step_id) > 1:
current_progress_step_id = current_progress_step_id.sorted('create_date', reverse=True)[0]
step.current_progress_step_id = current_progress_step_id
step.current_step_state = current_progress_step_id.step_state
else:
@@ -130,3 +130,37 @@ class TestOnboarding(TestOnboardingCommon):
self.onboarding_1._search_or_create_progress()
self.assert_onboarding_is_not_done(self.onboarding_1)
def test_no_crash_on_multiple_progress_records(self):
existing_progress = self.env['onboarding.progress'].search([
('onboarding_id', '=', self.onboarding_1.id), ('company_id', '=', False)
])
self.assertEqual(len(existing_progress), 1)
extra_progress = self.env['onboarding.progress'].create({
'onboarding_id': self.onboarding_1.id,
'company_id': False
})
self.env['onboarding.progress.step'].create([{
'step_id': self.onboarding_1_step_1.id,
'progress_id': progress.id
} for progress in (existing_progress, extra_progress)
])
nb_progress = self.env['onboarding.progress'].search([
('onboarding_id', '=', self.onboarding_1.id), ('company_id', '=', False)], count=True)
nb_progress_steps = self.env['onboarding.progress.step'].search([
('step_id', '=', self.onboarding_1_step_1.id)], count=True)
# Even though multiple onboarding progress (& steps) records exist
self.assertEqual(nb_progress, 2)
self.assertEqual(nb_progress_steps, 2)
# no error is raised, and so we can interact
_ = self.onboarding_1_step_1.current_progress_step_id
self.onboarding_1_step_1.action_set_just_done()
# Same with onboarding progress
_ = self.onboarding_1.current_progress_id
self.onboarding_1.action_close()