add survey_score_ranges: displays different messages depending on the score obtained, allowing different score ranges
This commit is contained in:
parent
9cabf044c8
commit
4d1eaebc06
11 changed files with 269 additions and 1 deletions
3
survey_score_ranges/models/__init__.py
Normal file
3
survey_score_ranges/models/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from . import survey_score_range
|
||||
from . import survey_survey
|
||||
from . import survey_user_input
|
||||
75
survey_score_ranges/models/survey_score_range.py
Normal file
75
survey_score_ranges/models/survey_score_range.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class SurveyScoreRange(models.Model):
|
||||
_name = "survey.score.range"
|
||||
_description = "Survey Score Range"
|
||||
_order = "survey_id, min_score, max_score, id"
|
||||
|
||||
name = fields.Char("Name", required=True, translate=True)
|
||||
survey_id = fields.Many2one(
|
||||
"survey.survey", string="Survey", required=True, ondelete="cascade", index=True
|
||||
)
|
||||
min_score = fields.Float("Min Score", required=True, help="Inclusive lower bound")
|
||||
max_score = fields.Float(
|
||||
"Max Score",
|
||||
required=True,
|
||||
help="Inclusive upper bound (use same value as min for exact match). Deje vacío para indicar sin límite superior.",
|
||||
default=0.0,
|
||||
)
|
||||
no_upper_limit = fields.Boolean(
|
||||
"No upper limit",
|
||||
help="If checked, max_score is ignored and the range is open-ended ( >= min_score ).",
|
||||
)
|
||||
result_html = fields.Html(
|
||||
"Result Content", translate=True, sanitize=True, sanitize_overridable=True
|
||||
)
|
||||
active = fields.Boolean(default=True)
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
"min_le_max",
|
||||
"CHECK( min_score <= max_score )",
|
||||
"El mínimo debe ser menor o igual que el máximo.",
|
||||
)
|
||||
]
|
||||
|
||||
@api.constrains("min_score", "max_score", "no_upper_limit", "survey_id", "active")
|
||||
def _check_overlapping(self):
|
||||
for rec in self:
|
||||
if rec.no_upper_limit:
|
||||
domain = [
|
||||
("id", "!=", rec.id),
|
||||
("survey_id", "=", rec.survey_id.id),
|
||||
("active", "=", True),
|
||||
"|",
|
||||
("no_upper_limit", "=", True),
|
||||
("max_score", ">=", rec.min_score),
|
||||
]
|
||||
else:
|
||||
domain = [
|
||||
("id", "!=", rec.id),
|
||||
("survey_id", "=", rec.survey_id.id),
|
||||
("active", "=", True),
|
||||
("min_score", "<=", rec.max_score),
|
||||
"|",
|
||||
("no_upper_limit", "=", True),
|
||||
("max_score", ">=", rec.min_score),
|
||||
]
|
||||
overlaps = self.search_count(domain)
|
||||
if overlaps:
|
||||
raise ValidationError(
|
||||
_("Los rangos de puntuación no pueden solaparse.")
|
||||
)
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
for r in self:
|
||||
if r.no_upper_limit:
|
||||
label = _("%s (%s+ pts)") % (r.name, r.min_score)
|
||||
else:
|
||||
label = _("%s (%s-%s pts)") % (r.name, r.min_score, r.max_score)
|
||||
res.append((r.id, label))
|
||||
return res
|
||||
13
survey_score_ranges/models/survey_survey.py
Normal file
13
survey_score_ranges/models/survey_survey.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class SurveySurvey(models.Model):
|
||||
_inherit = "survey.survey"
|
||||
|
||||
enable_score_ranges = fields.Boolean(
|
||||
"Enable Score Ranges", help="Show a result page based on score ranges."
|
||||
)
|
||||
score_range_ids = fields.One2many(
|
||||
"survey.score.range", "survey_id", string="Score Ranges"
|
||||
)
|
||||
50
survey_score_ranges/models/survey_user_input.py
Normal file
50
survey_score_ranges/models/survey_user_input.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class SurveyUserInput(models.Model):
|
||||
_inherit = "survey.user_input"
|
||||
|
||||
result_range_id = fields.Many2one(
|
||||
"survey.score.range",
|
||||
string="Score Range",
|
||||
compute="_compute_result_range_id",
|
||||
store=True,
|
||||
compute_sudo=True,
|
||||
)
|
||||
result_range_html = fields.Html(
|
||||
string="Result Range Content",
|
||||
compute="_compute_result_range_html",
|
||||
sanitize=False,
|
||||
)
|
||||
|
||||
@api.depends(
|
||||
"scoring_total", "survey_id.enable_score_ranges", "survey_id.score_range_ids"
|
||||
)
|
||||
def _compute_result_range_id(self):
|
||||
for user_input in self:
|
||||
selected = False
|
||||
if user_input.survey_id.enable_score_ranges and user_input.state == "done":
|
||||
total = user_input.scoring_total
|
||||
ranges = user_input.survey_id.score_range_ids.filtered("active").sorted(
|
||||
lambda r: r.min_score
|
||||
)
|
||||
for r in ranges:
|
||||
if r.no_upper_limit:
|
||||
if total >= r.min_score:
|
||||
selected = r
|
||||
else:
|
||||
if total >= r.min_score and total <= r.max_score:
|
||||
selected = r
|
||||
if selected:
|
||||
break
|
||||
user_input.result_range_id = selected
|
||||
|
||||
@api.depends("result_range_id")
|
||||
def _compute_result_range_html(self):
|
||||
for user_input in self:
|
||||
user_input.result_range_html = (
|
||||
user_input.result_range_id.result_html
|
||||
if user_input.result_range_id
|
||||
else False
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue