diff options
| -rw-r--r-- | addons/survey/controllers/main.py | 3 | ||||
| -rw-r--r-- | addons/survey/models/survey_survey.py | 9 | ||||
| -rw-r--r-- | addons/survey/tests/common.py | 3 | ||||
| -rw-r--r-- | addons/survey/tests/test_survey_flow.py | 1 | ||||
| -rw-r--r-- | addons/survey/tests/test_survey_invite.py | 52 | ||||
| -rw-r--r-- | addons/survey/views/survey_survey_views.xml | 42 | ||||
| -rw-r--r-- | addons/survey/wizard/survey_invite.py | 27 | ||||
| -rw-r--r-- | addons/survey/wizard/survey_invite_views.xml | 3 |
8 files changed, 74 insertions, 66 deletions
diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py index 398579dca0b..55d349b4098 100644 --- a/addons/survey/controllers/main.py +++ b/addons/survey/controllers/main.py @@ -63,8 +63,7 @@ class Survey(http.Controller): if not answer_sudo and survey_sudo.access_mode == 'token': return 'token_required' - # Public -> no auth required; Token -> token check hereabove - if survey_sudo.access_mode not in ['public', 'token'] and request.env.user._is_public(): + if survey_sudo.users_login_required and request.env.user._is_public(): return 'survey_auth' if survey_sudo.is_closed or not survey_sudo.active: diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index 3c60d6c343a..3e396413515 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -45,12 +45,11 @@ class Survey(models.Model): user_input_ids = fields.One2many('survey.user_input', 'survey_id', string='User responses', readonly=True, groups='survey.group_survey_user') # security / access access_mode = fields.Selection([ - ('public', 'Everyone'), - ('authentication', 'Login Required'), - ('internal', 'Employees Only'), - ('token', 'Invitation only')], string='Access Mode', - default='authentication', required=True) + ('public', 'Anyone with the link'), + ('token', 'Invited people only')], string='Access Mode', + default='public', required=True) access_token = fields.Char('Access Token', default=lambda self: self._get_default_access_token()) + 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") diff --git a/addons/survey/tests/common.py b/addons/survey/tests/common.py index 4235739ba14..f5be81b7f0e 100644 --- a/addons/survey/tests/common.py +++ b/addons/survey/tests/common.py @@ -64,7 +64,8 @@ class SurveyCase(common.SavepointCase): self.survey = self.env['survey.survey'].sudo(self.survey_manager).create({ 'title': 'Test Survey', - 'access_mode': 'authentication', + 'access_mode': 'public', + 'users_login_required': True, 'users_can_go_back': False, }) self.page_0 = self.env['survey.page'].sudo(self.survey_manager).create({ diff --git a/addons/survey/tests/test_survey_flow.py b/addons/survey/tests/test_survey_flow.py index 396b56f32b9..85c36621816 100644 --- a/addons/survey/tests/test_survey_flow.py +++ b/addons/survey/tests/test_survey_flow.py @@ -48,6 +48,7 @@ class TestSurveyFlow(common.SurveyCase, HttpCase): survey = self.env['survey.survey'].create({ 'title': 'Public Survey for Tarte Al Djotte', 'access_mode': 'public', + 'users_login_required': False, }) # First page is about customer data diff --git a/addons/survey/tests/test_survey_invite.py b/addons/survey/tests/test_survey_invite.py index 92c74bc89a8..3b977d0221d 100644 --- a/addons/survey/tests/test_survey_invite.py +++ b/addons/survey/tests/test_survey_invite.py @@ -47,7 +47,7 @@ class TestSurveyInvite(common.SurveyCase): Answer = self.env['survey.user_input'] deadline = fields.Datetime.now() + relativedelta(months=1) - self.survey.write({'access_mode': 'public'}) + self.survey.write({'access_mode': 'public', 'users_login_required': False}) action = self.survey.action_send_survey() invite_form = Form(self.env[action['res_model']].with_context(action['context'])) @@ -73,7 +73,7 @@ class TestSurveyInvite(common.SurveyCase): def test_survey_invite_authentication_nosignup(self): Answer = self.env['survey.user_input'] - self.survey.write({'access_mode': 'authentication'}) + self.survey.write({'access_mode': 'public', 'users_login_required': True}) action = self.survey.action_send_survey() invite_form = Form(self.env[action['res_model']].with_context(action['context'])) @@ -102,7 +102,7 @@ class TestSurveyInvite(common.SurveyCase): self.survey.invalidate_cache() Answer = self.env['survey.user_input'] - self.survey.write({'access_mode': 'authentication'}) + self.survey.write({'access_mode': 'public', 'users_login_required': True}) action = self.survey.action_send_survey() invite_form = Form(self.env[action['res_model']].with_context(action['context'])) @@ -123,38 +123,31 @@ class TestSurveyInvite(common.SurveyCase): self.assertEqual(answers.mapped('partner_id'), self.customer | self.user_emp.partner_id | self.user_portal.partner_id) @users('survey_manager') - def test_survey_invite_internal(self): + def test_survey_invite_public(self): Answer = self.env['survey.user_input'] - self.survey.write({'access_mode': 'internal'}) + self.survey.write({'access_mode': 'public', 'users_login_required': False}) action = self.survey.action_send_survey() invite_form = Form(self.env[action['res_model']].with_context(action['context'])) - with self.assertRaises(UserError): # do not allow to add customer (partner without user) - invite_form.partner_ids.add(self.customer) - with self.assertRaises(UserError): # do not allow to add portal user - invite_form.partner_ids.add(self.user_portal.partner_id) - invite_form.partner_ids.clear() - invite_form.partner_ids.add(self.user_emp.partner_id) - with self.assertRaises(UserError): - invite_form.emails = 'test1@example.com, Raoulette Vignolette <test2@example.com>' - invite_form.emails = False + invite_form.partner_ids.add(self.customer) + invite_form.emails = 'test1@example.com, Raoulette Vignolette <test2@example.com>' invite = invite_form.save() invite.action_invite() answers = Answer.search([('survey_id', '=', self.survey.id)]) - self.assertEqual(len(answers), 1) + self.assertEqual(len(answers), 3) self.assertEqual( set(answers.mapped('email')), - set([self.user_emp.email])) - self.assertEqual(answers.mapped('partner_id'), self.user_emp.partner_id) + set(['test1@example.com', 'Raoulette Vignolette <test2@example.com>', self.customer.email])) + self.assertEqual(answers.mapped('partner_id'), self.customer) @users('survey_manager') - def test_survey_invite_public(self): + def test_survey_invite_token(self): Answer = self.env['survey.user_input'] - self.survey.write({'access_mode': 'public'}) + self.survey.write({'access_mode': 'token', 'users_login_required': False}) action = self.survey.action_send_survey() invite_form = Form(self.env[action['res_model']].with_context(action['context'])) @@ -172,22 +165,29 @@ class TestSurveyInvite(common.SurveyCase): self.assertEqual(answers.mapped('partner_id'), self.customer) @users('survey_manager') - def test_survey_invite_token(self): + def test_survey_invite_token_internal(self): Answer = self.env['survey.user_input'] - self.survey.write({'access_mode': 'token'}) + self.survey.write({'access_mode': 'token', 'users_login_required': True}) action = self.survey.action_send_survey() invite_form = Form(self.env[action['res_model']].with_context(action['context'])) - invite_form.partner_ids.add(self.customer) - invite_form.emails = 'test1@example.com, Raoulette Vignolette <test2@example.com>' + with self.assertRaises(UserError): # do not allow to add customer (partner without user) + invite_form.partner_ids.add(self.customer) + with self.assertRaises(UserError): # do not allow to add portal user + invite_form.partner_ids.add(self.user_portal.partner_id) + invite_form.partner_ids.clear() + invite_form.partner_ids.add(self.user_emp.partner_id) + with self.assertRaises(UserError): + invite_form.emails = 'test1@example.com, Raoulette Vignolette <test2@example.com>' + invite_form.emails = False invite = invite_form.save() invite.action_invite() answers = Answer.search([('survey_id', '=', self.survey.id)]) - self.assertEqual(len(answers), 3) + self.assertEqual(len(answers), 1) self.assertEqual( set(answers.mapped('email')), - set(['test1@example.com', 'Raoulette Vignolette <test2@example.com>', self.customer.email])) - self.assertEqual(answers.mapped('partner_id'), self.customer) + set([self.user_emp.email])) + self.assertEqual(answers.mapped('partner_id'), self.user_emp.partner_id) diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml index 04dd90c305e..42d7e877677 100644 --- a/addons/survey/views/survey_survey_views.xml +++ b/addons/survey/views/survey_survey_views.xml @@ -12,7 +12,7 @@ <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_send_survey" string="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> @@ -35,22 +35,36 @@ <group> <group> <field name="access_mode"/> - <field name="users_can_go_back"/> - </group> - <group> + <field name="public_url" readonly="1" + attrs="{'invisible': [('access_mode', '!=', 'public')]}" + widget="CopyClipboardText"/> <field name="category" invisible="1"/> - <field name="quizz_mode"/> </group> </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> + <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 name="options"> + <group string="Candidates" name="candidates"> + <field name="users_login_required"/> + </group> + <group string="Questions" name="questions"> + <field name="users_can_go_back" string="Enable back button"/> + </group> + <group string="Scoring Informations" name="scoring"> + <field name="quizz_mode"/> + </group> + </group> + </page> + </notebook> </sheet> <div class="oe_chatter"> <field name="message_follower_ids" widget="mail_followers"/> diff --git a/addons/survey/wizard/survey_invite.py b/addons/survey/wizard/survey_invite.py index 98d45dc0626..a6c5d193375 100644 --- a/addons/survey/wizard/survey_invite.py +++ b/addons/survey/wizard/survey_invite.py @@ -57,11 +57,12 @@ class SurveyInvite(models.TransientModel): survey_id = fields.Many2one('survey.survey', string='Survey', required=True) survey_url = fields.Char(related="survey_id.public_url", readonly=True) survey_access_mode = fields.Selection(related="survey_id.access_mode", readonly=True) + survey_users_login_required = fields.Boolean(related="survey_id.users_login_required", readonly=True) deadline = fields.Datetime(string="Answer deadline") @api.onchange('emails') def _onchange_emails(self): - if self.emails and (self.survey_access_mode == 'internal' or (self.survey_access_mode == 'authentication' and not self.survey_id.users_can_signup)): + if self.emails and (self.survey_users_login_required and not self.survey_id.users_can_signup): raise UserError(_('This survey does not allow external people to participate. You should create user accounts or update survey access mode accordingly.')) if not self.emails: return @@ -77,27 +78,19 @@ class SurveyInvite(models.TransientModel): raise UserError(_("Some emails you just entered are incorrect: %s") % (', '.join(error))) self.emails = '\n'.join(valid) - @api.onchange('survey_access_mode') - def _onchange_survey_access_mode(self): - if self.survey_access_mode == 'internal': + @api.onchange('survey_users_login_required') + def _onchange_survey_users_login_required(self): + if self.survey_users_login_required and not self.survey_id.users_can_signup: return {'domain': { - 'partner_ids': [('user_ids.groups_id', 'in', [self.env.ref('base.group_user').id])] - }} - elif self.survey_access_mode == 'authentication': - if not self.survey_id.users_can_signup: - return {'domain': { - 'partner_ids': [('user_ids.groups_id', 'in', [self.env.ref('base.group_user').id, self.env.ref('base.group_portal').id])] + 'partner_ids': [('user_ids', '!=', False)] }} + return {'domain': { + 'partner_ids': [] + }} @api.onchange('partner_ids') def _onchange_partner_ids(self): - if self.survey_access_mode == 'internal' and self.partner_ids: - invalid_partners = self.partner_ids.filtered(lambda partner: not partner.user_ids or not all(user.has_group('base.group_user') for user in partner.user_ids)) - if invalid_partners: - raise UserError( - _('The following recipients are not valid users belonging to the employee group: %s. You should create user accounts for them.' % - (','.join(invalid_partners.mapped('name'))))) - elif self.survey_access_mode == 'authentication' and self.partner_ids: + if self.survey_users_login_required and self.partner_ids: if not self.survey_id.users_can_signup: invalid_partners = self.env['res.partner'].search([ ('user_ids', '=', False), diff --git a/addons/survey/wizard/survey_invite_views.xml b/addons/survey/wizard/survey_invite_views.xml index f9e19be04ee..cc67c069d5b 100644 --- a/addons/survey/wizard/survey_invite_views.xml +++ b/addons/survey/wizard/survey_invite_views.xml @@ -9,6 +9,7 @@ <group col="1"> <group col="2"> <field name="survey_access_mode" invisible="1"/> + <field name="survey_users_login_required" invisible="1"/> <field name="survey_id" readonly="context.get('default_survey_id')"/> <field name="existing_mode" widget="radio" invisible="1" /> <field name="survey_url" label="Public share URL" readonly="1" widget="CopyClipboardText" @@ -21,7 +22,7 @@ context="{'force_email':True, 'show_email':True, 'no_create_edit': True}"/> <field name="emails" attrs="{ - 'invisible': [('survey_access_mode', 'in', ['authentication', 'internal'])], + 'invisible': [('survey_users_login_required', '=', True)], 'readonly': [('existing_mode', '=', 'resend')] }" placeholder="Add a list of email of recipients (will not be converted into contacts). Separated by commas, semicolons or newline..."/> |
