[FIX] survey_record_generation: questions without answer no longer empty fields
When a question was not displayed (conditional question) or skipped, its field was still given to create() with a None value. The field was then emptied instead of keeping its default or computed value. Since the link to an already created record is given at creation, this also made sale.subscription.line price_unit equal to 0 when the "free amount" question was not displayed, instead of the product price. Fields without value are now left out of the values, which also allows several conditional questions to fill up the same field (e.g. one list of amounts per periodicity). Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user