diff options
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/hr/views/hr_views.xml | 2 | ||||
| -rw-r--r-- | addons/hr_recruitment/models/hr_job.py | 45 | ||||
| -rw-r--r-- | addons/hr_recruitment/models/hr_recruitment.py | 6 | ||||
| -rw-r--r-- | addons/hr_recruitment/static/src/js/recruitment.js | 18 | ||||
| -rw-r--r-- | addons/hr_recruitment/views/hr_job_views.xml | 45 | ||||
| -rw-r--r-- | addons/hr_recruitment/views/hr_recruitment_templates.xml | 1 | ||||
| -rw-r--r-- | addons/hr_recruitment/views/hr_recruitment_views.xml | 23 | ||||
| -rw-r--r-- | addons/hr_recruitment_survey/views/hr_applicant_views.xml | 4 | ||||
| -rw-r--r-- | addons/hr_recruitment_survey/views/hr_job_views.xml | 1 | ||||
| -rw-r--r-- | addons/website_hr_recruitment/views/hr_job_views.xml | 2 |
10 files changed, 100 insertions, 47 deletions
diff --git a/addons/hr/views/hr_views.xml b/addons/hr/views/hr_views.xml index 9f71be2a9c4..8519fdd9020 100644 --- a/addons/hr/views/hr_views.xml +++ b/addons/hr/views/hr_views.xml @@ -506,7 +506,7 @@ <h1><field name="name" placeholder="e.g. Sales Manager"/></h1> </div> <group> - <group string="Recruitment" name="recruitment"> + <group name="recruitment"> <field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/> <field name="department_id"/> <field name="no_of_recruitment"/> diff --git a/addons/hr_recruitment/models/hr_job.py b/addons/hr_recruitment/models/hr_job.py index 9510a2f0660..4e710b73706 100644 --- a/addons/hr_recruitment/models/hr_job.py +++ b/addons/hr_recruitment/models/hr_job.py @@ -6,21 +6,29 @@ from odoo import api, fields, models, _ class Job(models.Model): _name = "hr.job" _inherit = ["mail.alias.mixin", "hr.job"] + _order = "state desc, name asc" @api.model def _default_address_id(self): return self.env.user.company_id.partner_id + def _get_default_favorite_user_ids(self): + return [(6, 0, [self.env.uid])] + address_id = fields.Many2one( 'res.partner', "Job Location", default=_default_address_id, help="Address where employees are working") application_ids = fields.One2many('hr.applicant', 'job_id', "Applications") application_count = fields.Integer(compute='_compute_application_count', string="Application Count") + new_application_count = fields.Integer( + compute='_compute_new_application_count', string="New Application", + help="Number of applications that are new in the flow (typically at first step of the flow)") manager_id = fields.Many2one( 'hr.employee', related='department_id.manager_id', string="Department Manager", readonly=True, store=True) - user_id = fields.Many2one('res.users', "Recruitment Responsible", tracking=True) - hr_responsible_id = fields.Many2one('res.users', "HR Responsible", tracking=True, + user_id = fields.Many2one('res.users', "Responsible", tracking=True) + hr_responsible_id = fields.Many2one( + 'res.users', "HR Responsible", tracking=True, help="Person responsible of validating the employee's contracts.") document_ids = fields.One2many('ir.attachment', compute='_compute_document_ids', string="Documents") documents_count = fields.Integer(compute='_compute_document_ids', string="Document Count") @@ -28,6 +36,22 @@ class Job(models.Model): 'mail.alias', "Alias", ondelete="restrict", required=True, help="Email alias for this job position. New emails will automatically create new applicants for this job position.") color = fields.Integer("Color Index") + is_favorite = fields.Boolean(compute='_compute_is_favorite', inverse='_inverse_is_favorite') + favorite_user_ids = fields.Many2many('res.users', 'job_favorite_user_rel', 'job_id', 'user_id', default=_get_default_favorite_user_ids) + + def _compute_is_favorite(self): + for job in self: + job.is_favorite = self.env.user in job.favorite_user_ids + + def _inverse_is_favorite(self): + unfavorited_jobs = favorited_jobs = self.env['hr.job'] + for job in self: + if self.env.user in job.favorite_user_ids: + unfavorited_jobs |= job + else: + favorited_jobs |= job + favorited_jobs.write({'favorite_user_ids': [(4, self.env.uid)]}) + unfavorited_jobs.write({'favorite_user_ids': [(3, self.env.uid)]}) def _compute_document_ids(self): applicants = self.mapped('application_ids').filtered(lambda self: not self.emp_id) @@ -54,6 +78,22 @@ class Job(models.Model): for job in self: job.application_count = result.get(job.id, 0) + def _get_first_stage(self): + self.ensure_one() + return self.env['hr.recruitment.stage'].search([ + '|', + ('job_id', '=', False), + ('job_id', '=', 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} + mapped_data = dict.fromkeys(self.ids, 0) + for applicant in self.mapped('application_ids'): + if applicant.stage_id.id == first_stages.get(applicant.job_id.id): + mapped_data[applicant.job_id.id] += 1 + for job in self: + job.new_application_count = mapped_data.get(job.id) + def get_alias_model_name(self, vals): return 'hr.applicant' @@ -68,6 +108,7 @@ class Job(models.Model): @api.model def create(self, vals): + vals['favorite_user_ids'] = vals.get('favorite_user_ids', []) + [(4, self.env.uid)] return super(Job, self.with_context(mail_create_nolog=True)).create(vals) @api.multi diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index 0e4b5fa400c..b1299e50299 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -96,14 +96,12 @@ class Applicant(models.Model): def _default_stage_id(self): if self._context.get('default_job_id'): - ids = self.env['hr.recruitment.stage'].search([ + return self.env['hr.recruitment.stage'].search([ '|', ('job_id', '=', False), ('job_id', '=', self._context['default_job_id']), ('fold', '=', False) - ], order='sequence asc', limit=1).ids - if ids: - return ids[0] + ], order='sequence asc', limit=1).id return False def _default_company_id(self): diff --git a/addons/hr_recruitment/static/src/js/recruitment.js b/addons/hr_recruitment/static/src/js/recruitment.js new file mode 100644 index 00000000000..e9758ddabf8 --- /dev/null +++ b/addons/hr_recruitment/static/src/js/recruitment.js @@ -0,0 +1,18 @@ +odoo.define('job.update_kanban', function (require) { + 'use strict'; + var KanbanRecord = require('web.KanbanRecord'); + + KanbanRecord.include({ + /** + * @override + * @private + */ + _openRecord: function () { + if (this.modelName === 'hr.job' && this.$(".o_hr_job_boxes a").length) { + this.$(".o_hr_job_boxes a").first().click(); + } else { + this._super.apply(this, arguments); + } + } + }); +}); diff --git a/addons/hr_recruitment/views/hr_job_views.xml b/addons/hr_recruitment/views/hr_job_views.xml index 945ea855bca..fff1cfe6d54 100644 --- a/addons/hr_recruitment/views/hr_job_views.xml +++ b/addons/hr_recruitment/views/hr_job_views.xml @@ -16,19 +16,22 @@ <field name="name"/> <field name="alias_name"/> <field name="alias_domain"/> + <field name="is_favorite"/> <field name="department_id"/> <field name="no_of_recruitment"/> <field name="color"/> + <field name="new_application_count"/> <field name="no_of_hired_employee"/> <field name="manager_id"/> <field name="state"/> <field name="user_id"/> <templates> <t t-name="kanban-box"> - <div t-attf-class="#{kanban_color(record.color.raw_value)}"> + <div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click"> <div t-attf-class="o_kanban_card_header"> <div class="o_kanban_card_header_title"> - <div class="o_primary"><t t-esc="record.name.value"/></div> + <div class="o_primary col-12"><t t-esc="record.name.value"/></div> + <field name="is_favorite" widget="boolean_favorite" nolabel="1"/> <div t-if="record.alias_name.value and record.alias_domain.value and record.state.raw_value == 'recruit'" class="o_secondary o_job_alias"> <small> <i class="fa fa-envelope-o" role="img" aria-label="Alias" title="Alias"></i> <field name="alias_id"/> </small> </div> @@ -39,24 +42,17 @@ </div> <div class="container o_kanban_card_content"> <t t-if="record.state.raw_value == 'recruit'"> - <div class="row"> - <div name="application_button" class="col-6 o_kanban_primary_left"> - <button class="btn btn-primary" name="%(action_hr_job_applications)d" type="action">Application(s)</button> - </div> + <div> + <field name="new_application_count"/> New Applications <br/> + <field name="no_of_hired_employee"/> Hired Employees </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-book' role="img" aria-label="Documents"/> + <span title='Documents'><i class='fa fa-paperclip' role="img" aria-label="Documents"/> </span> </a> </div> - <div class="o_recruitment_kanban_box o_kanban_primary_bottom bottom_block"> - <span> - <field name="no_of_hired_employee"/> - Hired Employees - </span> - </div> </div> </t> <t t-if="record.state.raw_value == 'open'"> @@ -66,18 +62,19 @@ </div> </div> </t> - </div><div class="container o_kanban_card_manage_pane dropdown-menu" role="menu"> - <div t-if="widget.editable" class="o_kanban_card_manage_settings row"> - <div class="col-8" role="menuitem" aria-haspopup="true"> - <ul class="oe_kanban_colorpicker" data-field="color" role="menu"/> - </div> - <div class="col-4"> - <a role="menuitem" t-if="record.state.raw_value == 'recruit'" name="set_open" type="object">Recruitment Done</a> - <a role="menuitem" t-if="record.state.raw_value == 'open'" name="set_recruit" type="object">Start recruitment</a> - <br role="separator"/> - <a role="menuitem" name="edit_job" type="edit">Edit</a> - </div> + </div> + <div class="o_kanban_card_manage_pane dropdown-menu" role="menu"> + <div class="o_kanban_card_manage_section"> + <div role="menuitem"><a t-if="record.state.raw_value == 'recruit'" name="set_open" type="object">Recruitment Done</a></div> + <div role="menuitem"><a t-if="record.state.raw_value == 'open'" name="set_recruit" type="object">Start recruitment</a></div> + <div role="menuitem"><a t-if="widget.editable" name="edit_job" type="edit">Edit</a></div> </div> + <div role="menuitem" aria-haspopup="true"> + <ul class="oe_kanban_colorpicker" data-field="color" role="menu"/> + </div> + </div> + <div class="o_hr_job_boxes"> + <a class="o_hr_job_box" name="%(action_hr_job_applications)d" type="action"/> </div> </div> </t> diff --git a/addons/hr_recruitment/views/hr_recruitment_templates.xml b/addons/hr_recruitment/views/hr_recruitment_templates.xml index ac00cd7c2ec..dd5e72ee93f 100644 --- a/addons/hr_recruitment/views/hr_recruitment_templates.xml +++ b/addons/hr_recruitment/views/hr_recruitment_templates.xml @@ -4,6 +4,7 @@ <template id="assets_backend" name="hr_recruitment assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> <link rel="stylesheet" type="text/scss" href="/hr_recruitment/static/src/scss/hr_job.scss"/> + <script type="text/javascript" src="/hr_recruitment/static/src/js/recruitment.js"></script> <script type="text/javascript" src="/hr_recruitment/static/src/js/tour.js"></script> </xpath> </template> diff --git a/addons/hr_recruitment/views/hr_recruitment_views.xml b/addons/hr_recruitment/views/hr_recruitment_views.xml index dd11f066c78..b298ebc7bb1 100644 --- a/addons/hr_recruitment/views/hr_recruitment_views.xml +++ b/addons/hr_recruitment/views/hr_recruitment_views.xml @@ -62,7 +62,7 @@ </field> </record> - <record model="ir.ui.view" id="crm_case_form_view_job"> + <record model="ir.ui.view" id="hr_applicant_view_form"> <field name="name">Jobs - Recruitment Form</field> <field name="model">hr.applicant</field> <field name="arch" type="xml"> @@ -202,7 +202,8 @@ <field name="model">hr.applicant</field> <field name="arch" type="xml"> <search string="Search Applicants"> - <field name="partner_name" filter_domain="['|','|',('name','ilike',self),('partner_name','ilike',self),('email_from','ilike',self)]" string="Subject / Applicant"/> + <field name="partner_name" filter_domain="['|', ('name', 'ilike', self), ('partner_name', 'ilike', self)]" string="Subject / Applicant"/> + <field name="email_from" filter_domain="[('email_from', 'ilike', self)]" string="Email"/> <filter string="My Applications" name="my_applications" domain="[('user_id', '=', uid)]"/> <filter string="Unassigned" name="unassigned" domain="[('user_id', '=', False)]"/> <filter string="Unread Messages" name="message_needaction" domain="[('message_needaction','=',True)]"/> @@ -296,13 +297,13 @@ <t t-name="kanban-box"> <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click oe_applicant_kanban oe_semantic_html_override"> <div class="o_dropdown_kanban dropdown"> - <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> <span class="fa fa-ellipsis-v"/> </a> <div class="dropdown-menu" role="menu"> <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> <a role="menuitem" name="action_makeMeeting" type="object" class="dropdown-item">Schedule Interview</a> + <div role="separator" class="dropdown-divider"></div> <ul class="oe_kanban_colorpicker" data-field="color"/> </div> </div> @@ -335,7 +336,7 @@ </div> <div class="oe_kanban_bottom_right"> <a name="action_get_attachment_tree_view" type="object"> - <span title='Documents'><i class='fa fa-book' role="img" aria-label="Documents"/> + <span title='Documents'><i class='fa fa-paperclip' role="img" aria-label="Documents"/> <t t-esc="record.attachment_number.raw_value"/> </span> </a> @@ -403,6 +404,9 @@ <separator/> <filter string="Unread Messages" name="message_needaction" domain="[('message_needaction','=',True)]"/> </field> + <xpath expr="//filter[@name='in_position']" position="before"> + <filter string="My Favorites" name="my_favorite_jobs" domain="[('favorite_user_ids', 'in', uid)]"/> + </xpath> </field> </record> @@ -466,7 +470,7 @@ <field name="arch" type="xml"> <xpath expr="//field[@name='department_id']" position="after"> <field name="address_id" context="{'show_address': 1}" domain= "[('is_company', '=', True )]" options="{'always_reload': True}"/> - <label for="alias_name" string="Email alias" attrs="{'invisible': [('alias_domain', '=', False)]}" help="Define a specific contact address for this job position. If you keep it empty, the default email address will be used which is in human resources settings"/> + <label for="alias_name" string="Email Alias" attrs="{'invisible': [('alias_domain', '=', False)]}" help="Define a specific contact address for this job position. If you keep it empty, the default email address will be used which is in human resources settings"/> <div name="alias_def" attrs="{'invisible': [('alias_domain', '=', False)]}"> <field name="alias_id" class="oe_read_only" string="Email Alias" required="0"/> <div class="oe_edit_only" name="edit_alias"> @@ -475,11 +479,6 @@ </div> <field name="user_id"/> </xpath> - <xpath expr="//group[@name='recruitment']" position="after"> - <group string="Offer" name="offer"> - <field name="hr_responsible_id"/> - </group> - </xpath> <div name="button_box" position="inside"> <button class="oe_stat_button" icon="fa-file-o" @@ -495,7 +494,7 @@ <field name="no_of_employee" widget="statinfo" string="Employees"/> </button> <button class="oe_stat_button" - icon="fa-book" + icon="fa-paperclip" name="action_get_attachment_tree_view" type="object"> <field name="documents_count" widget="statinfo" string="Documents"/> @@ -570,7 +569,7 @@ <record model="ir.actions.act_window.view" id="action_hr_sec_form_view_act_job"> <field name="sequence" eval="2"/> <field name="view_mode">form</field> - <field name="view_id" ref="crm_case_form_view_job"/> + <field name="view_id" ref="hr_applicant_view_form"/> <field name="act_window_id" ref="crm_case_categ0_act_job"/> </record> diff --git a/addons/hr_recruitment_survey/views/hr_applicant_views.xml b/addons/hr_recruitment_survey/views/hr_applicant_views.xml index b1c7c09dedb..66dc2a8c268 100644 --- a/addons/hr_recruitment_survey/views/hr_applicant_views.xml +++ b/addons/hr_recruitment_survey/views/hr_applicant_views.xml @@ -12,10 +12,10 @@ </field> </record> - <record id="crm_case_form_view_job_inherit" model="ir.ui.view"> + <record id="hr_applicant_view_form_inherit" model="ir.ui.view"> <field name="name">hr.applicant.form.inherit</field> <field name="model">hr.applicant</field> - <field name="inherit_id" ref="hr_recruitment.crm_case_form_view_job"/> + <field name="inherit_id" ref="hr_recruitment.hr_applicant_view_form"/> <field name="arch" type="xml"> <xpath expr="//button[@name='action_makeMeeting']" position="after"> <button name="action_start_survey" diff --git a/addons/hr_recruitment_survey/views/hr_job_views.xml b/addons/hr_recruitment_survey/views/hr_job_views.xml index 7223f1c6834..6f4795f08ec 100644 --- a/addons/hr_recruitment_survey/views/hr_job_views.xml +++ b/addons/hr_recruitment_survey/views/hr_job_views.xml @@ -24,7 +24,6 @@ <field name="survey_id"/> </xpath> <xpath expr='//a[@name="edit_job"]' position="after"> - <br/> <a t-if="record.survey_id.raw_value" name="action_print_survey" type="object" title="Display Interview Form">Interview Form</a> <span t-if="!record.survey_id.raw_value">No Interview Form</span> </xpath> diff --git a/addons/website_hr_recruitment/views/hr_job_views.xml b/addons/website_hr_recruitment/views/hr_job_views.xml index 951203e37ab..610c6f30d8b 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}">Website Editor</a> + <a t-attf-href="#{record.website_url.raw_value}">Job Description</a> </span> </div> </xpath> |
