[IMP] survey_record_generation: first refacto of record creation #8

Merged
mondot merged 1 commits from survey_record_generation-refacto into 16.0 2025-10-23 16:22:48 +00:00
5 changed files with 440 additions and 146 deletions

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 16.0\n" "Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-15 10:34+0000\n" "POT-Creation-Date: 2025-10-23 13:02+0000\n"
"PO-Revision-Date: 2025-04-15 10:34+0000\n" "PO-Revision-Date: 2025-10-23 13:02+0000\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -170,11 +170,6 @@ msgstr "Aide"
msgid "ID" msgid "ID"
msgstr "" msgstr ""
#. module: survey_record_generation
#: model:ir.model,name:survey_record_generation.model_survey_question
msgid "Inherit Survey Question for extra fields"
msgstr "Question du sondage"
#. module: survey_record_generation #. 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_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____last_update
@@ -329,6 +324,11 @@ msgstr "Sondage"
msgid "Survey Label" msgid "Survey Label"
msgstr "Étiquette du sondage" 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 #. module: survey_record_generation
#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__survey_record_creation_id #: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__survey_record_creation_id
msgid "Survey Record Creation" msgid "Survey Record Creation"
@@ -341,7 +341,7 @@ msgstr "Sondage Création d'enregistrement Valeur des champs"
#. module: survey_record_generation #. module: survey_record_generation
#: model:ir.model,name:survey_record_generation.model_survey_user_input #: model:ir.model,name:survey_record_generation.model_survey_user_input
msgid "Survey User Input for custom matrix" msgid "Survey User Input"
msgstr "Entrée utilisateur du sondage" msgstr "Entrée utilisateur du sondage"
#. module: survey_record_generation #. module: survey_record_generation
@@ -354,11 +354,12 @@ msgstr "Génération d'enregistrement depuis la participation"
#: code:addons/survey_record_generation/models/survey_user_input.py:0 #: code:addons/survey_record_generation/models/survey_user_input.py:0
#, python-format #, python-format
msgid "" msgid ""
"The field %s is mandatory. In Record Creation tab, drag " "The field %(field)s is mandatory for model %(model)s. In Record Creation "
"%s at the top of the table" "tab, drag %(record)s on top of the model %(model)s."
msgstr "" msgstr ""
"Le champ %s est obligatoire. Dans l'onglet Création d'un enregistrement, glissez " "Le champs %(field)s est obligatoire pour le modèle %(model)s. Dans l'onglet "
"%s sur la première ligne du tableau" "Création d'un enregistrement, placez la ligne %(record)s au dessus de la "
"ligne du modèle %(model)s."
#. module: survey_record_generation #. module: survey_record_generation
#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__unicity_check #: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__unicity_check
@@ -368,6 +369,7 @@ msgstr "Contrainte d'unicité"
#. module: survey_record_generation #. 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_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__displayed_value
#: model:ir.model.fields,field_description:survey_record_generation.field_survey_record_creation_field_values__fixed_value_boolean
#: 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_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_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_datetime
@@ -400,6 +402,49 @@ msgstr "Message d'erreur"
msgid "You should append at least one record in %s" msgid "You should append at least one record in %s"
msgstr "Vous devez au moins ajouter un enregistrement dans %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."
msgstr ""
"[Survey record generation] La valeur '%(type)s' pour le champs 'answer_values_type' n'est pas supportée "
"(pour la question %(question)s). Veuillez utiliser 'Enregistrement' ou 'Valeur' à la place."
#. 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)."
msgstr ""
"[Survey record generation] La valeur booléenne %s(value)s n'est pas "
"supportée (pour la question %(question)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 question type %(type)s is not recognized (for"
" question %(question)s)."
msgstr ""
"[Survey record generation] Le type de question %(type)s n'est pas reconnu "
"(pour la question %(question)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 question type %(type)s is not supported yet."
msgstr ""
"[Survey record generation] Le type de question %(type)s n'est pas encore "
"supporté."
#. module: survey_record_generation #. module: survey_record_generation
#. odoo-python #. 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
@@ -431,4 +476,4 @@ msgstr ""
#. module: survey_record_generation #. module: survey_record_generation
#: model:ir.model,name:survey_record_generation.model_survey_record_creation_field_values_x2m #: model:ir.model,name:survey_record_generation.model_survey_record_creation_field_values_x2m
msgid "survey.record.creation.field.values.x2m" msgid "survey.record.creation.field.values.x2m"
msgstr "" msgstr ""

View File

@@ -1,12 +1,14 @@
import logging import logging
import ast import ast
from typing import Literal
from odoo import api, fields, models, _, Command from odoo import api, fields, models, _, Command
from odoo.exceptions import UserError from odoo.exceptions import UserError
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
AnswerValuesType: Literal["no", "value", "record"]
class SurveyQuestion(models.Model): class SurveyQuestion(models.Model):
_inherit = 'survey.question' _inherit = 'survey.question'
@@ -14,8 +16,8 @@ class SurveyQuestion(models.Model):
model_id = fields.Many2one('ir.model', string="Model") model_id = fields.Many2one('ir.model', string="Model")
model_name = fields.Char(related="model_id.model") model_name = fields.Char(related="model_id.model")
fill_domain = fields.Char("Domain", default="[]") 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) 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') @api.onchange('model_id')
def onchange_model_id(self): def onchange_model_id(self):
self.fill_domain = "[]" self.fill_domain = "[]"

View File

@@ -1,13 +1,25 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import models, fields, _ from typing import TYPE_CHECKING, Any, Literal
from odoo import _, fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.fields import Command
if TYPE_CHECKING:
from .survey_question import AnswerValuesType
from .survey_record_creation import SurveyRecordCreation
from .survey_record_creation_field_values import SurveyRecordCreationFieldValues
class SurveyUserInput(models.Model): class SurveyUserInput(models.Model):
_inherit = "survey.user_input" _inherit = "survey.user_input"
generated_record_ids = fields.One2many('survey.generated.record', 'user_input_id', 'Generated records') generated_record_ids = fields.One2many(
generated_records_count = fields.Integer("Attempts Count", compute='_compute_generated_records_count') "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): def _compute_generated_records_count(self):
for user_input in self: for user_input in self:
@@ -16,112 +28,290 @@ class SurveyUserInput(models.Model):
def action_redirect_to_generated_records(self): def action_redirect_to_generated_records(self):
self.ensure_one() self.ensure_one()
action = self.env['ir.actions.act_window']._for_xml_id('survey_record_generation.survey_generated_record_action') action = self.env["ir.actions.act_window"]._for_xml_id(
""" context = dict(self.env.context or {}) "survey_record_generation.survey_generated_record_action"
)
context['create'] = False
context['search_default_survey_id'] = self.survey_id.id
context['search_default_group_by_survey'] = False
if self.partner_id:
context['search_default_partner_id'] = self.partner_id.id
elif self.email:
context['search_default_email'] = self.email
action['context'] = context """
return action return action
def _mark_done(self, ignore_when_res_partner_mandatory_fields_are_missing = False): def _mark_done(
self, ignore_when_res_partner_mandatory_fields_are_missing: bool = False
):
# generate records # generate records
for user_input in self: for user_input in self:
created_records = {} created_records = {}
fields_to_update = [] other_record_fields_to_update: list[SurveyRecordCreationFieldValues] = []
for record_creation in user_input.survey_id.survey_record_creation_ids.sorted('sequence'): record_creation: SurveyRecordCreation
model = record_creation.model_id.model for (
vals = {} record_creation
ModelClass = self.env[model] ) in user_input.survey_id.survey_record_creation_ids.sorted("sequence"):
model: str = record_creation.model_id.model
vals: dict = {}
field_value: SurveyRecordCreationFieldValues
for field_value in record_creation.field_values_ids: for field_value in record_creation.field_values_ids:
if field_value.value_origin == 'fixed': value, other_record_fields_to_update = (
vals[field_value.field_id.name] = field_value.get_fixed_value_for_record_creation() self.get_value_based_on_value_origin(
elif field_value.value_origin == 'question': field_value=field_value,
# find user_input_lines of the question user_input=user_input,
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] created_records=created_records,
model=model,
other_record_fields_to_update=other_record_fields_to_update,
)
)
field_name: str = field_value.field_id.name
if not user_input_lines: vals[field_name] = value
continue
if field_value.question_id.question_type in ['simple_choice', 'multiple_choice','matrix']: duplicate = self.find_duplicate_if_there_are_fields_with_unicity_check(
if field_value.question_id.answer_values_type == 'record': model, record_creation, vals
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':
if record_ids:
vals[field_value.field_id.name] = record_ids[0]
else:
vals[field_value.field_id.name] = None
else:
vals[field_value.field_id.name] = record_ids
if field_value.question_id.answer_values_type == 'value':
if field_value.field_id.ttype == "boolean":
boolean_value = user_input_lines[0].suggested_answer_id.value_char in [True, 1, "1", "True", "true", "Oui", "oui", "Yes", "yes"]
vals[field_value.field_id.name] = boolean_value
else:
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 if the field to update is mandatory
if ModelClass._fields[field_value.field_id.name].required:
# check if the other record is already created, if yes add it to vals
if len(created_records) > 0 and created_records[field_value.other_created_record_id.id]:
linked_record = created_records[field_value.other_created_record_id.id]
vals[field_value.field_id.name] = linked_record.id
else:
raise UserError(
_("The field %s is mandatory. In Record Creation tab, drag %s at the top of the table")
% (field_value.field_id.display_name, field_value.other_created_record_id.name)
)
# 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: if duplicate:
record = duplicate record = duplicate
else: else:
if model == "res.partner" and ignore_when_res_partner_mandatory_fields_are_missing: if (
# this part has been developed for Calim specific needs : being able to create several Contacts with the same survey model == "res.partner"
# TODO : find a way to make it generic for all models ? and ignore_when_res_partner_mandatory_fields_are_missing
):
# this part has been developed for Calim specific needs :
# being able to ignore some Contacts creation
# TODO : find a way to make it generic for all models
if not vals.get("lastname") and not vals.get("firstname"): if not vals.get("lastname") and not vals.get("firstname"):
continue continue
# Create record # Create record
record = self.env[model].create(vals) record = self.env[model].create(vals)
# Link generated records to user input # Link generated records to user input
self.env['survey.generated.record'].create({ self.env["survey.generated.record"].create(
'survey_record_creation_name':record_creation.name, {
'survey_record_creation_id':record_creation.id, "survey_record_creation_name": record_creation.name,
'user_input_id':user_input.id, "survey_record_creation_id": record_creation.id,
"created_record_id":"%s,%s" % (model,record.id) "user_input_id": user_input.id,
}) "created_record_id": f"{model},{record.id}",
}
)
created_records[record_creation.id] = record created_records[record_creation.id] = record
# update linked records # update linked record
for field_to_update in fields_to_update: for field_to_update in other_record_fields_to_update:
record_to_update = created_records.get(field_to_update.survey_record_creation_id.id) record_to_update = created_records.get(
field_to_update.survey_record_creation_id.id
)
if record_to_update: if record_to_update:
linked_record = created_records[field_to_update.other_created_record_id.id] linked_record = created_records[
record_to_update.write({field_to_update.field_id.name:linked_record.id}) field_to_update.other_created_record_id.id
]
value = self.get_value_for_relational_field(
field_to_update, linked_record
)
record_to_update.write({field_to_update.field_id.name: value})
return super()._mark_done() return super()._mark_done()
def get_value_based_on_value_origin(
self,
field_value: "SurveyRecordCreationFieldValues",
user_input: "SurveyUserInput",
created_records: dict[Any, Any],
model: str,
other_record_fields_to_update: list["SurveyRecordCreationFieldValues"],
) -> tuple[Any, list["SurveyRecordCreationFieldValues"]]:
value: Any = None
if field_value.value_origin == "fixed":
value = field_value.get_fixed_value_for_record_creation()
elif field_value.value_origin == "question":
value = self.get_value_from_user_answer(field_value, user_input)
elif field_value.value_origin == "other_record":
# if the other_record value is a required field, get it or raise
value = self.get_required_value_from_other_record(
model, created_records, field_value
)
# otherwise, we update the record later (out of this for loop)
if not value:
other_record_fields_to_update.append(field_value)
return value, other_record_fields_to_update
@staticmethod
def get_value_for_relational_field(
field_to_update: "SurveyRecordCreationFieldValues", linked_record
) -> Any:
field_type = field_to_update.field_id.ttype
if field_type == "many2one":
return linked_record.id
else:
# many2many or one2many
return [Command.set(linked_record.ids)]
def find_duplicate_if_there_are_fields_with_unicity_check(
self, model: str, record_creation: "SurveyRecordCreation", vals: dict[Any, Any]
) -> Any:
# check duplicates
unique_fields = [
field_value.field_id.name
for field_value in record_creation.field_values_ids.filtered(
lambda r: r.unicity_check
)
]
duplicate = None
if unique_fields:
uniq_domain = []
for uniq_field in unique_fields:
uniq_domain.append((uniq_field, "=", vals[uniq_field]))
duplicate = self.env[model].search(uniq_domain, limit=1)
return duplicate
def get_required_value_from_other_record(
self,
model: str,
created_records: dict[Any, Any],
field_value: "SurveyRecordCreationFieldValues",
) -> Any:
model_class = self.env[model]
if model_class._fields[field_value.field_id.name].required:
# check if the other record is already created,
# if yes add it to vals, else raise
if (
len(created_records) > 0
and created_records[field_value.other_created_record_id.id]
):
linked_record = created_records[field_value.other_created_record_id.id]
return self.get_value_for_relational_field(field_value, linked_record)
else:
raise UserError(
_(
"The field %(field)s is mandatory for model %(model)s. "
"In Record Creation tab, drag %(record)s "
"on top of the model %(model)s."
)
% {
"field": field_value.field_id.display_name,
"model": model,
"record": field_value.other_created_record_id.name,
}
)
def get_value_from_user_answer(
self,
field_value: "SurveyRecordCreationFieldValues",
user_input: "SurveyUserInput",
) -> Any:
# find user_input_lines (which are user's answers) for 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:
# If the question has not been displayed to the user,
# there are no user_input_lines
return None
if user_input_lines[0].skipped:
# The question has been ignored by the user
return None
question_type = field_value.question_id.question_type
if question_type in [
"char_box",
"text_box",
"numerical_box",
"date",
"datetime",
]:
return user_input_lines[0][f"value_{user_input_lines[0].answer_type}"]
elif question_type in ["simple_choice", "multiple_choice", "matrix"]:
answer_values_type = field_value.question_id.answer_values_type
return self.get_value_based_on_answer_values_type(
answer_values_type, field_value, question_type, user_input_lines
)
else:
raise UserError(
_(
"[Survey record generation] The question type %(type)s is not "
"recognized (for question %(question)s)."
)
% {"type": question_type, "question": field_value.question_id.title}
)
def get_value_based_on_answer_values_type(
self,
answer_values_type: "AnswerValuesType",
field_value: "SurveyRecordCreationFieldValues",
question_type: Literal["simple_choice", "multiple_choice", "matrix"],
user_input_lines: list[Any],
) -> Any:
if answer_values_type == "record":
answered_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
):
answered_record_ids.append(
user_input_line.suggested_answer_id.record_id.id
)
if not answered_record_ids:
return None
if question_type == "simple_choice":
return answered_record_ids[0]
elif question_type == "multiple_choice":
return answered_record_ids
else:
raise UserError(
_(
"[Survey record generation] The question type"
" %(type)s is not supported yet."
)
% {"type": question_type}
)
elif answer_values_type == "value":
answer_value_char = user_input_lines[0].suggested_answer_id.value_char
if field_value.field_id.ttype != "boolean":
return answer_value_char
else:
return self.get_boolean_value(
answer_value_char=answer_value_char,
question_title=field_value.question_id.title,
)
else:
raise UserError(
_(
"[Survey record generation] The answer values type '%(type)s' "
"is not supported (for question %(question)s). Use 'record' or "
"'value' instead."
)
% {
"type": answer_values_type,
"question": field_value.question_id.title,
}
)
@staticmethod
def get_boolean_value(answer_value_char: str, question_title: str) -> bool:
# Below code is a trick to be able to use "simple_choice" question
# with values 'yes' and 'no' and transform it to boolean.
if boolean_value := answer_value_char in [
"1",
"True",
"true",
"Oui",
"oui",
"Yes",
"yes",
]:
return boolean_value
else:
raise UserError(
_(
"[Survey record generation] The boolean value %s(value)s "
"is not supported (for question %(question)s)."
)
% {
"value": answer_value_char,
"question": question_title,
}
)

View File

@@ -1,3 +1,4 @@
* `Elabore <https://www.elabore.coop>`_ * `Elabore <https://www.elabore.coop>`_
* Clément Thomas * Clément Thomas
* Quentin Mondot

View File

@@ -1,9 +1,9 @@
from datetime import date from datetime import date
from odoo.addons.survey.tests.common import SurveyCase
from psycopg2 import IntegrityError from psycopg2 import IntegrityError
from odoo.addons.survey.tests.common import SurveyCase
class TestSurveyRecordCreation(SurveyCase): class TestSurveyRecordCreation(SurveyCase):
def setUp(self): def setUp(self):
@@ -36,7 +36,9 @@ class TestSurveyRecordCreation(SurveyCase):
[("model", "=", "res.partner"), ("name", "=", "name")] [("model", "=", "res.partner"), ("name", "=", "name")]
) )
# And linked the res_partner field "name" to the answer of question_name # And linked the res_partner field "name" to the answer of question_name
self.name_survey_record_creation_field_values = self.env["survey.record.creation.field.values"].create( self.name_survey_record_creation_field_values = self.env[
"survey.record.creation.field.values"
].create(
{ {
"survey_record_creation_id": self.survey_record_creation.id, "survey_record_creation_id": self.survey_record_creation.id,
"survey_id": self.survey.id, "survey_id": self.survey.id,
@@ -80,7 +82,8 @@ class TestSurveyRecordCreation(SurveyCase):
question=self.question_name, answer=self.answer, answer_value="Jean" question=self.question_name, answer=self.answer, answer_value="Jean"
) )
### "numerical_box" type of question, tested with FLOAT field "partner_latitude" ### ### "numerical_box" type of question,
# tested with FLOAT field "partner_latitude" ###
self.question_partner_latitude = self._add_question( self.question_partner_latitude = self._add_question(
page=None, page=None,
name="Partner latitude", name="Partner latitude",
@@ -144,11 +147,15 @@ class TestSurveyRecordCreation(SurveyCase):
], ],
survey_id=self.survey.id, survey_id=self.survey.id,
sequence=1, sequence=1,
answer_values_type="value" answer_values_type="value",
) )
self.question_type.suggested_answer_ids[0].value_char = self.question_type.suggested_answer_ids[0].value self.question_type.suggested_answer_ids[
self.question_type.suggested_answer_ids[1].value_char = self.question_type.suggested_answer_ids[1].value 0
].value_char = self.question_type.suggested_answer_ids[0].value
self.question_type.suggested_answer_ids[
1
].value_char = self.question_type.suggested_answer_ids[1].value
type_field = self.env["ir.model.fields"].search( type_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "type")] [("model", "=", "res.partner"), ("name", "=", "type")]
@@ -165,8 +172,9 @@ class TestSurveyRecordCreation(SurveyCase):
) )
self._add_answer_line( self._add_answer_line(
question=self.question_type, answer=self.answer, question=self.question_type,
answer_value=self.question_type.suggested_answer_ids[0].id answer=self.answer,
answer_value=self.question_type.suggested_answer_ids[0].id,
) )
### "simple_choice" type of question, tested with MANY2ONE field "title" ### ### "simple_choice" type of question, tested with MANY2ONE field "title" ###
@@ -184,11 +192,15 @@ class TestSurveyRecordCreation(SurveyCase):
], ],
survey_id=self.survey.id, survey_id=self.survey.id,
sequence=1, sequence=1,
answer_values_type="record" answer_values_type="record",
) )
self.question_title.suggested_answer_ids[0].record_id = f"res.partner.title,{mister_title.id}" self.question_title.suggested_answer_ids[
self.question_title.suggested_answer_ids[1].record_id = f"res.partner.title,{madam_title.id}" 0
].record_id = f"res.partner.title,{mister_title.id}"
self.question_title.suggested_answer_ids[
1
].record_id = f"res.partner.title,{madam_title.id}"
title_field = self.env["ir.model.fields"].search( title_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "title")] [("model", "=", "res.partner"), ("name", "=", "title")]
@@ -205,13 +217,17 @@ class TestSurveyRecordCreation(SurveyCase):
) )
self._add_answer_line( self._add_answer_line(
question=self.question_title, answer=self.answer, question=self.question_title,
answer_value=self.question_title.suggested_answer_ids[0].id answer=self.answer,
answer_value=self.question_title.suggested_answer_ids[0].id,
) )
### "multiple_choice" type of question, tested with MANY2MANY field "category" ### ### "multiple_choice" type of question,
# tested with MANY2MANY field "category" ###
adult_category = self.env["res.partner.category"].create({"name": "Adult"}) adult_category = self.env["res.partner.category"].create({"name": "Adult"})
teenager_category = self.env["res.partner.category"].create({"name": "Teenager"}) teenager_category = self.env["res.partner.category"].create(
{"name": "Teenager"}
)
child_category = self.env["res.partner.category"].create({"name": "Child"}) child_category = self.env["res.partner.category"].create({"name": "Child"})
self.question_category = self._add_question( self.question_category = self._add_question(
page=None, page=None,
@@ -224,12 +240,18 @@ class TestSurveyRecordCreation(SurveyCase):
], ],
survey_id=self.survey.id, survey_id=self.survey.id,
sequence=1, sequence=1,
answer_values_type="record" answer_values_type="record",
) )
self.question_category.suggested_answer_ids[0].record_id = f"res.partner.category,{adult_category.id}" self.question_category.suggested_answer_ids[
self.question_category.suggested_answer_ids[1].record_id = f"res.partner.category,{teenager_category.id}" 0
self.question_category.suggested_answer_ids[2].record_id = f"res.partner.category,{child_category.id}" ].record_id = f"res.partner.category,{adult_category.id}"
self.question_category.suggested_answer_ids[
1
].record_id = f"res.partner.category,{teenager_category.id}"
self.question_category.suggested_answer_ids[
2
].record_id = f"res.partner.category,{child_category.id}"
category_field = self.env["ir.model.fields"].search( category_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "category_id")] [("model", "=", "res.partner"), ("name", "=", "category_id")]
@@ -246,12 +268,14 @@ class TestSurveyRecordCreation(SurveyCase):
) )
self._add_answer_line( self._add_answer_line(
question=self.question_category, answer=self.answer, question=self.question_category,
answer_value=self.question_category.suggested_answer_ids[0].id answer=self.answer,
answer_value=self.question_category.suggested_answer_ids[0].id,
) )
self._add_answer_line( self._add_answer_line(
question=self.question_category, answer=self.answer, question=self.question_category,
answer_value=self.question_category.suggested_answer_ids[1].id answer=self.answer,
answer_value=self.question_category.suggested_answer_ids[1].id,
) )
self.answer._mark_done() self.answer._mark_done()
@@ -280,7 +304,7 @@ class TestSurveyRecordCreation(SurveyCase):
"model_id": res_partner_bank_model.id, "model_id": res_partner_bank_model.id,
} }
) )
# Below we test "value_origin": "other_record" # Below we test "value_origin": "other_record" with a required field
partner_field = self.env["ir.model.fields"].search( partner_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner.bank"), ("name", "=", "partner_id")] [("model", "=", "res.partner.bank"), ("name", "=", "partner_id")]
) )
@@ -308,6 +332,20 @@ class TestSurveyRecordCreation(SurveyCase):
"fixed_value_char": "FR76 1444 5004 0004 0000 0000 000", "fixed_value_char": "FR76 1444 5004 0004 0000 0000 000",
} }
) )
# Below we test "value_origin": "other_record" with a NOT required field
bank_ids_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "bank_ids")]
)
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": bank_ids_field.id,
"value_origin": "other_record",
"other_created_record_id": self.bank_survey_record_creation.id,
}
)
self.answer = self._add_answer( self.answer = self._add_answer(
survey=self.survey, partner=False, email="jean@test.fr" survey=self.survey, partner=False, email="jean@test.fr"
@@ -325,7 +363,8 @@ class TestSurveyRecordCreation(SurveyCase):
self.assertTrue(bank_account.acc_number == "FR76 1444 5004 0004 0000 0000 000") self.assertTrue(bank_account.acc_number == "FR76 1444 5004 0004 0000 0000 000")
def test_records_of_same_model_are_created(self): def test_records_of_same_model_are_created(self):
# When we have 2 survey.record.creation on res.partner, we check that 2 contacts are created # When we have 2 survey.record.creation on res.partner,
# we check that 2 contacts are created
self.second_question_name = self._add_question( self.second_question_name = self._add_question(
page=None, page=None,
name="Name of second person", name="Name of second person",
@@ -334,9 +373,7 @@ class TestSurveyRecordCreation(SurveyCase):
sequence=1, sequence=1,
) )
self.second_contact_survey_record_creation = self.env[ self.second_contact_creation = self.env["survey.record.creation"].create(
"survey.record.creation"
].create(
{ {
"name": "Second contact", "name": "Second contact",
"survey_id": self.survey.id, "survey_id": self.survey.id,
@@ -345,7 +382,7 @@ class TestSurveyRecordCreation(SurveyCase):
) )
self.env["survey.record.creation.field.values"].create( self.env["survey.record.creation.field.values"].create(
{ {
"survey_record_creation_id": self.second_contact_survey_record_creation.id, "survey_record_creation_id": self.second_contact_creation.id,
"survey_id": self.survey.id, "survey_id": self.survey.id,
"model_id": self.res_partner_model.id, "model_id": self.res_partner_model.id,
"field_id": self.name_field.id, "field_id": self.name_field.id,
@@ -402,11 +439,14 @@ class TestSurveyRecordCreation(SurveyCase):
survey=self.survey, partner=False, email="jean@test.fr" survey=self.survey, partner=False, email="jean@test.fr"
) )
self._add_answer_line( self._add_answer_line(
question=self.question_email, answer=self.answer, answer_value="jean@test.fr" question=self.question_email,
answer=self.answer,
answer_value="jean@test.fr",
) )
with self.assertRaises(IntegrityError): with self.assertRaises(IntegrityError):
# TODO : propose a better user experience than IntegrityError when a mandatory field is missing # TODO : propose a better user experience than IntegrityError when
# a mandatory field is missing
self.answer._mark_done() self.answer._mark_done()
def test_survey_submitted_twice_by_same_user(self): def test_survey_submitted_twice_by_same_user(self):
@@ -479,10 +519,14 @@ class TestSurveyRecordCreation(SurveyCase):
], ],
survey_id=self.survey.id, survey_id=self.survey.id,
sequence=1, sequence=1,
answer_values_type="record" answer_values_type="record",
) )
self.question_title.suggested_answer_ids[0].record_id = f"res.partner.title,{mister_title.id}" self.question_title.suggested_answer_ids[
self.question_title.suggested_answer_ids[1].record_id = f"res.partner.title,{madam_title.id}" 0
].record_id = f"res.partner.title,{mister_title.id}"
self.question_title.suggested_answer_ids[
1
].record_id = f"res.partner.title,{madam_title.id}"
self.question_street = self._add_question( self.question_street = self._add_question(
page=None, page=None,
@@ -539,10 +583,18 @@ class TestSurveyRecordCreation(SurveyCase):
question=self.question_name, answer=self.answer, answer_value="Jean" question=self.question_name, answer=self.answer, answer_value="Jean"
) )
self._add_answer_line( self._add_answer_line(
question=self.question_email, answer=self.answer, answer_value=False, skipped=True, answer_type=False question=self.question_email,
answer=self.answer,
answer_value=False,
skipped=True,
answer_type=False,
) )
self._add_answer_line( self._add_answer_line(
question=self.question_title, answer=self.answer, answer_value=False, skipped=True, answer_type=False question=self.question_title,
answer=self.answer,
answer_value=False,
skipped=True,
answer_type=False,
) )
self.answer._mark_done() self.answer._mark_done()
@@ -563,11 +615,15 @@ class TestSurveyRecordCreation(SurveyCase):
], ],
survey_id=self.survey.id, survey_id=self.survey.id,
sequence=1, sequence=1,
answer_values_type="value" answer_values_type="value",
) )
self.question_employee.suggested_answer_ids[0].value_char = self.question_employee.suggested_answer_ids[0].value self.question_employee.suggested_answer_ids[
self.question_employee.suggested_answer_ids[1].value_char = self.question_employee.suggested_answer_ids[1].value 0
].value_char = self.question_employee.suggested_answer_ids[0].value
self.question_employee.suggested_answer_ids[
1
].value_char = self.question_employee.suggested_answer_ids[1].value
employee_field = self.env["ir.model.fields"].search( employee_field = self.env["ir.model.fields"].search(
[("model", "=", "res.partner"), ("name", "=", "employee")] [("model", "=", "res.partner"), ("name", "=", "employee")]
@@ -587,12 +643,12 @@ class TestSurveyRecordCreation(SurveyCase):
survey=self.survey, partner=False, email="jean@test.fr" survey=self.survey, partner=False, email="jean@test.fr"
) )
self._add_answer_line( self._add_answer_line(
question=self.question_name, answer=self.answer, question=self.question_name, answer=self.answer, answer_value="Jean"
answer_value="Jean"
) )
self._add_answer_line( self._add_answer_line(
question=self.question_employee, answer=self.answer, question=self.question_employee,
answer_value=self.question_employee.suggested_answer_ids[0].id answer=self.answer,
answer_value=self.question_employee.suggested_answer_ids[0].id,
) )
self.answer._mark_done() self.answer._mark_done()