diff --git a/survey_record_generation/models/survey_user_input.py b/survey_record_generation/models/survey_user_input.py index 8cccae0..68b2192 100644 --- a/survey_record_generation/models/survey_user_input.py +++ b/survey_record_generation/models/survey_user_input.py @@ -61,6 +61,11 @@ class SurveyUserInput(models.Model): ) field_name: str = field_value.field_id.name + if value is None: + # No value (e.g. question not displayed or skipped): + # keep the default/computed value of the field, and + # let another question fill up the same field. + continue vals[field_name] = value existing_record = self.find_existing_record(record_creation, vals) @@ -195,7 +200,7 @@ class SurveyUserInput(models.Model): if unique_fields: uniq_domain = [] for uniq_field in unique_fields: - uniq_domain.append((uniq_field, "=", vals[uniq_field])) + uniq_domain.append((uniq_field, "=", vals.get(uniq_field, False))) duplicate = self.env[model].search(uniq_domain, limit=1) return duplicate diff --git a/survey_record_generation/tests/test_computed_fields.py b/survey_record_generation/tests/test_computed_fields.py index 79f14ce..4ae40b2 100644 --- a/survey_record_generation/tests/test_computed_fields.py +++ b/survey_record_generation/tests/test_computed_fields.py @@ -110,3 +110,11 @@ class TestComputedFields(SurveyCase): self.assertEqual(len(line), 1) self.assertEqual(line.price_unit, 33.0) + + def test_computed_field_applies_when_question_is_not_displayed(self): + # E.g. the "free amount" question is only displayed when the user + # chose "Other amount": otherwise the line keeps the computed price. + line = self._submit() + + self.assertEqual(len(line), 1) + self.assertEqual(line.price_unit, 20.0) diff --git a/survey_record_generation/tests/test_survey_record_creation.py b/survey_record_generation/tests/test_survey_record_creation.py index 79e5e75..17f007e 100644 --- a/survey_record_generation/tests/test_survey_record_creation.py +++ b/survey_record_generation/tests/test_survey_record_creation.py @@ -1072,3 +1072,82 @@ class TestSurveyRecordCreation(SurveyCase): self.assertEqual(self.answer.partner_id, jean) self.assertNotEqual(self.answer.partner_id, jeanne) self.assertEqual(self.answer.email, jean.email) + + def test_question_not_displayed_does_not_override_default_value(self): + # When a question is not displayed to the user (e.g. a conditional + # question), the field must keep its default (or computed) value + # instead of being emptied. + question_type = self._add_question( + page=None, + name="Type", + qtype="simple_choice", + labels=[{"value": "contact"}, {"value": "other"}], + survey_id=self.survey.id, + sequence=2, + answer_values_type="value", + ) + for suggested_answer in question_type.suggested_answer_ids: + suggested_answer.value_char = suggested_answer.value + type_field = self.env["ir.model.fields"]._get("res.partner", "type") + self.env["survey.record.creation.field.values"].create( + { + "survey_record_creation_id": self.survey_record_creation.id, + "survey_id": self.survey.id, + "model_id": self.res_partner_model.id, + "field_id": type_field.id, + "value_origin": "question", + "question_id": question_type.id, + } + ) + + self.answer = self._add_answer( + survey=self.survey, partner=False, email="jean@test.fr" + ) + self._add_answer_line( + question=self.question_name, answer=self.answer, answer_value="Jean" + ) + self.answer._mark_done() + + partner = self.env["res.partner"].search([("name", "=", "Jean")]) + self.assertEqual(partner.type, "contact") + + def test_several_conditional_questions_on_the_same_field(self): + # Several questions can fill up the same field (e.g. one list of + # amounts per periodicity, displayed conditionally): the answered + # question wins, the questions not displayed are ignored. + street_field = self.env["ir.model.fields"]._get("res.partner", "street") + questions = self.env["survey.question"] + for sequence, name in enumerate(["Street (France)", "Street (abroad)"], 2): + question = self._add_question( + page=None, + name=name, + qtype="char_box", + survey_id=self.survey.id, + sequence=sequence, + ) + self.env["survey.record.creation.field.values"].create( + { + "survey_record_creation_id": self.survey_record_creation.id, + "survey_id": self.survey.id, + "model_id": self.res_partner_model.id, + "field_id": street_field.id, + "value_origin": "question", + "question_id": question.id, + } + ) + questions |= question + + self.answer = self._add_answer( + survey=self.survey, partner=False, email="jean@test.fr" + ) + self._add_answer_line( + question=self.question_name, answer=self.answer, answer_value="Jean" + ) + # Only the first question is displayed and answered + self._add_answer_line( + question=questions[0], answer=self.answer, answer_value="1 rue de Paris" + ) + self.answer._mark_done() + + partner = self.env["res.partner"].search([("name", "=", "Jean")]) + self.assertEqual(partner.street, "1 rue de Paris")