[IMP] survey_event_registration_generation: manage multiple training products fields in survey

This commit is contained in:
clementthomas
2023-10-31 12:10:12 +01:00
parent 7bc095e265
commit 0c4b367112
9 changed files with 172 additions and 68 deletions

View File

@@ -8,30 +8,47 @@ from odoo import http
class Survey(main.Survey):
@http.route(['/survey_event/get_events_from_product'], type='json', auth="public", methods=['POST'])
def get_events_from_product(self, product_id, **kw):
if not product_id:
def get_events_from_product(self, product_ids, only_visible_in_survey, **kw):
"""
Called from survey_form.js when event product answer change, reload event list
"""
if not product_ids:
return []
events = request.env['event.event'].sudo().get_events_visible_in_survey(product_id)
events = request.env['event.event'].sudo().get_events_from_event_products(product_ids, only_visible_in_survey=only_visible_in_survey)
return [{'id':event.id,'name':event.name} for event in events]
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'].sudo().get_event_products_visible_in_survey()
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:
event_product_id = None
event_products_ids = None
if next_event_question.event_product_question_id:
event_product_id = self._get_answer_event_product(next_event_question.event_product_question_id, answer_sudo).id
result['events'] = request.env['event.event'].sudo().get_events_visible_in_survey(event_product_id)
event_products_ids = self._get_answer_event_product(next_event_question.event_product_question_id, answer_sudo).id
result['events'] = request.env['event.event'].sudo().get_events_from_event_products(event_products_ids)
return result
def _get_answer_event_product(self, question, answer_sudo):
"""return value(s) selected in for Event Product question.
Question can be event_product (only one event product selected)
or multiple_event_products (several event products can be selected)
Args:
question (survey.question): Event product question
answer_sudo (survey.user.input)
Returns:
List<product.product>: List of selected event products
"""
for user_input_line in answer_sudo.user_input_line_ids:
if user_input_line.question_id == question:
return user_input_line.value_event_product
if question.question_type == 'event_product':
return [user_input_line.value_event_product]
if question.question_type == 'multiple_event_products':
return user_input_line.value_multiple_event_products
def _get_next_event_question(self, answer_sudo):

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-10-24 08:53+0000\n"
"PO-Revision-Date: 2023-10-24 08:53+0000\n"
"POT-Creation-Date: 2023-10-31 09:56+0000\n"
"PO-Revision-Date: 2023-10-31 09:56+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -69,6 +69,12 @@ msgstr "Inscription à une session de formation"
msgid "Event registration field"
msgstr "Champ d'inscription à une formation"
#. module: survey_event_registration_generation
#: model:ir.model.fields,help:survey_event_registration_generation.field_event_event__visible_in_survey
#: model:ir.model.fields,help:survey_event_registration_generation.field_product_product__visible_in_survey
msgid "Events in step configured as 'visible in survey'."
msgstr "Événements dans une étape configurée comme 'visible dans les questionnaires'."
#. module: survey_event_registration_generation
#: model_terms:ir.ui.view,arch_db:survey_event_registration_generation.survey_form
msgid "Events registrations"
@@ -93,6 +99,19 @@ msgstr ""
"Si vous indiquez la question du produit de formation, seuls les sessions de "
"formation correspondantes seront proposés"
#. module: survey_event_registration_generation
#: model:ir.model.fields,help:survey_event_registration_generation.field_survey_question__show_events_and_event_products_only_visible_in_survey
msgid ""
"In event step configuration, you can check 'Visible in surveys'. \n"
" If this option is checked, \n"
" If question display events, they are filtered with only events in step 'Visible in survey'. \n"
" If question display event products, they are filtered with only products of events in step 'Visible in survey'."
msgstr ""
"Dans la configuration des étapes d'événement, vous pouvez cocher la case 'Visible dans les questionnaires'. \n"
" Si cette option est cochée, \n"
" Si la question affiche des événements, ils seront filtrer pour n'afficher que les événements dans une étape 'Visible dans les questionnaires'. \n"
" Si la question affiche des produits d'événement, ils seront filtrés pour n'afficher que les produits des événements dans une étape 'Visible dans les questionnaires'."
#. module: survey_event_registration_generation
#: model:ir.model.fields,field_description:survey_event_registration_generation.field_survey_user_input_line__value_multiple_event_products
#: model:ir.model.fields.selection,name:survey_event_registration_generation.selection__survey_question__question_type__multiple_event_products
@@ -125,6 +144,11 @@ msgstr ""
"Selectionnez la question portant sur le produit de formation, afin de filter"
" les sessions de formation selectionnées"
#. module: survey_event_registration_generation
#: model:ir.model.fields,field_description:survey_event_registration_generation.field_survey_question__show_events_and_event_products_only_visible_in_survey
msgid "Show events or event products in step visible in survey"
msgstr "Montrer les événements ou les produits d'événement 'visibles dans les questionnaires'."
#. module: survey_event_registration_generation
#: model:ir.model,name:survey_event_registration_generation.model_survey_survey
msgid "Survey"
@@ -145,6 +169,12 @@ msgstr "Entrée utilisateur du questionnaire"
msgid "Survey User Input Line"
msgstr "Ligne d'entrée pour l'utilisateur du questionnaire"
#. module: survey_event_registration_generation
#: model:ir.model.fields,field_description:survey_event_registration_generation.field_event_event__visible_in_survey
#: model:ir.model.fields,field_description:survey_event_registration_generation.field_product_product__visible_in_survey
msgid "Visible in survey"
msgstr "Visible dans les questionnaires"
#. module: survey_event_registration_generation
#: model:ir.model.fields,field_description:survey_event_registration_generation.field_event_stage__visible_in_survey
msgid "Visible in surveys"

View File

@@ -4,18 +4,27 @@ from odoo import models, fields, api
class EventEvent(models.Model):
_inherit = 'event.event'
def get_events_visible_in_survey(self, product_id=None):
"""Search events in stage visible in survey.
Optionnaly filtered by product present in ticket.
visible_in_survey = fields.Boolean('Visible in survey', related='stage_id.visible_in_survey', readonly=True,
help="""Events in step configured as 'visible in survey'.""")
def get_events_from_event_products(self, product_ids=None, only_visible_in_survey=False):
"""Search events in stage filtered by product present in ticket..
Args:
product_id (product.product, optional): to filter only events with tickets using this product. Defaults to None.
product_ids (list[product.product ids], optional): to filter only events with tickets using product in this list. Defaults to None.
Returns:
event.event: Events
"""
if product_id:
event_tickets = self.env['event.event.ticket'].search([('product_id','=',product_id)])
return self.env['event.event'].search([('stage_id.visible_in_survey','=',True),('event_ticket_ids','in',event_tickets.id)])
return self.env['event.event'].search([('stage_id.visible_in_survey','=',True)])
event_search = []
if product_ids:
event_tickets = self.env['event.event.ticket'].search([('product_id','in',product_ids)])
event_search.append(('event_ticket_ids','in',event_tickets.ids))
if only_visible_in_survey:
event_search.append(('visible_in_survey','=',True))
return self.env['event.event'].search(event_search)

View File

@@ -4,15 +4,20 @@ from odoo import models, fields, api
class ProductProduct(models.Model):
_inherit = 'product.product'
def get_event_products_visible_in_survey(self):
"""Search products used in tickets of events visibles in surveys
visible_in_survey = fields.Boolean('Visible in survey', compute='_compute_visible_in_survey', readonly=True,
help="""Events in step configured as 'visible in survey'.""")
Returns:
product.product: products
"""
events = self.env['event.event'].get_events_visible_in_survey()
products = set()
def _compute_visible_in_survey(self):
#get all events in step 'visible in survey'
product_ids = set()
events = self.env['event.event'].search([('visible_in_survey','=',True)])
for event in events:
for ticket in event.event_ticket_ids:
products.add(ticket.product_id)
return list(products)
product_ids.add(ticket.product_id.id)
for event_product in self:
if event_product.id in product_ids:
event_product.visible_in_survey = True
else:
event_product.visible_in_survey = False

View File

@@ -1,3 +1,4 @@
from email.policy import default
from odoo import models, fields, api
@@ -8,6 +9,12 @@ class SurveyQuestion(models.Model):
selection_add=[('event_product', 'Event product'),('event', 'Event'),('multiple_event_products', 'Multiple event products')]) #event_product : List product used in tickets of visible events
#event : List events visible in surveys
show_events_and_event_products_only_visible_in_survey = fields.Boolean('Show events or event products in step visible in survey',
help="""In event step configuration, you can check 'Visible in surveys'.
If this option is checked,
If question display events, they are filtered with only events in step 'Visible in survey'.
If question display event products, they are filtered with only products of events in step 'Visible in survey'.""")
event_product_question_id = fields.Many2one(
'survey.question', string="Event product question", copy=False, compute="_compute_event_product_question_id",

View File

@@ -19,7 +19,7 @@ class SurveyUserInput(models.Model):
event_id = fields.Many2one('event.event', 'Event', compute='compute_event_id', store=True) #related event - answer of "event" question
event_product_id = fields.Many2one('product.product', 'Event product', compute='compute_event_product_id', store=True) #related event product - answer of "event product" question
event_products_ids = fields.Many2many('product.product', string='Event products', compute='compute_event_products_ids', store=True) #related event products - answer of "event product" or "multiple event product" question
@api.depends('user_input_line_ids')
def compute_event_id(self):
@@ -32,13 +32,16 @@ class SurveyUserInput(models.Model):
break
@api.depends('user_input_line_ids')
def compute_event_product_id(self):
"""set event_product_id as answer of "event product" question
def compute_event_products_ids(self):
"""set event_products_ids as answer of "event product" or "multiple event products" question
"""
for user_input in self:
for user_input_line in user_input.user_input_line_ids:
if user_input_line.answer_type == 'event_product':
user_input.event_product_id = user_input_line.value_event_product
user_input.event_products_ids = [user_input_line.value_event_product.id]
break
if user_input_line.answer_type == 'multiple_event_products':
user_input.event_products_ids = user_input_line.value_multiple_event_products
break
def save_lines(self, question, answer, comment=None):

View File

@@ -31,21 +31,40 @@ SurveyFormWidget.include({
},
_onChangeChoiceItem: function (event) {
var event_select = $('select[data-question-type="event"]:visible')
//Check if event product selection change
if ($(event.currentTarget).data('questionType') == 'event_product') {
//Check if event selection visible
if (event_select) {
var question_type = $(event.currentTarget).data('questionType');
if (question_type == 'event_product' || question_type == 'multiple_event_products') {
//Current question (for event products) id
var event_product_question_id = event.currentTarget.name;
//find event selector concerned by this event product question
var event_selects = $('select[data-question-type="event"][data-event-product-question-id="'+event_product_question_id+'"]:visible');
//find all event products selected in this question
var event_product_ids = [];
if (question_type == 'multiple_event_products') {
// find event products selected in case of multiple event products question
event_product_ids = $('input[name="'+event_product_question_id+'"]:checked').map(function() {
return parseInt($(this).attr("value"));
}).get();
} else {
// find event products selected in case of simple event product question
event_product_ids = [parseInt($(event.currentTarget).find(":selected").val())];
}
// populate concerned events selectors
event_selects.each(function( index ) {
var event_select = $(this);
//Disable event selection
event_select.prop('disabled', 'disabled');
//Get event product id
var eventProductId = parseInt($(event.currentTarget).find(":selected").val())
//Ajax : get new events
ajax.jsonRpc('/survey_event/get_events_from_product', 'call', {
'product_id': eventProductId,
'product_ids': event_product_ids,
'only_visible_in_survey': event_select.data('only-visible-in-survey') === "True"
}).then((new_events) => {
// Delete old events
$(event_select).find('option').remove()
@@ -61,7 +80,8 @@ SurveyFormWidget.include({
event_select.prop('disabled', false);
});
}
})
}

View File

@@ -8,16 +8,20 @@
<field name="arch" type="xml">
<xpath expr="//field[@name='comments_allowed']/.." position="after">
<group name="event_registration" string="Event registration">
<!-- related event product question, to filter events, in case of event question -->
<field name="event_product_question_id" options="{'no_open': True, 'no_create': True}"
attrs="{'invisible': [('question_type','!=','event')]}"
help="Select the question asking for event product, to filter proposed events." />
<!-- event registration field, filtered by event_registration_allowed_field_ids (invisible) -->
<field name="event_registration_field" widget="selection" />
<field name="event_registration_allowed_field_ids" invisible="1" />
</group>
</xpath>
<xpath expr="//field[@name='validation_required']" position="before">
<field name="show_events_and_event_products_only_visible_in_survey"
attrs="{'invisible': [('question_type', 'not in', ['event_product', 'event', 'multiple_event_products'])]}"
/>
<!-- related event product question, to filter events, in case of event question -->
<field name="event_product_question_id" options="{'no_open': True, 'no_create': True}"
attrs="{'invisible': [('question_type','!=','event')],'required': [('question_type','=','event')]}"
help="Select the question asking for event product, to filter proposed events." />
</xpath>
</field>
</record>

View File

@@ -23,10 +23,12 @@
t-att-data-question-type="question.question_type">
<option>Please select...</option>
<t t-foreach="event_products" t-as="event_product">
<option
t-att-value="event_product.id"
t-att-selected="answer_lines and (answer_lines[0].value_event_product.id == event_product.id)">
<t t-esc="event_product.name"/></option>
<t t-if="not question.show_events_and_event_products_only_visible_in_survey or (question.show_events_and_event_products_only_visible_in_survey and event_product.visible_in_survey)">
<option
t-att-value="event_product.id"
t-att-selected="answer_lines and (answer_lines[0].value_event_product.id == event_product.id)">
<t t-esc="event_product.name"/></option>
</t>
</t>
</select>
</div>
@@ -41,16 +43,18 @@
<div class="d-flex flex-wrap col-lg-12">
<t t-set="has_correct_answer" t-value="scoring_display_correction and any(label.is_correct for label in question.suggested_answer_ids)"/>
<t t-foreach="event_products" t-as="event_product">
<label t-att-class="'o_survey_choice_btn form-label me-2 py-1 px-3 rounded %s' % ('o_survey_selected' if answer_line else '')">
<t t-if="not question.show_events_and_event_products_only_visible_in_survey or (question.show_events_and_event_products_only_visible_in_survey and event_product.visible_in_survey)">
<label t-att-class="'o_survey_choice_btn form-label me-2 py-1 px-3 rounded %s' % ('o_survey_selected' if answer_line else '')">
<input type="checkbox" t-att-value='event_product.id' class="o_survey_form_choice_item invisible position-absolute"
t-att-name="question.id" />
<span class="ms-2 text-break" t-field='event_product.name'/>
<input type="checkbox" t-att-value='event_product.id' class="o_survey_form_choice_item invisible position-absolute"
t-att-name="question.id" t-att-data-question-type="question.question_type" />
<span class="ms-2 text-break" t-field='event_product.name'/>
<i class="fa fa-check-circle float-end mt-1 position-relative"></i>
<i class="fa fa-circle-thin float-end mt-1 position-relative"></i>
<i class="fa fa-check-circle float-end mt-1 position-relative"></i>
<i class="fa fa-circle-thin float-end mt-1 position-relative"></i>
</label>
</label>
</t>
</t>
</div>
</div>
@@ -63,14 +67,19 @@
<div class="o_survey_comment_container p-0">
<select class="o_survey_form_choice_item"
t-att-name="question.id"
t-att-data-event-product-question-id="question.event_product_question_id.id"
t-att-data-event-product-question-type="question.event_product_question_id.question_type"
t-att-placeholder="question.question_placeholder"
t-att-data-question-type="question.question_type">
t-att-data-question-type="question.question_type"
t-att-data-only-visible-in-survey="question.show_events_and_event_products_only_visible_in_survey">
<option>Please select...</option>
<t t-foreach="events" t-as="event">
<option
t-att-value="event.id"
t-att-selected="answer_lines and (answer_lines[0].value_event.id == event.id)">
<t t-esc="event.name"/></option>
<t t-if="not question.show_events_and_event_products_only_visible_in_survey or (question.show_events_and_event_products_only_visible_in_survey and event.visible_in_survey)">
<option
t-att-value="event.id"
t-att-selected="answer_lines and (answer_lines[0].value_event.id == event.id)">
<t t-esc="event.name"/></option>
</t>
</t>
</select>
</div>