Merge pull request 'Recruimtent changes & Vendor update' (#30) from feature/share_module into srivyn_test
Reviewed-on: https://gitea.ftprotech.in/administrator/odoo18/pulls/30
This commit is contained in:
commit
bc925cac3b
|
|
@ -1906,8 +1906,9 @@ class HrRecruitmentAutoDocWizard(models.TransientModel):
|
||||||
"target_to": self._parse_date_value(parsed_data.get("end_date")),
|
"target_to": self._parse_date_value(parsed_data.get("end_date")),
|
||||||
"job_category": int(job_category_id) if job_category_id and job_category_id.isdigit() else False,
|
"job_category": int(job_category_id) if job_category_id and job_category_id.isdigit() else False,
|
||||||
"address_id":False,
|
"address_id":False,
|
||||||
"recruitment_type": 'external'
|
"recruitment_type": 'external',
|
||||||
|
"requested_by": parsed_data.get("requested_by") or False,
|
||||||
|
"no_of_recruitment": parsed_data.get("no_of_positions") or 1,
|
||||||
}
|
}
|
||||||
if request_id:
|
if request_id:
|
||||||
create_vals["recruitment_sequence"] = request_id
|
create_vals["recruitment_sequence"] = request_id
|
||||||
|
|
@ -2207,6 +2208,8 @@ class HrRecruitmentAutoDocWizardLine(models.TransientModel):
|
||||||
budget = fields.Char()
|
budget = fields.Char()
|
||||||
experience_years = fields.Float()
|
experience_years = fields.Float()
|
||||||
job_category = fields.Char()
|
job_category = fields.Char()
|
||||||
|
requested_by = fields.Many2one('res.partner',domain="[('contact_type', '=', 'external')]")
|
||||||
|
no_of_positions = fields.Integer('Number of Positions')
|
||||||
|
|
||||||
def action_save_line_changes(self):
|
def action_save_line_changes(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
|
@ -2286,6 +2289,8 @@ class HrRecruitmentAutoDocWizardLine(models.TransientModel):
|
||||||
"budget": self.budget,
|
"budget": self.budget,
|
||||||
"experience_years": self.experience_years,
|
"experience_years": self.experience_years,
|
||||||
"job_category": self.job_category,
|
"job_category": self.job_category,
|
||||||
|
"requested_by": self.requested_by.id if self.requested_by else False,
|
||||||
|
"no_of_positions": self.no_of_positions if self.no_of_positions else 1,
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
data.update({
|
data.update({
|
||||||
|
|
|
||||||
|
|
@ -160,15 +160,21 @@
|
||||||
<field name="end_date"/>
|
<field name="end_date"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
|
<field name="requested_by"/>
|
||||||
|
<field name="no_of_positions"/>
|
||||||
<field name="budget"/>
|
<field name="budget"/>
|
||||||
<field name="experience_years"/>
|
<field name="experience_years"/>
|
||||||
<field name="job_category"/>
|
<field name="job_category"/>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
<group>
|
||||||
<group>
|
<group>
|
||||||
<field name="job_summary" nolabel="1" placeholder="Job Summary"/>
|
<field name="job_summary" nolabel="1" placeholder="Job Summary"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
<field name="requirements" nolabel="1" placeholder="Requirements"/>
|
<field name="requirements" nolabel="1" placeholder="Requirements"/>
|
||||||
</group>
|
</group>
|
||||||
|
</group>
|
||||||
</page>
|
</page>
|
||||||
<page string="Skills">
|
<page string="Skills">
|
||||||
<group>
|
<group>
|
||||||
|
|
|
||||||
|
|
@ -389,8 +389,7 @@ class HRApplicant(models.Model):
|
||||||
render_ctx = dict(recruitment_manager=manager_id)
|
render_ctx = dict(recruitment_manager=manager_id)
|
||||||
mail_template.with_context(render_ctx).send_mail(
|
mail_template.with_context(render_ctx).send_mail(
|
||||||
self.id,
|
self.id,
|
||||||
force_send=True,
|
force_send=True)
|
||||||
email_layout_xmlid='mail.mail_notification_light')
|
|
||||||
rec.application_submitted = True
|
rec.application_submitted = True
|
||||||
|
|
||||||
def approve_applicant(self):
|
def approve_applicant(self):
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,45 @@ class ResPartner(models.Model):
|
||||||
|
|
||||||
contact_type = fields.Selection([('internal','In-House'),('external','Client-Side')], required=True, default='internal')
|
contact_type = fields.Selection([('internal','In-House'),('external','Client-Side')], required=True, default='internal')
|
||||||
company_id = fields.Many2one('res.company', default=lambda self: self.env.user.company_id)
|
company_id = fields.Many2one('res.company', default=lambda self: self.env.user.company_id)
|
||||||
|
|
||||||
|
# Vendor Statistics Fields
|
||||||
|
total_positions_requested = fields.Integer(compute='_compute_vendor_statistics', string='Positions Requested')
|
||||||
|
total_submitted = fields.Integer(compute='_compute_vendor_statistics', string='Total Submitted')
|
||||||
|
total_hired = fields.Integer(compute='_compute_vendor_statistics', string='Total Hired')
|
||||||
|
total_rejected = fields.Integer(compute='_compute_vendor_statistics', string='Total Rejected')
|
||||||
|
job_recruitment_ids = fields.One2many('hr.job.recruitment', 'requested_by', string='Job Requests')
|
||||||
|
|
||||||
|
@api.depends('contact_type')
|
||||||
|
def _compute_vendor_statistics(self):
|
||||||
|
for partner in self:
|
||||||
|
if partner.contact_type == 'external':
|
||||||
|
# Get all job recruitments requested by this vendor
|
||||||
|
job_recruitments = self.env['hr.job.recruitment'].search([
|
||||||
|
('requested_by', '=', partner.id)
|
||||||
|
])
|
||||||
|
|
||||||
|
partner.total_positions_requested = sum(job_recruitments.mapped('no_of_recruitment'))
|
||||||
|
partner.total_submitted = sum(job_recruitments.mapped('no_of_submissions'))
|
||||||
|
partner.total_hired = sum(job_recruitments.mapped('no_of_hired_employee'))
|
||||||
|
partner.total_rejected = sum(job_recruitments.mapped('no_of_refused_submissions'))
|
||||||
|
else:
|
||||||
|
partner.total_positions_requested = 0
|
||||||
|
partner.total_submitted = 0
|
||||||
|
partner.total_hired = 0
|
||||||
|
partner.total_rejected = 0
|
||||||
|
|
||||||
|
def action_create_job_request(self):
|
||||||
|
"""Action to create a new job request from vendor"""
|
||||||
|
self.ensure_one()
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'name': _('Create Job Request'),
|
||||||
|
'res_model': 'hr.job.recruitment',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'current',
|
||||||
|
'context': {
|
||||||
|
'default_requested_by': self.id,
|
||||||
|
'default_recruitment_type': 'external',
|
||||||
|
'default_address_id': self.id if self.is_company else (self.parent_id.id if self.parent_id else False),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -218,6 +218,17 @@
|
||||||
<xpath expr="//filter[@name='refused']" position="attributes">
|
<xpath expr="//filter[@name='refused']" position="attributes">
|
||||||
<attribute name="string">Rejected</attribute>
|
<attribute name="string">Rejected</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//group" position="before">
|
||||||
|
<searchtab name="inprogress_records_tab" string="In Progress">
|
||||||
|
<filter string="In Progress" name="ongoing" domain="[('date_closed', '=', False), ('active', '=', True), ('refuse_reason_id', '=', False)]"/>
|
||||||
|
</searchtab>
|
||||||
|
<searchtab name="hired_records_tab" string="Hired">
|
||||||
|
<filter string="Hired" name="hired" domain="[('date_closed', '!=', False)]"/>
|
||||||
|
</searchtab>
|
||||||
|
<searchtab name="refused_records_tab" string="Refused">
|
||||||
|
<filter string="Refused" name="refused" domain="[('active', '=', False), ('refuse_reason_id', '!=', False)]"/>
|
||||||
|
</searchtab>
|
||||||
|
</xpath>
|
||||||
<xpath expr="//filter[@name='refuse_reason_id']" position="attributes">
|
<xpath expr="//filter[@name='refuse_reason_id']" position="attributes">
|
||||||
<attribute name="string">Reject Reason</attribute>
|
<attribute name="string">Reject Reason</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,20 @@
|
||||||
<filter string="Unpublished" name="unpublished_records_tab_filter"
|
<filter string="Unpublished" name="unpublished_records_tab_filter"
|
||||||
domain="[('website_published','=',False)]"/>
|
domain="[('website_published','=',False)]"/>
|
||||||
</searchtab>
|
</searchtab>
|
||||||
|
<searchtab name="open_records_tab" string="Open">
|
||||||
|
<filter name="open_status" string="Open"
|
||||||
|
domain="[('recruitment_status','=', 'open')]"/>
|
||||||
|
</searchtab>
|
||||||
|
<searchtab name="closed_records_tab" string="Closed">
|
||||||
|
<filter name="closed_status" string="Closed"
|
||||||
|
domain="[('recruitment_status','=', 'closed')]"/>
|
||||||
|
</searchtab>
|
||||||
|
<searchtab name="hold_records_tab" string="Hold">
|
||||||
|
<filter name="hold_status" string="Hold"
|
||||||
|
domain="[('recruitment_status','=', 'hold')]"/>
|
||||||
|
</searchtab>
|
||||||
|
|
||||||
|
|
||||||
<filter string="Published Records" name="published_records" domain="[('website_published','=',True)]"/>
|
<filter string="Published Records" name="published_records" domain="[('website_published','=',True)]"/>
|
||||||
<filter string="UnPublished Records" name="unpublished_records" domain="[('website_published','=',False)]"/>
|
<filter string="UnPublished Records" name="unpublished_records" domain="[('website_published','=',False)]"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,19 @@
|
||||||
<field name="model">hr.candidate</field>
|
<field name="model">hr.candidate</field>
|
||||||
<field name="inherit_id" ref="hr_recruitment.hr_candidate_view_search"/>
|
<field name="inherit_id" ref="hr_recruitment.hr_candidate_view_search"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//group" position="before">
|
||||||
|
<searchtab name="inprogress_records_tab" string="Application In Progress">
|
||||||
|
<filter string="Application in Progress" name="application_in_progress" domain="[('applicant_ids.application_status', '=', 'ongoing')]"/>
|
||||||
|
</searchtab>
|
||||||
|
<searchtab name="hired_records_tab" string="Hired">
|
||||||
|
<filter string="Hired" name="hired" domain="[('applicant_ids.application_status', '=', 'hired')]"/>
|
||||||
|
</searchtab>
|
||||||
|
|
||||||
|
<searchtab name="refused_records_tab" string="Refused">
|
||||||
|
<filter string="Refused" name="refused" context="{'active_test': False}" domain="[('applicant_ids.application_status', '=', 'refused')]"/>
|
||||||
|
</searchtab>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="//field[@name='partner_name']" position="after">
|
<xpath expr="//field[@name='partner_name']" position="after">
|
||||||
<field name="candidate_sequence"/>
|
<field name="candidate_sequence"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,58 @@
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
|
<div class="row" invisible="contact_type != 'external'">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card bg-secondary">
|
||||||
|
<div class="card-header bg-primary text-white" style="color: white;">
|
||||||
|
<h5 class="mb-0" style="color: white;"><i class="fa fa-chart-bar me-2"/>Recruitment Statistics</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" style="background-color: #f8f9fa;">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-center p-3">
|
||||||
|
<div class="text-muted small">Positions Requested</div>
|
||||||
|
<div class="display-4 fw-bold text-primary">
|
||||||
|
<field name="total_positions_requested"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-center p-3">
|
||||||
|
<div class="text-muted small">Total Submitted</div>
|
||||||
|
<div class="display-4 fw-bold text-success">
|
||||||
|
<field name="total_submitted"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-center p-3">
|
||||||
|
<div class="text-muted small">Total Hired</div>
|
||||||
|
<div class="display-4 fw-bold text-info">
|
||||||
|
<field name="total_hired"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="text-center p-3">
|
||||||
|
<div class="text-muted small">Total Rejected</div>
|
||||||
|
<div class="display-4 fw-bold text-danger">
|
||||||
|
<field name="total_rejected"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="oe_button_box" invisible="contact_type != 'external'">
|
||||||
|
<button name="action_create_job_request" type="object" class="btn btn-primary">
|
||||||
|
<i class="fa fa-plus me-1"/>Create Job Request
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<notebook>
|
<notebook>
|
||||||
|
|
||||||
<page string="Contacts & Addresses">
|
<page string="Contacts & Addresses">
|
||||||
|
|
@ -137,6 +189,22 @@
|
||||||
|
|
||||||
</page>
|
</page>
|
||||||
|
|
||||||
|
<page string="Job Requests" invisible="contact_type != 'external'">
|
||||||
|
<field name="id" invisible="1"/>
|
||||||
|
<field name="contact_type" invisible="1"/>
|
||||||
|
<field name="job_recruitment_ids" widget="many2many">
|
||||||
|
<list>
|
||||||
|
<field name="recruitment_sequence"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="no_of_recruitment"/>
|
||||||
|
<field name="no_of_submissions"/>
|
||||||
|
<field name="no_of_hired_employee"/>
|
||||||
|
<field name="no_of_refused_submissions"/>
|
||||||
|
<field name="recruitment_status"/>
|
||||||
|
</list>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
|
||||||
</notebook>
|
</notebook>
|
||||||
|
|
||||||
</sheet>
|
</sheet>
|
||||||
|
|
@ -182,43 +250,88 @@
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="phone"/>
|
<field name="phone"/>
|
||||||
<field name="email"/>
|
<field name="email"/>
|
||||||
|
<field name="total_positions_requested"/>
|
||||||
|
<field name="total_submitted"/>
|
||||||
|
<field name="total_hired"/>
|
||||||
|
<field name="total_rejected"/>
|
||||||
|
|
||||||
<templates>
|
<templates>
|
||||||
<t t-name="card">
|
<t t-name="card">
|
||||||
|
<div class="oe_kanban_global_click">
|
||||||
<div class="oe_kanban_global_click d-flex p-2">
|
<div class="o_kanban_card_header">
|
||||||
|
<div class="o_kanban_card_header_title">
|
||||||
<!-- Avatar -->
|
|
||||||
<div class="me-2">
|
<div class="me-2">
|
||||||
<field name="image_128"
|
<field name="image_128"
|
||||||
widget="image"
|
widget="image"
|
||||||
class="rounded"
|
class="rounded-circle oe_avatar"
|
||||||
options="{'size': [48,48]}"/>
|
style="width:64px; height:64px; min-width:64px; min-height:64px; object-fit:cover;"
|
||||||
|
options="{'size': [64, 64]}"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex-grow-1">
|
||||||
<!-- Details -->
|
<strong class="o_kanban_record_title">
|
||||||
<div class="flex-grow-1 overflow-hidden">
|
|
||||||
|
|
||||||
<div class="fw-bold text-truncate">
|
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
</div>
|
</strong>
|
||||||
|
<div t-if="record.email.raw_value" class="text-muted small">
|
||||||
<div t-if="record.phone.raw_value"
|
|
||||||
class="text-muted small">
|
|
||||||
<i class="fa fa-phone me-1"/>
|
|
||||||
<field name="phone"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div t-if="record.email.raw_value"
|
|
||||||
class="text-muted small text-truncate">
|
|
||||||
<i class="fa fa-envelope me-1"/>
|
<i class="fa fa-envelope me-1"/>
|
||||||
<field name="email"/>
|
<field name="email"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div t-if="record.phone.raw_value" class="text-muted small">
|
||||||
|
<i class="fa fa-phone me-1"/>
|
||||||
|
<field name="phone"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="o_kanban_card_content">
|
||||||
|
<div class="row g-2 mb-2">
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="card bg-light border-0" style="background-color: #f8f9fa;">
|
||||||
|
<div class="card-body p-2 text-center">
|
||||||
|
<div class="text-muted small mb-1" style="color: black;">Requested</div>
|
||||||
|
<div class="fw-bold text-primary fs-5">
|
||||||
|
<field name="total_positions_requested"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="card bg-light border-0" style="background-color: #f8f9fa;">
|
||||||
|
<div class="card-body p-2 text-center">
|
||||||
|
<div class="text-muted small mb-1" style="color: black;">Submitted</div>
|
||||||
|
<div class="fw-bold text-success fs-5">
|
||||||
|
<field name="total_submitted"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="card bg-light border-0" style="background-color: #f8f9fa;">
|
||||||
|
<div class="card-body p-2 text-center">
|
||||||
|
<div class="text-muted small mb-1" style="color: black;">Hired</div>
|
||||||
|
<div class="fw-bold text-info fs-5">
|
||||||
|
<field name="total_hired"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="card bg-light border-0" style="background-color: #f8f9fa;">
|
||||||
|
<div class="card-body p-2 text-center">
|
||||||
|
<div class="text-muted small mb-1" style="color: black;">Rejected</div>
|
||||||
|
<div class="fw-bold text-danger fs-5">
|
||||||
|
<field name="total_rejected"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="o_kanban_card_manage">
|
||||||
|
<button name="action_create_job_request" type="object" class="btn btn-primary btn-sm">
|
||||||
|
<i class="fa fa-plus me-1"/>Create Job Request
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</t>
|
</t>
|
||||||
</templates>
|
</templates>
|
||||||
</kanban>
|
</kanban>
|
||||||
|
|
|
||||||
|
|
@ -571,7 +571,8 @@
|
||||||
<page string="Jobs">
|
<page string="Jobs">
|
||||||
<field name="applicant_history_ids" nolabel="1" readonly="1">
|
<field name="applicant_history_ids" nolabel="1" readonly="1">
|
||||||
<list>
|
<list>
|
||||||
<field name="job_id"/>
|
<field name="hr_job_recruitment"/>
|
||||||
|
<field name="job_id" invisible="1" column_invisible="1"/>
|
||||||
<field name="stage_id"/>
|
<field name="stage_id"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="create_date"/>
|
<field name="create_date"/>
|
||||||
|
|
|
||||||
|
|
@ -343,7 +343,8 @@
|
||||||
<page string="Jobs">
|
<page string="Jobs">
|
||||||
<field name="applicant_ids" nolabel="1">
|
<field name="applicant_ids" nolabel="1">
|
||||||
<list>
|
<list>
|
||||||
<field name="job_id"/>
|
<field name="hr_job_recruitment"/>
|
||||||
|
<field name="job_id" invisible="1" column_invisible="1"/>
|
||||||
<field name="stage_id"/>
|
<field name="stage_id"/>
|
||||||
<field name="user_id"/>
|
<field name="user_id"/>
|
||||||
<field name="create_date"/>
|
<field name="create_date"/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue