[REF] survey: improve access mode options and survey form view
In this commit we extend access option on survey model. Access mode is now defined as * public: everyone can access this survey. People having a link to the survey can create answers and fill survey. Those are used for example as satisfaction surveys; * login required: only users can access this survey. Depending on auth signup configuration this either limits survey access or forces people to create an account; * employees only: only users belonging to base.group_user can access this survey. Those are used for example for internal polls; * on invitation only: only people receiving a token can access this survey. They do not need to be an user, having a token is sufficient. Those are used for example for appraisals; Note that survey officers and managers can always create and update answers according to their ACLs. In this commit we also improve a bit survey form view while changing the access field. Surveys users now have access to all buttons and some labels have been updated to better fit current Odoo style. Archive button is now always displayed as it is considered as a standard way of managing surveys. This commit is linked to task ID 1911586 and PR #28986.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<record id="survey_recruitment_form" model="survey.survey">
|
||||
<field name="title">Recruitment Form</field>
|
||||
<field name="stage_id" ref="survey.stage_permanent"/>
|
||||
<field name="auth_required" eval="True"/>
|
||||
<field name="access_mode">token</field>
|
||||
<field name="users_can_go_back" eval="True"/>
|
||||
<field name="description" type="html">
|
||||
<p>
|
||||
|
||||
@@ -59,8 +59,11 @@ class Survey(http.Controller):
|
||||
|
||||
if not answer_sudo and ensure_token:
|
||||
return 'token_required'
|
||||
if not answer_sudo and survey_sudo.access_mode == 'token':
|
||||
return 'token_required'
|
||||
|
||||
if survey_sudo.auth_required and request.env.user._is_public():
|
||||
# Public -> no auth required; Token -> token check hereabove
|
||||
if survey_sudo.access_mode not in ['public', 'token'] and request.env.user._is_public():
|
||||
return 'survey_auth'
|
||||
|
||||
if survey_sudo.is_closed or not survey_sudo.active:
|
||||
@@ -99,7 +102,7 @@ class Survey(http.Controller):
|
||||
has_survey_access = True
|
||||
can_answer = bool(answer_sudo)
|
||||
if not can_answer:
|
||||
can_answer = survey_sudo.auth_required is False
|
||||
can_answer = survey_sudo.access_mode == 'public'
|
||||
|
||||
return {
|
||||
'survey_sudo': survey_sudo,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<record model="survey.survey" id="survey_feedback">
|
||||
<field name="title">User Feedback Form</field>
|
||||
<field name="stage_id" ref="survey.stage_in_progress" />
|
||||
<field name="auth_required" eval="False" />
|
||||
<field name="access_mode">public</field>
|
||||
<field name="users_can_go_back" eval="True" />
|
||||
<field name="description" type="html">
|
||||
<p>This survey allows you to give a feedback about your experience with our eCommerce solution.
|
||||
@@ -229,4 +229,4 @@
|
||||
<field name="state">skip</field>
|
||||
</record>
|
||||
|
||||
</data></odoo>
|
||||
</data></odoo>
|
||||
@@ -35,14 +35,26 @@ class Survey(models.Model):
|
||||
page_ids = fields.One2many('survey.page', 'survey_id', string='Pages', copy=True)
|
||||
user_input_ids = fields.One2many('survey.user_input', 'survey_id', string='User responses', readonly=True, groups='survey.group_survey_user')
|
||||
# security / access
|
||||
auth_required = fields.Boolean('Login required', help="Users with a public link will be requested to login before taking part to the survey")
|
||||
access_mode = fields.Selection([
|
||||
('public', 'Everyone'),
|
||||
('authentication', 'Login Required'),
|
||||
('internal', 'Employees Only'),
|
||||
('token', 'Invitation only')], string='Access Mode',
|
||||
default='authentication', required=True)
|
||||
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
|
||||
tot_sent_survey = fields.Integer("Number of sent surveys", compute="_compute_survey_statistic")
|
||||
tot_start_survey = fields.Integer("Number of started surveys", compute="_compute_survey_statistic")
|
||||
tot_comp_survey = fields.Integer("Number of completed surveys", compute="_compute_survey_statistic")
|
||||
|
||||
@api.multi
|
||||
def _compute_users_can_signup(self):
|
||||
signup_allowed = self.env['res.users'].sudo()._get_signup_invitation_scope() == 'b2c'
|
||||
for survey in self:
|
||||
survey.users_can_signup = signup_allowed
|
||||
|
||||
@api.multi
|
||||
def _compute_survey_statistic(self):
|
||||
UserInput = self.env['survey.user_input']
|
||||
@@ -125,8 +137,15 @@ class Survey(models.Model):
|
||||
raise UserError(_('Creating token for archived surveys is not allowed.'))
|
||||
elif self.is_closed:
|
||||
raise UserError(_('Creating token for closed surveys is not allowed.'))
|
||||
if self.auth_required and (not user or user._is_public()):
|
||||
raise UserError(_('Creating token for external users is not allowed for surveys requesting authentication.'))
|
||||
if self.access_mode == 'authentication':
|
||||
# signup possible -> should have at least a partner to create an account
|
||||
if self.users_can_signup and not user and not partner:
|
||||
raise UserError(_('Creating token for external people is not allowed for surveys requesting authentication.'))
|
||||
# no signup possible -> should be a not public user (employee or portal users)
|
||||
if not self.users_can_signup and (not user or user._is_public()):
|
||||
raise UserError(_('Creating token for external people is not allowed for surveys requesting authentication.'))
|
||||
if self.access_mode == 'internal' and (not user or not user.has_group('base.group_user')):
|
||||
raise UserError(_('Creating token for anybody else than employees is not allowed for internal surveys.'))
|
||||
|
||||
@api.model
|
||||
def next_page(self, user_input, page_id, go_back=False):
|
||||
|
||||
@@ -64,7 +64,7 @@ class SurveyCase(common.SavepointCase):
|
||||
|
||||
self.survey = self.env['survey.survey'].sudo(self.survey_manager).create({
|
||||
'title': 'Test Survey',
|
||||
'auth_required': True,
|
||||
'access_mode': 'authentication',
|
||||
'users_can_go_back': False,
|
||||
})
|
||||
self.page_0 = self.env['survey.page'].sudo(self.survey_manager).create({
|
||||
|
||||
@@ -47,7 +47,7 @@ class TestSurveyFlow(common.SurveyCase, HttpCase):
|
||||
with self.sudo(self.survey_manager):
|
||||
survey = self.env['survey.survey'].create({
|
||||
'title': 'Public Survey for Tarte Al Djotte',
|
||||
'auth_required': False,
|
||||
'access_mode': 'public',
|
||||
})
|
||||
|
||||
# First page is about customer data
|
||||
|
||||
@@ -9,12 +9,11 @@
|
||||
<field name="id" invisible="1"/>
|
||||
<field name="tot_start_survey" invisible="1"/>
|
||||
<field name="is_closed" invisible="1"/>
|
||||
<header groups="survey.group_survey_manager">
|
||||
<button name="action_test_survey" string="Test Survey" type="object" attrs="{'invisible': [('id', '=', False)]}"/>
|
||||
<button name="action_print_survey" string="Print Survey" type="object" attrs="{'invisible': [('id', '=', False)]}"/>
|
||||
<button name="action_send_survey" string="Share and invite by email" type="object" class="oe_highlight" attrs="{'invisible': [('id', '=', False)]}"/>
|
||||
<button name="action_result_survey" string="View results" type="object" attrs="{'invisible': ['|',('id', '=', False), ('tot_start_survey', '!=', 0)]}"/>
|
||||
<button name="action_result_survey" string="View results" type="object" class="oe_highlight" attrs="{'invisible': [('tot_start_survey', '=', 0)]}"/>
|
||||
<header>
|
||||
<button name="action_test_survey" string="Test" type="object" attrs="{'invisible': [('id', '=', False)]}"/>
|
||||
<button name="action_print_survey" string="Print" type="object" attrs="{'invisible': [('id', '=', False)]}"/>
|
||||
<button name="action_send_survey" string="Share and invite" type="object" class="oe_highlight" attrs="{'invisible': [('id', '=', False)]}"/>
|
||||
<button name="action_result_survey" string="View results" type="object" class="oe_highlight" attrs="{'invisible': [('id', '=', False)]}"/>
|
||||
<field name="stage_id" widget="statusbar" options="{'clickable': '1'}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
@@ -25,7 +24,7 @@
|
||||
icon="fa-pencil-square-o">
|
||||
<field string="Answers" name="tot_comp_survey" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive" attrs="{'invisible': [('is_closed', '=', False)]}">
|
||||
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
|
||||
<field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
|
||||
</button>
|
||||
</div>
|
||||
@@ -33,24 +32,20 @@
|
||||
<label for="title" class="oe_edit_only"/>
|
||||
<h1><field name="title" placeholder="Survey Title"/></h1>
|
||||
</div>
|
||||
<notebook>
|
||||
<page string="Edit Pages and Questions">
|
||||
<field name="page_ids" mode="tree" context="{'default_survey_id': active_id}" nolabel="1">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title"/>
|
||||
<field name="question_ids"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Options">
|
||||
<group class="o_label_nowrap">
|
||||
<field name="users_can_go_back" string="User can come back in the previous page"/>
|
||||
<field name="auth_required"/>
|
||||
<field name="quizz_mode" groups="base.group_no_one"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<group>
|
||||
<field name="access_mode"/>
|
||||
<field name="quizz_mode"/>
|
||||
<field name="users_can_go_back"/>
|
||||
</group>
|
||||
<group string="Edit Pages and Questions">
|
||||
<field name="page_ids" mode="tree" context="{'default_survey_id': active_id}" nolabel="1">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title"/>
|
||||
<field name="question_ids"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
@@ -85,7 +80,7 @@
|
||||
<field name="tot_start_survey" />
|
||||
<field name="tot_comp_survey" />
|
||||
<field name="color" />
|
||||
<field name="auth_required" />
|
||||
<field name="access_mode"/>
|
||||
<field name="activity_ids" />
|
||||
<field name="activity_state" />
|
||||
<templates>
|
||||
@@ -108,7 +103,7 @@
|
||||
</div>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<ul class="list-unstyled">
|
||||
<li id="survey_test">
|
||||
<li>
|
||||
<a type="object" name="action_test_survey">Test</a>
|
||||
</li>
|
||||
<li>
|
||||
@@ -165,12 +160,10 @@
|
||||
</p><p>
|
||||
You can create surveys for different purposes: customer opinion, services feedback, recruitment interviews, employee's periodical evaluations, marketing campaigns, etc.
|
||||
</p><p>
|
||||
Design easily your survey, send invitations to answer by email and analyse answers.
|
||||
Design easily your survey, send invitations to answer by email and analyze answers.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<act_window context="{'search_default_survey_id': [active_id], 'default_survey_id': active_id}" id="act_survey_pages" name="Pages" res_model="survey.page" src_model="survey.survey"/>
|
||||
<act_window context="{'search_default_survey_id': [active_id], 'default_survey_id': active_id}" id="act_survey_question" name="Questions" res_model="survey.question" src_model="survey.survey"/>
|
||||
|
||||
<menuitem name="Surveys" id="menu_survey_form" action="action_survey_form" parent="menu_surveys" sequence="1"/>
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<div class="jumbotron mt32">
|
||||
<h1>Login required</h1>
|
||||
<p>This survey is open only to registered people. Please
|
||||
<a t-att-href="'/web/login?redirect=%s' % ('/survey/start/%s?token=%s' % (survey, token))">log in</a>.
|
||||
<a t-att-href="'/web/login?redirect=%s' % ('/survey/start/%s?token=%s' % (survey.id, token))">log in</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<form string="Survey User inputs" create="false">
|
||||
<header>
|
||||
<button name="action_survey_resend" string="Send Invitation Again" type="object" class="oe_highlight" attrs="{'invisible': ['|', ('input_type','=','manually'), ('state', '=', 'done')]}"/>
|
||||
<button name="action_print_answers" states="done" string="Print These Answers" type="object" class="oe_highlight" />
|
||||
<button name="action_print_answers" states="done" string="Print" type="object" class="oe_highlight" />
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
||||
Reference in New Issue
Block a user