From 84bb9c748db26656d3ecd062183afe5f042dc569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 21 Nov 2019 14:59:33 +0000 Subject: [PATCH] [REF] survey: remove unused or unnecessary fields to clean models PURPOSE As new features are about to land in survey, notably live interactions [1] and new survey building [2] performing a pre cleaning is necessary. In this PR we clean survey models by: removing unnecessary fields, cleaning some code and finally renaming models. SPECIFICATIONS: QUESTION FIELD ON SURVEY.SURVEY On survey.survey, remove question field, unnecessary related on title. Question model holds two fields for its title: ``title`` and ``question``. Question is simply a related on title, making the two fields completely redundant. It is mainly due to historical reasons, when updating models for certifications and eLearning. In this commit we keep only title field and remove the question related field as it adds unnecessary complexity to the model. SPECIFICATIONS: INPUT_TYPE FIELD ON SURVEY.USER_INPUT On survey.user_input, remove input_type and its garbage collect. ``input_type`` field exists on user input model to tell whether answer has been created through invite or through manual click on a survey page. It has been added a long time ago when surveys were either open to everyone, either closed and on invite only. Since eLearning and certification surveys access mode on surveys has evolved. Notably being able to distinguish invite from manual survey user input is not necessary anymore. Indeed what is important is the way people can reach the survey, not how they created their user input. Invitation creates token and this can be used if people effectively want to find invitation-related user inputs. Since 09ea5c7d49d544927542130078ab6e3ad5b70584 manual entries still in draft are garbage collected. Reason is still unclear as it is not obvious that tons of unnecessary entries will be created. As this seems like unnecessary optimization this commit removes that feature along with the input_type field. SPECIFICATIONS: REPLACE URLS FIELDS BY METHODS ON SURVEY.{SURVEY, USER_INPUT} On survey.{survey, user_input}, remove url fields replaced by methods In this commit we remove some remaining of URL fields that are better found using methods. Both survey and user input holds a "start" url field that is replaced by a method call ``get_start_url`` on both survey (generic) and user input (token specific) models. We also introduced a ``get_print_url`` method doing the same for the printable version of survey / user input. SPECIFICATIONS: REMOVE CATEGORY FIELD ON SURVEY.SURVEY On survey.survey, remove unused category field. Survey model holds a ``category`` field whose purpose is to be able to somehow categorize surveys according to their use. However using this field is not easy as it is hidden and is a simple selection field. Module should add their own key. Its sole use is in ``hr_recruitment_survey`` which is a niche module. Let us clean models and lessen model complexity. LINKS [0] Related to Task ID 2061901 (survey models cleaning and preparation) [1] Task ID 1972640 (live interactions) [2] Task ID 2119587 (new frontend for building surveys) PR #40765 --- addons/hr_recruitment_survey/__manifest__.py | 1 - .../data/survey_demo.xml | 1 - .../hr_recruitment_survey/models/__init__.py | 1 - .../models/hr_applicant.py | 8 +-- addons/hr_recruitment_survey/models/hr_job.py | 3 +- .../models/survey_survey.py | 9 ---- .../views/hr_job_views.xml | 2 +- .../views/survey_survey_views.xml | 13 ----- addons/survey/controllers/main.py | 3 +- addons/survey/data/mail_template_data.xml | 2 +- .../survey/data/survey_demo_certification.xml | 4 -- addons/survey/data/survey_demo_feedback.xml | 4 -- addons/survey/models/__init__.py | 1 - addons/survey/models/ir_autovacuum.py | 13 ----- addons/survey/models/survey_question.py | 3 +- addons/survey/models/survey_survey.py | 51 ++++++++----------- addons/survey/models/survey_user.py | 22 +++----- addons/survey/tests/common.py | 1 - addons/survey/views/survey_question_views.xml | 12 +++-- addons/survey/views/survey_survey_views.xml | 2 - addons/survey/views/survey_templates.xml | 4 +- .../views/survey_templates_statistics.xml | 2 +- addons/survey/views/survey_user_views.xml | 6 --- addons/survey/wizard/survey_invite.py | 10 +++- addons/survey/wizard/survey_invite_views.xml | 2 +- .../data/survey_demo.xml | 2 - .../models/slide_slide.py | 6 +-- 27 files changed, 57 insertions(+), 131 deletions(-) delete mode 100644 addons/hr_recruitment_survey/models/survey_survey.py delete mode 100644 addons/hr_recruitment_survey/views/survey_survey_views.xml delete mode 100644 addons/survey/models/ir_autovacuum.py diff --git a/addons/hr_recruitment_survey/__manifest__.py b/addons/hr_recruitment_survey/__manifest__.py index 38a986dde72..32b1f5f4f4c 100644 --- a/addons/hr_recruitment_survey/__manifest__.py +++ b/addons/hr_recruitment_survey/__manifest__.py @@ -14,7 +14,6 @@ 'security/hr_recruitment_survey_security.xml', 'views/hr_job_views.xml', 'views/hr_applicant_views.xml', - 'views/survey_survey_views.xml', 'views/res_config_setting_views.xml', ], 'demo': [ diff --git a/addons/hr_recruitment_survey/data/survey_demo.xml b/addons/hr_recruitment_survey/data/survey_demo.xml index 0b875b7738d..86b25eec9d2 100644 --- a/addons/hr_recruitment_survey/data/survey_demo.xml +++ b/addons/hr_recruitment_survey/data/survey_demo.xml @@ -4,7 +4,6 @@ Recruitment Form open token - hr_recruitment

diff --git a/addons/hr_recruitment_survey/models/__init__.py b/addons/hr_recruitment_survey/models/__init__.py index dc295255d0c..b7409ff12e6 100644 --- a/addons/hr_recruitment_survey/models/__init__.py +++ b/addons/hr_recruitment_survey/models/__init__.py @@ -3,4 +3,3 @@ from . import hr_job from . import hr_applicant -from . import survey_survey diff --git a/addons/hr_recruitment_survey/models/hr_applicant.py b/addons/hr_recruitment_survey/models/hr_applicant.py index c778efa0121..969253c7740 100644 --- a/addons/hr_recruitment_survey/models/hr_applicant.py +++ b/addons/hr_recruitment_survey/models/hr_applicant.py @@ -18,13 +18,9 @@ class Applicant(models.Model): else: response = self.response_id # grab the token of the response and start surveying - return self.survey_id.with_context(survey_token=response.token).action_start_survey() + return self.survey_id.action_start_survey(answer=response) def action_print_survey(self): """ If response is available then print this response otherwise print survey form (print template of the survey) """ self.ensure_one() - if not self.response_id: - return self.survey_id.action_print_survey() - else: - response = self.response_id - return self.survey_id.with_context(survey_token=response.token).action_print_survey() + return self.survey_id.action_print_survey(answer=self.response_id) diff --git a/addons/hr_recruitment_survey/models/hr_job.py b/addons/hr_recruitment_survey/models/hr_job.py index 72550f53e19..32377181af8 100644 --- a/addons/hr_recruitment_survey/models/hr_job.py +++ b/addons/hr_recruitment_survey/models/hr_job.py @@ -1,6 +1,6 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import api, fields, models +from odoo import fields, models class Job(models.Model): @@ -8,7 +8,6 @@ class Job(models.Model): survey_id = fields.Many2one( 'survey.survey', "Interview Form", - domain=[('category', '=', 'hr_recruitment')], help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job") def action_print_survey(self): diff --git a/addons/hr_recruitment_survey/models/survey_survey.py b/addons/hr_recruitment_survey/models/survey_survey.py deleted file mode 100644 index 21674e84ee6..00000000000 --- a/addons/hr_recruitment_survey/models/survey_survey.py +++ /dev/null @@ -1,9 +0,0 @@ -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import fields, models - - -class Survey(models.Model): - _inherit = 'survey.survey' - - category = fields.Selection(selection_add=[('hr_recruitment', 'Recruitment')]) diff --git a/addons/hr_recruitment_survey/views/hr_job_views.xml b/addons/hr_recruitment_survey/views/hr_job_views.xml index 746b6c645a1..0b147acc90a 100644 --- a/addons/hr_recruitment_survey/views/hr_job_views.xml +++ b/addons/hr_recruitment_survey/views/hr_job_views.xml @@ -9,7 +9,7 @@

+ context="{'default_access_mode': 'token'}"/>
diff --git a/addons/hr_recruitment_survey/views/survey_survey_views.xml b/addons/hr_recruitment_survey/views/survey_survey_views.xml deleted file mode 100644 index a6f51da722e..00000000000 --- a/addons/hr_recruitment_survey/views/survey_survey_views.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - survey.survey.view.form.inherit.hr_recruitment - survey.survey - - - - 0 - - - - diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py index a7f7325a86f..93c4523f5b6 100644 --- a/addons/survey/controllers/main.py +++ b/addons/survey/controllers/main.py @@ -182,7 +182,6 @@ class Survey(http.Controller): def _prepare_retry_additional_values(self, answer): return { - 'input_type': answer.input_type, 'deadline': answer.deadline, } @@ -524,7 +523,7 @@ class Survey(http.Controller): Survey = request.env['survey.survey'] result = [] if question.question_type == 'multiple_choice': - result.append({'key': ustr(question.question), + result.append({'key': ustr(question.title), 'values': Survey.prepare_result(question, current_filters)['answers'] }) if question.question_type == 'simple_choice': diff --git a/addons/survey/data/mail_template_data.xml b/addons/survey/data/mail_template_data.xml index 5c5d8fecc33..13f09ecd752 100644 --- a/addons/survey/data/mail_template_data.xml +++ b/addons/survey/data/mail_template_data.xml @@ -16,7 +16,7 @@ We are conducting a survey and your response would be appreciated. % endif
- % if object.survey_id.certificate: Start Certification diff --git a/addons/survey/data/survey_demo_certification.xml b/addons/survey/data/survey_demo_certification.xml index f531ea7d89d..e0e3f83e7fd 100644 --- a/addons/survey/data/survey_demo_certification.xml +++ b/addons/survey/data/survey_demo_certification.xml @@ -312,7 +312,6 @@ - manually douglas.fletcher51@example.com done @@ -329,7 +328,6 @@ - manually billy.fox45@example.com done @@ -346,7 +344,6 @@ - manually brandon.freeman55@example.com done @@ -363,7 +360,6 @@ - manually oscar.morgan11@example.com done diff --git a/addons/survey/data/survey_demo_feedback.xml b/addons/survey/data/survey_demo_feedback.xml index 538231a4e61..293b38684df 100644 --- a/addons/survey/data/survey_demo_feedback.xml +++ b/addons/survey/data/survey_demo_feedback.xml @@ -198,28 +198,24 @@ - manually mark.brown23@example.com done - manually billy.fox45@example.com done - manually Evelyne Gargouillis <evelyne@example.com> done - manually Martin Tamarre <martin@example.com> skip diff --git a/addons/survey/models/__init__.py b/addons/survey/models/__init__.py index b539d063303..82414c70e61 100644 --- a/addons/survey/models/__init__.py +++ b/addons/survey/models/__init__.py @@ -1,7 +1,6 @@ # -*- encoding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import ir_autovacuum from . import survey_survey from . import survey_question from . import survey_user diff --git a/addons/survey/models/ir_autovacuum.py b/addons/survey/models/ir_autovacuum.py deleted file mode 100644 index 466cfda6f0d..00000000000 --- a/addons/survey/models/ir_autovacuum.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import api, models - - -class AutoVacuum(models.AbstractModel): - _inherit = 'ir.autovacuum' - - @api.model - def power_on(self, *args, **kwargs): - self.env['survey.user_input'].do_clean_emptys() - return super(AutoVacuum, self).power_on(*args, **kwargs) diff --git a/addons/survey/models/survey_question.py b/addons/survey/models/survey_question.py index db6f8f43e6f..dcfb8ef0126 100644 --- a/addons/survey/models/survey_question.py +++ b/addons/survey/models/survey_question.py @@ -37,7 +37,7 @@ class SurveyQuestion(models.Model): """ _name = 'survey.question' _description = 'Survey Question' - _rec_name = 'question' + _rec_name = 'title' _order = 'sequence,id' @api.model @@ -49,7 +49,6 @@ class SurveyQuestion(models.Model): # question generic data title = fields.Char('Title', required=True, translate=True) - question = fields.Char('Question', related="title") description = fields.Html('Description', help="Use this field to add additional explanations about your question", translate=True) survey_id = fields.Many2one('survey.survey', string='Survey', ondelete='cascade') scoring_type = fields.Selection(related='survey_id.scoring_type', string='Scoring Type', readonly=True) diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index 135aa653acf..fbd8be671cb 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -3,10 +3,10 @@ import random import uuid +import werkzeug from collections import Counter, OrderedDict from itertools import product -from werkzeug import urls from odoo import api, fields, models, _ from odoo.exceptions import UserError @@ -36,10 +36,6 @@ class Survey(models.Model): ('draft', 'Draft'), ('open', 'In Progress'), ('closed', 'Closed') ], string="Survey Stage", default='draft', required=True, group_expand='_read_group_states') - category = fields.Selection([ - ('default', 'Generic Survey')], string='Category', - default='default', required=True, - help='Category is used to know in which context the survey is used. Various apps may define their own categories when they use survey like jobs recruitment or employee appraisal surveys.') # questions question_and_page_ids = fields.One2many('survey.question', 'survey_id', string='Sections and Questions', copy=True) page_ids = fields.One2many('survey.question', string='Pages', compute="_compute_page_and_question_ids") @@ -65,7 +61,6 @@ class Survey(models.Model): users_login_required = fields.Boolean('Login Required', help="If checked, users have to login before answering even with a valid token.") users_can_go_back = fields.Boolean('Users can go back', help="If checked, users can go back to previous pages.") users_can_signup = fields.Boolean('Users can signup', compute='_compute_users_can_signup') - public_url = fields.Char("Public link", compute="_compute_survey_url") # statistics answer_count = fields.Integer("Registered", compute="_compute_survey_statistic") answer_done_count = fields.Integer("Attempts", compute="_compute_survey_statistic") @@ -150,12 +145,6 @@ class Survey(models.Model): for survey in self: survey.update(stat.get(survey._origin.id, default_vals)) - def _compute_survey_url(self): - """ Computes a public URL for the survey """ - base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - for survey in self: - survey.public_url = urls.url_join(base_url, "survey/start/%s" % (survey.access_token)) - @api.depends('question_and_page_ids') def _compute_page_and_question_ids(self): for survey in self: @@ -448,18 +437,6 @@ class Survey(models.Model): def action_close(self): self.write({'state': 'closed'}) - def action_start_survey(self): - """ Open the website page with the survey form """ - self.ensure_one() - token = self.env.context.get('survey_token') - trail = "?answer_token=%s" % token if token else "" - return { - 'type': 'ir.actions.act_url', - 'name': "Start Survey", - 'target': 'self', - 'url': self.public_url + trail - } - def action_send_survey(self): """ Open a window to compose an email, pre-filled with the survey message """ # Ensure that this survey has at least one page with at least one question. @@ -486,16 +463,26 @@ class Survey(models.Model): 'context': local_context, } - def action_print_survey(self): + def action_start_survey(self, answer=None): + """ Open the website page with the survey form """ + self.ensure_one() + url = '%s?%s' % (self.get_start_url(), werkzeug.urls.url_encode({'answer_token': answer.token or None})) + return { + 'type': 'ir.actions.act_url', + 'name': "Start Survey", + 'target': 'self', + 'url': url, + } + + def action_print_survey(self, answer=None): """ Open the website page with the survey printable view """ self.ensure_one() - token = self.env.context.get('survey_token') - trail = "?answer_token=%s" % token if token else "" + url = '%s?%s' % (self.get_print_url(), werkzeug.urls.url_encode({'answer_token': answer.token or None})) return { 'type': 'ir.actions.act_url', 'name': "Print Survey", 'target': 'self', - 'url': '/survey/print/%s%s' % (self.access_token, trail) + 'url': url } def action_result_survey(self): @@ -555,6 +542,12 @@ class Survey(models.Model): 'url': '/survey/%s/get_certification_preview' % (self.id) } + def get_start_url(self): + return 'survey/start/%s' % self.access_token + + def get_print_url(self): + return 'survey/print/%s' % self.access_token + # ------------------------------------------------------------ # GRAPH / RESULTS # ------------------------------------------------------------ @@ -609,7 +602,7 @@ class Survey(models.Model): labels = label else: labels = Label.browse([row_id, answer_id]) - filter_display_data.append({'question_text': question.question, + filter_display_data.append({'question_text': question.title, 'labels': labels.mapped('value')}) return filter_display_data diff --git a/addons/survey/models/survey_user.py b/addons/survey/models/survey_user.py index 926221ed758..e535253605f 100644 --- a/addons/survey/models/survey_user.py +++ b/addons/survey/models/survey_user.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -import datetime import logging import uuid @@ -24,9 +23,6 @@ class SurveyUserInput(models.Model): scoring_type = fields.Selection(string="Scoring", related="survey_id.scoring_type") start_datetime = fields.Datetime('Start date and time', readonly=True) deadline = fields.Datetime('Deadline', help="Datetime until customer can open the survey and submit answers") - input_type = fields.Selection([ - ('manually', 'Manual'), ('link', 'Invitation')], - string='Answer Type', default='manually', required=True, readonly=True) state = fields.Selection([ ('new', 'Not started yet'), ('skip', 'Partially completed'), @@ -113,16 +109,6 @@ class SurveyUserInput(models.Model): user_input.attempt_number = attempt_number - @api.model - def do_clean_emptys(self): - """ Remove empty user inputs that have been created manually - (used as a cronjob declared in data/survey_cron.xml) - """ - an_hour_ago = fields.Datetime.to_string(datetime.datetime.now() - datetime.timedelta(hours=1)) - self.search([('input_type', '=', 'manually'), - ('state', '=', 'new'), - ('create_date', '<', an_hour_ago)]).unlink() - def action_resend(self): partners = self.env['res.partner'] emails = [] @@ -175,9 +161,13 @@ class SurveyUserInput(models.Model): if challenges: Challenge._cron_update(ids=challenges.ids, commit=False) - def _get_survey_url(self): + def get_start_url(self): self.ensure_one() - return '/survey/start/%s?answer_token=%s' % (self.survey_id.access_token, self.token) + return '%s?answer_token=%s' % (self.survey_id.get_start_url(), self.token) + + def get_print_url(self): + self.ensure_one() + return '%s?answer_token=%s' % (self.survey_id.get_print_url(), self.access_token) class SurveyUserInputLine(models.Model): diff --git a/addons/survey/tests/common.py b/addons/survey/tests/common.py index f279ef9e445..9d000da6f13 100644 --- a/addons/survey/tests/common.py +++ b/addons/survey/tests/common.py @@ -191,7 +191,6 @@ class TestSurveyCommon(common.SavepointCase): 'survey_id': survey.id, 'partner_id': partner.id if partner else False, 'email': kwargs.pop('email', False), - 'input_type': 'manually', } base_avals.update(kwargs) return self.env['survey.user_input'].create(base_avals) diff --git a/addons/survey/views/survey_question_views.xml b/addons/survey/views/survey_question_views.xml index 6d924c0b562..887e380f3cb 100644 --- a/addons/survey/views/survey_question_views.xml +++ b/addons/survey/views/survey_question_views.xml @@ -167,7 +167,7 @@ - + @@ -178,11 +178,11 @@ survey.question - + - + @@ -221,8 +221,10 @@ survey.label - - + + + + diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml index 56d20ca768b..d53dcfb8242 100644 --- a/addons/survey/views/survey_survey_views.xml +++ b/addons/survey/views/survey_survey_views.xml @@ -49,7 +49,6 @@ - @@ -244,7 +243,6 @@ - diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml index 1a599b41477..6023023d370 100644 --- a/addons/survey/views/survey_templates.xml +++ b/addons/survey/views/survey_templates.xml @@ -172,7 +172,7 @@

- + *

@@ -372,7 +372,7 @@

- + *

diff --git a/addons/survey/views/survey_templates_statistics.xml b/addons/survey/views/survey_templates_statistics.xml index 66e5a225661..73bd99e867a 100644 --- a/addons/survey/views/survey_templates_statistics.xml +++ b/addons/survey/views/survey_templates_statistics.xml @@ -50,7 +50,7 @@

Question - + Matrix: diff --git a/addons/survey/views/survey_user_views.xml b/addons/survey/views/survey_user_views.xml index 8b9c454c1f2..9012ffc18c5 100644 --- a/addons/survey/views/survey_user_views.xml +++ b/addons/survey/views/survey_user_views.xml @@ -14,8 +14,6 @@ - - @@ -46,7 +44,6 @@ -