@@ -125,7 +125,7 @@
-
+
@@ -154,8 +154,11 @@
-
-
+
+
+
+
+
@@ -390,7 +393,7 @@
Applications
hr.applicant
- kanban,tree,form,graph,calendar,pivot
+ kanban,tree,form,graph,calendar,pivot,activity
{'search_default_job_id': [active_id], 'default_job_id': active_id}
@@ -599,14 +602,14 @@
-
+
kanban
-
+
tree
diff --git a/addons/hr_recruitment/views/res_config_settings_views.xml b/addons/hr_recruitment/views/res_config_settings_views.xml
index 51361c3cc0a..c8433383779 100644
--- a/addons/hr_recruitment/views/res_config_settings_views.xml
+++ b/addons/hr_recruitment/views/res_config_settings_views.xml
@@ -32,9 +32,10 @@
-
+
- Use interview forms during recruitment process
+ Send an Interview Survey to the applicant during
+ the recruitment process
diff --git a/addons/hr_recruitment_survey/models/__init__.py b/addons/hr_recruitment_survey/models/__init__.py
index b7409ff12e6..c1e428c5a64 100644
--- a/addons/hr_recruitment_survey/models/__init__.py
+++ b/addons/hr_recruitment_survey/models/__init__.py
@@ -3,3 +3,4 @@
from . import hr_job
from . import hr_applicant
+from . import survey_invite
diff --git a/addons/hr_recruitment_survey/models/hr_applicant.py b/addons/hr_recruitment_survey/models/hr_applicant.py
index 969253c7740..1a9f4c246c8 100644
--- a/addons/hr_recruitment_survey/models/hr_applicant.py
+++ b/addons/hr_recruitment_survey/models/hr_applicant.py
@@ -1,6 +1,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import api, fields, models
+from odoo import fields, models, _
+from odoo.exceptions import UserError
class Applicant(models.Model):
@@ -8,19 +9,26 @@ class Applicant(models.Model):
survey_id = fields.Many2one('survey.survey', related='job_id.survey_id', string="Survey", readonly=True)
response_id = fields.Many2one('survey.user_input', "Response", ondelete="set null")
-
- def action_start_survey(self):
- self.ensure_one()
- # create a response and link it to this applicant
- if not self.response_id:
- response = self.survey_id._create_answer(partner=self.partner_id)
- self.response_id = response.id
- else:
- response = self.response_id
- # grab the token of the response and start surveying
- return self.survey_id.action_start_survey(answer=response)
+ response_state = fields.Selection(related='response_id.state', readonly=True)
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()
return self.survey_id.action_print_survey(answer=self.response_id)
+
+ def action_send_survey(self):
+ self.ensure_one()
+
+ # if an applicant does not already has associated partner_id create it
+ if not self.partner_id:
+ if not self.partner_name:
+ raise UserError(_('You must define a Contact Name for this applicant.'))
+ self.partner_id = self.env['res.partner'].create({
+ 'is_company': False,
+ 'type': 'private',
+ 'name': self.partner_name,
+ 'email': self.email_from,
+ 'phone': self.partner_phone,
+ 'mobile': self.partner_mobile
+ })
+ return self.survey_id.with_context(default_partner_ids=self.partner_id.ids, active_model='hr.applicant', active_id=self.id).action_send_survey()
diff --git a/addons/hr_recruitment_survey/models/survey_invite.py b/addons/hr_recruitment_survey/models/survey_invite.py
new file mode 100644
index 00000000000..2007fd3c735
--- /dev/null
+++ b/addons/hr_recruitment_survey/models/survey_invite.py
@@ -0,0 +1,35 @@
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models, _
+
+
+class SurveyInvite(models.TransientModel):
+ _inherit = "survey.invite"
+
+ applicant_id = fields.Many2one('hr.applicant', string='Applicant', default=lambda self: self.env.context.get('active_id', None))
+
+ def action_invite(self):
+ self.ensure_one()
+
+ if not self.applicant_id.response_id:
+ response = self.applicant_id.survey_id._create_answer(partner=self.applicant_id.partner_id)
+ self.applicant_id.response_id = response.id
+
+ body = _('The survey has been sent to "%s".', self.applicant_id.partner_name)
+ self.applicant_id.message_post(body=body)
+
+ return super().action_invite()
+
+
+class SurveyUserInput(models.Model):
+ _inherit = "survey.user_input"
+
+ applicant_id = fields.One2many('hr.applicant', 'response_id', string='Applicant')
+
+ def _mark_done(self):
+ odoobot = self.env.ref('base.partner_root')
+ for user_input in self:
+ if user_input.applicant_id:
+ body = _('The applicant "%s" has finished the survey.', user_input.applicant_id.partner_name)
+ user_input.applicant_id.message_post(body=body, author_id=odoobot.id)
+ return super()._mark_done()
diff --git a/addons/hr_recruitment_survey/tests/test_recruitment_survey.py b/addons/hr_recruitment_survey/tests/test_recruitment_survey.py
index f47ad40a1be..0b5614c7997 100644
--- a/addons/hr_recruitment_survey/tests/test_recruitment_survey.py
+++ b/addons/hr_recruitment_survey/tests/test_recruitment_survey.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo.tests import common
+from odoo.tests import common, Form
class TestRecruitmentSurvey(common.SingleTransactionCase):
@@ -14,26 +14,50 @@ class TestRecruitmentSurvey(common.SingleTransactionCase):
cls.department_admins = cls.env['hr.department'].create({'name': 'Admins'})
cls.survey_sysadmin = cls.env['survey.survey'].create({'title': 'Questions for Sysadmin job offer'})
+ # We need this, so that when we send survey, we don't get an error
+ cls.question_ft = cls.env['survey.question'].create({
+ 'title': 'Test Free Text',
+ 'survey_id': cls.survey_sysadmin.id,
+ 'sequence': 2,
+ 'question_type': 'text_box',
+ })
+
cls.job = cls.env['hr.job'].create({
'name': 'Technical worker',
'survey_id': cls.survey_sysadmin.id,
})
cls.job_sysadmin = cls.env['hr.applicant'].create({
'name': 'Technical worker',
+ 'partner_name': 'Jane Doe',
+ 'email_from': 'customer@example.com',
'department_id': cls.department_admins.id,
'description': 'A nice Sys Admin job offer !',
'job_id': cls.job.id,
})
- def test_start_survey(self):
+ def test_send_survey(self):
# We ensure that response is False because we don't know test order
self.job_sysadmin.response_id = False
- action_start = self.job_sysadmin.action_start_survey()
- self.assertEqual(action_start['type'], 'ir.actions.act_url')
+ Answer = self.env['survey.user_input']
+ answers = Answer.search([('survey_id', '=', self.survey_sysadmin.id)])
+ answers.unlink()
+
+ self.survey_sysadmin.write({'access_mode': 'public', 'users_login_required': False})
+ action = self.job_sysadmin.action_send_survey()
+
+ invite_form = Form(self.env[action['res_model']].with_context({
+ 'active_id': self.job_sysadmin.id,
+ **action['context'],
+ }))
+ invite = invite_form.save()
+ invite.action_invite()
+
self.assertNotEqual(self.job_sysadmin.response_id.id, False)
- self.assertIn(self.job_sysadmin.response_id.access_token, action_start['url'])
- action_start_with_response = self.job_sysadmin.action_start_survey()
- self.assertEqual(action_start_with_response, action_start)
+ answers = Answer.search([('survey_id', '=', self.survey_sysadmin.id)])
+ self.assertEqual(len(answers), 1)
+ self.assertEqual(
+ set(answers.mapped('email')),
+ set([self.job_sysadmin.email_from]))
def test_print_survey(self):
# We ensure that response is False because we don't know test order
diff --git a/addons/hr_recruitment_survey/views/hr_applicant_views.xml b/addons/hr_recruitment_survey/views/hr_applicant_views.xml
index 2bc997866ec..7e178c40ce0 100644
--- a/addons/hr_recruitment_survey/views/hr_applicant_views.xml
+++ b/addons/hr_recruitment_survey/views/hr_applicant_views.xml
@@ -17,19 +17,10 @@
hr.applicant
+
+
+
-
diff --git a/addons/hr_recruitment_survey/views/hr_job_views.xml b/addons/hr_recruitment_survey/views/hr_job_views.xml
index a89ff06448e..5c1ca594bd4 100644
--- a/addons/hr_recruitment_survey/views/hr_job_views.xml
+++ b/addons/hr_recruitment_survey/views/hr_job_views.xml
@@ -23,9 +23,11 @@
-
- Preview Interview
- Create Interview Form
+
+
diff --git a/addons/hr_recruitment_survey/views/res_config_setting_views.xml b/addons/hr_recruitment_survey/views/res_config_setting_views.xml
index c39bc42a7b5..309e11a7628 100644
--- a/addons/hr_recruitment_survey/views/res_config_setting_views.xml
+++ b/addons/hr_recruitment_survey/views/res_config_setting_views.xml
@@ -8,10 +8,10 @@
+
diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py
index 21ca100b7d4..ba2d02bb75d 100644
--- a/addons/survey/controllers/main.py
+++ b/addons/survey/controllers/main.py
@@ -558,7 +558,6 @@ class Survey(http.Controller):
return self._redirect_with_error(access_data, access_data['validity_code'])
survey_sudo, answer_sudo = access_data['survey_sudo'], access_data['answer_sudo']
-
return request.render('survey.survey_page_print', {
'is_html_empty': is_html_empty,
'review': review,
diff --git a/addons/website_hr_recruitment/models/hr_recruitment.py b/addons/website_hr_recruitment/models/hr_recruitment.py
index 58e7d72b671..9fa0c65b82e 100644
--- a/addons/website_hr_recruitment/models/hr_recruitment.py
+++ b/addons/website_hr_recruitment/models/hr_recruitment.py
@@ -3,7 +3,7 @@
from werkzeug import urls
-from odoo import api, fields, models
+from odoo import api, fields, models, _
from odoo.tools.translate import html_translate
@@ -31,7 +31,9 @@ class Applicant(models.Model):
def website_form_input_filter(self, request, values):
if 'partner_name' in values:
- values.setdefault('name', '%s\'s Application' % values['partner_name'])
+ applicant_job = self.env['hr.job'].sudo().search([('id', '=', values['job_id'])]).name if 'job_id' in values else False
+ name = '%s - %s' % (values['partner_name'], applicant_job) if applicant_job else _("%s's Application", values['partner_name'])
+ values.setdefault('name', name)
if values.get('job_id'):
stage = self.env['hr.recruitment.stage'].sudo().search([
('fold', '=', False),
diff --git a/addons/website_hr_recruitment/views/hr_job_views.xml b/addons/website_hr_recruitment/views/hr_job_views.xml
index 7c4ed6ecfb5..28f757fc16e 100644
--- a/addons/website_hr_recruitment/views/hr_job_views.xml
+++ b/addons/website_hr_recruitment/views/hr_job_views.xml
@@ -11,11 +11,22 @@