[FIX] survey: copy the triggering question to the right question

Steps to reproduce:

  - Install 'survey' module
  - Create a survey with 2 questions
  - Change the sequence of the questions
  - Edit the second question (last in the sequence)
  - Set it as conditional
  - Select first question as trigger (with any answer)
  - Duplicate the survey

Issue:

  The triggering question is not set on the right question.

Cause:

  When copying the survey, we map the old question to the new ones but
  there are by default sorted by order of creation and not by sequence
  and therefore the mapping is wrong.

Solution:

  Order the questions and answers by sequence before mapping them.

opw-3330476

closes odoo/odoo#127681

X-original-commit: 70f7e13c38acd07ea04324bc78e379dac6051e41
Signed-off-by: Nasreddin Boulif (bon) <bon@odoo.com>
This commit is contained in:
Nasreddin Boulif (bon)
2023-07-06 23:44:32 +02:00
parent a49106aad7
commit 2cdebb3783
2 changed files with 51 additions and 5 deletions
+11 -5
View File
@@ -396,13 +396,19 @@ class Survey(models.Model):
if default and 'question_ids' in default:
return clone
questions_map = {src.id: dst.id for src, dst in zip(self.question_ids, clone.question_ids)}
src_questions = self.question_ids
dst_questions = clone.question_ids.sorted()
questions_map = {src.id: dst.id for src, dst in zip(src_questions, dst_questions)}
answers_map = {
source_answer.id: copy_answer.id
for source_answer, copy_answer
in zip(self.question_ids.suggested_answer_ids, clone.question_ids.suggested_answer_ids)
src_answer.id: dst_answer.id
for src, dst
in zip(src_questions, dst_questions)
for src_answer, dst_answer
in zip(src.suggested_answer_ids, dst.suggested_answer_ids.sorted())
}
for src, dst in zip(self.question_ids, clone.question_ids):
for src, dst in zip(src_questions, dst_questions):
if src.is_conditional:
dst.is_conditional = True
dst.triggering_question_id = questions_map.get(src.triggering_question_id.id)
+40
View File
@@ -406,6 +406,46 @@ class TestSurveyInternals(common.TestSurveyCommon):
self.assertNotEqual(q_food_not_vegetarian_cloned.triggering_answer_id.id,
q_is_vegetarian.suggested_answer_ids[1].id)
@users('survey_manager')
def test_copy_conditional_question_with_sequence_changed(self):
""" Create a survey with two questions, change the sequence of the questions,
set the second question as conditional on the first one, and check that the conditional
question is still conditional on the first one after copying the survey."""
def get_question_by_title(survey, title):
return survey.question_ids.filtered(lambda q: q.title == title)[0]
# Create the survey questions
q_1 = self._add_question(
self.page_0, 'Q1', 'multiple_choice', survey_id=self.survey.id,
sequence=200, labels=[{'value': 'Yes'}, {'value': 'No'}])
q_2 = self._add_question(
self.page_0, 'Q2', 'multiple_choice', survey_id=self.survey.id,
sequence=300, labels=[{'value': 'Yes'}, {'value': 'No'}])
# Change the sequence of the second question to be before the first one
q_2.write({'sequence': 100})
# Set a conditional question on the first question
q_1.write({
'is_conditional': True,
'triggering_question_id': q_2.id,
'triggering_answer_id': q_2.suggested_answer_ids[0].id,
})
(q_1 | q_2).invalidate_recordset()
# Clone the survey
cloned_survey = self.survey.copy()
# Check that the sequence of the questions are the same as the original survey
self.assertEqual(get_question_by_title(cloned_survey, 'Q1').sequence, q_1.sequence)
self.assertEqual(get_question_by_title(cloned_survey, 'Q2').sequence, q_2.sequence)
# Check that the conditional question is correctly copied to the right question
self.assertEqual(get_question_by_title(cloned_survey, 'Q1').triggering_question_id.title, q_1.triggering_question_id.title)
self.assertFalse(get_question_by_title(cloned_survey, 'Q2').triggering_question_id)
@users('survey_manager')
def test_unlink_triggers(self):
# Create the survey questions