# -*- 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