From aff1a6caae4105412c4f2ae029bd00f49aff8c66 Mon Sep 17 00:00:00 2001 From: Quentin Mondot Date: Thu, 9 Apr 2026 09:42:36 +0200 Subject: [PATCH] [IMP] survey_record_generation : new option update_existing_fields --- survey_record_generation/README.rst | 5 ++ survey_record_generation/__manifest__.py | 2 +- survey_record_generation/i18n/fr.po | 66 +++++--------- .../models/survey_record_creation.py | 5 ++ .../models/survey_user_input.py | 15 ++-- .../tests/test_survey_record_creation.py | 88 ++++++++++++++++++- .../views/survey_survey_views.xml | 19 ++-- 7 files changed, 139 insertions(+), 61 deletions(-) diff --git a/survey_record_generation/README.rst b/survey_record_generation/README.rst index e03d218..acfd1ef 100644 --- a/survey_record_generation/README.rst +++ b/survey_record_generation/README.rst @@ -72,7 +72,12 @@ Record generation configuration For m2o or m2m links, question should be configured before. See Question answers configuration section below. * **other created record**: If value come from other created record (m2o case only) +#. Several options exist for the *record creation* : + #. You can check "Ignore creation if a mandatory field is missing" to prevent the form to crash if some record creations fail. + #. You can check "Update existing records" to update existing records instead of creating it. For this, you need to + precise the "Field to retrieve existing records". Only the first matched record will be updated. By default + the existing values are not replaced, except if you check the option "Update existing values". Question answers configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/survey_record_generation/__manifest__.py b/survey_record_generation/__manifest__.py index f439c17..22845c1 100644 --- a/survey_record_generation/__manifest__.py +++ b/survey_record_generation/__manifest__.py @@ -2,7 +2,7 @@ { "name": "Survey record generation", - 'summary': 'Allow to create record of any model when sending the form', + 'summary': 'Allow to create or update record of any model when sending the form', 'description': """ Allow to create record of any model when sending the form : ---------------------------------------------------- diff --git a/survey_record_generation/i18n/fr.po b/survey_record_generation/i18n/fr.po index 574b4e5..85473d0 100644 --- a/survey_record_generation/i18n/fr.po +++ b/survey_record_generation/i18n/fr.po @@ -4,10 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" +"Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-11-13 16:41+0000\n" -"PO-Revision-Date: 2025-11-13 16:41+0000\n" +"POT-Creation-Date: 2026-04-09 07:55+0000\n" +"PO-Revision-Date: 2026-04-09 07:55+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -44,8 +44,6 @@ msgstr "Question autorisée" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#, python-format msgid "Answer to question: %s" msgstr "Réponse à la question : %s" @@ -130,8 +128,6 @@ msgstr "Type de champ" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#, python-format msgid "Field type is : %s" msgstr "Le type de champ est : %s" @@ -198,22 +194,14 @@ msgid "" "error is ignored." msgstr "" "Si un champs requis est manquant lors de la création de l'enregistrement, " -"une erreur est levée lors de la soumission du formulaire. " -"En activant cette option, l'erreur sera ignorée." +"une erreur est levée lors de la soumission du formulaire. En activant cette " +"option, l'erreur sera ignorée." #. module: survey_record_generation #: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__ignore_if_mandatory_field_is_missing msgid "Ignore creation if a mandatory field is missing" msgstr "Ignorer la création si un champs requis est manquant" -#. module: survey_record_generation -#: model:ir.model.fields,field_description:survey_record_generation.field_survey_generated_record____last_update -#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation____last_update -#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values____last_update -#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m____last_update -msgid "Last Modified on" -msgstr "Dernière modification le" - #. module: survey_record_generation #: model:ir.model.fields,field_description:survey_record_generation.field_survey_generated_record__write_uid #: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__write_uid @@ -269,8 +257,6 @@ msgstr "Pas d'enregistrements générés trouvés" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_question.py:0 -#: code:addons/survey_record_generation/models/survey_question.py:0 -#, python-format msgid "No record found in %s" msgstr "Pas d'enregistrements trouvés parmis %s" @@ -292,7 +278,7 @@ msgstr "" #: model_terms:ir.ui.view,arch_db:survey_record_generation.survey_survey_view_form msgid "" "Only the first matched record will be updated.\n" -" Also to be noticed, the unicity check feature has priority over updating the existing record." +" Also to be noticed, the unicity check feature has priority over updating the existing record." msgstr "" "Attention, seul le premier enregistrement trouvé sera mis à jour. Aussi, si " "vous avez des champs avec une contrainte d'unicité, cette contrainte aura la" @@ -301,8 +287,6 @@ msgstr "" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#, python-format msgid "Other created record: " msgstr "Autre enregistrement créé : " @@ -353,8 +337,6 @@ msgstr "Modèle relatif" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_record_creation.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation.py:0 -#, python-format msgid "Some required fields are not set : %s" msgstr "Certains champs requis ne sont pas remplis : %s" @@ -388,17 +370,25 @@ msgstr "Sondage Création d'enregistrement Valeur des champs" #. module: survey_record_generation #: model:ir.model,name:survey_record_generation.model_survey_user_input msgid "Survey User Input" -msgstr "Saisie utilisateur du sondage" +msgstr "Entrée utilisateur du sondage" #. module: survey_record_generation #: model:ir.model.fields,field_description:survey_record_generation.field_survey_generated_record__survey_record_creation_id msgid "Survey record creation" msgstr "Génération d'enregistrement depuis la participation" +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation__update_existing_values +msgid "" +"The default behavior is to not update the existing fields. If checked, the " +"existing fields will be updated. " +msgstr "" +"Le comportement par défaut est de ne pas mettre à jour les valeurs existantes. Si cette option est cochée, " +"les valeurs existantes seront écrasées." + #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_user_input.py:0 -#, python-format msgid "" "The field %(field)s is mandatory for model %(model)s. In Record Creation " "tab, drag %(record)s on top of the model %(model)s." @@ -407,20 +397,16 @@ msgstr "" "Création d'un enregistrement, placez la ligne %(record)s au dessus de la " "ligne du modèle %(model)s." -#. module: survey_record_generation -#. odoo-python -#: code:addons/survey_record_generation/models/survey_user_input.py:0 -#, python-format -msgid "" -"The field %s is mandatory. In Record Creation tab, drag %s at the top of the" -" table" -msgstr "" - #. module: survey_record_generation #: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__unicity_check msgid "Unicity constraint" msgstr "Contrainte d'unicité" +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__update_existing_values +msgid "Update existing values" +msgstr "Écraser les valeurs existantes" + #. module: survey_record_generation #: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__update_existing_records msgid "Update existing records" @@ -455,17 +441,12 @@ msgstr "Message d'erreur" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#, python-format msgid "You should append at least one record in %s" msgstr "Vous devez au moins ajouter un enregistrement dans %s" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_user_input.py:0 -#, python-format msgid "" "[Survey record generation] The answer values type '%(type)s' is not " "supported (for question %(question)s). Use 'record' or 'value' instead." @@ -477,7 +458,6 @@ msgstr "" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_user_input.py:0 -#, python-format msgid "" "[Survey record generation] The boolean value %s(value)s is not supported " "(for question %(question)s)." @@ -488,7 +468,6 @@ msgstr "" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_user_input.py:0 -#, python-format msgid "" "[Survey record generation] The question type %(type)s is not recognized (for" " question %(question)s)." @@ -499,7 +478,6 @@ msgstr "" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_user_input.py:0 -#, python-format msgid "" "[Survey record generation] The question type %(type)s is not supported yet." msgstr "" @@ -509,8 +487,6 @@ msgstr "" #. module: survey_record_generation #. odoo-python #: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 -#, python-format msgid "possible values are %s" msgstr "les valeurs possibles sont %s" diff --git a/survey_record_generation/models/survey_record_creation.py b/survey_record_generation/models/survey_record_creation.py index fb2eeb1..c4f7118 100644 --- a/survey_record_generation/models/survey_record_creation.py +++ b/survey_record_generation/models/survey_record_creation.py @@ -27,6 +27,11 @@ class SurveyRecordCreation(models.Model): help="Choose the field you want to use to retrieve the existing record. " "WARNING: We update only the first record found.", ) + update_existing_values = fields.Boolean( + string="Update existing values", + help="The default behavior is to not update the existing fields. " + "If checked, the existing fields will be updated. ", + ) allowed_field_ids = fields.Many2many( "ir.model.fields", compute="_compute_allowed_field_ids", diff --git a/survey_record_generation/models/survey_user_input.py b/survey_record_generation/models/survey_user_input.py index 8e3bf7d..a490741 100644 --- a/survey_record_generation/models/survey_user_input.py +++ b/survey_record_generation/models/survey_user_input.py @@ -71,12 +71,15 @@ class SurveyUserInput(models.Model): if duplicate: record = duplicate elif existing_record: - vals_with_keys_not_in_record = { - k: v - for k, v in vals.items() - if not getattr(existing_record, k, False) - } - existing_record.write(vals_with_keys_not_in_record) + if record_creation.update_existing_values: + existing_record.write(vals) + else: + vals_with_keys_not_in_record = { + k: v + for k, v in vals.items() + if not getattr(existing_record, k, False) + } + existing_record.write(vals_with_keys_not_in_record) record = existing_record else: try: diff --git a/survey_record_generation/tests/test_survey_record_creation.py b/survey_record_generation/tests/test_survey_record_creation.py index 243ebf1..4d9ee09 100644 --- a/survey_record_generation/tests/test_survey_record_creation.py +++ b/survey_record_generation/tests/test_survey_record_creation.py @@ -722,9 +722,91 @@ class TestSurveyRecordCreation(SurveyCase): 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") + self.assertEqual(len(partner), 1) + self.assertEqual(partner.email, "jean@test.fr") + self.assertEqual(partner.function, "happiness office manager") + + def test_update_all_fields_when_updating_records(self): + # A contact with name 'Jean' and email 'jean@test.fr' already exists. + # We'll update the fields 'function' AND 'email' of this partner + # because the option 'update_existing_values' is True + self.env["res.partner"].create( + { + "name": "Jean", + "email": "jean@test.fr", + } + ) + 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, + "update_existing_values": True, + } + ) + 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="IAmTheNewEmailReplacingTheOldOne@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.assertEqual(len(partner), 1) + self.assertEqual(partner.email, "IAmTheNewEmailReplacingTheOldOne@test.fr") + self.assertEqual(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 diff --git a/survey_record_generation/views/survey_survey_views.xml b/survey_record_generation/views/survey_survey_views.xml index e2b486c..cbfe3cb 100644 --- a/survey_record_generation/views/survey_survey_views.xml +++ b/survey_record_generation/views/survey_survey_views.xml @@ -16,12 +16,19 @@
- - - - - - + + + + + + + + + + + + +