[IMP] survey_record_generation: feature be able to update existing record

This commit is contained in:
2025-10-24 16:57:49 +02:00
parent fd25c2b970
commit dd5dbcc492
4 changed files with 246 additions and 30 deletions

View File

@@ -14,6 +14,14 @@ class SurveyRecordCreation(models.Model):
name = fields.Char('Name') name = fields.Char('Name')
survey_id = fields.Many2one('survey.survey', string="Survey") survey_id = fields.Many2one('survey.survey', string="Survey")
model_id = fields.Many2one('ir.model', "Model", help="Model of generated record") model_id = fields.Many2one('ir.model', "Model", help="Model of generated record")
update_existing_records = fields.Boolean(
string="Update existing records",
)
field_to_retrieve_existing_records = fields.Many2one(
"ir.model.fields",
domain="[('model_id','=',model_id),('readonly','=',False),('ttype','in',['char','text'])]",
ondelete="cascade"
)
field_values_ids = fields.One2many('survey.record.creation.field.values', 'survey_record_creation_id', string="Field values") field_values_ids = fields.One2many('survey.record.creation.field.values', 'survey_record_creation_id', string="Field values")
warning_message = fields.Html('Warning message', compute="_compute_warning_message") warning_message = fields.Html('Warning message', compute="_compute_warning_message")
sequence = fields.Integer("sequence") sequence = fields.Integer("sequence")
@@ -40,4 +48,3 @@ class SurveyRecordCreation(models.Model):

View File

@@ -64,12 +64,21 @@ class SurveyUserInput(models.Model):
vals[field_name] = value vals[field_name] = value
existing_record = self.find_existing_record(record_creation, vals)
duplicate = self.find_duplicate_if_there_are_fields_with_unicity_check( duplicate = self.find_duplicate_if_there_are_fields_with_unicity_check(
model, record_creation, vals model, record_creation, vals
) )
if duplicate: if duplicate:
record = duplicate record = duplicate
elif existing_record:
vals = {
k: v
for k, v in vals.items()
if not getattr(existing_record, k, False)
}
record = existing_record.write(vals)
else: else:
if ( if (
model == "res.partner" model == "res.partner"
@@ -110,6 +119,20 @@ class SurveyUserInput(models.Model):
return super()._mark_done() return super()._mark_done()
def find_existing_record(
self, record_creation: "SurveyRecordCreation", vals: dict
) -> Any:
if record_creation.update_existing_records:
model = record_creation.model_id.model
search_field = record_creation.field_to_retrieve_existing_records
existing_value = vals.get(search_field.name)
if existing_value:
return self.env[model].search(
domain=[(search_field.name, "=", existing_value)], limit=1
)
return None
def get_value_based_on_value_origin( def get_value_based_on_value_origin(
self, self,
field_value: "SurveyRecordCreationFieldValues", field_value: "SurveyRecordCreationFieldValues",

View File

@@ -495,9 +495,9 @@ class TestSurveyRecordCreation(SurveyCase):
) )
self.second_answer._mark_done() self.second_answer._mark_done()
partners = self.env["res.partner"].search([("name", "=", "Jean")]) partner = self.env["res.partner"].search([("name", "=", "Jean")])
self.assertTrue(partner.name == "Jean") self.assertTrue(partner.name == "Jean")
self.assertFalse(len(partners) == 2) self.assertTrue(len(partner) == 1)
def test_some_questions_are_not_answered(self): def test_some_questions_are_not_answered(self):
self.question_email = self._add_question( self.question_email = self._add_question(
@@ -654,3 +654,187 @@ class TestSurveyRecordCreation(SurveyCase):
partner = self.env["res.partner"].search([("name", "=", "Jean")]) partner = self.env["res.partner"].search([("name", "=", "Jean")])
self.assertTrue(partner.employee) self.assertTrue(partner.employee)
def test_update_existing_record(self):
# A contact with name 'Jean' already exists.
# We'll update the email of this partner (and not create a new one)
self.env["res.partner"].create({"name": "Jean"})
self.question_email = self._add_question(
page=None,
name="Email",
qtype="char_box",
survey_id=self.survey.id,
sequence=1,
)
self.survey_record_creation.write(
{
"update_existing_records": True,
"field_to_retrieve_existing_records": self.name_field.id,
}
)
email_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "email")]
)
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": email_field.id,
"value_origin": "question",
"question_id": self.question_email.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._add_answer_line(
question=self.question_email,
answer=self.answer,
answer_value="jean@test.fr",
)
self.answer._mark_done()
partner = self.env["res.partner"].search([("name", "=", "Jean")])
self.assertTrue(len(partner) == 1)
self.assertTrue(partner.email == "jean@test.fr")
def test_update_only_empty_fields_when_updating_records(self):
# A contact with name 'Jean' and email 'jean@test.fr' already exists.
# We'll update the field 'function' of this partner and won't update the email
# because it's already filled up
self.env["res.partner"].create(
{
"name": "Jean",
"email": "jean@test.fr",
# when the survey is submitted, email should not be updated
}
)
self.question_email = self._add_question(
page=None,
name="Email",
qtype="char_box",
survey_id=self.survey.id,
sequence=1,
)
self.question_function = self._add_question(
page=None,
name="Function",
qtype="char_box",
survey_id=self.survey.id,
sequence=1,
)
self.survey_record_creation.write(
{
"update_existing_records": True,
"field_to_retrieve_existing_records": self.name_field.id,
}
)
email_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "email")]
)
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": email_field.id,
"value_origin": "question",
"question_id": self.question_email.id,
}
)
function_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "function")]
)
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": function_field.id,
"value_origin": "question",
"question_id": self.question_function.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._add_answer_line(
question=self.question_email,
answer=self.answer,
answer_value="ThisEmailShouldNotBeUpdated@test.fr",
)
self._add_answer_line(
question=self.question_function,
answer=self.answer,
answer_value="happiness office manager",
)
self.answer._mark_done()
partner = self.env["res.partner"].search([("name", "=", "Jean")])
self.assertTrue(len(partner) == 1)
self.assertTrue(partner.email == "jean@test.fr")
self.assertTrue(partner.function == "happiness office manager")
def test_unicity_check_has_priority_over_update(self):
# In this test, we verify that if a field is set up with unicity_check
# it has priority over updating the existing record
self.name_survey_record_creation_field_values.unicity_check = True
self.env["res.partner"].create({"name": "Jean"})
self.question_email = self._add_question(
page=None,
name="Email",
qtype="char_box",
survey_id=self.survey.id,
sequence=1,
)
self.survey_record_creation.write(
{
"update_existing_records": True,
"field_to_retrieve_existing_records": self.name_field.id,
}
)
email_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "email")]
)
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": email_field.id,
"value_origin": "question",
"question_id": self.question_email.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._add_answer_line(
question=self.question_email,
answer=self.answer,
answer_value="jean@test.fr",
)
self.answer._mark_done()
partner = self.env["res.partner"].search([("name", "=", "Jean")])
self.assertTrue(len(partner) == 1)
self.assertTrue(getattr(partner, "Email", None) is None)

View File

@@ -18,6 +18,8 @@
<group> <group>
<field name="name" /> <field name="name" />
<field name="model_id" /> <field name="model_id" />
<field name="update_existing_records" />
<field name="field_to_retrieve_existing_records" />
<field name="field_values_ids"> <field name="field_values_ids">
<tree> <tree>
<field name="field_id" /> <field name="field_id" />