diff options
| author | Kevin Baptiste <kba@odoo.com> | 2019-07-09 12:21:24 +0000 |
|---|---|---|
| committer | Yannick Tivisse <yti@odoo.com> | 2019-07-17 07:02:01 +0000 |
| commit | 81a2ad4e05ad1f6018969de56911fcd98ae2f07b (patch) | |
| tree | fd5b7891ef3f00849ed8ffffaea5c3aad3e575b7 | |
| parent | bd3a553ad9c81e458a65959f9a4cf0748ae08301 (diff) | |
[IMP] hr_recruitment: Improve general usability (back2basics)
TaskID: 2033500
closes odoo/odoo#34858
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
10 files changed, 69 insertions, 70 deletions
diff --git a/addons/hr_recruitment/models/hr_job.py b/addons/hr_recruitment/models/hr_job.py index 280a096b5df..b72e362c5b0 100644 --- a/addons/hr_recruitment/models/hr_job.py +++ b/addons/hr_recruitment/models/hr_job.py @@ -82,8 +82,8 @@ class Job(models.Model): self.ensure_one() return self.env['hr.recruitment.stage'].search([ '|', - ('job_id', '=', False), - ('job_id', '=', self.id)], order='sequence asc', limit=1) + ('job_ids', '=', False), + ('job_ids', '=', self.id)], order='sequence asc', limit=1) def _compute_new_application_count(self): first_stages = {job.id: job._get_first_stage().id for job in self} diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index a142a94bd92..92cd84ca3cb 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -4,6 +4,7 @@ from odoo import api, fields, models, SUPERUSER_ID from odoo.tools.translate import _ from odoo.exceptions import UserError +from odoo.osv import expression AVAILABLE_PRIORITIES = [ ('0', 'Normal'), @@ -47,19 +48,19 @@ class RecruitmentStage(models.Model): _description = "Recruitment Stages" _order = 'sequence' - name = fields.Char("Stage name", required=True, translate=True) + name = fields.Char("Stage Name", required=True, translate=True) sequence = fields.Integer( "Sequence", default=10, help="Gives the sequence order when displaying a list of stages.") - job_id = fields.Many2one('hr.job', string='Job Specific', - ondelete='cascade', - help='Specific job that uses this stage. Other jobs will not use this stage.') + job_ids = fields.Many2many( + 'hr.job', string='Job Specific', + help='Specific jobs that uses this stage. Other jobs will not use this stage.') requirements = fields.Text("Requirements") template_id = fields.Many2one( - 'mail.template', "Automated Email", + 'mail.template', "Email Template", help="If set, a message is posted on the applicant using the template when the applicant is set to the stage.") fold = fields.Boolean( - "Folded in Recruitment Pipe", + "Folded in Kanban", help="This stage is folded in the kanban view when there are no records in that stage to display.") legend_blocked = fields.Char( 'Red Kanban Label', default=lambda self: _('Blocked'), translate=True, required=True) @@ -98,8 +99,8 @@ class Applicant(models.Model): if self._context.get('default_job_id'): return self.env['hr.recruitment.stage'].search([ '|', - ('job_id', '=', False), - ('job_id', '=', self._context['default_job_id']), + ('job_ids', '=', False), + ('job_ids', '=', self._context['default_job_id']), ('fold', '=', False) ], order='sequence asc', limit=1).id return False @@ -113,15 +114,21 @@ class Applicant(models.Model): company_id = self.env.company return company_id + def _get_stage_id_domain(self): + domain = [('job_ids', '=', False)] + if self.job_id: + domain = expression.OR([domain, [('job_ids', 'in', self.job_id)]]) + return domain + name = fields.Char("Subject / Application Name", required=True) active = fields.Boolean("Active", default=True, help="If the active field is set to false, it will allow you to hide the case without removing it.") description = fields.Text("Description") email_from = fields.Char("Email", size=128, help="Applicant email") probability = fields.Float("Probability") - partner_id = fields.Many2one('res.partner', "Contact") + partner_id = fields.Many2one('res.partner', "Contact", copy=False) create_date = fields.Datetime("Creation Date", readonly=True, index=True) stage_id = fields.Many2one('hr.recruitment.stage', 'Stage', ondelete='restrict', tracking=True, - domain="['|', ('job_id', '=', False), ('job_id', '=', job_id)]", + domain=_get_stage_id_domain, copy=False, index=True, group_expand='_read_group_stage_ids', default=_default_stage_id) @@ -185,7 +192,7 @@ class Applicant(models.Model): ('email_from', 'in', list(set(self.mapped('email_from'))))], ['email_from'], ['email_from']) application_data_mapped = dict((data['email_from'], data['email_from_count']) for data in application_data) for applicant in self.filtered(lambda applicant: applicant.email_from): - applicant.application_count = application_data_mapped.get(applicant.email_from, 0) + applicant.application_count = application_data_mapped.get(applicant.email_from, 1) - 1 @api.multi def _get_attachment_number(self): @@ -200,9 +207,9 @@ class Applicant(models.Model): def _read_group_stage_ids(self, stages, domain, order): # retrieve job_id from the context and write the domain: ids + contextual columns (job or default) job_id = self._context.get('default_job_id') - search_domain = [('job_id', '=', False)] + search_domain = [('job_ids', '=', False)] if job_id: - search_domain = ['|', ('job_id', '=', job_id)] + search_domain + search_domain = ['|', ('job_ids', '=', job_id)] + search_domain if stages: search_domain = ['|', ('id', 'in', stages.ids)] + search_domain @@ -227,8 +234,8 @@ class Applicant(models.Model): if not stage_id: stage_ids = self.env['hr.recruitment.stage'].search([ '|', - ('job_id', '=', False), - ('job_id', '=', job.id), + ('job_ids', '=', False), + ('job_ids', '=', job.id), ('fold', '=', False) ], order='sequence asc', limit=1).ids stage_id = stage_ids[0] if stage_ids else False @@ -239,6 +246,21 @@ class Applicant(models.Model): 'stage_id': stage_id }} + @api.onchange('email_from') + def onchange_email_from(self): + if self.partner_id and self.email_from and not self.partner_id.email: + self.partner_id.email = self.email_from + + @api.onchange('partner_phone') + def onchange_partner_phone(self): + if self.partner_id and self.partner_phone and not self.partner_id.phone: + self.partner_id.phone = self.partner_phone + + @api.onchange('partner_mobile') + def onchange_partner_mobile(self): + if self.partner_id and self.partner_mobile and not self.partner_id.mobile: + self.partner_id.mobile = self.partner_mobile + @api.onchange('partner_id') def onchange_partner_id(self): self.partner_phone = self.partner_id.phone @@ -385,7 +407,10 @@ class Applicant(models.Model): if applicant.partner_id: applicant._message_add_suggested_recipient(recipients, partner=applicant.partner_id, reason=_('Contact')) elif applicant.email_from: - applicant._message_add_suggested_recipient(recipients, email=applicant.email_from, reason=_('Contact Email')) + email_from = applicant.email_from + if applicant.partner_name: + email_from = '%s<%s>' % (applicant.partner_name, email_from) + applicant._message_add_suggested_recipient(recipients, email=email_from, reason=_('Contact Email')) return recipients @api.model @@ -434,7 +459,9 @@ class Applicant(models.Model): if applicant.partner_id: address_id = applicant.partner_id.address_get(['contact'])['contact'] contact_name = applicant.partner_id.display_name - else : + else: + if not applicant.partner_name: + raise UserError(_('You must define a Contact Name for this applicant.')) new_partner_id = self.env['res.partner'].create({ 'is_company': False, 'name': applicant.partner_name, @@ -443,11 +470,10 @@ class Applicant(models.Model): 'mobile': applicant.partner_mobile }) address_id = new_partner_id.address_get(['contact'])['contact'] - if applicant.job_id and (applicant.partner_name or contact_name): - applicant.job_id.write({'no_of_hired_employee': applicant.job_id.no_of_hired_employee + 1}) + if applicant.partner_name or contact_name: employee = self.env['hr.employee'].create({ 'name': applicant.partner_name or contact_name, - 'job_id': applicant.job_id.id, + 'job_id': applicant.job_id.id or False, 'address_home_id': address_id, 'department_id': applicant.department_id.id or False, 'address_id': applicant.company_id and applicant.company_id.partner_id @@ -457,11 +483,11 @@ class Applicant(models.Model): 'work_phone': applicant.department_id and applicant.department_id.company_id and applicant.department_id.company_id.phone or False}) applicant.write({'emp_id': employee.id}) - applicant.job_id.message_post( - body=_('New Employee %s Hired') % applicant.partner_name if applicant.partner_name else applicant.name, - subtype="hr_recruitment.mt_job_applicant_hired") - else: - raise UserError(_('You must define an Applied Job and a Contact Name for this applicant.')) + if applicant.job_id: + applicant.job_id.write({'no_of_hired_employee': applicant.job_id.no_of_hired_employee + 1}) + applicant.job_id.message_post( + body=_('New Employee %s Hired') % applicant.partner_name if applicant.partner_name else applicant.name, + subtype="hr_recruitment.mt_job_applicant_hired") employee_action = self.env.ref('hr.open_view_employee_list') dict_act_window = employee_action.read([])[0] diff --git a/addons/hr_recruitment/views/hr_job_views.xml b/addons/hr_recruitment/views/hr_job_views.xml index 00e281816e2..f48e273c025 100644 --- a/addons/hr_recruitment/views/hr_job_views.xml +++ b/addons/hr_recruitment/views/hr_job_views.xml @@ -26,7 +26,7 @@ <field name="user_id"/> <templates> <t t-name="kanban-box"> - <div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click"> + <div t-attf-class="#{kanban_color(record.color.raw_value)}"> <div t-attf-class="o_kanban_card_header"> <div class="o_kanban_card_header_title"> <div class="o_primary col-12"><t t-esc="record.name.value"/></div> @@ -41,17 +41,16 @@ </div> <div class="container o_kanban_card_content"> <t t-if="record.state.raw_value == 'recruit'"> - <div> - <field name="new_application_count"/> New Applications <br/> - <field name="no_of_hired_employee"/> Hired Employees + <div class="row"> + <div class="col-6"> + <button class="btn btn-secondary" name="%(action_hr_job_applications)d" type="action">Applications</button> + </div> + <div class="col-6"> + <field name="new_application_count"/> New Applications <br/> + <field name="no_of_hired_employee"/> Hired Employees + </div> </div> <div name="kanban_boxes" class="row o_recruitment_kanban_boxes"> - <div class="o_recruitment_kanban_box o_kanban_primary_bottom bottom_block"> - <a name="action_get_attachment_tree_view" type="object"> - <span title='Documents'><i class='fa fa-paperclip' role="img" aria-label="Documents"/> - </span> - </a> - </div> </div> </t> <t t-if="record.state.raw_value == 'open'"> diff --git a/addons/hr_recruitment/views/hr_recruitment_views.xml b/addons/hr_recruitment/views/hr_recruitment_views.xml index c67213542db..e42af785aa4 100644 --- a/addons/hr_recruitment/views/hr_recruitment_views.xml +++ b/addons/hr_recruitment/views/hr_recruitment_views.xml @@ -69,9 +69,9 @@ <form string="Jobs - Recruitment Form"> <header> <button string="Create Employee" name="create_employee_from_applicant" type="object" - class="oe_highlight" attrs="{'invisible': ['|',('emp_id', '!=', False),('active', '=', False)]}"/> + class="oe_highlight" attrs="{'invisible': ['|',('emp_id', '!=', False),('active', '=', False)]}" confirm="Are you sure?"/> <button string="Refuse" name="archive_applicant" type="object" attrs="{'invisible': [('active', '=', False)]}"/> - <button string="Reopen Application" name="reset_applicant" type="object" attrs="{'invisible': [('active', '=', True)]}"/> + <button string="Restore" name="reset_applicant" type="object" attrs="{'invisible': [('active', '=', True)]}"/> <field name="stage_id" widget="statusbar" options="{'clickable': '1', 'fold_field': 'fold'}" attrs="{'invisible': [('active', '=', False),('emp_id', '=', False)]}"/> </header> <sheet> @@ -82,7 +82,7 @@ icon="fa-file-o" type="object" attrs="{'invisible': [('application_count', '=', 0)]}"> - <field name="application_count" widget="statinfo" string="Applications"/> + <field name="application_count" widget="statinfo" string="Other Applications"/> </button> <button name="action_makeMeeting" class="oe_stat_button" icon="fa-calendar" type="object" help="Schedule interview with this applicant"> @@ -125,7 +125,7 @@ </div> <group> <group> - <field name="partner_id"/> + <field name="partner_id" invisible="1" /> <field name="email_from" widget="email"/> <field name="email_cc" groups="base.group_no_one"/> <field name="partner_phone"/> @@ -704,11 +704,11 @@ action = act <group> <field name="name"/> <field name="sequence" groups="base.group_no_one"/> - <field name="job_id"/> + <field name="template_id" domain= "[('model_id.model', '=', 'hr.applicant')]"/> </group> <group name="stage_details"> <field name="fold"/> - <field name="template_id" domain= "[('model_id.model', '=', 'hr.applicant')]"/> + <field name="job_ids" widget="many2many_tags"/> </group> </group> <group name="tooltips" string="Tooltips"> diff --git a/addons/website_hr_recruitment/data/config_data.xml b/addons/website_hr_recruitment/data/config_data.xml index 06fa323d962..46ecb179e0b 100644 --- a/addons/website_hr_recruitment/data/config_data.xml +++ b/addons/website_hr_recruitment/data/config_data.xml @@ -31,7 +31,6 @@ 'email_from', 'partner_name', 'partner_phone', - 'residence_country', 'job_id', 'department_id', ]"/> diff --git a/addons/website_hr_recruitment/models/hr_recruitment.py b/addons/website_hr_recruitment/models/hr_recruitment.py index bb441a6fc98..1cbaab7541b 100644 --- a/addons/website_hr_recruitment/models/hr_recruitment.py +++ b/addons/website_hr_recruitment/models/hr_recruitment.py @@ -29,8 +29,6 @@ class Applicant(models.Model): _inherit = 'hr.applicant' - residence_country = fields.Char(string="Residence Country") - def website_form_input_filter(self, request, values): if 'partner_name' in values: values.setdefault('name', '%s\'s Application' % values['partner_name']) diff --git a/addons/website_hr_recruitment/static/tests/tours/website_hr_recruitment.js b/addons/website_hr_recruitment/static/tests/tours/website_hr_recruitment.js index 620a9639f18..19f6852bed6 100644 --- a/addons/website_hr_recruitment/static/tests/tours/website_hr_recruitment.js +++ b/addons/website_hr_recruitment/static/tests/tours/website_hr_recruitment.js @@ -19,10 +19,6 @@ odoo.define('website_hr_recruitment.tour', function(require) { trigger: "input[name=partner_phone]", run: "text 118.218" }, { - content: "Complete Residence Country", - trigger: "input[name=residence_country]", - run: "text Belgium" - }, { content: "Complete Subject", trigger: "textarea[name=description]", run: "text ### HR RECRUITMENT TEST DATA ###" diff --git a/addons/website_hr_recruitment/views/hr_job_views.xml b/addons/website_hr_recruitment/views/hr_job_views.xml index 610c6f30d8b..1cf5ff07407 100644 --- a/addons/website_hr_recruitment/views/hr_job_views.xml +++ b/addons/website_hr_recruitment/views/hr_job_views.xml @@ -9,7 +9,7 @@ <field name="website_url" invisible="1"/> <div class="o_recruitment_kanban_box o_kanban_primary_bottom bottom_block" style="padding-left:8px; text-align:right"> <span> - <a t-attf-href="#{record.website_url.raw_value}">Job Description</a> + <a t-attf-href="#{record.website_url.raw_value}">Website Description</a> </span> </div> </xpath> diff --git a/addons/website_hr_recruitment/views/hr_recruitment_views.xml b/addons/website_hr_recruitment/views/hr_recruitment_views.xml index bce275036bc..3c487f3c07a 100644 --- a/addons/website_hr_recruitment/views/hr_recruitment_views.xml +++ b/addons/website_hr_recruitment/views/hr_recruitment_views.xml @@ -47,15 +47,4 @@ </field> </record> - <record id="view_hr_applicant_form_inherit_website" model="ir.ui.view"> - <field name="name">hr.applicant.form</field> - <field name="model">hr.applicant</field> - <field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/> - <field name="arch" type="xml"> - <xpath expr="//field[@name='type_id']" position="after"> - <field name="residence_country"/> - </xpath> - </field> - </record> - </odoo> diff --git a/addons/website_hr_recruitment/views/website_hr_recruitment_templates.xml b/addons/website_hr_recruitment/views/website_hr_recruitment_templates.xml index 67a57615f42..3d339130bd7 100644 --- a/addons/website_hr_recruitment/views/website_hr_recruitment_templates.xml +++ b/addons/website_hr_recruitment/views/website_hr_recruitment_templates.xml @@ -144,14 +144,6 @@ <input type="text" class="form-control o_website_form_input" name="partner_phone" required=""/> </div> </div> - <div class="form-group row form-field o_website_form_required_custom"> - <div class="col-lg-3 col-md-4 text-right"> - <label class="col-form-label" for="residence_country">Your Residence Country</label> - </div> - <div class="col-lg-7 col-md-8"> - <input type="text" class="form-control o_website_form_input" name="residence_country" required=""/> - </div> - </div> <div class="form-group row form-field"> <div class="col-lg-3 col-md-4 text-right"> <label class="col-form-label" for="description">Short Introduction</label> |
