diff --git a/setup/survey_record_generation/odoo/addons/survey_record_generation b/setup/survey_record_generation/odoo/addons/survey_record_generation new file mode 120000 index 00000000..aa35f945 --- /dev/null +++ b/setup/survey_record_generation/odoo/addons/survey_record_generation @@ -0,0 +1 @@ +../../../../survey_record_generation \ No newline at end of file diff --git a/setup/survey_record_generation/setup.py b/setup/survey_record_generation/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/survey_record_generation/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/survey_record_generation/README.rst b/survey_record_generation/README.rst new file mode 100644 index 00000000..e03d218a --- /dev/null +++ b/survey_record_generation/README.rst @@ -0,0 +1,146 @@ +======================== +Survey record generation +======================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:03eeb5c11b7d8330051c416331c84103b2641351fdc1d0a1bad43acd09501a33 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsurvey-lightgray.png?logo=github + :target: https://github.com/OCA/survey/tree/16.0/survey_record_generation + :alt: OCA/survey +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/survey-16-0/survey-16-0-survey_record_generation + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/survey&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to generate any record from surveys answers. + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +In several cases we want to use survey application to create records. +Website form application give the same possibility but the design is integrated on the web site. +Futhermore this module add other functionnalities like "duplicate" check, or creation of several interconnected records + +Typical use case : Information request form + +#. Submitting the form will create a contact (partner) only if it does not already exist in the database. +#. Submitting the form will also create a crm opportunity linked to previously created partner + + + +Configuration +============= + +Record generation configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. |Image of record creation list| image:: https://raw.githubusercontent.com/OCA/survey/16.0/survey_record_generation/static/description/record-creations.png + +#. Go to the the survey +#. In *Record creation* tab add a new line +#. Set a name for created record, select the Model of the record (eg: Prospect) +#. Add a field configuration. So for each field : + + .. |Image of record creation fields| image:: https://raw.githubusercontent.com/OCA/survey/16.0/survey_record_generation/static/description/record-creation-customer.png + + #. You can check "unicity constraint" to prevent duplicates. + In case of duplicates and if other record use this record to fill a m2o field, the founded record will be used + #. You can configure explicitly where Odoo should retrieve the value of field : + * **fixed**: To set explicit value + * **question**: If value come from user's answer + 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) + + + +Question answers configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In a survey question : to configure value of choices + +.. |Question answers| image:: https://raw.githubusercontent.com/OCA/survey/16.0/survey_record_generation/static/description/question-answers.png + +#. Configure a multiple choice question +#. Select value type associated to answer: + * **Value** > eg: to fill a selection field + * **Record** > to fill m2o or m2m field +#. In case of *record* type: + #. Select referenced model + #. You can directly fill answers (eventualy with help of the domain field) + #. Or create new answers and set associated record +#. In case of *value* type: + #. Add new selectable answers and set associated value + + +Usage +===== + +When a survey is properly configured, once it is submited by a user, records should be created. + +To find records generated from a participation go to: + +#. Survey > participation +#. Click on **# Generated records** button (top-right) + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Elabore + +Contributors +~~~~~~~~~~~~ + +* `Elabore `_ + + * Clément Thomas + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/survey `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/survey_record_generation/__init__.py b/survey_record_generation/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/survey_record_generation/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/survey_record_generation/__manifest__.py b/survey_record_generation/__manifest__.py new file mode 100644 index 00000000..241d543a --- /dev/null +++ b/survey_record_generation/__manifest__.py @@ -0,0 +1,20 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "Survey record generation", + "summary": "Allow to create record of any model when user responds to a survey", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Elabore, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/survey", + "category": "", + "depends": ["survey"], + "data": [ + "security/ir.model.access.csv", + "views/survey_survey_views.xml", + "views/survey_question_views.xml", + "views/survey_user_input_views.xml", + "views/survey_generated_record_views.xml", + ], + "installable": True, +} diff --git a/survey_record_generation/i18n/fr.po b/survey_record_generation/i18n/fr.po new file mode 100644 index 00000000..94c10a64 --- /dev/null +++ b/survey_record_generation/i18n/fr.po @@ -0,0 +1,347 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * survey_record_generation +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-02-24 17:06+0000\n" +"PO-Revision-Date: 2025-02-24 17:06+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__value_origin +msgid "" +"* Fixed: you can set the value in value field\n" +" * Question: Response of the question will set the value. If you do not see your question, maybe the type of question do not match the type of field\n" +" * From other created record: You can set other record creation to link several created records. Can only be used with many2one fields." +msgstr "" +"* Fixé: Vous pouvez attribuer une valeur au champ\n" +" * Question: La réponse à la question attribuera la valeur. Si vous ne voyez pas votre question, peut-être que le type de question ne correspond pas au type de champ\n" +" * Depuis un autre enregistrement créé: Vous pouvez attribuer un autre enregistrement créé pour lier plusieurs enregistrements. Peut être utilisé uniquement avec les champs one2many." + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__allowed_question_ids +msgid "Allowed Question" +msgstr "Question autorisée" + +#. module: survey_record_generation +#. odoo-python +#: 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" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__answer_values_type +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question_answer__answer_values_type +msgid "Associate value to answer" +msgstr "Associer une valeur à la réponse" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__create_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__create_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__create_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__create_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__display_name +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__display_name +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__display_name +msgid "Display Name" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__fill_domain +msgid "Domain" +msgstr "Domaine" + +#. module: survey_record_generation +#: model_terms:ir.ui.view,arch_db:survey_record_generation.survey_question_form +msgid "Empty and fill" +msgstr "Vider et remplir" + +#. module: survey_record_generation +#: model_terms:ir.ui.view,arch_db:survey_record_generation.survey_question_form +msgid "" +"Empty the list and fill it with all items of selected model matching domain" +msgstr "Vide la liste et la remplie avec tous les enregistrements du modèle sélectionné qui correspondent au domaine" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_id +msgid "Field" +msgstr "Champ" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_type +msgid "Field Type" +msgstr "Type de champ" + +#. module: survey_record_generation +#. odoo-python +#: 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" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__field_values_ids +msgid "Field values" +msgstr "Valeurs des champs" + +#. module: survey_record_generation +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_record_creation_field_values__value_origin__fixed +msgid "Fixed" +msgstr "Fixé" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_many2many +msgid "Fixed Value Many2Many" +msgstr "Valeur fixée Many2Many" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__field_relation +msgid "For relationship fields, the technical name of the target model" +msgstr "Pour les champs relationnels, le nom technique du modèle ciblé" + +#. module: survey_record_generation +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_record_creation_field_values__value_origin__other_record +msgid "From other created record" +msgstr "Depuis un autre enregistrement créé" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_help +msgid "Help" +msgstr "Aide" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__id +msgid "ID" +msgstr "ID" + +#. module: survey_record_generation +#: 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_record_creation__write_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__write_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__write_uid +msgid "Last Updated by" +msgstr "Dernière modification par" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__write_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__write_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__write_date +msgid "Last Updated on" +msgstr "Dernière modification le" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_survey__survey_record_creation_ids +msgid "List of records created when survey submitted" +msgstr "Liste des enregistrements créés lorsque le sondage est envoyé" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__model_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__model_name +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question_answer__model_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__model_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__model_id +msgid "Model" +msgstr "Modèle" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation__model_id +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__model_id +msgid "Model of generated record" +msgstr "Modèle de l'enregistrement généré" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__name +msgid "Name" +msgstr "Nom" + +#. module: survey_record_generation +#. odoo-python +#: 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" + +#. module: survey_record_generation +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_question__answer_values_type__no +msgid "No values" +msgstr "Pas de valeur" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__unicity_check +msgid "" +"On record creation, if another record exists with same value, record will " +"not be created." +msgstr "" +"Lors de la création d'un enregistrement, si un autre enregistrement existe avec la même valeur, l'enregistrement ne sera " +"pas créé." + +#. module: survey_record_generation +#. odoo-python +#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 +#, python-format +msgid "Other created record: " +msgstr "Autre enregistrement créé : " + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__other_created_record_id +msgid "Other record" +msgstr "Autre enregistrement" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__question_id +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_record_creation_field_values__value_origin__question +msgid "Question" +msgstr "Question" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_many2one +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__value_reference +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_question__answer_values_type__record +msgid "Record" +msgstr "Enregistrement" + +#. module: survey_record_generation +#: model_terms:ir.ui.view,arch_db:survey_record_generation.survey_survey_view_form +msgid "Record creation" +msgstr "Création d'un enregistrement" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_survey__survey_record_creation_ids +msgid "Records creation" +msgstr "Création d'enregistrements" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question_answer__record_id +msgid "Referenced record" +msgstr "Enregistrement référencé" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_relation +msgid "Related Model" +msgstr "Modèle relatif" + +#. module: survey_record_generation +#. odoo-python +#: 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" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_survey +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__survey_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__survey_id +msgid "Survey" +msgstr "Sondage" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_question_answer +msgid "Survey Label" +msgstr "Étiquette du sondage" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_question +msgid "Survey Question" +msgstr "Question du sondage" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__survey_record_creation_id +msgid "Survey Record Creation" +msgstr "Sondage Création d'enregistrements" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__survey_record_creation_field_values_id +msgid "Survey Record Creation Field Values" +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 "Entrée utilisateur du sondage" + +#. 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_question_answer__value_char +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__displayed_value +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_char +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_datetime +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_float +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_html +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_integer +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_selection +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_text +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_question__answer_values_type__value +msgid "Value" +msgstr "Valeur" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__value_origin +msgid "Value origin" +msgstr "Origine de la valeur" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__warning_message +msgid "Warning message" +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 +#, 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_record_creation_field_values.py:0 +#, python-format +msgid "possible values are %s" +msgstr "les valeurs possibles sont %s" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_record_creation +msgid "survey.record.creation" +msgstr "survey.record.creation" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_record_creation_field_values +msgid "survey.record.creation.field.values" +msgstr "survey.record.creation.field.values" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_record_creation_field_values_x2m +msgid "survey.record.creation.field.values.x2m" +msgstr "survey.record.creation.field.values.x2m" diff --git a/survey_record_generation/i18n/survey_record_generation.pot b/survey_record_generation/i18n/survey_record_generation.pot new file mode 100644 index 00000000..bf08c4eb --- /dev/null +++ b/survey_record_generation/i18n/survey_record_generation.pot @@ -0,0 +1,342 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * survey_record_generation +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-02-24 17:06+0000\n" +"PO-Revision-Date: 2025-02-24 17:06+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__value_origin +msgid "" +"* Fixed: you can set the value in value field\n" +" * Question: Response of the question will set the value. If you do not see your question, maybe the type of question do not match the type of field\n" +" * From other created record: You can set other record creation to link several created records. Can only be used with many2one fields." +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__allowed_question_ids +msgid "Allowed Question" +msgstr "" + +#. module: survey_record_generation +#. odoo-python +#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 +#, python-format +msgid "Answer to question: %s" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__answer_values_type +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question_answer__answer_values_type +msgid "Associate value to answer" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__create_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__create_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__create_uid +msgid "Created by" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__create_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__create_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__create_date +msgid "Created on" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__display_name +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__display_name +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__display_name +msgid "Display Name" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__fill_domain +msgid "Domain" +msgstr "" + +#. module: survey_record_generation +#: model_terms:ir.ui.view,arch_db:survey_record_generation.survey_question_form +msgid "Empty and fill" +msgstr "" + +#. module: survey_record_generation +#: model_terms:ir.ui.view,arch_db:survey_record_generation.survey_question_form +msgid "" +"Empty the list and fill it with all items of selected model matching domain" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_id +msgid "Field" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_type +msgid "Field Type" +msgstr "" + +#. module: survey_record_generation +#. odoo-python +#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 +#, python-format +msgid "Field type is : %s" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__field_values_ids +msgid "Field values" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_record_creation_field_values__value_origin__fixed +msgid "Fixed" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_many2many +msgid "Fixed Value Many2Many" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__field_relation +msgid "For relationship fields, the technical name of the target model" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_record_creation_field_values__value_origin__other_record +msgid "From other created record" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_help +msgid "Help" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__id +msgid "ID" +msgstr "" + +#. module: survey_record_generation +#: 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 "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__write_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__write_uid +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__write_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__write_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__write_date +msgid "Last Updated on" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_survey__survey_record_creation_ids +msgid "List of records created when survey submitted" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__model_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question__model_name +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question_answer__model_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__model_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__model_id +msgid "Model" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation__model_id +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__model_id +msgid "Model of generated record" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__name +msgid "Name" +msgstr "" + +#. module: survey_record_generation +#. odoo-python +#: code:addons/survey_record_generation/models/survey_question.py:0 +#, python-format +msgid "No record found in %s" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_question__answer_values_type__no +msgid "No values" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,help:survey_record_generation.field_survey_record_creation_field_values__unicity_check +msgid "" +"On record creation, if another record exists with same value, record will " +"not be created." +msgstr "" + +#. module: survey_record_generation +#. odoo-python +#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 +#, python-format +msgid "Other created record: " +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__other_created_record_id +msgid "Other record" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__question_id +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_record_creation_field_values__value_origin__question +msgid "Question" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_many2one +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__value_reference +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_question__answer_values_type__record +msgid "Record" +msgstr "" + +#. module: survey_record_generation +#: model_terms:ir.ui.view,arch_db:survey_record_generation.survey_survey_view_form +msgid "Record creation" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_survey__survey_record_creation_ids +msgid "Records creation" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question_answer__record_id +msgid "Referenced record" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__field_relation +msgid "Related Model" +msgstr "" + +#. module: survey_record_generation +#. odoo-python +#: code:addons/survey_record_generation/models/survey_record_creation.py:0 +#, python-format +msgid "Some required fields are not set : %s" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_survey +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__survey_id +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__survey_id +msgid "Survey" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_question_answer +msgid "Survey Label" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_question +msgid "Survey Question" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__survey_record_creation_id +msgid "Survey Record Creation" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values_x2m__survey_record_creation_field_values_id +msgid "Survey Record Creation Field Values" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_user_input +msgid "Survey User Input" +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 "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_question_answer__value_char +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__displayed_value +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_char +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_date +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_datetime +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_float +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_html +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_integer +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_selection +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_text +#: model:ir.model.fields.selection,name:survey_record_generation.selection__survey_question__answer_values_type__value +msgid "Value" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__value_origin +msgid "Value origin" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation__warning_message +msgid "Warning message" +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 "You should append at least one record in %s" +msgstr "" + +#. module: survey_record_generation +#. odoo-python +#: code:addons/survey_record_generation/models/survey_record_creation_field_values.py:0 +#, python-format +msgid "possible values are %s" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_record_creation +msgid "survey.record.creation" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_record_creation_field_values +msgid "survey.record.creation.field.values" +msgstr "" + +#. module: survey_record_generation +#: model:ir.model,name:survey_record_generation.model_survey_record_creation_field_values_x2m +msgid "survey.record.creation.field.values.x2m" +msgstr "" diff --git a/survey_record_generation/models/__init__.py b/survey_record_generation/models/__init__.py new file mode 100644 index 00000000..0e582b15 --- /dev/null +++ b/survey_record_generation/models/__init__.py @@ -0,0 +1,7 @@ +from . import survey_question_answer +from . import survey_question +from . import survey_record_creation_field_values +from . import survey_record_creation +from . import survey_survey +from . import survey_user_input +from . import survey_generated_record diff --git a/survey_record_generation/models/survey_generated_record.py b/survey_record_generation/models/survey_generated_record.py new file mode 100644 index 00000000..aba7bf28 --- /dev/null +++ b/survey_record_generation/models/survey_generated_record.py @@ -0,0 +1,22 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import api, fields, models + + +class SurveyGeneratedRecord(models.Model): + _name = "survey.generated.record" + + survey_record_creation_name = fields.Char("Name", readonly=True) + survey_record_creation_id = fields.Many2one( + "survey.record.creation", "Survey record creation", readonly=True + ) + user_input_id = fields.Many2one("survey.user_input", "Participation", readonly=True) + created_record_id = fields.Reference( + string="Referenced record", selection="_selection_target_model", readonly=True + ) + + @api.model + def _selection_target_model(self): + return [ + (model.model, model.name) + for model in self.env["ir.model"].sudo().search([]) + ] diff --git a/survey_record_generation/models/survey_question.py b/survey_record_generation/models/survey_question.py new file mode 100644 index 00000000..0a776e15 --- /dev/null +++ b/survey_record_generation/models/survey_question.py @@ -0,0 +1,56 @@ +import ast +import logging + +from odoo import Command, _, api, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class SurveyQuestion(models.Model): + _inherit = "survey.question" + + model_id = fields.Many2one("ir.model", string="Model") + model_name = fields.Char(related="model_id.model") + fill_domain = fields.Char("Domain", default="[]") + answer_values_type = fields.Selection( + [("no", "No values"), ("value", "Value"), ("record", "Record")], + string="Associate value to answer", + default="no", + required=True, + ) + + @api.onchange("model_id") + def onchange_model_id(self): + self.fill_domain = "[]" + if self.model_id: + rec = self.env[self.model_id.model].search([], limit=1) + if not rec: + raise UserError(_("No record found in %s", self.model_id.name)) + else: + for answer in self.suggested_answer_ids: + answer.record_id = f"{self.model_id.model},{rec.id}" + + def fill(self): + for question in self: + if question.model_id: + new_suggested_answer_ids = [Command.clear()] + record_model = question.model_id.model + + if question.fill_domain: + domain = ast.literal_eval(question.fill_domain) + else: + domain = [] + + records = self.env[record_model].search(domain) + + new_suggested_answer_ids += [ + Command.create( + { + "value": record.display_name, + "record_id": f"{record_model},{record.id}", + } + ) + for record in records + ] + question.suggested_answer_ids = new_suggested_answer_ids diff --git a/survey_record_generation/models/survey_question_answer.py b/survey_record_generation/models/survey_question_answer.py new file mode 100644 index 00000000..7cac9266 --- /dev/null +++ b/survey_record_generation/models/survey_question_answer.py @@ -0,0 +1,43 @@ +import logging + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class SurveyQuestionAnswer(models.Model): + _inherit = "survey.question.answer" + + record_id = fields.Reference( + string="Referenced record", selection="_selection_target_model" + ) + model_id = fields.Many2one("ir.model", related="question_id.model_id") + answer_values_type = fields.Selection(related="question_id.answer_values_type") + value_char = fields.Char("Value") + + @api.model + def _selection_target_model(self): + return [ + (model.model, model.name) + for model in self.env["ir.model"].sudo().search([]) + ] + + @api.onchange("record_id") + def onchange_record_id(self): + if self.record_id: + self.value = self.record_id.display_name + + @api.model + def default_get(self, fields): + result = super().default_get(fields) + if not result.get("model_id") or "record_id" not in fields: + return result + + model = self.env["ir.model"].browse(result.get("model_id")).model + res = self.env[model].search([], limit=1) + if res: + result["record_id"] = "%s,%s" % ( + model, + res.id, + ) + return result diff --git a/survey_record_generation/models/survey_record_creation.py b/survey_record_generation/models/survey_record_creation.py new file mode 100644 index 00000000..4673f2d8 --- /dev/null +++ b/survey_record_generation/models/survey_record_creation.py @@ -0,0 +1,51 @@ +import logging + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class SurveyRecordCreation(models.Model): + """Configure list of models for wich record will be created on survey submission""" + + _name = "survey.record.creation" + + name = fields.Char() + survey_id = fields.Many2one("survey.survey", string="Survey") + model_id = fields.Many2one("ir.model", "Model", help="Model of generated record") + 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") + + @api.onchange("model_id") + def clear_field_values_ids(self): + self.field_values_ids = None + + @api.depends("model_id", "field_values_ids") + def _compute_warning_message(self): + for record_creation in self: + # check if all mandatory fields set + if record_creation.model_id: + required_field_ids = self.model_id.field_id.filtered( + lambda f: f.required and "property_" not in f.name + ) + set_field_ids = self.field_values_ids.field_id + missing_fields = required_field_ids - set_field_ids + + if missing_fields: + record_creation.warning_message = _( + "Some required fields are not set : %s", + ", ".join( + [ + f"{f.field_description} ({f.name})" + for f in missing_fields + ] + ), + ) + else: + record_creation.warning_message = None + else: + record_creation.warning_message = None diff --git a/survey_record_generation/models/survey_record_creation_field_values.py b/survey_record_generation/models/survey_record_creation_field_values.py new file mode 100644 index 00000000..04574319 --- /dev/null +++ b/survey_record_generation/models/survey_record_creation_field_values.py @@ -0,0 +1,321 @@ +import logging + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.tools.misc import format_date + +_logger = logging.getLogger(__name__) + + +type_mapping = { + "char": [ + "char_box", + "numerical_box", + "date", + "datetime", + "simple_choice", + "multiple_choice", + ], + "text": ["char_box", "date", "simple_choice"], + "html": ["text_box", "numerical_box", "datetime", "simple_choice"], + "integer": ["numerical_box"], + "float": ["numerical_box"], + "date": ["date"], + "datetime": ["datetime"], + "many2one": ["simple_choice"], + "many2many": ["multiple_choice"], + "selection": ["char_box", "simple_choice"], +} + + +class SurveyRecordCreationFieldValues(models.Model): + """Configure default values of records created on survey submission""" + + _name = "survey.record.creation.field.values" + + survey_record_creation_id = fields.Many2one("survey.record.creation") + survey_id = fields.Many2one( + "survey.survey", related="survey_record_creation_id.survey_id" + ) + model_id = fields.Many2one("ir.model", related="survey_record_creation_id.model_id") + + field_id = fields.Many2one( + "ir.model.fields", + domain="[('model_id','=',model_id),('readonly','=',False),('ttype','in',['char','selection','text','html','integer','float','date','datetime','many2one','many2many'])]", # noqa: B950 + ondelete="cascade", + ) + field_relation = fields.Char(related="field_id.relation") + field_type = fields.Selection(related="field_id.ttype") + field_help = fields.Html("Help", compute="_compute_field_help") + + value_origin = fields.Selection( + [ + ("fixed", "Fixed"), + ("question", "Question"), + ("other_record", "From other created record"), + ], + string="Value origin", + required=True, + default="fixed", + help="""* Fixed: you can set the value in value field + * Question: Response of the question will set the value. + If you do not see your question, maybe the type of question + do not match the type of field + * From other created record: + You can set other record creation to link several created records. + Can only be used with many2one fields.""", + ) + + fixed_value_many2one = fields.Reference( + string="Record", selection="_selection_target_model" + ) + fixed_value_many2many = fields.One2many( + "survey.record.creation.field.values.x2m", + "survey_record_creation_field_values_id", + ) + fixed_value_char = fields.Char("Value") + fixed_value_selection = fields.Char("Value") + fixed_value_text = fields.Text("Value") + fixed_value_html = fields.Html("Value") + fixed_value_integer = fields.Integer("Value") + fixed_value_float = fields.Float("Value") + fixed_value_date = fields.Date("Value") + fixed_value_datetime = fields.Datetime("Value") + + displayed_value = fields.Char("Value", compute="_compute_displayed_value") + other_created_record_id = fields.Many2one( + "survey.record.creation", + string="Other record", + domain="[('survey_id','=',survey_id),('model_id.model','=',field_relation)]", + ) + + allowed_question_ids = fields.Many2many( + "survey.question", compute="_compute_allowed_question_ids" + ) + question_id = fields.Many2one( + "survey.question", + string="Question", + domain="[('id','in',allowed_question_ids)]", + ) + + unicity_check = fields.Boolean( + "Unicity constraint", + help="On record creation, if another record exists with same value, record will not be created.", # noqa: B950 + ) + + @api.depends("field_id") + def _compute_field_help(self): + for record in self: + field_help = _("Field type is : %s", record.field_type) + if record.field_type == "selection": + field_help += "
" + _( + "possible values are %s", + ", ".join( + [ + f"{s.value} ({s.name})" + for s in record.field_id.selection_ids + ] + ), + ) + record.field_help = field_help + + @api.depends("field_id") + def _compute_allowed_question_ids(self): + for record_creation_field_values in self: + if ( + not record_creation_field_values.survey_id + or not record_creation_field_values.field_id + ): + record_creation_field_values.allowed_question_ids = None + return + question_domain = [ + ("survey_id", "=", record_creation_field_values.survey_id.id) + ] + + if record_creation_field_values.field_id.ttype in ["many2one", "many2many"]: + question_domain.extend( + [ + "|", + "&", + ("answer_values_type", "=", "record"), + ( + "model_id", + "=", + record_creation_field_values.field_id.relation, + ), + ("answer_values_type", "=", "value"), + ] + ) + if record_creation_field_values.field_id.ttype in type_mapping: + question_domain.append( + ( + "question_type", + "in", + type_mapping[record_creation_field_values.field_id.ttype], + ) + ) + + record_creation_field_values.allowed_question_ids = self.env[ + "survey.question" + ].search(question_domain) + + @api.model + def _selection_target_model(self): + return [ + (model.model, model.name) + for model in self.env["ir.model"].sudo().search([]) + ] + + @api.onchange("field_id", "origin") + def clean_values(self): + # clean values + self.fixed_value_many2many = None + self.fixed_value_many2one = None + self.fixed_value_char = None + self.fixed_value_selection = None + self.fixed_value_text = None + self.fixed_value_html = None + self.fixed_value_integer = None + self.fixed_value_float = None + self.fixed_value_date = None + self.fixed_value_datetime = None + self.other_created_record_id = None + self.question_id = None + + @api.onchange("field_id") + def _onchange_field_id(self): + # Set reference field model and select first record + if ( + self.field_id + and self.field_id.ttype == "many2one" + and self.field_id.relation + ): + rec = self.env[self.field_id.relation].search([], limit=1) + if rec: + self.fixed_value_many2one = f"{self.field_id.relation},{rec.id}" + else: + model_name = ( + self.env["ir.model"] + .search([("model", "=", self.field_id.relation)]) + .name + ) + self.fixed_value_many2one = None + raise UserError( + _("You should append at least one record in %s", model_name) + ) + else: + self.fixed_value_many2one = None + + def get_fixed_value_for_record_creation(self): + """return val used in create() method""" + if self.value_origin == "fixed": + if self.field_type == "many2one": + if self.fixed_value_many2one: + return self.fixed_value_many2one.id + elif self.field_type == "many2many": + return [ + m2m.value_reference.id + for m2m in self.fixed_value_many2many + if m2m.value_reference + ] + else: + return self["fixed_value_" + self.field_type] + + @api.onchange( + "fixed_value_char", + "fixed_value_selection", + "fixed_value_text", + "fixed_value_html", + "fixed_value_integer", + "fixed_value_float", + "fixed_value_date", + "fixed_value_datetime", + "fixed_value_many2one", + "fixed_value_many2many", + "other_created_record_id", + "question_id", + ) + def _compute_displayed_value(self): + for record in self: + if record.field_id: + if ( + record.value_origin == "other_record" + and record.other_created_record_id + ): + record.displayed_value = ( + _("Other created record: ") + + record.other_created_record_id.name + ) + elif record.value_origin == "fixed": + if record.field_id.ttype == "many2one": + if record.fixed_value_many2one: + record.displayed_value = ( + record.fixed_value_many2one.display_name + ) + else: + record.displayed_value = None + elif record.field_id.ttype == "many2many": + if record.fixed_value_many2many: + record.displayed_value = ", ".join( + [ + r.value_reference.display_name + for r in record.fixed_value_many2many + if r.value_reference + ] + ) + else: + record.displayed_value = None + elif record.field_id.ttype == "date": + record.displayed_value = format_date( + self.env, record.fixed_value_date + ) + elif record.field_id.ttype == "datetime": + record.displayed_value = format_date( + self.env, record.fixed_value_datetime + ) + else: + record.displayed_value = str( + record["fixed_value_" + record.field_id.ttype] + ) + else: # value_origin = question + record.displayed_value = _( + "Answer to question: %s", record.question_id.title + ) + else: + record.displayed_value = "" + + +class SurveyRecordCreationFieldValuesX2m(models.Model): + """O2m an M2m default values""" + + _name = "survey.record.creation.field.values.x2m" + + survey_record_creation_field_values_id = fields.Many2one( + "survey.record.creation.field.values" + ) + value_reference = fields.Reference( + string="Record", selection="_selection_target_model" + ) + + @api.model + def _selection_target_model(self): + return [ + (model.model, model.name) + for model in self.env["ir.model"].sudo().search([]) + ] + + @api.onchange("survey_record_creation_field_values_id") + def _onchange_model_name(self): + # Set reference field model and select first record + field = self.survey_record_creation_field_values_id.field_id + if field and "2many" in field.ttype and field.relation: + rec = self.env[field.relation].search([], limit=1) + if rec: + self.value_reference = f"{field.relation},{rec.id}" + else: + model_name = ( + self.env["ir.model"].search([("model", "=", field.relation)]).name + ) + raise ValueError( + _("You should append at least one record in %s", (model_name,)) + ) diff --git a/survey_record_generation/models/survey_survey.py b/survey_record_generation/models/survey_survey.py new file mode 100644 index 00000000..48d9c6c0 --- /dev/null +++ b/survey_record_generation/models/survey_survey.py @@ -0,0 +1,16 @@ +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class SurveySurvey(models.Model): + _inherit = "survey.survey" + + survey_record_creation_ids = fields.One2many( + "survey.record.creation", + "survey_id", + "Records creation", + help="List of records created when survey submitted", + ) diff --git a/survey_record_generation/models/survey_user_input.py b/survey_record_generation/models/survey_user_input.py new file mode 100644 index 00000000..794cba81 --- /dev/null +++ b/survey_record_generation/models/survey_user_input.py @@ -0,0 +1,133 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class SurveyUserInput(models.Model): + _inherit = "survey.user_input" + + generated_record_ids = fields.One2many( + "survey.generated.record", "user_input_id", "Generated records" + ) + generated_records_count = fields.Integer( + "Attempts Count", compute="_compute_generated_records_count" + ) + + def _compute_generated_records_count(self): + for user_input in self: + user_input.generated_records_count = len(user_input.generated_record_ids) + + def action_redirect_to_generated_records(self): + self.ensure_one() + + action = self.env["ir.actions.act_window"]._for_xml_id( + "survey_record_generation.survey_generated_record_action" + ) + return action + + def _mark_done(self): # noqa: C901 + # generate records + for user_input in self: + created_records = {} + fields_to_update = [] + + for record_creation in user_input.survey_id.survey_record_creation_ids: + model = record_creation.model_id.model + vals = {} + + for field_value in record_creation.field_values_ids: + if field_value.value_origin == "fixed": + vals[ + field_value.field_id.name + ] = field_value.get_fixed_value_for_record_creation() + elif field_value.value_origin == "question": + # find user_input_lines of the question + user_input_lines = [ + user_input_line + for user_input_line in user_input.user_input_line_ids + if user_input_line.question_id == field_value.question_id + ] + + if not user_input_lines: + continue + + if field_value.question_id.question_type in [ + "simple_choice", + "multiple_choice", + "matrix", + ]: + if field_value.question_id.answer_values_type == "record": + record_ids = [] + for user_input_line in user_input_lines: + if ( + user_input_line.suggested_answer_id + and user_input_line.suggested_answer_id.record_id + ): + record_ids.append( + user_input_line.suggested_answer_id.record_id.id + ) + if ( + field_value.question_id.question_type + == "simple_choice" + ): + vals[field_value.field_id.name] = record_ids[0] + else: + vals[field_value.field_id.name] = record_ids + if field_value.question_id.answer_values_type == "value": + vals[field_value.field_id.name] = user_input_lines[ + 0 + ].suggested_answer_id.value_char + elif user_input_lines[ + 0 + ].answer_type: # if value not filled by user, answer_type not set + vals[field_value.field_id.name] = user_input_lines[0][ + f"value_{user_input_lines[0].answer_type}" + ] + else: + vals[field_value.field_id.name] = None + elif field_value.value_origin == "other_record": + fields_to_update.append(field_value) + + # check duplicates + uniq_fields = [ + field_value.field_id.name + for field_value in record_creation.field_values_ids.filtered( + lambda r: r.unicity_check + ) + ] + duplicate = None + if uniq_fields: + uniq_domain = [] + for uniq_field in uniq_fields: + uniq_domain.append((uniq_field, "=", vals[uniq_field])) + duplicate = self.env[model].search(uniq_domain, limit=1) + + if duplicate: + record = duplicate + else: + # Create record + record = self.env[model].create(vals) + # Link generated records to user input + self.env["survey.generated.record"].create( + { + "survey_record_creation_name": record_creation.name, + "survey_record_creation_id": record_creation.id, + "user_input_id": user_input.id, + "created_record_id": "%s,%s" % (model, record.id), + } + ) + + created_records[record_creation.id] = record + + # update linked records + for field_to_update in fields_to_update: + record_to_update = created_records[ + field_to_update.survey_record_creation_id.id + ] + linked_record = created_records[ + field_to_update.other_created_record_id.id + ] + record_to_update.write( + {field_to_update.field_id.name: linked_record.id} + ) + + return super()._mark_done() diff --git a/survey_record_generation/readme/CONFIGURE.rst b/survey_record_generation/readme/CONFIGURE.rst new file mode 100644 index 00000000..99d1c5c7 --- /dev/null +++ b/survey_record_generation/readme/CONFIGURE.rst @@ -0,0 +1,40 @@ +Record generation configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. |Image of record creation list| image:: ../static/description/record-creations.png + +#. Go to the the survey +#. In *Record creation* tab add a new line +#. Set a name for created record, select the Model of the record (eg: Prospect) +#. Add a field configuration. So for each field : + + .. |Image of record creation fields| image:: ../static/description/record-creation-customer.png + + #. You can check "unicity constraint" to prevent duplicates. + In case of duplicates and if other record use this record to fill a m2o field, the founded record will be used + #. You can configure explicitly where Odoo should retrieve the value of field : + * **fixed**: To set explicit value + * **question**: If value come from user's answer + 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) + + + +Question answers configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In a survey question : to configure value of choices + +.. |Question answers| image:: ../static/description/question-answers.png + +#. Configure a multiple choice question +#. Select value type associated to answer: + * **Value** > eg: to fill a selection field + * **Record** > to fill m2o or m2m field +#. In case of *record* type: + #. Select referenced model + #. You can directly fill answers (eventualy with help of the domain field) + #. Or create new answers and set associated record +#. In case of *value* type: + #. Add new selectable answers and set associated value + diff --git a/survey_record_generation/readme/CONTEXT.rst b/survey_record_generation/readme/CONTEXT.rst new file mode 100644 index 00000000..68875900 --- /dev/null +++ b/survey_record_generation/readme/CONTEXT.rst @@ -0,0 +1,10 @@ +In several cases we want to use survey application to create records. +Website form application give the same possibility but the design is integrated on the web site. +Futhermore this module add other functionnalities like "duplicate" check, or creation of several interconnected records + +Typical use case : Information request form + +#. Submitting the form will create a contact (partner) only if it does not already exist in the database. +#. Submitting the form will also create a crm opportunity linked to previously created partner + + diff --git a/survey_record_generation/readme/CONTRIBUTORS.rst b/survey_record_generation/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..ed90ebeb --- /dev/null +++ b/survey_record_generation/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Elabore `_ + + * Clément Thomas \ No newline at end of file diff --git a/survey_record_generation/readme/DESCRIPTION.rst b/survey_record_generation/readme/DESCRIPTION.rst new file mode 100644 index 00000000..2f732efb --- /dev/null +++ b/survey_record_generation/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows to generate any record from surveys answers. \ No newline at end of file diff --git a/survey_record_generation/readme/USAGE.rst b/survey_record_generation/readme/USAGE.rst new file mode 100644 index 00000000..6c9047c3 --- /dev/null +++ b/survey_record_generation/readme/USAGE.rst @@ -0,0 +1,6 @@ +When a survey is properly configured, once it is submited by a user, records should be created. + +To find records generated from a participation go to: + +#. Survey > participation +#. Click on **# Generated records** button (top-right) diff --git a/survey_record_generation/security/ir.model.access.csv b/survey_record_generation/security/ir.model.access.csv new file mode 100644 index 00000000..3439c1d2 --- /dev/null +++ b/survey_record_generation/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_survey_record_creation,survey.record.creation,survey_record_generation.model_survey_record_creation,survey.group_survey_user,1,1,1,1 +access_survey_record_creation_field_values,survey.record.creation.field.values,survey_record_generation.model_survey_record_creation_field_values,survey.group_survey_user,1,1,1,1 +access_survey_record_creation_field_values_x2m,survey.record.creation.field.values.x2m,survey_record_generation.model_survey_record_creation_field_values_x2m,survey.group_survey_user,1,1,1,1 +access_survey_generated_record,survey.generated.record,survey_record_generation.model_survey_generated_record,survey.group_survey_user,1,1,1,1 diff --git a/survey_record_generation/static/description/index.html b/survey_record_generation/static/description/index.html new file mode 100644 index 00000000..8c697d4d --- /dev/null +++ b/survey_record_generation/static/description/index.html @@ -0,0 +1,526 @@ + + + + + +Survey record generation + + + +
+

Survey record generation

+ + +

Beta License: AGPL-3 OCA/survey Translate me on Weblate Try me on Runboat

+

This module allows to generate any record from surveys answers.

+

Table of contents

+ +
+

Use Cases / Context

+

In several cases we want to use survey application to create records. +Website form application give the same possibility but the design is integrated on the web site. +Futhermore this module add other functionnalities like “duplicate” check, or creation of several interconnected records

+

Typical use case : Information request form

+
    +
  1. Submitting the form will create a contact (partner) only if it does not already exist in the database.
  2. +
  3. Submitting the form will also create a crm opportunity linked to previously created partner
  4. +
+
+
+

Configuration

+
+

Record generation configuration

+
    +
  1. Go to the the survey

    +
  2. +
  3. In Record creation tab add a new line

    +
  4. +
  5. Set a name for created record, select the Model of the record (eg: Prospect)

    +
  6. +
  7. Add a field configuration. So for each field :

    +
    +
      +
    1. +
      You can check “unicity constraint” to prevent duplicates.
      +
      In case of duplicates and if other record use this record to fill a m2o field, the founded record will be used
      +
      +
    2. +
    3. +
      You can configure explicitly where Odoo should retrieve the value of field :
      +
        +
      • fixed: To set explicit value
      • +
      • +
        question: If value come from user’s answer
        +
        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)
      • +
      +
      +
      +
    4. +
    +
    +
  8. +
+
+
+

Question answers configuration

+

In a survey question : to configure value of choices

+
    +
  1. Configure a multiple choice question
  2. +
  3. +
    Select value type associated to answer:
    +
      +
    • Value > eg: to fill a selection field
    • +
    • Record > to fill m2o or m2m field
    • +
    +
    +
    +
  4. +
  5. +
    In case of record type:
    +
      +
    1. Select referenced model
    2. +
    3. You can directly fill answers (eventualy with help of the domain field)
    4. +
    5. Or create new answers and set associated record
    6. +
    +
    +
    +
  6. +
  7. +
    In case of value type:
    +
      +
    1. Add new selectable answers and set associated value
    2. +
    +
    +
    +
  8. +
+
+
+
+

Usage

+

When a survey is properly configured, once it is submited by a user, records should be created.

+

To find records generated from a participation go to:

+
    +
  1. Survey > participation
  2. +
  3. Click on # Generated records button (top-right)
  4. +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Elabore
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/survey project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/survey_record_generation/static/description/question-answers.png b/survey_record_generation/static/description/question-answers.png new file mode 100644 index 00000000..50d6e02b Binary files /dev/null and b/survey_record_generation/static/description/question-answers.png differ diff --git a/survey_record_generation/static/description/record-creation-customer.png b/survey_record_generation/static/description/record-creation-customer.png new file mode 100644 index 00000000..8fc8feb5 Binary files /dev/null and b/survey_record_generation/static/description/record-creation-customer.png differ diff --git a/survey_record_generation/static/description/record-creations.png b/survey_record_generation/static/description/record-creations.png new file mode 100644 index 00000000..03a7c271 Binary files /dev/null and b/survey_record_generation/static/description/record-creations.png differ diff --git a/survey_record_generation/views/survey_generated_record_views.xml b/survey_record_generation/views/survey_generated_record_views.xml new file mode 100644 index 00000000..90f22b95 --- /dev/null +++ b/survey_record_generation/views/survey_generated_record_views.xml @@ -0,0 +1,59 @@ + + + + survey.generated.record.view.tree + survey.generated.record + + + + + + + + + + + + survey.generated.record.view.form + survey.generated.record + +
+ + + + + + +
+
+
+ + + survey.generated.record.view.search + survey.generated.record + + + + + + + + + + + + + Generated records + survey.generated.record + tree,form + + {'search_default_group_by_survey_record_creation_name': True} + +

+ No generated records found +

+
+
+
diff --git a/survey_record_generation/views/survey_question_views.xml b/survey_record_generation/views/survey_question_views.xml new file mode 100644 index 00000000..52d2ccda --- /dev/null +++ b/survey_record_generation/views/survey_question_views.xml @@ -0,0 +1,50 @@ + + + + survey.question.view.form.inherit.record.generation + survey.question + + + + + + + + + + + +