[REF] survey: on survey.user_input, rename question_ids field to predefined_question_ids

PURPOSE

As new features are about to land in survey, notably live interactions [1]
and new survey building [2] performing a pre cleaning is necessary. In this
PR we clean survey models by: removing unnecessary fields, cleaning some code
and finally renaming models.

SPECIFICATIONS

``question_ids`` field name is quite difficult to understand as we wonder why
there is such a field on user input model. As its purpose is to store questions
user has to answer (randomly chosen or all chosen) let us rename it to
``predefined_question_ids``.

Moreover starting from now on if it is now given at create it is automatically
computed. Classic flows go through ``survey._create_answer()`` method that
prepares them accordingly. However tests or demo data do not necessarily go
through that method and it makes scoring fail (notably) if people forget
to define them.

Let us automatically generate them at user input create if not given.

LINKS

[0] Related to Task ID 2061901 (survey models cleaning and preparation)
[1] Task ID 1972640 (live interactions)
[2] Task ID 2119587 (new frontend for building surveys)

PR #40765
This commit is contained in:
Thibault Delavallée
2019-12-05 15:21:28 +00:00
parent 3a094f2294
commit 2a35d92b6c
6 changed files with 19 additions and 56 deletions
@@ -314,64 +314,24 @@
<field name="partner_id" ref="base.res_partner_address_3"/>
<field name="email">douglas.fletcher51@example.com</field>
<field name="state">done</field>
<field name="question_ids" eval="[
ref('vendor_certification_page_1_question_1'),
ref('vendor_certification_page_1_question_2'),
ref('vendor_certification_page_1_question_3'),
ref('vendor_certification_page_1_question_4'),
ref('vendor_certification_page_1_question_5'),
ref('vendor_certification_page_2_question_1'),
ref('vendor_certification_page_2_question_2'),
ref('vendor_certification_page_2_question_3'),
]"/>
</record>
<record model="survey.user_input" id="survey_vendor_certification_answer_2">
<field name="survey_id" ref="survey.vendor_certification" />
<field name="partner_id" ref="base.res_partner_address_7"/>
<field name="email">billy.fox45@example.com</field>
<field name="state">done</field>
<field name="question_ids" eval="[
ref('vendor_certification_page_1_question_1'),
ref('vendor_certification_page_1_question_2'),
ref('vendor_certification_page_1_question_3'),
ref('vendor_certification_page_1_question_4'),
ref('vendor_certification_page_1_question_5'),
ref('vendor_certification_page_2_question_1'),
ref('vendor_certification_page_2_question_2'),
ref('vendor_certification_page_2_question_3'),
]"/>
</record>
<record model="survey.user_input" id="survey_vendor_certification_answer_3">
<field name="survey_id" ref="survey.vendor_certification" />
<field name="partner_id" ref="base.res_partner_address_15"/>
<field name="email">brandon.freeman55@example.com</field>
<field name="state">done</field>
<field name="question_ids" eval="[
ref('vendor_certification_page_1_question_1'),
ref('vendor_certification_page_1_question_2'),
ref('vendor_certification_page_1_question_3'),
ref('vendor_certification_page_1_question_4'),
ref('vendor_certification_page_1_question_5'),
ref('vendor_certification_page_2_question_1'),
ref('vendor_certification_page_2_question_2'),
ref('vendor_certification_page_2_question_3'),
]"/>
</record>
<record model="survey.user_input" id="survey_vendor_certification_answer_4">
<field name="survey_id" ref="survey.vendor_certification" />
<field name="partner_id" ref="base.res_partner_address_25"/>
<field name="email">oscar.morgan11@example.com</field>
<field name="state">done</field>
<field name="question_ids" eval="[
ref('vendor_certification_page_1_question_1'),
ref('vendor_certification_page_1_question_2'),
ref('vendor_certification_page_1_question_3'),
ref('vendor_certification_page_1_question_4'),
ref('vendor_certification_page_1_question_5'),
ref('vendor_certification_page_2_question_1'),
ref('vendor_certification_page_2_question_2'),
ref('vendor_certification_page_2_question_3'),
]"/>
</record>
</data>
</odoo>
+3 -4
View File
@@ -238,7 +238,6 @@ class Survey(models.Model):
answer_vals = {
'survey_id': survey.id,
'test_entry': test_entry,
'question_ids': [(6, 0, survey._prepare_answer_questions().ids)]
}
if user and not user._is_public():
answer_vals['partner_id'] = user.partner_id.id
@@ -286,7 +285,7 @@ class Survey(models.Model):
if check_attempts and not self._has_attempts_left(partner or (user and user.partner_id), email, invite_token):
raise UserError(_('No attempts left.'))
def _prepare_answer_questions(self):
def _prepare_user_input_predefined_questions(self):
""" Will generate the questions for a randomized survey.
It uses the random_questions_count of every sections of the survey to
pick a random number of questions and returns the merged recordset """
@@ -350,7 +349,7 @@ class Survey(models.Model):
return None
elif self.questions_layout == 'page_per_question' and self.questions_selection == 'random':
return list(enumerate(
user_input.question_ids
user_input.predefined_question_ids
))
else:
return list(enumerate(
@@ -425,7 +424,7 @@ class Survey(models.Model):
# we need the intersection of the questions of this page AND the questions prepared for that user_input
# (because randomized surveys do not use all the questions of every page)
if answer:
questions = questions & answer.question_ids
questions = questions & answer.predefined_question_ids
return questions, page_or_question_id
# ------------------------------------------------------------
+11 -2
View File
@@ -41,7 +41,7 @@ class SurveyUserInput(models.Model):
email = fields.Char('E-mail', readonly=True)
# questions / answers
user_input_line_ids = fields.One2many('survey.user_input.line', 'user_input_id', string='Answers', copy=True)
question_ids = fields.Many2many('survey.question', string='Predefined Questions', readonly=True)
predefined_question_ids = fields.Many2many('survey.question', string='Predefined Questions', readonly=True)
scoring_percentage = fields.Float("Score (%)", compute="_compute_scoring_percentage", store=True, compute_sudo=True) # stored for perf reasons
scoring_success = fields.Boolean('Quizz Passed', compute='_compute_scoring_success', store=True, compute_sudo=True) # stored for perf reasons
@@ -54,7 +54,7 @@ class SurveyUserInput(models.Model):
for user_input in self:
total_possible_score = sum([
answer_score if answer_score > 0 else 0
for answer_score in user_input.question_ids.mapped('suggested_answer_ids.answer_score')
for answer_score in user_input.predefined_question_ids.mapped('suggested_answer_ids.answer_score')
])
if total_possible_score == 0:
@@ -109,6 +109,15 @@ class SurveyUserInput(models.Model):
user_input.attempts_number = attempts_number
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if 'predefined_question_ids' not in vals:
suvey_id = vals.get('survey_id', self.env.context.get('default_survey_id'))
survey = self.env['survey.survey'].browse(suvey_id)
vals['predefined_question_ids'] = [(6, 0, survey._prepare_user_input_predefined_questions().ids)]
return super(SurveyUserInput, self).create(vals_list)
def action_resend(self):
partners = self.env['res.partner']
emails = []
+1 -1
View File
@@ -42,7 +42,7 @@ class TestSurveyRandomize(TransactionCase):
'questions_selection': 'random'
})
generated_questions = self.survey1._prepare_answer_questions()
generated_questions = self.survey1._prepare_user_input_predefined_questions()
self.assertEqual(len(generated_questions.ids), 10, msg="Expected 10 unique questions")
self.assertEqual(len(generated_questions.filtered(lambda question: question.page_id == page_1)), 3, msg="Expected 3 questions in page 1")
+4 -4
View File
@@ -79,7 +79,7 @@
<t t-if="survey.questions_layout == 'one_page'">
<t t-foreach='survey.question_and_page_ids' t-as='question'>
<h2 t-if="question.is_page" t-field='question.title' class="o_survey_title" />
<t t-if="not question.is_page and question in answer.question_ids" t-call="survey.question_container"/>
<t t-if="not question.is_page and question in answer.predefined_question_ids" t-call="survey.question_container"/>
</t>
<div class="text-center mt16 mb256">
@@ -93,7 +93,7 @@
<input type="hidden" name="page_id" t-att-value="page.id" />
<t t-foreach='page.question_ids' t-as='question'>
<t t-if="question in answer.question_ids" t-call="survey.question_container"/>
<t t-if="question in answer.predefined_question_ids" t-call="survey.question_container"/>
</t>
<div class="text-center mt16 mb256">
@@ -110,7 +110,7 @@
<t t-call="survey.question_container"/>
<div class="text-center mt16 mb256">
<button t-if="survey.users_can_go_back and question != answer.question_ids[0]" type="submit" class="btn btn-secondary"
<button t-if="survey.users_can_go_back and question != answer.predefined_question_ids[0]" type="submit" class="btn btn-secondary"
name="button_submit" value="previous" t-att-data-previous-page-id="previous_page_id">Previous page</button>
<button type="submit" t-att-value="'next' if not last else 'finish'" class="btn btn-primary">
<t t-esc="'Next Page' if not last else 'Submit Survey'"/>
@@ -368,7 +368,7 @@
<h1 t-field='question.title' />
<div t-if="question.description" t-field='question.description' class="oe_no_empty"/>
</div>
<t t-if="not question.is_page and not answer or (question in answer.question_ids)" >
<t t-if="not question.is_page and not answer or (question in answer.predefined_question_ids)" >
<t t-set="answer_lines" t-value="answer.user_input_line_ids.filtered(lambda line: line.question_id == question)"/>
<div class="js_question-wrapper" t-att-id="question.id">
<h2>
@@ -109,11 +109,6 @@
<field name="partner_id" ref="base.res_partner_address_3"/>
<field name="email">douglas.fletcher51@example.com</field>
<field name="state">done</field>
<field name="question_ids" eval="[
ref('furniture_certification_page_1_question_1'),
ref('furniture_certification_page_1_question_2'),
ref('furniture_certification_page_1_question_3'),
]"/>
</record>
<record model="survey.user_input" id="furniture_certification_answer_2">
<field name="survey_id" ref="website_slides_survey.furniture_certification" />