From 637a68a46e90a636ea2c9d279a81ce5bda46aa0b Mon Sep 17 00:00:00 2001 From: Dharmraj Jhala Date: Thu, 4 Jun 2020 05:01:15 +0000 Subject: [PATCH] [IMP] survey: allow to duplicate survey with badge Before this commit, if a badge is set on the survey, duplicating it always results into a traceback due to sql constraint. Indeed due to uniqueness constraints between survey and badge having the same badge for a duplicated survey was leading to an error. We had two options * duplicate the badge itself; * remove sql constraint and add a required on badge in view when having a certification (aka, survey giving a badge); First solution is somehow limited. It means updating badge name, checking its goal, ensuring all parameters are ok. Moreover it is quite hidden when duplicating survey. End users will maybe not see what to are doing. We choose to remove copy flag on flag and badge. That way end users have to manually re-check the flag, and create a new badge. We remove the hard constraint and set a required in the view so that functionally behavior is the same. Task ID-2265556 PR odoo/odoo#52391 --- addons/survey/models/survey_survey.py | 9 ++-- .../survey/tests/test_certification_badge.py | 42 ++++--------------- addons/survey/views/survey_survey_views.xml | 3 +- 3 files changed, 15 insertions(+), 39 deletions(-) diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index 12f6d7114e3..f2138216323 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -128,8 +128,8 @@ class Survey(models.Model): # - If the certification badge is set, show certification_badge_id_dummy in 'no create' mode. # So it can be edited but not removed or replaced. certification_give_badge = fields.Boolean('Give Badge', compute='_compute_certification_give_badge', - readonly=False, store=True) - certification_badge_id = fields.Many2one('gamification.badge', 'Certification Badge') + readonly=False, store=True, copy=False) + certification_badge_id = fields.Many2one('gamification.badge', 'Certification Badge', copy=False) certification_badge_id_dummy = fields.Many2one(related='certification_badge_id', string='Certification Badge ') # live sessions session_state = fields.Selection([ @@ -166,8 +166,6 @@ class Survey(models.Model): ('attempts_limit_check', "CHECK( (is_attempts_limited=False) OR (attempts_limit is not null AND attempts_limit > 0) )", 'The attempts limit needs to be a positive number if the survey has a limited number of attempts.'), ('badge_uniq', 'unique (certification_badge_id)', "The badge for each survey should be unique!"), - ('give_badge_check', "CHECK(certification_give_badge=False OR (certification_give_badge=True AND certification_badge_id is not null))", - 'Certification badge must be configured if Give Badge is set.'), ] def _compute_users_can_signup(self): @@ -1011,6 +1009,9 @@ class Survey(models.Model): def _create_certification_badge_trigger(self): self.ensure_one() + if not self.certification_badge_id: + raise ValueError(_('Certification Badge is not configured for the survey %(survey_name)s', survey_name=self.title)) + goal = self.env['gamification.goal.definition'].create({ 'name': self.title, 'description': _("%s certification passed", self.title), diff --git a/addons/survey/tests/test_certification_badge.py b/addons/survey/tests/test_certification_badge.py index 037b1e211c3..cb5924e39e2 100644 --- a/addons/survey/tests/test_certification_badge.py +++ b/addons/survey/tests/test_certification_badge.py @@ -65,40 +65,6 @@ class TestCertificationBadge(common.TestSurveyCommon): self.assertTrue(self.certification_survey.active) self.assertTrue(self.certification_badge.active) - def test_give_badge_without_badge(self): - with mute_logger('odoo.sql_db'): - with self.assertRaises(IntegrityError): - self.certification_survey.write({'certification_give_badge': True}) - self.certification_survey.flush(['certification_give_badge']) - - def test_remove_badge_with_give_badge(self): - self.certification_survey.write({ - 'certification_give_badge': True, - 'certification_badge_id': self.certification_badge.id - }) - with mute_logger('odoo.sql_db'): - with self.assertRaises(IntegrityError): - self.certification_survey.write({'certification_badge_id': None}) - self.certification_survey.flush(['certification_badge_id']) - - def test_remove_badge_with_give_badge_multi(self): - self.certification_survey.write({ - 'certification_give_badge': True, - 'certification_badge_id': self.certification_badge.id - }) - self.certification_survey_2.write({ - 'certification_give_badge': True, - 'certification_badge_id': self.certification_badge_2.id - }) - surveys = self.env['survey.survey'].browse([ - self.certification_survey.id, - self.certification_survey_2.id - ]) - with mute_logger('odoo.sql_db'): - with self.assertRaises(IntegrityError): - surveys.write({'certification_badge_id': None}) - surveys.flush(['certification_badge_id']) - def test_set_same_badge_on_multiple_survey(self): self.certification_survey.write({ 'certification_give_badge': True, @@ -114,6 +80,7 @@ class TestCertificationBadge(common.TestSurveyCommon): self.certification_survey.flush() def test_badge_configuration(self): + """ Test badge synchronization """ # add a certification badge on a new survey challenge = self.env['gamification.challenge'].search([('reward_id', '=', self.certification_badge.id)]) self.assertEqual(len(challenge), 0, """A challenge should not exist or be linked to the certification badge @@ -166,6 +133,13 @@ class TestCertificationBadge(common.TestSurveyCommon): self.assertEqual(len(goal), 1, "A goal should be created if the certification badge is activated on a certification survey") + # If 'certification_give_badge' is True but no certification badge is linked, ValueError should be raised + duplicate_survey = self.certification_survey.copy() + self.assertFalse(duplicate_survey.certification_give_badge, "Value for field 'certification_give_badge' should not be copied") + self.assertEqual(duplicate_survey.certification_badge_id, self.env['gamification.badge'], "Badge should be empty") + with self.assertRaises(ValueError): + duplicate_survey.write({'certification_give_badge': True}) + def test_certification_badge_access(self): self.certification_badge.with_user(self.survey_manager).write( {'description': "Spoiler alert: I'm Aegon Targaryen and I sleep with the Dragon Queen, who is my aunt by the way! So I can do whatever I want! Even if I know nothing!"}) diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml index 7fa7c76969d..66939d4b3ab 100644 --- a/addons/survey/views/survey_survey_views.xml +++ b/addons/survey/views/survey_survey_views.xml @@ -121,7 +121,8 @@ icon="fa-external-link" target="_blank" class="btn-link pt-0"/> -