diff --git a/addons/hr_recruitment_survey/data/survey_demo.xml b/addons/hr_recruitment_survey/data/survey_demo.xml index 86b25eec9d2..11f02802989 100644 --- a/addons/hr_recruitment_survey/data/survey_demo.xml +++ b/addons/hr_recruitment_survey/data/survey_demo.xml @@ -83,58 +83,58 @@ matrix simple - + 1 Not important - + 3 Important - + 4 Very important - - + + 1 Having a good pay - - + + 2 Getting on with colleagues - - + + 3 Having a nice office environment - - + + 5 Working with state of the art technology - - + + 6 Office location - - + + 7 Management quality - - + + 8 Having freebies such as tea, coffee and stationery - - + + 9 Getting perks such as free parking, gym passes diff --git a/addons/survey/data/survey_demo_certification.xml b/addons/survey/data/survey_demo_certification.xml index e0e3f83e7fd..4c16664c273 100644 --- a/addons/survey/data/survey_demo_certification.xml +++ b/addons/survey/data/survey_demo_certification.xml @@ -46,12 +46,12 @@ dropdown - + 1 No - + 2 Yes @@ -66,34 +66,34 @@ multiple_choice 4 - + 1 Chair floor protection 1.0 - + 2 Fanta -1.0 - + 3 Conference chair 1.0 - + 4 Drawer 1.0 - + 5 Customizable Lamp @@ -107,34 +107,34 @@ multiple_choice 4 - + 1 Color 1.0 - + 2 Height -1.0 - + 3 Width 1.0 - + 4 Legs 1.0 - + 5 Number of drawers @@ -149,24 +149,24 @@ dropdown - + 1 1 - + 2 2 2.0 - + 3 3 - + 4 4 @@ -196,34 +196,34 @@ dropdown - + 1 20$ - + 2 50$ - + 3 80$ - + 4 100$ 2.0 - + 5 200$ - + 6 300$ @@ -236,40 +236,40 @@ multiple_choice 2 - + 1 Corner Desk Right Sit 1.0 - + 2 Desk Combination 1.0 - + 3 Cabinet with Doors -1.0 - + 4 Large Desk 1.0 - + 5 Letter Tray -1.0 - + 6 Office Chair Black @@ -284,27 +284,27 @@ dropdown - + 1 Very underpriced - + 2 Underpriced - + 3 Correctly priced - + 4 A little bit overpriced - + 5 A lot overpriced diff --git a/addons/survey/data/survey_demo_feedback.xml b/addons/survey/data/survey_demo_feedback.xml index 293b38684df..40467a2428c 100644 --- a/addons/survey/data/survey_demo_feedback.xml +++ b/addons/survey/data/survey_demo_feedback.xml @@ -48,22 +48,22 @@ - + 1 Once a day - + 2 Once a week - + 3 Once a month - + 4 Once a year @@ -95,42 +95,42 @@ - + 1 High quality - + 2 Useful - + 3 Unique - + 4 Good value for money - + 5 Overpriced - + 6 Impractical - + 7 Ineffective - + 8 Poor quality @@ -143,48 +143,48 @@ multiple - + 1 Totally disagree - + 2 Disagree - + 3 Agree - + 4 Totally agree - - + + 1 The new layout and design is fresh and up-to-date - - + + 2 It is easy to find the product that I want - - + + 3 The tool to compare the products is useful to make a choice - - + + 4 The checkout process is clear and secure - - + + 5 I have added products to my wishlist diff --git a/addons/survey/models/survey_question.py b/addons/survey/models/survey_question.py index dcfb8ef0126..f58f8347282 100644 --- a/addons/survey/models/survey_question.py +++ b/addons/survey/models/survey_question.py @@ -74,15 +74,15 @@ class SurveyQuestion(models.Model): ('multiple_choice', 'Multiple choice: multiple answers allowed'), ('matrix', 'Matrix')], string='Question Type') # -- simple choice / multiple choice / matrix - labels_ids = fields.One2many( - 'survey.label', 'question_id', string='Types of answers', copy=True, + suggested_answer_ids = fields.One2many( + 'survey.question.answer', 'question_id', string='Types of answers', copy=True, help='Labels used for proposed choices: simple choice, multiple choice and columns of matrix') # -- matrix matrix_subtype = fields.Selection([ ('simple', 'One choice per row'), ('multiple', 'Multiple choices per row')], string='Matrix Type', default='simple') - labels_ids_2 = fields.One2many( - 'survey.label', 'question_id_2', string='Rows of the Matrix', copy=True, + matrix_row_ids = fields.One2many( + 'survey.question.answer', 'matrix_question_id', string='Matrix Rows', copy=True, help='Labels used for proposed choices: rows of matrix') # -- display options column_nb = fields.Selection([ @@ -261,7 +261,7 @@ class SurveyQuestion(models.Model): def _validate_matrix(self, answers): # Validate that each line has been answered - if self.constr_mandatory and len(self.labels_ids_2) != len(answers): + if self.constr_mandatory and len(self.matrix_row_ids) != len(answers): return {self.id: self.constr_error_msg} return {} @@ -276,26 +276,33 @@ class SurveyQuestion(models.Model): def get_correct_answer_ids(self): self.ensure_one() - return self.labels_ids.filtered(lambda label: label.is_correct) + return self.suggested_answer_ids.filtered(lambda label: label.is_correct) -class SurveyLabel(models.Model): - """ A suggested answer for a question """ - _name = 'survey.label' +class SurveyQuestionAnswer(models.Model): + """ A preconfigured answer for a question. This model stores values used + for + + * simple choice, multiple choice: proposed values for the selection / + radio; + * matrix: row and column values; + + """ + _name = 'survey.question.answer' _rec_name = 'value' - _order = 'sequence,id' + _order = 'sequence, id' _description = 'Survey Label' question_id = fields.Many2one('survey.question', string='Question', ondelete='cascade') - question_id_2 = fields.Many2one('survey.question', string='Question 2', ondelete='cascade') + matrix_question_id = fields.Many2one('survey.question', string='Question (as matrix row)', ondelete='cascade') sequence = fields.Integer('Label Sequence order', default=10) value = fields.Char('Suggested value', translate=True, required=True) is_correct = fields.Boolean('Is a correct answer') answer_score = fields.Float('Score for this choice', help="A positive score indicates a correct choice; a negative or null score indicates a wrong answer") - @api.constrains('question_id', 'question_id_2') + @api.constrains('question_id', 'matrix_question_id') def _check_question_not_empty(self): - """Ensure that field question_id XOR field question_id_2 is not null""" + """Ensure that field question_id XOR field matrix_question_id is not null""" for label in self: - if not bool(label.question_id) != bool(label.question_id_2): + if not bool(label.question_id) != bool(label.matrix_question_id): raise ValidationError(_("A label must be attached to only one question.")) diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index fbd8be671cb..25a8b2df3e9 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -593,7 +593,7 @@ class Survey(models.Model): """ filter_display_data = [] if filters: - Label = self.env['survey.label'] + Label = self.env['survey.question.answer'] for current_filter in filters: row_id, answer_id = current_filter['row_id'], current_filter['answer_id'] label = Label.browse(answer_id) @@ -616,7 +616,7 @@ class Survey(models.Model): # Calculate and return statistics for choice if question.question_type in ['simple_choice', 'multiple_choice']: comments = [] - answers = OrderedDict((label.id, {'text': label.value, 'count': 0, 'answer_id': label.id, 'answer_score': label.answer_score}) for label in question.labels_ids) + answers = OrderedDict((label.id, {'text': label.value, 'count': 0, 'answer_id': label.id, 'answer_score': label.answer_score}) for label in question.suggested_answer_ids) for input_line in input_lines: if input_line.answer_type == 'suggestion' and answers.get(input_line.value_suggested.id) and (not(current_filters) or input_line.user_input_id.id in current_filters): answers[input_line.value_suggested.id]['count'] += 1 @@ -630,8 +630,8 @@ class Survey(models.Model): answers = OrderedDict() res = dict() comments = [] - [rows.update({label.id: label.value}) for label in question.labels_ids_2] - [answers.update({label.id: label.value}) for label in question.labels_ids] + [rows.update({label.id: label.value}) for label in question.matrix_row_ids] + [answers.update({label.id: label.value}) for label in question.suggested_answer_ids] for cell in product(rows, answers): res[cell] = 0 for input_line in input_lines: @@ -692,7 +692,7 @@ class Survey(models.Model): ) for question in scored_questions: - question_answer_correct = question.labels_ids.filtered(lambda answer: answer.is_correct) + question_answer_correct = question.suggested_answer_ids.filtered(lambda answer: answer.is_correct) for user_answer in user_answers: user_answer_lines_question = user_answer.user_input_line_ids.filtered(lambda line: line.question_id == question) user_answer_correct = user_answer_lines_question.filtered(lambda line: line.answer_is_correct and not line.skipped).mapped('value_suggested') diff --git a/addons/survey/models/survey_user.py b/addons/survey/models/survey_user.py index e535253605f..eb0a0127c12 100644 --- a/addons/survey/models/survey_user.py +++ b/addons/survey/models/survey_user.py @@ -54,7 +54,7 @@ class SurveyUserInput(models.Model): for user_input in self: total_possible_score = sum([ answer_score if answer_score > 0 else 0 - for answer_score in user_input.question_ids.mapped('labels_ids.answer_score') + for answer_score in user_input.question_ids.mapped('suggested_answer_ids.answer_score') ]) if total_possible_score == 0: @@ -196,8 +196,8 @@ class SurveyUserInputLine(models.Model): value_date = fields.Date('Date answer') value_datetime = fields.Datetime('Datetime answer') value_free_text = fields.Text('Free Text answer') - value_suggested = fields.Many2one('survey.label', string="Suggested answer") - value_suggested_row = fields.Many2one('survey.label', string="Row answer") + value_suggested = fields.Many2one('survey.question.answer', string="Suggested answer") + value_suggested_row = fields.Many2one('survey.question.answer', string="Row answer") answer_score = fields.Float('Score') answer_is_correct = fields.Boolean('Correct', compute='_compute_answer_is_correct') @@ -233,13 +233,13 @@ class SurveyUserInputLine(models.Model): for vals in vals_list: value_suggested = vals.get('value_suggested') if value_suggested: - vals.update({'answer_score': self.env['survey.label'].browse(int(value_suggested)).answer_score}) + vals.update({'answer_score': self.env['survey.question.answer'].browse(int(value_suggested)).answer_score}) return super(SurveyUserInputLine, self).create(vals_list) def write(self, vals): value_suggested = vals.get('value_suggested') if value_suggested: - vals.update({'answer_score': self.env['survey.label'].browse(int(value_suggested)).answer_score}) + vals.update({'answer_score': self.env['survey.question.answer'].browse(int(value_suggested)).answer_score}) return super(SurveyUserInputLine, self).write(vals) def _get_save_line_values(self, answer, answer_type): diff --git a/addons/survey/security/ir.model.access.csv b/addons/survey/security/ir.model.access.csv index 2bf75531ba4..12f19339230 100644 --- a/addons/survey/security/ir.model.access.csv +++ b/addons/survey/security/ir.model.access.csv @@ -7,10 +7,10 @@ access_survey_question_all,survey.question.all,model_survey_question,,0,0,0,0 access_survey_question_user,survey.question.user,model_survey_question,base.group_user,0,0,0,0 access_survey_question_survey_user,survey.question.survey.user,model_survey_question,group_survey_user,1,1,1,1 access_survey_question_survey_manager,survey.question.survey.manager,model_survey_question,group_survey_manager,1,1,1,1 -access_survey_label_all,survey.label.all,model_survey_label,,0,0,0,0 -access_survey_label_user,survey.label.user,model_survey_label,base.group_user,0,0,0,0 -access_survey_label_survey_user,survey.label.survey.user,model_survey_label,group_survey_user,1,1,1,1 -access_survey_label_survey_manager,survey.label.survey.manager,model_survey_label,group_survey_manager,1,1,1,1 +access_survey_question_answer_all,survey.question.answer.all,model_survey_question_answer,,0,0,0,0 +access_survey_question_answer_user,survey.question.answer.user,model_survey_question_answer,base.group_user,0,0,0,0 +access_survey_question_answer_survey_user,survey.question.answer.survey.user,model_survey_question_answer,group_survey_user,1,1,1,1 +access_survey_question_answer_survey_manager,survey.question.answer.survey.manager,model_survey_question_answer,group_survey_manager,1,1,1,1 access_survey_user_input_all,survey.user_input.all,model_survey_user_input,,0,0,0,0 access_survey_user_input_user,survey.user_input.user,model_survey_user_input,base.group_user,0,0,0,0 access_survey_user_input_survey_user,survey.user_input.survey.user,model_survey_user_input,group_survey_user,1,1,1,1 diff --git a/addons/survey/security/survey_security.xml b/addons/survey/security/survey_security.xml index 46bf54e53ac..4b53a1d29fa 100644 --- a/addons/survey/security/survey_security.xml +++ b/addons/survey/security/survey_security.xml @@ -87,9 +87,9 @@ - - Survey label: manager: all - + + Survey question answer: manager: all + [(1, '=', 1)] @@ -97,9 +97,9 @@ - - Survey label: officer: read all - + + Survey question answer: officer: read all + [(1, '=', 1)] @@ -107,10 +107,10 @@ - - Survey label: officer: create/write/unlink linked to own survey only - - [('survey_id.create_uid', '=', user.id)] + + Survey question answer: officer: create/write/unlink linked to own survey only + + ['|', ('question_id.survey_id.create_uid', '=', user.id), ('matrix_question_id.survey_id.create_uid', '=', user.id)] diff --git a/addons/survey/tests/common.py b/addons/survey/tests/common.py index 9d000da6f13..74a74dc463c 100644 --- a/addons/survey/tests/common.py +++ b/addons/survey/tests/common.py @@ -163,7 +163,7 @@ class TestSurveyCommon(common.SavepointCase): 'constr_error_msg': constr_error_msg, } if qtype in ('simple_choice', 'multiple_choice'): - base_qvalues['labels_ids'] = [ + base_qvalues['suggested_answer_ids'] = [ (0, 0, { 'value': label['value'], 'answer_score': label.get('answer_score', 0), @@ -172,11 +172,11 @@ class TestSurveyCommon(common.SavepointCase): ] elif qtype == 'matrix': base_qvalues['matrix_subtype'] = kwargs.pop('matrix_subtype', 'simple') - base_qvalues['labels_ids'] = [ + base_qvalues['suggested_answer_ids'] = [ (0, 0, {'value': label['value'], 'answer_score': label.get('answer_score', 0)}) for label in kwargs.pop('labels') ] - base_qvalues['labels_ids_2'] = [ + base_qvalues['matrix_row_ids'] = [ (0, 0, {'value': label['value'], 'answer_score': label.get('answer_score', 0)}) for label in kwargs.pop('labels_2') ] diff --git a/addons/survey/tests/test_certification_flow.py b/addons/survey/tests/test_certification_flow.py index 4625fff5d5e..4df1245d2c2 100644 --- a/addons/survey/tests/test_certification_flow.py +++ b/addons/survey/tests/test_certification_flow.py @@ -116,13 +116,13 @@ class TestCertificationFlow(common.TestSurveyCommon, HttpCase): csrf_token = self._find_csrf_token(response.text) with patch.object(IrMailServer, 'connect'): - self._answer_question(q01, q01.labels_ids.ids[3], answer_token, csrf_token) - self._answer_question(q02, q02.labels_ids.ids[1], answer_token, csrf_token) + self._answer_question(q01, q01.suggested_answer_ids.ids[3], answer_token, csrf_token) + self._answer_question(q02, q02.suggested_answer_ids.ids[1], answer_token, csrf_token) self._answer_question(q03, "I think they're great!", answer_token, csrf_token) - self._answer_question(q04, q04.labels_ids.ids[0], answer_token, csrf_token, button_submit='previous') + self._answer_question(q04, q04.suggested_answer_ids.ids[0], answer_token, csrf_token, button_submit='previous') self._answer_question(q03, "Just kidding, I don't like it...", answer_token, csrf_token) - self._answer_question(q04, q04.labels_ids.ids[0], answer_token, csrf_token) - self._answer_question(q05, [q05.labels_ids.ids[0], q05.labels_ids.ids[1], q05.labels_ids.ids[3]], answer_token, csrf_token) + self._answer_question(q04, q04.suggested_answer_ids.ids[0], answer_token, csrf_token) + self._answer_question(q05, [q05.suggested_answer_ids.ids[0], q05.suggested_answer_ids.ids[1], q05.suggested_answer_ids.ids[3]], answer_token, csrf_token) user_inputs.invalidate_cache() # Check that certification is successfully passed diff --git a/addons/survey/tests/test_survey.py b/addons/survey/tests/test_survey.py index 6c64d47f763..fc79ae5c053 100644 --- a/addons/survey/tests/test_survey.py +++ b/addons/survey/tests/test_survey.py @@ -130,10 +130,10 @@ class TestSurveyInternals(common.TestSurveyCommon): for i in range(3): answer = self._add_answer(self.survey, False, email='public@example.com') self._add_answer_line( - question, answer, random.choice(question.labels_ids.ids), + question, answer, random.choice(question.suggested_answer_ids.ids), answer_type='suggestion', answer_fname='value_suggested') lines = [line.value_suggested.id for line in question.user_input_line_ids] - answers = [{'text': label.value, 'count': lines.count(label.id), 'answer_id': label.id, 'answer_score': label.answer_score} for label in question.labels_ids] + answers = [{'text': label.value, 'count': lines.count(label.id), 'answer_id': label.id, 'answer_score': label.answer_score} for label in question.suggested_answer_ids] prp_result = self.env['survey.survey'].prepare_result(question)['answers'] self.assertItemsEqual(prp_result, answers) @@ -147,12 +147,12 @@ class TestSurveyInternals(common.TestSurveyCommon): for i in range(3): answer = self._add_answer(self.survey, False, email='public@example.com') self._add_answer_line( - question, answer, random.choice(question.labels_ids.ids), - answer_type='suggestion', answer_fname='value_suggested', value_suggested_row=random.choice(question.labels_ids_2.ids) + question, answer, random.choice(question.suggested_answer_ids.ids), + answer_type='suggestion', answer_fname='value_suggested', value_suggested_row=random.choice(question.matrix_row_ids.ids) ) lines = [(line.value_suggested_row.id, line.value_suggested.id) for line in question.user_input_line_ids] res = {} - for i in product(question.labels_ids_2.ids, question.labels_ids.ids): + for i in product(question.matrix_row_ids.ids, question.suggested_answer_ids.ids): res[i] = lines.count((i)) self.assertEqual(self.env['survey.survey'].prepare_result(question)['result'], res) diff --git a/addons/survey/tests/test_survey_flow.py b/addons/survey/tests/test_survey_flow.py index 472eaff55fd..5f45d2856fd 100644 --- a/addons/survey/tests/test_survey_flow.py +++ b/addons/survey/tests/test_survey_flow.py @@ -106,7 +106,7 @@ class TestSurveyFlow(common.TestSurveyCommon, HttpCase): # Customer submit second page answers answer_data = { - page1_q0.id: {'value': [page1_q0.labels_ids.ids[0], page1_q0.labels_ids.ids[1]]}, + page1_q0.id: {'value': [page1_q0.suggested_answer_ids.ids[0], page1_q0.suggested_answer_ids.ids[1]]}, } post_data = self._format_submission_data(page_1, answer_data, {'csrf_token': csrf_token, 'token': answer_token, 'button_submit': 'next'}) r = self._access_submit(survey, answer_token, post_data) diff --git a/addons/survey/tests/test_survey_ui_certification.py b/addons/survey/tests/test_survey_ui_certification.py index f5a6e5645c4..a98f8966e55 100644 --- a/addons/survey/tests/test_survey_ui_certification.py +++ b/addons/survey/tests/test_survey_ui_certification.py @@ -38,7 +38,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'question_type': 'simple_choice', 'display_mode': 'dropdown', 'constr_mandatory': True, - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 'No', 'sequence': 1, @@ -54,7 +54,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'sequence': 3, 'question_type': 'multiple_choice', 'column_nb': '4', - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 'Chair floor protection', 'sequence': 1, @@ -85,7 +85,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'sequence': 4, 'question_type': 'multiple_choice', 'column_nb': '4', - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 'Color', 'sequence': 1, @@ -117,7 +117,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'question_type': 'simple_choice', 'display_mode': 'dropdown', 'constr_mandatory': True, - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 1, 'sequence': 1, @@ -150,7 +150,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'question_type': 'simple_choice', 'display_mode': 'dropdown', 'constr_mandatory': True, - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': '20$', 'sequence': 1, @@ -178,7 +178,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'sequence': 9, 'question_type': 'multiple_choice', 'column_nb': '2', - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 'Corner Desk Right Sit', 'sequence': 1, @@ -214,7 +214,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'question_type': 'simple_choice', 'display_mode': 'dropdown', 'constr_mandatory': True, - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 'Very underpriced', 'sequence': 1, diff --git a/addons/survey/tests/test_survey_ui_feedback.py b/addons/survey/tests/test_survey_ui_feedback.py index 2e10d757f8e..2447f7916dc 100644 --- a/addons/survey/tests/test_survey_ui_feedback.py +++ b/addons/survey/tests/test_survey_ui_feedback.py @@ -43,7 +43,7 @@ class TestUiFeedback(HttpCaseWithUserDemo): 'comments_allowed': True, 'comment_count_as_answer': True, 'constr_mandatory': True, - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 'Once a day', 'sequence': 1, @@ -78,7 +78,7 @@ class TestUiFeedback(HttpCaseWithUserDemo): 'constr_mandatory': True, 'comments_allowed': True, 'comment_count_as_answer': False, - 'labels_ids': [ + 'suggested_answer_ids': [ (0, 0, { 'value': 'High quality', 'sequence': 1, @@ -113,7 +113,7 @@ class TestUiFeedback(HttpCaseWithUserDemo): 'question_type': 'matrix', 'matrix_subtype': 'multiple', 'constr_mandatory': True, - 'labels_ids': [(0, 0, { + 'suggested_answer_ids': [(0, 0, { 'value': 'Totally disagree', 'sequence': 1 }), (0, 0, { @@ -126,7 +126,7 @@ class TestUiFeedback(HttpCaseWithUserDemo): 'value': 'Totally agree', 'sequence': 4, })], - 'labels_ids_2': [(0, 0, { + 'matrix_row_ids': [(0, 0, { 'value': 'The new layout and design is fresh and up-to-date', 'sequence': 1, }), (0, 0, { diff --git a/addons/survey/views/survey_question_views.xml b/addons/survey/views/survey_question_views.xml index 887e380f3cb..d39254a2246 100644 --- a/addons/survey/views/survey_question_views.xml +++ b/addons/survey/views/survey_question_views.xml @@ -102,8 +102,8 @@ - - - survey_label_tree - survey.label + + survey.question.answer.view.tree + survey.question.answer - + - - survey_label_search - survey.label + + survey.question.answer.view.search + survey.question.answer @@ -229,11 +229,11 @@ - + Suggested Values - survey.label + survey.question.answer tree,form - + {'search_default_group_by_question': True}

@@ -249,7 +249,7 @@ sequence="2"/> diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml index 6023023d370..78d5bdb3968 100644 --- a/addons/survey/views/survey_templates.xml +++ b/addons/survey/views/survey_templates.xml @@ -241,7 +241,7 @@ @@ -293,7 +293,7 @@

-
+