Odoo Mindscape. Understand Odoo faster. Explore modules, fields, dependencies and version differences in one place instead of digging through the source code.

Module: Surveys

Entity: survey.user_input.line

Compute Method: _compute_answer_score

Inputs Method Outputs
""" Get values for: answer_is_correct and associated answer_score.

        Calculates whether an answer_is_correct and its score based on 'answer_type' and
        corresponding question. Handles choice (answer_type == 'suggestion') questions
        separately from other question types. Each selected choice answer is handled as an
        individual answer.

        If score depends on the speed of the answer, it is adjusted as follows:
         - If the user answers in less than 2 seconds, they receive 100% of the possible points.
         - If user answers after that, they receive 50% of the possible points + the remaining
            50% scaled by the time limit and time taken to answer [i.e. a minimum of 50% of the
            possible points is given to all correct answers]

        Example of updated values:
            * {'answer_is_correct': False, 'answer_score': 0} (default)
            * {'answer_is_correct': True, 'answer_score': 2.0}
        """
for line in self:
            answer_is_correct, answer_score = False, 0
            if line.answer_type:
                # record selected suggested choice answer_score (can be: pos, neg, or 0)
                if line.question_id.question_type in ['simple_choice', 'multiple_choice']:
                    if line.answer_type == 'suggestion' and line.suggested_answer_id:
                        answer_score = line.suggested_answer_id.answer_score
                        answer_is_correct = line.suggested_answer_id.is_correct
                # for all other scored question cases, record question answer_score (can be: pos or 0)
                elif line.question_id.question_type in ['date', 'datetime', 'numerical_box']:
                    answer = line[f'value_{line.answer_type}']
                    if line.answer_type == 'numerical_box':
                        answer = float(answer)
                    elif line.answer_type == 'date':
                        answer = fields.Date.from_string(answer)
                    elif line.answer_type == 'datetime':
                        answer = fields.Datetime.from_string(answer)
                    if answer and answer == line.question_id[f'answer_{line.answer_type}']:
                        answer_is_correct = True
                        answer_score = line.question_id.answer_score

            # Session speed rating
            if (
                answer_score > 0
                and line.user_input_id.survey_id.session_speed_rating
                and line.user_input_id.is_session_answer
                and line.question_id.is_time_limited
            ):
                max_score_delay = 2
                time_limit = line.question_id.time_limit
                now = fields.Datetime.now()
                seconds_to_answer = (now - line.user_input_id.survey_id.session_question_start_time).total_seconds()
                question_remaining_time = time_limit - seconds_to_answer
                # if answered within the max_score_delay => leave score as is
                if question_remaining_time < 0 or line.question_id != line.user_input_id.survey_id.session_question_id:
                    answer_score /= 2
                elif seconds_to_answer > max_score_delay:  # linear decrease in score after 2 sec
                    score_proportion = (time_limit - seconds_to_answer) / (time_limit - max_score_delay)
                    answer_score = (answer_score / 2) * (1 + score_proportion)

            line.answer_is_correct = answer_is_correct
            line.answer_score = answer_score

Back to entity