[IMP] survey_event_registration_generation: event registration generation

This commit is contained in:
clementthomas
2023-09-18 16:54:59 +02:00
parent 4baaad2054
commit a1fb5bc5ca
8 changed files with 232 additions and 13 deletions

View File

@@ -12,7 +12,9 @@
"depends": ["survey"],
"data": [
'views/survey_question_views.xml',
'views/survey_templates.xml'
'views/survey_survey_views.xml',
'views/survey_templates.xml',
#'security/ir.model.access.csv',
],
'assets': {
'survey.survey_assets': [

View File

@@ -7,7 +7,7 @@ from odoo.http import request
class Survey(main.Survey):
def _prepare_survey_data(self, survey_sudo, answer_sudo, **post):
result = super(Survey, self)._prepare_survey_data(survey_sudo, answer_sudo, **post)
result['event_products'] = request.env['product.product'].search([('detailed_type','=','event')])
result['event_products'] = request.env['product.product'].sudo().search([('detailed_type','=','event')])
next_event_question = self._get_next_event_question(answer_sudo)
if next_event_question:
@@ -15,10 +15,10 @@ class Survey(main.Survey):
if next_event_question.event_product_question_id:
event_product = self._get_answer_event_product(next_event_question.event_product_question_id, answer_sudo)
if event_product:
event_tickets = request.env['event.event.ticket'].search([('product_id','=',event_product.id)])
event_tickets = request.env['event.event.ticket'].sudo().search([('product_id','=',event_product.id)])
result['events'] = event_tickets.event_id
else:
result['events'] = request.env['event.event'].search([])
result['events'] = request.env['event.event'].sudo().search([])
return result

View File

@@ -1,3 +1,4 @@
from . import survey_question
from . import survey_user_input
from . import survey_user_input_line
from . import survey_survey

View File

@@ -9,7 +9,7 @@ class SurveyQuestion(models.Model):
event_product_question_id = fields.Many2one(
'survey.question', string="Event ticket question", copy=False, compute="_compute_event_product_question_id",
'survey.question', string="Event product question", copy=False, compute="_compute_event_product_question_id",
store=True, readonly=False, help="If you specify question of event product, only events of selected product will be proposed.",
domain="[('survey_id', '=', survey_id), \
'&', ('question_type', '=', 'event_product'), \
@@ -17,12 +17,95 @@ class SurveyQuestion(models.Model):
('sequence', '<', sequence), \
'&', ('sequence', '=', sequence), ('id', '<', id)]")
event_registration_allowed_field_ids = fields.Many2many(
comodel_name="ir.model.fields",
compute="_compute_event_registration_allowed_field_ids",
)
event_registration_field = fields.Many2one(
string="Event registration field",
comodel_name="ir.model.fields",
domain="[('id', 'in', event_registration_allowed_field_ids)]",
)
@api.depends("question_type")
def _compute_event_registration_allowed_field_ids(self):
type_mapping = {
"char_box": ["char", "text"],
"text_box": ["html"],
"numerical_box": ["integer", "float", "html", "char"],
"date": ["date", "text", "char"],
"datetime": ["datetime", "html", "char"],
"simple_choice": ["many2one", "html", "char"],
"multiple_choice": ["many2many", "html", "char"],
}
for record in self:
if record.question_type == "event":
record.event_registration_allowed_field_ids = (
self.env["ir.model.fields"]
.search(
[
("model", "=", "event.registration"),
("name", "=", "event_id"),
]
)
.ids
)
record.event_registration_allowed_field_ids = (
self.env["ir.model.fields"]
.search(
[
("model", "=", "event.registration"),
("ttype", "in", type_mapping.get(record.question_type, [])),
]
)
.ids
)
@api.depends('question_type')
def _compute_event_product_question_id(self):
""" Used as an 'onchange' : Reset the event ticket question if user change question type
""" Used as an 'onchange' : Reset the event product question if user change question type
Avoid CacheMiss : set the value to False if the value is not set yet."""
for question in self:
if not question.question_type == 'event' or question.triggering_question_id is None:
question.triggering_question_id = False
if not question.question_type == 'event' or question.event_product_question_id is None:
question.event_product_question_id = False
class SurveyQuestionAnswer(models.Model):
_inherit = "survey.question.answer"
@api.model
def default_get(self, fields):
result = super().default_get(fields)
if (
not result.get("event_registration_field")
or "event_registration_field_resource_ref" not in fields
):
return result
registration_field = self.env["ir.model.fields"].browse(result["event_registration_field"])
# Otherwise we'll just use the value (char, text)
if registration_field.ttype not in {"many2one", "many2many"}:
return result
res = self.env[registration_field.relation].search([], limit=1)
if res:
result["event_registration_field_resource_ref"] = "%s,%s" % (
registration_field.relation,
res.id,
)
return result
@api.model
def _selection_event_registration_field_resource_ref(self):
return [(model.model, model.name) for model in self.env["ir.model"].search([])]
event_registration_field = fields.Many2one(related="question_id.event_registration_field")
event_registration_field_resource_ref = fields.Reference(
string="Event registration field value",
selection="_selection_event_registration_field_resource_ref",
)
@api.onchange("event_registration_field_resource_ref")
def _onchange_event_registration_field_resource_ref(self):
"""Set the default value as the display_name, although we can change it"""
if self.event_registration_field_resource_ref:
self.value = self.event_registration_field_resource_ref.display_name or ""

View File

@@ -0,0 +1,11 @@
# Copyright 2023 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class SurveySurvey(models.Model):
_inherit = "survey.survey"
generate_registration = fields.Boolean(
help="Generate registration for selected event",
)

View File

@@ -15,7 +15,14 @@ _logger = logging.getLogger(__name__)
class SurveyUserInput(models.Model):
_inherit = 'survey.user_input'
registration_id = fields.Many2one('event.registration', 'Event registration')
def save_lines(self, question, answer, comment=None):
"""
Inherit save_lines method, called after each answer
to save selected event or event_product in user_input.line
depending on the question type
"""
old_answers = self.env['survey.user_input.line'].search([
('user_input_id', '=', self.id),
('question_id', '=', question.id)
@@ -29,6 +36,9 @@ class SurveyUserInput(models.Model):
def _save_event_product(self, question, old_answers, answer):
"""
Save event product to user_input.line
"""
vals = self._get_line_answer_values(question, answer, question.question_type)
vals['value_event_product'] = int(vals['value_event_product'])
if old_answers:
@@ -38,6 +48,9 @@ class SurveyUserInput(models.Model):
return self.env['survey.user_input.line'].create(vals)
def _save_event(self, question, old_answers, answer):
"""
Save event to user_input.line
"""
vals = self._get_line_answer_values(question, answer, question.question_type)
vals['value_event'] = int(vals['value_event'])
if old_answers:
@@ -45,3 +58,77 @@ class SurveyUserInput(models.Model):
return old_answers
else:
return self.env['survey.user_input.line'].create(vals)
def _prepare_registration(self):
"""Extract registration values from the answers"""
elegible_inputs = self.user_input_line_ids.filtered(
lambda x: x.question_id.event_registration_field and not x.skipped
)
basic_inputs = elegible_inputs.filtered(
lambda x: x.answer_type not in {"suggestion"}
and x.question_id.event_registration_field.name != "comment"
)
vals = {}
for line in basic_inputs:
if line.question_id.event_registration_field.ttype == 'many2one':
vals[line.question_id.event_registration_field.name] = line[f"value_{line.answer_type}"].id
else:
vals[line.question_id.event_registration_field.name] = line[f"value_{line.answer_type}"]
for line in elegible_inputs - basic_inputs:
field_name = line.question_id.event_registration_field.name
if line.question_id.event_registration_field.ttype == "many2one":
vals[
field_name
] = line.suggested_answer_id.event_registration_field_resource_ref.id
elif line.question_id.event_registration_field.ttype == "many2many":
vals.setdefault(field_name, [])
vals[field_name] += [
(4, line.suggested_answer_id.event_registration_field_resource_ref.id)
]
# We'll use the comment field to add any other infos
elif field_name == "comment":
vals.setdefault("comment", "")
value = (
line.suggested_answer_id.value
if line.answer_type == "suggestion"
else line[f"value_{line.answer_type}"]
)
vals["comment"] += f"\n{line.question_id.title}: {value}"
else:
if line.question_id.question_type == "multiple_choice":
if not vals.get(field_name):
vals[field_name] = line.suggested_answer_id.value
else:
vals[field_name] += line.suggested_answer_id.value
else:
vals[field_name] = line.suggested_answer_id.value
return vals
def _create_registration_post_process(self, registration):
"""After creating the lead send an internal message with the input link"""
registration.message_post_with_view(
"mail.message_origin_link",
values={"self": registration, "origin": self.survey_id},
subtype_id=self.env.ref("mail.mt_note").id,
)
def _mark_done(self):
"""Generate registration when the survey is submitted"""
for user_input in self.filtered(
lambda r: r.survey_id.generate_registration and not self.registration_id
):
vals = user_input._prepare_registration()
registration = self.env["event.registration"].create(vals)
self._create_registration_post_process(registration)
self.update({"registration_id": registration.id})
res = super()._mark_done()
# after all, set partner id of registration as the partner of user input
for user_input in self:
if user_input.registration_id and user_input.partner_id:
user_input.registration_id.partner_id = user_input.partner_id
return res

View File

@@ -7,10 +7,31 @@
<xpath expr="//field[@name='comments_allowed']/.." position="after">
<group name="event_registration" string="Event registration">
<field name="event_product_question_id" options="{'no_open': True, 'no_create': True}"
attrs="{'invisible': [('question_type','!=','event')]}" />
<!-- <field name="allowed_field_ids" invisible="1" /> -->
attrs="{'invisible': [('question_type','!=','event')]}"
help="Select the question asking for event product, to filter proposed events." />
<field name="event_registration_field" widget="selection" />
<field name="event_registration_allowed_field_ids" invisible="1" />
</group>
</xpath>
<xpath expr="//field[@name='suggested_answer_ids']" position="attributes">
<attribute
name="context"
>{'default_question_id': active_id, 'default_event_registration_field': event_registration_field}</attribute>
</xpath>
<xpath
expr="//field[@name='suggested_answer_ids']//field[@name='value']"
position="after"
>
<field name="event_registration_field" invisible="1" />
<field
name="event_registration_field_resource_ref"
readonly="False"
options="{'hide_model': True, 'no_create': True, 'no_edit': True, 'no_open': True}"
attrs="{'column_invisible': [('parent.event_registration_field', '=', False)]}"
/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="survey_form" model="ir.ui.view">
<field name="model">survey.survey</field>
<field name="inherit_id" ref="survey.survey_survey_view_form" />
<field name="arch" type="xml">
<group name="options" position="inside">
<group name="event_options" string="Event">
<field name="generate_registration" />
</group>
</group>
</field>
</record>
</odoo>