[IMP] website_event[_questions]: allow setting event questions as mandatory

Purpose:

Allow users to make sure they will get an answer to the questions they ask
attendees while they register.
e.g.:
- You organize activities for kids and want to make sure you have a second
phone number available in case of emergencies
- You organize B2B events and need to know in which industry your attendees
work
- You use the Event/CRM bridge and plan to filter attendees based on those
answers
...

Specifications:

In the question form view, a boolean "Mandatory Answer" has been added.

In the list view, that field has been added as column.

In the registration form:
- "*", next to each mandatory question has been added
- "*" has been added next to name and email which were already mandatory
- the mandatory question have been actually made mandatory by preventing
user to submit empty answer

Remark: once_per_order was missing in the list view of the event template
questions. We have added it as well as "mandatory answer" field. The
question list view of the template and the event are now almost identical
(the button to the stat is obviously not present in the template).

Technical remarks:
- To ensures that multiple choice answer are filled by the users, we have
added an empty choice selected by default which forces the user to choose
one option.
- Empty answer were already filtered by the server and not inserted in the
database (in controller method _process_attendees_form, value evaluated
to false are not inserted)

Task-2745835

closes odoo/odoo#83586

Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
This commit is contained in:
Pierre-Yves Dufays
2022-03-02 10:00:50 +00:00
parent 923a92a0bb
commit 2faefd4757
6 changed files with 26 additions and 17 deletions
@@ -288,12 +288,12 @@
<h5 class="mt-1 pb-2 border-bottom">Ticket #<span t-esc="counter"/> <small class="text-muted">- <span t-esc="ticket['name']"/></small></h5>
<div class="row">
<div class="col-lg my-2">
<label>Name</label>
<label>Name *</label>
<input class="form-control" type="text" t-attf-name="#{counter}-name" required="This field is required"
t-att-value="default_first_attendee.get('name', '') if counter == 1 else ''"/>
</div>
<div class="col-lg my-2">
<label>Email</label>
<label>Email *</label>
<input class="form-control" type="email" t-attf-name="#{counter}-email" required="This field is required"
t-att-value="default_first_attendee.get('email', '') if counter == 1 else ''"/>
</div>
@@ -59,6 +59,7 @@ class EventEvent(models.Model):
'question_type': question.question_type,
'sequence': question.sequence,
'once_per_order': question.once_per_order,
'is_mandatory_answer': question.is_mandatory_answer,
'answer_ids': [(0, 0, {
'name': answer.name,
'sequence': answer.sequence
@@ -19,9 +19,10 @@ class EventQuestion(models.Model):
event_id = fields.Many2one('event.event', 'Event', ondelete='cascade')
answer_ids = fields.One2many('event.question.answer', 'question_id', "Answers", copy=True)
sequence = fields.Integer(default=10)
once_per_order = fields.Boolean('Ask only once per order',
once_per_order = fields.Boolean('Ask once per order',
help="If True, this question will be asked only once and its value will be propagated to every attendees."
"If not it will be asked for every attendee of a reservation.")
is_mandatory_answer = fields.Boolean('Mandatory Answer')
@api.constrains('event_type_id', 'event_id')
def _constrains_event(self):
@@ -9,11 +9,11 @@
<h1><field name="title" placeholder='e.g. "Do you have any diet restrictions?"' /></h1>
<group>
<group>
<div colspan="2">
<field name="once_per_order"/>
<label for="once_per_order"/>
</div>
<field name="question_type" widget="radio" options="{'horizontal': true}" />
<field name="is_mandatory_answer"/>
<field name="question_type" widget="radio" options="{'horizontal': true}"/>
</group>
<group>
<field name="once_per_order"/>
</group>
</group>
<notebook attrs="{'invisible': [('question_type', '!=', 'simple_choice')]}">
@@ -32,15 +32,19 @@
<template id="registration_event_question" name="Registration Event Question">
<label t-esc="question.title"/>
<span t-if="question.is_mandatory_answer">*</span>
<t t-if="question.question_type == 'simple_choice'">
<select t-attf-name="question_answer-#{registration_index}-#{question.id}" class="custom-select" required="true">
<select t-attf-name="question_answer-#{registration_index}-#{question.id}" class="custom-select"
t-att-required="question.is_mandatory_answer">
<option value=""/>
<t t-foreach="question.answer_ids" t-as="answer">
<option t-esc="answer.name" t-att-value="answer.id"/>
</t>
</select>
</t>
<t t-elif="question.question_type == 'text_box'">
<textarea t-attf-name="question_answer-#{registration_index}-#{question.id}" class="col-lg-12 form-control"/>
<textarea t-attf-name="question_answer-#{registration_index}-#{question.id}" class="col-lg-12 form-control"
t-att-required="question.is_mandatory_answer"/>
</t>
</template>
@@ -10,6 +10,8 @@
<field name="question_ids" class="w-100">
<tree sample="1">
<field name="title"/>
<field name="is_mandatory_answer"/>
<field name="once_per_order"/>
<field name="question_type" />
<field name="answer_ids" widget = "many2many_tags"/>
</tree>
@@ -31,6 +33,7 @@
<tree>
<field name="sequence" widget="handle" />
<field name="title"/>
<field name="is_mandatory_answer"/>
<field name="once_per_order"/>
<field name="question_type" string="Type" />
<field name="answer_ids" widget="many2many_tags"
@@ -43,13 +46,13 @@
<form string="Question">
<sheet>
<h1><field name="title" placeholder='e.g. "Do you have any diet restrictions?"' /></h1>
<group class="mb-0">
<group class="mb-0">
<div colspan="2">
<field name="once_per_order"/>
<label for="once_per_order"/>
</div>
<field name="question_type" widget="radio" options="{'horizontal': true}" />
<group>
<group>
<field name="is_mandatory_answer"/>
<field name="question_type" widget="radio" options="{'horizontal': true}"/>
</group>
<group>
<field name="once_per_order"/>
</group>
</group>
<notebook attrs="{'invisible': [('question_type', '!=', 'simple_choice')]}">