[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
This commit is contained in:
Dharmraj Jhala
2021-01-04 15:10:11 +00:00
committed by Thibault Delavallée
parent dcd644a7e0
commit 637a68a46e
3 changed files with 15 additions and 39 deletions
+5 -4
View File
@@ -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),
@@ -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!"})
+2 -1
View File
@@ -121,7 +121,8 @@
icon="fa-external-link" target="_blank" class="btn-link pt-0"/>
</div>
<field name="certification_give_badge" attrs="{'invisible': ['|', ('certification', '=', False), ('users_login_required', '=', False)]}" />
<field name="certification_badge_id" attrs="{'invisible': ['|', ('certification_give_badge', '=', False), ('certification_badge_id', '!=', False)]}"
<field name="certification_badge_id"
attrs="{'invisible': ['|', ('certification_give_badge', '=', False), ('certification_badge_id', '!=', False)], 'required': [('certification_give_badge', '=', True)]}"
domain="[('survey_id', '=', active_id), ('survey_id', '!=', False)]"
context="{'default_name': title,
'default_description': 'Congratulations, you have succeeded this certification',