[FIX] survey: compute matrix answers display_name too

We here fix the `SurveyQuestionAnswer._compute_display_name`
method introduced in 55fa52be.

`survey.question.answers` used as matrix rows and columns
require different treatment as they are not used in triggers
but are both shown on the `survey.user.input.line` views,
where the display shouldn't change (nor cause a crash).

It also doesn't make much sense to create answers outside the
context of a question, so we remove the button that already
wasn't shown on the tree view.

As users may not fully upgrade their views or may wish to customize,
we add a fallback question title in `_compute_display_name`too.

Task-3495142

closes odoo/odoo#135853

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Co-authored-by: Vivek Pathak <vivp@odoo.com>
This commit is contained in:
Florian Charlier
2023-09-22 15:06:04 +00:00
co-authored by Vivek Pathak
parent 282fbee342
commit e41b32f40b
3 changed files with 57 additions and 11 deletions
+9 -7
View File
@@ -681,17 +681,19 @@ class SurveyQuestionAnswer(models.Model):
is_correct = fields.Boolean('Correct')
answer_score = fields.Float('Score', help="A positive score indicates a correct choice; a negative or null score indicates a wrong answer")
@api.depends('value', 'question_id.title')
@api.depends('value', 'question_id.question_type', 'question_id.title', 'matrix_question_id')
def _compute_display_name(self):
"""Render an answer name as "Question title : Answer value" making sure it is not too long.
"""Render an answer name as "Question title : Answer value", making sure it is not too long.
This implementation makes sure we have at least 30 characters for the question title,
then we elide it, leaving the rest of the space for the answer.
Unless the answer is part of a matrix-type question, this implementation makes sure we have
at least 30 characters for the question title, then we elide it, leaving the rest of the
space for the answer.
"""
for answer in self:
# _origin (or fallback title) is (likely temporarily) needed to support survey snapshot
# during onchange for a deleted answer used as trigger in another question.
title = answer._origin.question_id.title
if not answer.question_id or answer.question_id.question_type == 'matrix':
answer.display_name = answer.value
continue
title = answer.question_id.title or _("[Question Title]")
n_extra_characters = len(title) + len(answer.value) + 3 - self.MAX_ANSWER_NAME_LENGTH # 3 for `" : "`
if n_extra_characters <= 0:
answer.display_name = f'{title} : {answer.value}'
+47 -3
View File
@@ -429,38 +429,82 @@ class TestSurveyInternals(common.TestSurveyCommon, MailCase):
)
self.assertFalse(bool(get_question_by_title(cloned_survey, 'Q2').triggering_answer_ids))
@users('survey_manager')
def test_matrix_rows_display_name(self):
"""Check that matrix rows' display name is not changed."""
# A case's shape is: (question title, row value, expected row display names)
cases = [
(
'Question 1',
'Row A is short, so what?',
'Row A is short, so what?',
), (
'Question 2',
'Row B is a very long question, but it is shown by itself so there shouldn\'t be any change',
'Row B is a very long question, but it is shown by itself so there shouldn\'t be any change',
),
]
for question_title, row_value, exp_display_name in cases:
question = self.env['survey.question'].create({
'title': question_title,
'matrix_row_ids': [Command.create({'value': row_value})],
})
with self.subTest(question=question_title, row=row_value):
self.assertEqual(question.matrix_row_ids[0].display_name, exp_display_name)
@users('survey_manager')
def test_suggested_answer_display_name(self):
"""Check that answers' display name is not too long and allows to identify the question & answer."""
# A case's shape is: (question_title, answer value, expected display name)
"""Check that answers' display name is not too long and allows to identify the question & answer.
When a matrix answer though, simply show the value as the question and row should be made
clear via the survey.user.input.line context."""
# A case's shape is: (question title, answer value, expected display name, additional create values)
cases = [
(
'Question 1',
'Answer A is short',
'Question 1 : Answer A is short',
{}
), (
'Question 2',
'Answer B is a very long answer, so it should itself be shortened or we would go too far',
'Question 2 : Answer B is a very long answer, so it should itself be shortened or we...',
{}
), (
'Question 3 is a very long question, so what can we do?',
'Answer A is short',
'Question 3 is a very long question, so what can we do? : Answer A is short',
{}
), (
'Question 4 is a very long question, so what can we do?',
'Answer B is a bit too long for Q4 now',
'Question 4 is a very long question, so what can... : Answer B is a bit too long for Q4 now',
{}
), (
'Question 5 is a very long question, so what can we do?',
'Answer C is so long that both the question and the answer will be shortened',
'Question 5 is a very long... : Answer C is so long that both the question and the...',
{}
), (
'Question 6',
'Answer A is short, so what?',
'Answer A is short, so what?',
{'question_type': 'matrix'},
), (
'Question 7',
'Answer B is a very long answer, but it is shown by itself so there shouldn\'t be any change',
'Answer B is a very long answer, but it is shown by itself so there shouldn\'t be any change',
{'question_type': 'matrix'},
),
]
for question_title, answer_value, exp_display_name in cases:
for question_title, answer_value, exp_display_name, other_values in cases:
question = self.env['survey.question'].create({
'title': question_title,
'suggested_answer_ids': [Command.create({'value': answer_value})],
**other_values
})
with self.subTest(question=question_title, answer=answer_value):
@@ -314,7 +314,7 @@
<field name="name">survey.question.answer.view.form</field>
<field name="model">survey.question.answer</field>
<field name="arch" type="xml">
<form string="Question Answer Form">
<form string="Question Answer Form" create="False">
<sheet>
<field name="question_type" invisible="1"/>
<group>