diff --git a/addons_extensions/hr_recruitment_extended/__manifest__.py b/addons_extensions/hr_recruitment_extended/__manifest__.py index 81c64b8df..d2fd3e4dd 100644 --- a/addons_extensions/hr_recruitment_extended/__manifest__.py +++ b/addons_extensions/hr_recruitment_extended/__manifest__.py @@ -27,6 +27,7 @@ 'data/cron.xml', 'data/sequence.xml', 'data/mail_template.xml', + 'views/job_category.xml', 'views/hr_location.xml', 'views/stages.xml', 'views/hr_applicant_views.xml', diff --git a/addons_extensions/hr_recruitment_extended/data/mail_template.xml b/addons_extensions/hr_recruitment_extended/data/mail_template.xml index c81523a74..3597e9271 100644 --- a/addons_extensions/hr_recruitment_extended/data/mail_template.xml +++ b/addons_extensions/hr_recruitment_extended/data/mail_template.xml @@ -4,7 +4,7 @@ Recruitment Deadline Alert - {{ object.company_id.email or user.email_formatted }} + {{ object.company.email or user.email_formatted }} {{ object.user_id.email }} Reminder: Recruitment Process Ending Soon - {{ object.job_id.name }} diff --git a/addons_extensions/hr_recruitment_extended/models/hr_applicant.py b/addons_extensions/hr_recruitment_extended/models/hr_applicant.py index 003dd9c40..ddb441afe 100644 --- a/addons_extensions/hr_recruitment_extended/models/hr_applicant.py +++ b/addons_extensions/hr_recruitment_extended/models/hr_applicant.py @@ -5,6 +5,7 @@ from dateutil.relativedelta import relativedelta from datetime import datetime from odoo.exceptions import ValidationError +import warnings class HRApplicant(models.Model): @@ -122,7 +123,11 @@ class HRApplicant(models.Model): for rec in self: submitted_count = len(self.sudo().search([('id','!=',rec.id),('submitted_to_client','=',True)]).ids) if submitted_count >= rec.hr_job_recruitment.no_of_eligible_submissions: - raise ValidationError(_("Max no of submissions for this JD has been reached")) + warnings.warn( + "Max no of submissions for this JD has been reached", + DeprecationWarning, + stacklevel=2, + ) rec.submitted_to_client = True rec.client_submission_date = fields.Datetime.now() diff --git a/addons_extensions/hr_recruitment_extended/models/hr_job.py b/addons_extensions/hr_recruitment_extended/models/hr_job.py index 56f7f4519..a8fb43dc4 100644 --- a/addons_extensions/hr_recruitment_extended/models/hr_job.py +++ b/addons_extensions/hr_recruitment_extended/models/hr_job.py @@ -8,6 +8,9 @@ class HRJob(models.Model): help='Number of new employees you expect to recruit.', default=1, compute="_compute_no_of_recruitment") hr_job_recruitments = fields.One2many('hr.job.recruitment', 'job_id', string='Recruitments') + job_category = fields.Many2one("job.category", string="Category") + company_id = fields.Many2one( exportable=False) + alias_id = fields.Many2one(exportable=False) @api.depends('hr_job_recruitments') def _compute_no_of_recruitment(self): diff --git a/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py b/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py index 72ad8c302..82be22788 100644 --- a/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py +++ b/addons_extensions/hr_recruitment_extended/models/hr_job_recruitment.py @@ -98,13 +98,6 @@ class HRJobRecruitment(models.Model): else: return self.env.company.partner_id - - @api.onchange('job_id') - def onchange_job_id(self): - for rec in self: - if rec.job_id and not rec.description: - rec.description = rec.job_id.description - job_id = fields.Many2one('hr.job', required=True) name = fields.Char(string='Job Position', required=True, index='trigram', translate=True, related='job_id.name') @@ -115,7 +108,7 @@ class HRJobRecruitment(models.Model): secondary_skill_ids = fields.Many2many('hr.skill', "hr_job_recruitment_hr_skill_rel", 'job_recruitment_id', 'hr_skill_id', "Secondary Skills") - no_of_recruitment = fields.Integer(string='Target', copy=False, + no_of_recruitment = fields.Integer(string='Number of Positions', copy=False, help='Number of new employees you expect to recruit.', default=1) @@ -143,7 +136,7 @@ class HRJobRecruitment(models.Model): help='Expected number of employees for this job position after new recruitment.') no_of_employee = fields.Integer(compute='_compute_employees', string="Current Number of Employees", store=True, help='Number of employees currently occupying this job position.') - company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company) + company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company, exportable=False) contract_type_id = fields.Many2one('hr.contract.type', string='Employment Type') # active = fields.Boolean(default=True) user_id = fields.Many2one('res.users', "Recruiter", @@ -156,7 +149,7 @@ class HRJobRecruitment(models.Model): address_id = fields.Many2one( 'res.partner', "Job Location", default=_default_address_id, domain="[('is_company','=',True),('contact_type','=',recruitment_type)]", - help="Select the location where the applicant will work. Addresses listed here are defined on the company's contact information.") + help="Select the location where the applicant will work. Addresses listed here are defined on the company's contact information.", exportable=False) recruitment_type = fields.Selection([('internal','Internal'),('external','External')], required=True, default='internal') requested_by = fields.Many2one('res.partner', string="Requested By", default=lambda self: self.env.user.partner_id, domain="[('contact_type','=',recruitment_type)]") @@ -204,6 +197,23 @@ class HRJobRecruitment(models.Model): experience = fields.Many2one('candidate.experience', string="Experience") + budget = fields.Char(string='Budget') + + job_category = fields.Many2one("job.category", string="Category") + + + + @api.onchange('job_id','job_category') + def onchange_job_id(self): + for rec in self: + if rec.job_id and not rec.description: + rec.description = rec.job_id.description + if rec.job_id and rec.job_id.job_category: + rec.job_category = rec.job_id.job_category.id + if rec.job_category and rec.job_category.default_user: + rec.user_id = rec.job_category.default_user.id + + @api.depends('application_ids.submitted_to_client') def _compute_no_of_submissions(self): counts = dict(self.env['hr.applicant']._read_group( diff --git a/addons_extensions/hr_recruitment_extended/models/hr_recruitment.py b/addons_extensions/hr_recruitment_extended/models/hr_recruitment.py index f705668f7..2b17e6964 100644 --- a/addons_extensions/hr_recruitment_extended/models/hr_recruitment.py +++ b/addons_extensions/hr_recruitment_extended/models/hr_recruitment.py @@ -415,3 +415,11 @@ class Location(models.Model): # else: # rec.hired = False # + + +class RecruitmentCategory(models.Model): + _name = 'job.category' + _rec_name = "category_name" + + category_name = fields.Char(string="Category Name") + default_user = fields.Many2one('res.users') \ No newline at end of file diff --git a/addons_extensions/hr_recruitment_extended/security/ir.model.access.csv b/addons_extensions/hr_recruitment_extended/security/ir.model.access.csv index c3538e010..2886c3c93 100644 --- a/addons_extensions/hr_recruitment_extended/security/ir.model.access.csv +++ b/addons_extensions/hr_recruitment_extended/security/ir.model.access.csv @@ -1,11 +1,22 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_hr_location,hr.location,model_hr_location,base.group_user,1,1,1,1 -access_hr_job_recruitment_user,access.hr.job.recruitment.user,model_hr_job_recruitment,base.group_user,1,1,1,1 -access_candidate_experience,access.candidate.experience.user,model_candidate_experience,base.group_user,1,1,1,1 +access_job_category_user,job.category.user,model_job_category,base.group_user,1,0,0,0 +access_job_category_manager,job.category.manager,model_job_category,hr_recruitment.group_hr_recruitment_user,1,1,1,1 + + +access_hr_job_recruitment_user,access.hr.job.recruitment.user,model_hr_job_recruitment,base.group_user,1,1,0,0 +access_hr_job_recruitment_manager,access.hr.job.recruitment.manager,model_hr_job_recruitment,hr_recruitment.group_hr_recruitment_user,1,1,1,1 + +hr_recruitment.access_hr_candidate_interviewer,hr.candidate.interviewer,hr_recruitment.model_hr_candidate,hr_recruitment.group_hr_recruitment_interviewer,1,1,1,0 + +access_candidate_experience,access.candidate.experience.manager,model_candidate_experience,hr_recruitment.group_hr_recruitment_user,1,1,1,1 +access_candidate_experience_user,access.candidate.experience.user,model_candidate_experience,base.group_user,1,0,0,0 + access_recruitment_attachments_user,access.recruitment.attachments.user,model_recruitment_attachments,base.group_user,1,1,1,1 access_post_onboarding_attachment_wizard,access.post.onboarding.attachment.wizard,model_post_onboarding_attachment_wizard,base.group_user,1,1,1,1 -access_employee_recruitment_attachments,employee.recruitment.attachments,model_employee_recruitment_attachments,base.group_user,1,1,1,1 \ No newline at end of file +access_employee_recruitment_attachments,employee.recruitment.attachments,model_employee_recruitment_attachments,base.group_user,1,1,1,1 + diff --git a/addons_extensions/hr_recruitment_extended/security/security.xml b/addons_extensions/hr_recruitment_extended/security/security.xml index b731492aa..1b65b06c9 100644 --- a/addons_extensions/hr_recruitment_extended/security/security.xml +++ b/addons_extensions/hr_recruitment_extended/security/security.xml @@ -22,6 +22,7 @@ Applicant Skill: Interviewer + [ '|', ('candidate_id.applicant_ids.hr_job_recruitment.interviewer_ids', 'in', user.id), @@ -78,18 +79,36 @@ - Applicant Interviewer + Edit/Create Own Applicants [ '|', ('hr_job_recruitment.interviewer_ids', 'in', user.id), ('interviewer_ids', 'in', user.id), ] - + + + + + Read all Applicants + + [ + '|', + ('hr_job_recruitment.interviewer_ids', 'not in', user.id), + ('interviewer_ids', 'not in', user.id), + ] + + + + + + + + Candidate Interviewer @@ -98,8 +117,76 @@ ('applicant_ids.hr_job_recruitment.interviewer_ids', 'in', user.id), ('applicant_ids.interviewer_ids', 'in', user.id), ] - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml b/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml index 688638feb..2e07c1b04 100644 --- a/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml +++ b/addons_extensions/hr_recruitment_extended/views/candidate_experience.xml @@ -35,6 +35,6 @@ name="Experience" parent="hr_recruitment.menu_hr_recruitment_config_applications" action="action_candidate_experience" - groups="base.group_no_one" + groups="hr_recruitment.group_hr_recruitment_user" sequence="30"/> diff --git a/addons_extensions/hr_recruitment_extended/views/hr_applicant_views.xml b/addons_extensions/hr_recruitment_extended/views/hr_applicant_views.xml index 5c061f01a..90227e3c6 100644 --- a/addons_extensions/hr_recruitment_extended/views/hr_applicant_views.xml +++ b/addons_extensions/hr_recruitment_extended/views/hr_applicant_views.xml @@ -7,9 +7,14 @@ - +

+
+ Budget : +
@@ -344,7 +354,7 @@ hr.job.recruitment kanban,list,form,search - {"search_default_Current":1} + {"search_default_Current":1,"search_default_my_assignments":1}

Ready to recruit more efficiently? @@ -365,5 +375,23 @@ action="action_hr_job_recruitment" sequence="1" groups="base.group_user"/> + + + + + + + + + + + + diff --git a/addons_extensions/hr_recruitment_extended/views/hr_recruitment.xml b/addons_extensions/hr_recruitment_extended/views/hr_recruitment.xml index 214b9acdc..9080a26a6 100644 --- a/addons_extensions/hr_recruitment_extended/views/hr_recruitment.xml +++ b/addons_extensions/hr_recruitment_extended/views/hr_recruitment.xml @@ -115,6 +115,12 @@ hr.job + + + + + + @@ -312,7 +318,13 @@ action="hr_recruitment_extended.action_server"/> --> - + + {'search_default_my_candidates': 1} + + + + + + + + + diff --git a/addons_extensions/hr_recruitment_extended/views/job_category.xml b/addons_extensions/hr_recruitment_extended/views/job_category.xml new file mode 100644 index 000000000..e2a77c03c --- /dev/null +++ b/addons_extensions/hr_recruitment_extended/views/job_category.xml @@ -0,0 +1,38 @@ + + + + + + job.category.list + job.category + + + + + + + + + + + Categories + job.category + list + +

+ Create a new Job Category +

+
+ + + + + + + + diff --git a/addons_extensions/website_hr_recruitment_extended/models/hr_recruitment_source.py b/addons_extensions/website_hr_recruitment_extended/models/hr_recruitment_source.py index 1b0e00a5c..510d749b1 100644 --- a/addons_extensions/website_hr_recruitment_extended/models/hr_recruitment_source.py +++ b/addons_extensions/website_hr_recruitment_extended/models/hr_recruitment_source.py @@ -11,7 +11,7 @@ class RecruitmentSource(models.Model): url = fields.Char(compute='_compute_url', string='Tracker URL') - @api.depends('source_id', 'source_id.name', 'job_id', 'job_id.company_id') + @api.depends('source_id', 'source_id.name', 'job_recruitment_id', 'job_recruitment_id.company_id') def _compute_url(self): for source in self: source.url = urls.url_join(source.job_recruitment_id.get_base_url(), "%s?%s" % (