-
-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ADD] survey_condition_validation_option
- condition validation for date and datetime about today option - condition validation for limit max or min count item into multiple selection
- Loading branch information
Showing
21 changed files
with
1,657 additions
and
0 deletions.
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
3
...ey_condition_validation_option/odoo/addons/survey_condition_validation_option/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from . import models |
16 changes: 16 additions & 0 deletions
16
...ondition_validation_option/odoo/addons/survey_condition_validation_option/__manifest__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Copyright 2024 TechnoLibre - Mathieu Benoit | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
{ | ||
"name": "Survey condition validation option", | ||
"version": "16.0.1.0.0", | ||
"author": "TechnoLibre, Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/survey", | ||
"license": "AGPL-3", | ||
"category": "Marketing/Surveys", | ||
"development_status": "Beta", | ||
"data": ["views/survey_question_views.xml"], | ||
"depends": [ | ||
"survey", | ||
], | ||
"installable": True, | ||
} |
3 changes: 3 additions & 0 deletions
3
...ition_validation_option/odoo/addons/survey_condition_validation_option/models/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) | ||
|
||
from . import survey_question |
229 changes: 229 additions & 0 deletions
229
...alidation_option/odoo/addons/survey_condition_validation_option/models/survey_question.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
#!/usr/bin/env python3 | ||
# © 2024 TechnoLibre (http://www.technolibre.ca) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) | ||
|
||
import logging | ||
from datetime import datetime | ||
|
||
from dateutil.relativedelta import relativedelta | ||
from pytz import timezone | ||
|
||
from odoo import _, api, exceptions, fields, models | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class SurveyQuestion(models.Model): | ||
_inherit = "survey.question" | ||
|
||
validation_min_multiple_choice_option = fields.Integer( | ||
default=-1, | ||
help="The option is affected by validation_max_multiple_choice_option, limit the selection value to be choose.", | ||
) | ||
|
||
validation_max_multiple_choice_option = fields.Integer( | ||
default=-1, | ||
help="The option is affected by validation_min_multiple_choice_option, limit the selection value to be choose.", | ||
) | ||
|
||
validation_min_datetime_option = fields.Selection( | ||
selection=[ | ||
("today", "Today"), | ||
], | ||
help="The option is affected by validation_max_datetime_option", | ||
) | ||
|
||
validation_max_datetime_option = fields.Selection( | ||
selection=[ | ||
("today", "Today"), | ||
], | ||
help="The option is affected by validation_min_datetime_option", | ||
) | ||
|
||
validation_min_date_option = fields.Selection( | ||
selection=[ | ||
("today", "Today"), | ||
], | ||
help="The option is affected by validation_max_date_option", | ||
) | ||
|
||
validation_max_date_option = fields.Selection( | ||
selection=[ | ||
("today", "Today"), | ||
], | ||
help="The option is affected by validation_min_date_option", | ||
) | ||
|
||
@api.depends("question_type") | ||
def _compute_validation_required(self): | ||
for question in self: | ||
if ( | ||
not question.validation_required | ||
or question.question_type | ||
not in [ | ||
"char_box", | ||
"numerical_box", | ||
"date", | ||
"datetime", | ||
"multiple_choice", | ||
] | ||
): | ||
question.validation_required = False | ||
|
||
def _validate_choice(self, answer, comment): | ||
# Empty comment | ||
if ( | ||
self.constr_mandatory | ||
and not answer | ||
and not ( | ||
self.comments_allowed | ||
and self.comment_count_as_answer | ||
and comment | ||
) | ||
): | ||
return { | ||
self.id: self.constr_error_msg | ||
or _("This question requires an answer.") | ||
} | ||
if ( | ||
self.validation_required | ||
and self.question_type == "multiple_choice" | ||
): | ||
lst_answer = answer if type(answer) == list else [answer] | ||
if self.validation_min_multiple_choice_option == -1: | ||
min_value = 0 | ||
else: | ||
min_value = self.validation_min_multiple_choice_option | ||
if self.validation_max_multiple_choice_option == -1: | ||
max_value = len(self.suggested_answer_ids) | ||
else: | ||
max_value = self.validation_max_multiple_choice_option | ||
if not (min_value <= len(lst_answer) <= max_value): | ||
return { | ||
self.id: self.constr_error_msg | ||
or _( | ||
"You need to select between %s and %s answers, you chose %s answer." | ||
% (min_value, max_value, len(answer)) | ||
) | ||
} | ||
# "Choisir entre %s et %s réponses. Vous avez choisi %s réponse(s)." | ||
return {} | ||
|
||
def _validate_date(self, answer): | ||
# Overwrite survey/models/survey_question.py | ||
isDatetime = self.question_type == "datetime" | ||
# Checks if user input is a date | ||
try: | ||
dateanswer = ( | ||
fields.Datetime.from_string(answer) | ||
if isDatetime | ||
else fields.Date.from_string(answer) | ||
) | ||
except ValueError: | ||
return {self.id: _("This is not a date")} | ||
if self.validation_required: | ||
|
||
# Calculate delay time | ||
user_tz = self.env.user.tz or "UTC" | ||
user_timezone = timezone(user_tz) | ||
heure_actuelle = datetime.now(user_timezone) | ||
decalage_horaire = ( | ||
heure_actuelle.utcoffset().total_seconds() / 3600 | ||
) | ||
diff_hour = int(decalage_horaire) | ||
|
||
# Check if answer is in the right range | ||
if isDatetime: | ||
if self.validation_min_datetime_option: | ||
if self.validation_min_datetime_option == "today": | ||
today = fields.Date.today() | ||
min_date = fields.datetime( | ||
today.year, today.month, today.day | ||
) - relativedelta(hours=diff_hour) | ||
else: | ||
_logger.error( | ||
f"Missing information about validation_min_datetime_option: {self.validation_min_datetime_option}" | ||
) | ||
min_date = False | ||
else: | ||
min_date = fields.Datetime.from_string( | ||
self.validation_min_datetime | ||
) | ||
if self.validation_max_datetime_option: | ||
if self.validation_max_datetime_option == "today": | ||
today = fields.Date.today() + relativedelta(days=1) | ||
max_date = fields.datetime( | ||
today.year, today.month, today.day, -diff_hour | ||
) | ||
else: | ||
_logger.error( | ||
f"Missing information about validation_max_datetime_option: {self.validation_max_datetime_option}" | ||
) | ||
max_date = False | ||
else: | ||
max_date = fields.Datetime.from_string( | ||
self.validation_max_datetime | ||
) | ||
dateanswer = fields.Datetime.from_string(answer) | ||
else: | ||
if self.validation_min_date_option: | ||
if self.validation_min_date_option == "today": | ||
min_date = fields.Date.today() | ||
else: | ||
_logger.error( | ||
f"Missing information about validation_min_date_option: {self.validation_min_date_option}" | ||
) | ||
min_date = False | ||
else: | ||
min_date = fields.Date.from_string( | ||
self.validation_min_date | ||
) | ||
if self.validation_max_date_option: | ||
if self.validation_max_date_option == "today": | ||
max_date = fields.Date.today() + relativedelta(days=1) | ||
else: | ||
_logger.error( | ||
f"Missing information about validation_max_date_option: {self.validation_max_date_option}" | ||
) | ||
max_date = False | ||
else: | ||
max_date = fields.Date.from_string( | ||
self.validation_max_date | ||
) | ||
dateanswer = fields.Date.from_string(answer) | ||
if ( | ||
min_date | ||
and max_date | ||
and not (min_date <= dateanswer < max_date) | ||
): | ||
date_min_show = min_date.astimezone(user_timezone).strftime( | ||
"%Y-%m-%d %H:%M:%S" | ||
) | ||
date_max_show = max_date.astimezone(user_timezone).strftime( | ||
"%Y-%m-%d %H:%M:%S" | ||
) | ||
return { | ||
self.id: self.validation_error_msg | ||
or _( | ||
"The date needs to be between %s and %s." | ||
% (date_min_show, date_max_show) | ||
) | ||
} | ||
elif min_date and not min_date <= dateanswer: | ||
date_min_show = min_date.astimezone(user_timezone).strftime( | ||
"%Y-%m-%d %H:%M:%S" | ||
) | ||
return { | ||
self.id: self.validation_error_msg | ||
or _("The date needs to be after %s." % date_min_show) | ||
} | ||
elif max_date and not dateanswer <= max_date: | ||
date_max_show = max_date.astimezone(user_timezone).strftime( | ||
"%Y-%m-%d %H:%M:%S" | ||
) | ||
return { | ||
self.id: self.validation_error_msg | ||
or _("The date needs to be before %s." % date_max_show) | ||
} | ||
|
||
return {} |
3 changes: 3 additions & 0 deletions
3
...n_option/odoo/addons/survey_condition_validation_option/readme/CONTRIBUTORS.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* `TechnoLibre <https://technolibre.ca>`_: | ||
|
||
* Mathieu Benoit |
4 changes: 4 additions & 0 deletions
4
...on_option/odoo/addons/survey_condition_validation_option/readme/DESCRIPTION.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
This module add conditional option to survey: | ||
|
||
* Add a condition of an option on date and datetime types to apply a minimum or maximum on today's day | ||
* Add a condition to set a minimum or maximum of answers on a multiple selection |
Binary file added
BIN
+9.23 KB
...tion/odoo/addons/survey_condition_validation_option/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions
55
...ion_option/odoo/addons/survey_condition_validation_option/views/survey_question_views.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<odoo> | ||
<data> | ||
<!-- QUESTIONS --> | ||
<record model="ir.ui.view" id="survey_question_form"> | ||
<field name="name">Form view for survey question</field> | ||
<field name="inherit_id" ref="survey.survey_question_form" /> | ||
<field name="model">survey.question</field> | ||
<field name="arch" type="xml"> | ||
<xpath expr="//field[@name='validation_min_datetime']" position="after"> | ||
<field | ||
name="validation_min_datetime_option" | ||
string="'Datetime minimum' option" | ||
attrs="{'invisible': ['|', ('question_type', '!=', 'datetime'), ('validation_required', '=', False)]}" | ||
/> | ||
</xpath> | ||
<!-- <field name="validation_required"--> | ||
<!-- attrs="{'invisible': [('question_type', 'not in', ['char_box', 'numerical_box', 'date', 'datetime'])]}"/>--> | ||
<xpath expr="//field[@name='validation_required']" position="attributes"> | ||
<attribute name="attrs"> | ||
{'invisible': [('question_type', 'not | ||
in', ['char_box', 'numerical_box', 'date', 'datetime', 'multiple_choice'])]} | ||
</attribute> | ||
</xpath> | ||
<xpath expr="//field[@name='validation_min_datetime']" position="attributes"> | ||
<attribute name="attrs"> | ||
{'invisible': ['|', '|', ('question_type', '!=', 'datetime'), ('validation_required', '=', False), ('validation_min_datetime_option', '!=', False)]} | ||
</attribute> | ||
</xpath> | ||
<xpath expr="//field[@name='validation_max_datetime']" position="after"> | ||
<field | ||
name="validation_max_datetime_option" | ||
string="'Datetime maximum' option" | ||
attrs="{'invisible': ['|', ('question_type', '!=', 'datetime'), ('validation_required', '=', False)]}" | ||
/> | ||
<field | ||
name="validation_min_multiple_choice_option" | ||
string="Multiple choice min" | ||
attrs="{'invisible': ['|', ('question_type', '!=', 'multiple_choice'), ('validation_required', '=', False)]}" | ||
/> | ||
<field | ||
name="validation_max_multiple_choice_option" | ||
string="Multiple choice max" | ||
attrs="{'invisible': ['|', ('question_type', '!=', 'multiple_choice'), ('validation_required', '=', False)]}" | ||
/> | ||
</xpath> | ||
<xpath expr="//field[@name='validation_max_datetime']" position="attributes"> | ||
<attribute name="attrs"> | ||
{'invisible': ['|', '|', ('question_type', '!=', 'datetime'), ('validation_required', '=', False), ('validation_max_datetime_option', '!=', False)]} | ||
</attribute> | ||
</xpath> | ||
</field> | ||
</record> | ||
</data> | ||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import setuptools | ||
|
||
setuptools.setup( | ||
setup_requires=['setuptools-odoo'], | ||
odoo_addon=True, | ||
) |
Oops, something went wrong.