86 lines
3.3 KiB
Python
86 lines
3.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
from odoo import fields, models, _
|
|
from odoo.exceptions import ValidationError
|
|
from odoo import models, fields, api, _
|
|
|
|
class SurveyQuestion(models.Model):
|
|
_inherit = "survey.question"
|
|
|
|
validation_multiple_answers_min = fields.Integer(
|
|
string="Minimum Number of Answers",
|
|
default=0,
|
|
help="Minimum number of answers required for this multiple choice question"
|
|
)
|
|
validation_multiple_answers_max = fields.Integer(
|
|
string="Maximum Number of Answers",
|
|
default=0,
|
|
help="Maximum number of answers allowed for this multiple choice question (0 = no limit)"
|
|
)
|
|
|
|
_sql_constraints = [
|
|
(
|
|
"non_neg_multiple_ans_min",
|
|
"CHECK (validation_multiple_answers_min >= 0)",
|
|
"The minimum number of answers must be non-negative!",
|
|
),
|
|
(
|
|
"non_neg_multiple_ans_max",
|
|
"CHECK (validation_multiple_answers_max >= 0)",
|
|
"The maximum number of answers must be non-negative!",
|
|
),
|
|
(
|
|
"validation_multiple_ans_range",
|
|
"CHECK (validation_multiple_answers_min <= validation_multiple_answers_max OR validation_multiple_answers_max = 0)",
|
|
"Max number of multiple answers cannot be smaller than min number!",
|
|
),
|
|
]
|
|
|
|
@api.constrains('validation_multiple_answers_min', 'validation_multiple_answers_max', 'question_type')
|
|
def _check_answer_limit_config(self):
|
|
"""Ensure answer limits are only configured for multiple_choice questions"""
|
|
for question in self:
|
|
if question.question_type != 'multiple_choice':
|
|
if question.validation_multiple_answers_min > 0 or question.validation_multiple_answers_max > 0:
|
|
raise ValidationError(_(
|
|
"Answer limits can only be configured for Multiple Choice questions."
|
|
))
|
|
|
|
def _validate_choice(self, answer, comment):
|
|
"""Override to add min/max answer validation for multiple_choice questions."""
|
|
# Call parent validation first
|
|
res = super()._validate_choice(answer, comment)
|
|
|
|
# If parent already found an error, return it
|
|
if res:
|
|
return res
|
|
|
|
# Only apply custom logic for multiple_choice questions
|
|
if self.question_type != "multiple_choice":
|
|
return res
|
|
|
|
# Normalize answer to list format
|
|
if isinstance(answer, list):
|
|
answer_count = len([a for a in answer if a]) # Count non-empty answers
|
|
elif answer:
|
|
answer_count = 1
|
|
else:
|
|
answer_count = 0
|
|
|
|
# Add comment to count if it counts as answer
|
|
if comment and self.comment_count_as_answer:
|
|
answer_count += 1
|
|
|
|
# Apply min/max validation ONLY if max is set (> 0)
|
|
if self.validation_multiple_answers_max > 0:
|
|
min_answers = self.validation_multiple_answers_min
|
|
max_answers = self.validation_multiple_answers_max
|
|
|
|
if not (min_answers <= answer_count <= max_answers):
|
|
error_msg = self.validation_error_msg or _(
|
|
"Please select between %(min)d and %(max)d answers.",
|
|
min=min_answers,
|
|
max=max_answers
|
|
)
|
|
return {self.id: error_msg}
|
|
|
|
return res |