diff --git a/addons/survey/__manifest__.py b/addons/survey/__manifest__.py index e21f4699d42..1c0235afb6d 100644 --- a/addons/survey/__manifest__.py +++ b/addons/survey/__manifest__.py @@ -2,7 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. { 'name': 'Surveys', - 'version': '3.1', + 'version': '3.2', 'category': 'Marketing/Surveys', 'description': """ Create beautiful surveys and visualize answers diff --git a/addons/survey/models/survey_question.py b/addons/survey/models/survey_question.py index 328f1b013b7..d9e7fef33dc 100644 --- a/addons/survey/models/survey_question.py +++ b/addons/survey/models/survey_question.py @@ -79,7 +79,8 @@ class SurveyQuestion(models.Model): ('datetime', 'Datetime'), ('simple_choice', 'Multiple choice: only one answer'), ('multiple_choice', 'Multiple choice: multiple answers allowed'), - ('matrix', 'Matrix')], string='Question Type') + ('matrix', 'Matrix')], string='Question Type', + compute='_compute_question_type', readonly=False, store=True) is_scored_question = fields.Boolean( 'Scored', compute='_compute_is_scored_question', readonly=False, store=True, copy=True, @@ -170,15 +171,11 @@ class SurveyQuestion(models.Model): 'All "Is a scored question = True" and "Question Type: Date" questions need an answer') ] - @api.onchange('validation_email') - def _onchange_validation_email(self): - if self.validation_email: - self.validation_required = False - - @api.onchange('is_page') - def _onchange_is_page(self): - if self.is_page: - self.question_type = False + @api.depends('is_page') + def _compute_question_type(self): + for question in self: + if not question.question_type or question.is_page: + question.question_type = False @api.depends('survey_id.question_and_page_ids.is_page', 'survey_id.question_and_page_ids.sequence') def _compute_question_ids(self): diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index 3f1ac0a7b41..aafe2937799 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -106,9 +106,10 @@ class Survey(models.Model): compute="_compute_is_attempts_limited", store=True, readonly=False) attempts_limit = fields.Integer('Number of attempts', default=1) is_time_limited = fields.Boolean('The survey is limited in time') - time_limit = fields.Float("Time limit (minutes)") + time_limit = fields.Float("Time limit (minutes)", default=10) # certification - certification = fields.Boolean('Is a Certification') + certification = fields.Boolean('Is a Certification', compute='_compute_certification', + readonly=False, store=True) certification_mail_template_id = fields.Many2one( 'mail.template', 'Email Template', domain="[('model', '=', 'survey.user_input')]", @@ -126,7 +127,8 @@ class Survey(models.Model): # - If the certification badge is not set, show certification_badge_id and only display create option in the m2o # - 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') + 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') certification_badge_id_dummy = fields.Many2one(related='certification_badge_id', string='Certification Badge ') # live sessions @@ -157,6 +159,8 @@ class Survey(models.Model): ('session_code_unique', 'unique(session_code)', 'Session code should be unique'), ('certification_check', "CHECK( scoring_type!='no_scoring' OR certification=False )", 'You can only create certifications for surveys that have a scoring mechanism.'), + ('scoring_success_min_check', "CHECK( scoring_success_min IS NULL OR (scoring_success_min>=0 AND scoring_success_min<=100) )", + 'The percentage of success has to be defined between 0 and 100.'), ('time_limit_check', "CHECK( (is_time_limited=False) OR (time_limit is not null AND time_limit > 0) )", 'The time limit needs to be a positive number if the survey is time limited.'), ('attempts_limit_check', "CHECK( (is_attempts_limited=False) OR (attempts_limit is not null AND attempts_limit > 0) )", @@ -207,9 +211,9 @@ class Survey(models.Model): @api.depends('question_and_page_ids.is_conditional', 'users_login_required', 'access_mode') def _compute_is_attempts_limited(self): for survey in self: - if any(question.is_conditional for question in survey.question_and_page_ids)\ - or (survey.access_mode == 'public' and not survey.users_login_required)\ - or survey.is_attempts_limited is None: + if not survey.is_attempts_limited or \ + (survey.access_mode == 'public' and not survey.users_login_required) or \ + any(question.is_conditional for question in survey.question_and_page_ids): survey.is_attempts_limited = False @api.depends('session_start_time', 'user_input_ids') @@ -276,36 +280,24 @@ class Survey(models.Model): for survey in self: survey.has_conditional_questions = any(question.is_conditional for question in survey.question_and_page_ids) - @api.onchange('scoring_success_min') - def _onchange_scoring_success_min(self): - if self.scoring_success_min < 0 or self.scoring_success_min > 100: - self.scoring_success_min = 80.0 + @api.depends('scoring_type') + def _compute_certification(self): + for survey in self: + if not survey.certification or survey.scoring_type == 'no_scoring': + survey.certification = False - @api.onchange('scoring_type') - def _onchange_scoring_type(self): - if self.scoring_type == 'no_scoring': - self.certification = False - self.is_time_limited = False - - @api.onchange('attempts_limit') - def _onchange_attempts_limit(self): - if self.attempts_limit <= 0: - self.attempts_limit = 1 - - @api.onchange('is_time_limited', 'time_limit') - def _onchange_time_limit(self): - if self.is_time_limited and (not self.time_limit or self.time_limit <= 0): - self.time_limit = 10 + @api.depends('users_login_required', 'certification') + def _compute_certification_give_badge(self): + for survey in self: + if not survey.certification_give_badge or \ + not survey.users_login_required or \ + not survey.certification: + survey.certification_give_badge = False def _read_group_states(self, values, domain, order): selection = self.env['survey.survey'].fields_get(allfields=['state'])['state']['selection'] return [s[0] for s in selection] - @api.onchange('users_login_required', 'certification') - def _onchange_set_certification_give_badge(self): - if not self.users_login_required or not self.certification: - self.certification_give_badge = False - # ------------------------------------------------------------ # CRUD # ------------------------------------------------------------ diff --git a/addons/survey/wizard/survey_invite.py b/addons/survey/wizard/survey_invite.py index 7896cddfa0e..da42a9a6860 100644 --- a/addons/survey/wizard/survey_invite.py +++ b/addons/survey/wizard/survey_invite.py @@ -28,8 +28,8 @@ class SurveyInvite(models.TransientModel): return self.env.user.partner_id # composer content - subject = fields.Char('Subject') - body = fields.Html('Contents', default='', sanitize_style=True) + subject = fields.Char('Subject', compute='_compute_template_values', readonly=False, store=True) + body = fields.Html('Contents', sanitize_style=True, compute='_compute_template_values', readonly=False, store=True) attachment_ids = fields.Many2many( 'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id', string='Attachments') @@ -137,12 +137,16 @@ class SurveyInvite(models.TransientModel): _('The following recipients have no user account: %s. You should create user accounts for them or allow external signup in configuration.' % (','.join(invalid_partners.mapped('name'))))) - @api.onchange('template_id') - def _onchange_template_id(self): - """ UPDATE ME """ - if self.template_id: - self.subject = self.template_id.subject - self.body = self.template_id.body_html + @api.depends('template_id') + def _compute_template_values(self): + for invite in self: + if not invite.subject: + invite.subject = '' + if not invite.body: + invite.body = '' + if invite.template_id: + invite.subject = invite.template_id.subject + invite.body = invite.template_id.body_html @api.model def create(self, values):