[FIX] survey: correctly consider all non-answered questions as skipped
Currently, if the survey participant does not answer questions of type: - simple_choice - multiple_choice - matrix The system does not register any survey.user_input_line with the "skipped" attribute set to True. Meaning that this question's answer will not appear in the survey statistics as skipped (in fact it will not appear at all). This commit makes sure we correctly save a user_input_line set as skipped=True when not answering to those types of questions. A unit test has been added to make sure that we consider every non-answered question type as properly skipped within the survey statistics. Task-2622869 X-original-commit: 87ea302044ff7ac26888000101254b1af2524046 Part-of: odoo/odoo#76606
This commit is contained in:
@@ -393,6 +393,7 @@ class SurveyQuestion(models.Model):
|
||||
if question.question_type in ['simple_choice', 'multiple_choice', 'matrix']:
|
||||
answer_lines = all_lines.filtered(
|
||||
lambda line: line.answer_type == 'suggestion' or (
|
||||
line.skipped and not line.answer_type) or (
|
||||
line.answer_type == 'char_box' and question.comment_count_as_answer)
|
||||
)
|
||||
comment_line_ids = all_lines.filtered(lambda line: line.answer_type == 'char_box')
|
||||
|
||||
@@ -274,6 +274,12 @@ class SurveyUserInput(models.Model):
|
||||
def _save_line_choice(self, question, old_answers, answers, comment):
|
||||
if not (isinstance(answers, list)):
|
||||
answers = [answers]
|
||||
|
||||
if not answers:
|
||||
# add a False answer to force saving a skipped line
|
||||
# this will make this question correctly considered as skipped in statistics
|
||||
answers = [False]
|
||||
|
||||
vals_list = []
|
||||
|
||||
if question.question_type == 'simple_choice':
|
||||
@@ -291,6 +297,11 @@ class SurveyUserInput(models.Model):
|
||||
def _save_line_matrix(self, question, old_answers, answers, comment):
|
||||
vals_list = []
|
||||
|
||||
if not answers and question.matrix_row_ids:
|
||||
# add a False answer to force saving a skipped line
|
||||
# this will make this question correctly considered as skipped in statistics
|
||||
answers = {question.matrix_row_ids[0].id: [False]}
|
||||
|
||||
if answers:
|
||||
for row_key, row_answer in answers.items():
|
||||
for answer in row_answer:
|
||||
|
||||
@@ -147,7 +147,7 @@ class SurveyCase(common.TransactionCase):
|
||||
return self.env['survey.user_input.line'].create(base_alvals)
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# UTILS
|
||||
# UTILS / CONTROLLER ENDPOINTS FLOWS
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def _access_start(self, survey):
|
||||
@@ -216,6 +216,36 @@ class SurveyCase(common.TransactionCase):
|
||||
post_data.update(**additional_post_data)
|
||||
return post_data
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# UTILS / TOOLS
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def _assert_skipped_question(self, question, survey_user):
|
||||
statistics = question._prepare_statistics(survey_user.user_input_line_ids)
|
||||
question_data = next(
|
||||
(question_data
|
||||
for question_data in statistics
|
||||
if question_data.get('question') == question),
|
||||
False
|
||||
)
|
||||
self.assertTrue(bool(question_data))
|
||||
self.assertEqual(len(question_data.get('answer_input_skipped_ids')), 1)
|
||||
|
||||
def _create_one_question_per_type(self):
|
||||
all_questions = self.env['survey.question']
|
||||
for (question_type, dummy) in self.env['survey.question']._fields['question_type'].selection:
|
||||
kwargs = {}
|
||||
if question_type == 'multiple_choice':
|
||||
kwargs['labels'] = [{'value': 'MChoice0'}, {'value': 'MChoice1'}]
|
||||
elif question_type == 'simple_choice':
|
||||
kwargs['labels'] = []
|
||||
elif question_type == 'matrix':
|
||||
kwargs['labels'] = [{'value': 'Column0'}, {'value': 'Column1'}]
|
||||
kwargs['labels_2'] = [{'value': 'Row0'}, {'value': 'Row1'}]
|
||||
all_questions |= self._add_question(self.page_0, 'Q0', question_type, **kwargs)
|
||||
|
||||
return all_questions
|
||||
|
||||
|
||||
class TestSurveyCommon(SurveyCase):
|
||||
def setUp(self):
|
||||
|
||||
@@ -11,17 +11,7 @@ class TestSurveyInternals(common.TestSurveyCommon):
|
||||
@users('survey_manager')
|
||||
def test_answer_validation_mandatory(self):
|
||||
""" For each type of question check that mandatory questions correctly check for complete answers """
|
||||
for (question_type, text) in self.env['survey.question']._fields['question_type'].selection:
|
||||
kwargs = {}
|
||||
if question_type == 'multiple_choice':
|
||||
kwargs['labels'] = [{'value': 'MChoice0'}, {'value': 'MChoice1'}]
|
||||
elif question_type == 'simple_choice':
|
||||
kwargs['labels'] = []
|
||||
elif question_type == 'matrix':
|
||||
kwargs['labels'] = [{'value': 'Column0'}, {'value': 'Column1'}]
|
||||
kwargs['labels_2'] = [{'value': 'Row0'}, {'value': 'Row1'}]
|
||||
question = self._add_question(self.page_0, 'Q0', question_type, **kwargs)
|
||||
|
||||
for question in self._create_one_question_per_type():
|
||||
self.assertDictEqual(
|
||||
question.validate_question(''),
|
||||
{question.id: 'TestError'}
|
||||
@@ -113,3 +103,19 @@ class TestSurveyInternals(common.TestSurveyCommon):
|
||||
question.validate_question('valid'),
|
||||
{}
|
||||
)
|
||||
|
||||
@users('survey_manager')
|
||||
def test_skipped_values(self):
|
||||
""" Create one question per type of questions.
|
||||
Make sure they are correctly registered as 'skipped' after saving an empty answer for each
|
||||
of them. """
|
||||
|
||||
questions = self._create_one_question_per_type()
|
||||
survey_user = self.survey._create_answer(user=self.survey_user)
|
||||
|
||||
for question in questions:
|
||||
answer = '' if question.question_type in ['char_box', 'text_box'] else None
|
||||
survey_user.save_lines(question, answer)
|
||||
|
||||
for question in questions:
|
||||
self._assert_skipped_question(question, survey_user)
|
||||
|
||||
Reference in New Issue
Block a user