[IMP] survey_record_generation: first refacto of survey.user_input _mark_done function

This commit is contained in:
2025-10-16 12:37:34 +02:00
parent 7d638c4e92
commit f1b92990a5
2 changed files with 78 additions and 55 deletions

View File

@@ -1,4 +1,6 @@
# 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 typing import Any
from odoo import models, fields, _ from odoo import models, fields, _
from odoo.exceptions import UserError from odoo.exceptions import UserError
@@ -40,62 +42,20 @@ class SurveyUserInput(models.Model):
for record_creation in user_input.survey_id.survey_record_creation_ids.sorted('sequence'): for record_creation in user_input.survey_id.survey_record_creation_ids.sorted('sequence'):
model = record_creation.model_id.model model = record_creation.model_id.model
vals = {} vals = {}
ModelClass = self.env[model]
for field_value in record_creation.field_values_ids: for field_value in record_creation.field_values_ids:
field_name = field_value.field_id.name
value = None
if field_value.value_origin == 'fixed': if field_value.value_origin == 'fixed':
vals[field_value.field_id.name] = field_value.get_fixed_value_for_record_creation() value = field_value.get_fixed_value_for_record_creation()
elif field_value.value_origin == 'question': elif field_value.value_origin == 'question':
# find user_input_lines of the question value = self.get_value_from_user_answer(field_value, 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]
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':
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': elif field_value.value_origin == 'other_record':
fields_to_update.append(field_value) fields_to_update.append(field_value)
# check if the field to update is mandatory value = self.get_value_from_other_record(model, created_records, field_value, value)
if ModelClass._fields[field_value.field_id.name].required: vals[field_name] = value
# 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]: duplicate = self.verify_fields_with_unicity_check(model, record_creation, vals)
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
@@ -108,16 +68,18 @@ class SurveyUserInput(models.Model):
# 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_name":record_creation.name,
'survey_record_creation_id':record_creation.id, "survey_record_creation_id":record_creation.id,
'user_input_id':user_input.id, "user_input_id":user_input.id,
"created_record_id":"%s,%s" % (model,record.id) "created_record_id":"%s,%s" % (model,record.id)
}) })
created_records[record_creation.id] = record created_records[record_creation.id] = record
# update linked records # update linked records
# TODO : not covered by test, because I don't get the purpose
# TODO : maybe in case of duplicate ?
for field_to_update in fields_to_update: for field_to_update in 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:
@@ -125,3 +87,63 @@ class SurveyUserInput(models.Model):
record_to_update.write({field_to_update.field_id.name:linked_record.id}) record_to_update.write({field_to_update.field_id.name:linked_record.id})
return super()._mark_done() return super()._mark_done()
def verify_fields_with_unicity_check(self, model, record_creation, 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_value_from_other_record(self, model, created_records: dict[Any, Any], field_value, value) -> Any:
ModelClass = self.env[model]
# 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]
value = 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)
)
return value
def get_value_from_user_answer(self, field_value, user_input) -> Any:
# 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:
return None
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":
if record_ids:
return record_ids[0]
else:
return None
else:
return 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"]
return boolean_value
else:
return 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
return user_input_lines[0][f"value_{user_input_lines[0].answer_type}"]
else:
return None

View File

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