diff --git a/website_event_questions_multiple/README.rst b/website_event_questions_multiple/README.rst index ec55dea30..67ab17f35 100644 --- a/website_event_questions_multiple/README.rst +++ b/website_event_questions_multiple/README.rst @@ -13,9 +13,9 @@ Questions on Events - Type multiple .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png :target: https://odoo-community.org/page/development-status :alt: Production/Stable -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fevent-lightgray.png?logo=github :target: https://github.com/OCA/event/tree/16.0/website_event_questions_multiple :alt: OCA/event @@ -28,7 +28,7 @@ Questions on Events - Type multiple |badge1| |badge2| |badge3| |badge4| |badge5| -This module allows to add new question type : Selection multiple which allows +This module allows to add new question type : Multiple Selection which allows attendees to select multiple answers to a question. **Table of contents** @@ -39,7 +39,7 @@ attendees to select multiple answers to a question. Configuration ============= -On an event, when creating a new question, you can select new type : Selection multiple +On an event, when creating a new question, you can select new type : Multiple Selection Bug Tracker =========== @@ -58,6 +58,7 @@ Authors ~~~~~~~ * Le Filament +* Odoo S.A. Contributors ~~~~~~~~~~~~ diff --git a/website_event_questions_multiple/__manifest__.py b/website_event_questions_multiple/__manifest__.py index 33a36fb71..62db09293 100644 --- a/website_event_questions_multiple/__manifest__.py +++ b/website_event_questions_multiple/__manifest__.py @@ -4,8 +4,8 @@ "category": "Marketing", "website": "https://github.com/OCA/event", "development_status": "Production/Stable", - "author": "Le Filament, Odoo Community Association (OCA)", - "license": "AGPL-3", + "author": "Le Filament, Odoo Community Association (OCA), Odoo S.A.", + "license": "LGPL-3", "application": False, "depends": ["website_event_questions"], "data": [ @@ -13,6 +13,11 @@ "views/event_questions_views.xml", "views/event_registration_views.xml", ], + "assets": { + "web.assets_frontend": [ + "website_event_questions_multiple/static/src/js/form_validation.esm.js" + ], + }, "installable": True, "auto_install": False, } diff --git a/website_event_questions_multiple/controllers/main.py b/website_event_questions_multiple/controllers/main.py index 09200377d..530cc1b49 100644 --- a/website_event_questions_multiple/controllers/main.py +++ b/website_event_questions_multiple/controllers/main.py @@ -1,6 +1,7 @@ # Copyright 2023 Le Filament (https://le-filament.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) +from odoo.exceptions import UserError from odoo.http import request from odoo.addons.website_event_questions.controllers.main import WebsiteEvent @@ -11,33 +12,85 @@ def _process_attendees_form(self, event, form_details): """Process data posted from the attendee details form. Extracts question answers: - For questions of type 'multiple_choice', extracting the suggested answer id""" - registrations = super(WebsiteEvent, self)._process_attendees_form( - event, form_details + registrations = super()._process_attendees_form(event, form_details) + + # list all question_multi_answer with is_mandatory_answer + mandatory_multiple_general_question_answer_count = {} + mandatory_multiple_specific_question_ids = set() + req_filter = ( + lambda q: q.question_type == "multiple_choice" and q.is_mandatory_answer ) + for general_question in event.general_question_ids.filtered(req_filter): + mandatory_multiple_general_question_answer_count[general_question.id] = 0 + for specific_question in event.specific_question_ids.filtered(req_filter): + mandatory_multiple_specific_question_ids.add(specific_question.id) + + mandatory_multiple_specific_question_answer_count = [ + {i: 0 for i in mandatory_multiple_specific_question_ids} + for j in range(len(registrations)) + ] general_answer_ids = [] for key, _value in form_details.items(): - if "question_multi_answer" in key: - dummy, registration_index, question_answer = key.split("-") - question_id, answer_id = question_answer.split("_") - question_sudo = request.env["event.question"].browse(int(question_id)) + # test html input prefix + if key.startswith("question_multi_answer"): + _html_input_prefix, registration_index_str, question_answer = key.split( + "-" + ) + registration_index = int(registration_index_str) + question_id_str, answer_id = question_answer.split("_") + question_id = int(question_id_str) + question_sudo = request.env["event.question"].browse(question_id) answer_sudo = request.env["event.question.answer"].browse( int(answer_id) ) - answer_values = None - if question_sudo.question_type == "multiple_choice": - answer_values = { - "question_id": int(question_id), - "value_text_box": answer_sudo.name, - } - - if answer_values and not int(registration_index): + assert ( + question_sudo.question_type == "multiple_choice" + ) # otherwise, html is malformed + answer_values = { + "question_id": question_id, + "value_text_box": answer_sudo.name, + } + # question with null registration index are general + if registration_index == 0: general_answer_ids.append((0, 0, answer_values)) - elif answer_values: - registrations[int(registration_index) - 1][ - "registration_answer_ids" - ].append((0, 0, answer_values)) + if question_sudo.is_mandatory_answer: + mandatory_multiple_general_question_answer_count[ + question_id + ] += 1 + # question with registration index are specific to one registration + else: + rindex = registration_index - 1 # zero-based array ¹indexing + registrations[rindex]["registration_answer_ids"].append( + (0, 0, answer_values) + ) + if question_sudo.is_mandatory_answer: + mandatory_multiple_specific_question_answer_count[rindex][ + question_id + ] += 1 + + # check that answers contain at least one for mandatory question + # general + for q, c in mandatory_multiple_general_question_answer_count.items(): + if c == 0: + raise UserError( + "Question " + + str(q) + + " is mandatory but did not receive an answer." + ) + # specific + for r, cc in enumerate(mandatory_multiple_specific_question_answer_count): + for q, c in cc.items(): + if c == 0: + raise UserError( + "Question " + + str(q) + + " is mandatory but did not receive an answer in ticket number " + + str(r) + + "." + ) + # append general question to all items for registration in registrations: registration["registration_answer_ids"].extend(general_answer_ids) diff --git a/website_event_questions_multiple/i18n/fr.po b/website_event_questions_multiple/i18n/fr.po new file mode 100644 index 000000000..c7757f8ea --- /dev/null +++ b/website_event_questions_multiple/i18n/fr.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * website_event_questions_multiple +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-03-06 11:52+0000\n" +"PO-Revision-Date: 2025-03-06 11:52+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: website_event_questions_multiple +#: model:ir.model,name:website_event_questions_multiple.model_event_question +msgid "Event Question" +msgstr "Question" + +#. module: website_event_questions_multiple +#: model:ir.model.fields.selection,name:website_event_questions_multiple.selection__event_question__question_type__multiple_choice +msgid "Multiple Selection" +msgstr "Sélection multiple" + +#. module: website_event_questions_multiple +#: model:ir.model.fields,field_description:website_event_questions_multiple.field_event_question__question_type +msgid "Question Type" +msgstr "Type de question" + +#. module: website_event_questions_multiple +#: model_terms:ir.ui.view,arch_db:website_event_questions_multiple.registration_event_question +msgid "Please select at least one checkbox." +msgstr "Veuillez cocher au moins une case." diff --git a/website_event_questions_multiple/static/description/index.html b/website_event_questions_multiple/static/description/index.html index 07cc77b75..0b42fe96b 100644 --- a/website_event_questions_multiple/static/description/index.html +++ b/website_event_questions_multiple/static/description/index.html @@ -369,8 +369,8 @@
This module allows to add new question type : Selection multiple which allows +
+This module allows to add new question type : Multiple Selection which allows attendees to select multiple answers to a question.
Table of contents
On an event, when creating a new question, you can select new type : Selection multiple
+On an event, when creating a new question, you can select new type : Multiple Selection