# Part of Odoo. See LICENSE file for full copyright and licensing details. import ast 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.company.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, domain="['|', ('company_id', '=', False), ('company_id', '=', company_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") all_application_count = fields.Integer(compute='_compute_all_application_count', string="All 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', "Recruiter", 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") alias_id = fields.Many2one( '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) app_to_job = dict((applicant.id, applicant.job_id.id) for applicant in applicants) attachments = self.env['ir.attachment'].search([ '|', '&', ('res_model', '=', 'hr.job'), ('res_id', 'in', self.ids), '&', ('res_model', '=', 'hr.applicant'), ('res_id', 'in', applicants.ids)]) result = dict.fromkeys(self.ids, self.env['ir.attachment']) for attachment in attachments: if attachment.res_model == 'hr.applicant': result[app_to_job[attachment.res_id]] |= attachment else: result[attachment.res_id] |= attachment for job in self: job.document_ids = result.get(job.id, False) job.documents_count = len(job.document_ids) def _compute_all_application_count(self): read_group_result = self.env['hr.applicant'].with_context(active_test=False).read_group([('job_id', 'in', self.ids)], ['job_id'], ['job_id']) result = dict((data['job_id'][0], data['job_id_count']) for data in read_group_result) for job in self: job.all_application_count = result.get(job.id, 0) def _compute_application_count(self): read_group_result = self.env['hr.applicant'].read_group([('job_id', 'in', self.ids)], ['job_id'], ['job_id']) result = dict((data['job_id'][0], data['job_id_count']) for data in read_group_result) 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_ids', '=', False), ('job_ids', '=', self.id)], order='sequence asc', limit=1) def _compute_new_application_count(self): for job in self: job.new_application_count = self.env["hr.applicant"].search_count( [("job_id", "=", job.id), ("stage_id", "=", job._get_first_stage().id)] ) def _alias_get_creation_values(self): values = super(Job, self)._alias_get_creation_values() values['alias_model_id'] = self.env['ir.model']._get('hr.applicant').id if self.id: values['alias_defaults'] = defaults = ast.literal_eval(self.alias_defaults or "{}") defaults.update({ 'job_id': self.id, 'department_id': self.department_id.id, 'company_id': self.department_id.company_id.id if self.department_id else self.company_id.id, }) return values @api.model def create(self, vals): vals['favorite_user_ids'] = vals.get('favorite_user_ids', []) + [(4, self.env.uid)] new_job = super(Job, self).create(vals) utm_linkedin = self.env.ref("utm.utm_source_linkedin", raise_if_not_found=False) if utm_linkedin: source_vals = { 'source_id': utm_linkedin.id, 'job_id': new_job.id, } self.env['hr.recruitment.source'].create(source_vals) return new_job def _creation_subtype(self): return self.env.ref('hr_recruitment.mt_job_new') def action_get_attachment_tree_view(self): action = self.env["ir.actions.actions"]._for_xml_id("base.action_attachment") action['context'] = { 'default_res_model': self._name, 'default_res_id': self.ids[0] } action['search_view_id'] = (self.env.ref('hr_recruitment.ir_attachment_view_search_inherit_hr_recruitment').id, ) action['domain'] = ['|', '&', ('res_model', '=', 'hr.job'), ('res_id', 'in', self.ids), '&', ('res_model', '=', 'hr.applicant'), ('res_id', 'in', self.mapped('application_ids').ids)] return action def close_dialog(self): return {'type': 'ir.actions.act_window_close'} def edit_dialog(self): form_view = self.env.ref('hr.view_hr_job_form') return { 'name': _('Job'), 'res_model': 'hr.job', 'res_id': self.id, 'views': [(form_view.id, 'form'),], 'type': 'ir.actions.act_window', 'target': 'inline' }