[IMP] hr_recruitment: Improve multi applicant count
Purpose: At the moment, you can only find multi applications for the same applicant based on the similar email. Not every application comes through the same email. We want to find same applicants based on the same email, phone or mobile phone. task - 2701472 closes odoo/odoo#86428 Signed-off-by: Kevin Baptiste <kba@odoo.com>
This commit is contained in:
@@ -180,7 +180,7 @@ class Applicant(models.Model):
|
||||
legend_blocked = fields.Char(related='stage_id.legend_blocked', string='Kanban Blocked')
|
||||
legend_done = fields.Char(related='stage_id.legend_done', string='Kanban Valid')
|
||||
legend_normal = fields.Char(related='stage_id.legend_normal', string='Kanban Ongoing')
|
||||
application_count = fields.Integer(compute='_compute_application_count', help='Applications with the same email')
|
||||
application_count = fields.Integer(compute='_compute_application_count', help='Applications with the same email or phone or mobile')
|
||||
refuse_reason_id = fields.Many2one('hr.applicant.refuse.reason', string='Refuse Reason', tracking=True)
|
||||
meeting_ids = fields.One2many('calendar.event', 'applicant_id', 'Meetings')
|
||||
meeting_display_text = fields.Char(compute='_compute_meeting_display')
|
||||
@@ -215,40 +215,42 @@ class Applicant(models.Model):
|
||||
applicant.day_close = False
|
||||
applicant.delay_close = False
|
||||
|
||||
@api.depends('email_from')
|
||||
@api.depends('email_from', 'partner_phone', 'partner_mobile')
|
||||
def _compute_application_count(self):
|
||||
self.flush(fnames=['email_from'])
|
||||
# Filter and gather emails at the same time
|
||||
applicants = self.env['hr.applicant']
|
||||
mails = set()
|
||||
for applicant in self:
|
||||
if applicant.email_from:
|
||||
if applicant.email_from or applicant.partner_phone or applicant.partner_mobile:
|
||||
applicants |= applicant
|
||||
mails.add(applicant.email_from.lower())
|
||||
# Done via SQL since read_group does not support grouping by lowercase field
|
||||
if mails:
|
||||
if applicants.ids:
|
||||
query = Query(self.env.cr, self._table, self._table_query)
|
||||
query.add_where('LOWER("hr_applicant".email_from) in %s', [tuple(mails)])
|
||||
query.add_where('hr_applicant.id in %s', [tuple(applicants.ids)])
|
||||
# Count into the companies that are selected from the multi-company widget
|
||||
company_ids = self.env.context.get('allowed_company_ids')
|
||||
if company_ids:
|
||||
query.add_where('other.company_id in %s', [tuple(company_ids)])
|
||||
self._apply_ir_rules(query)
|
||||
from_clause, where_clause, where_clause_params = query.get_sql()
|
||||
# In case the applicant phone or mobile is configured in wrong field
|
||||
query_str = """
|
||||
SELECT LOWER("%(table)s".email_from) as l_email_from,
|
||||
COUNT("%(table)s".id) as count
|
||||
FROM %(from)s
|
||||
SELECT hr_applicant.id as appl_id,
|
||||
COUNT(other.id) as count
|
||||
FROM hr_applicant
|
||||
JOIN hr_applicant other ON LOWER(other.email_from) = LOWER(hr_applicant.email_from)
|
||||
OR other.partner_phone = hr_applicant.partner_phone OR other.partner_phone = hr_applicant.partner_mobile
|
||||
OR other.partner_mobile = hr_applicant.partner_mobile OR other.partner_mobile = hr_applicant.partner_phone
|
||||
%(where)s
|
||||
GROUP BY l_email_from
|
||||
GROUP BY hr_applicant.id
|
||||
""" % {
|
||||
'table': self._table,
|
||||
'from': from_clause,
|
||||
'where': ('WHERE %s' % where_clause) if where_clause else '',
|
||||
}
|
||||
self.env.cr.execute(query_str, where_clause_params)
|
||||
|
||||
application_data_mapped = dict((data['l_email_from'], data['count']) for data in self.env.cr.dictfetchall())
|
||||
application_data_mapped = dict((data['appl_id'], data['count']) for data in self.env.cr.dictfetchall())
|
||||
else:
|
||||
application_data_mapped = dict()
|
||||
for applicant in applicants:
|
||||
applicant.application_count = application_data_mapped.get(applicant.email_from.lower(), 1) - 1
|
||||
applicant.application_count = application_data_mapped.get(applicant.id, 1) - 1
|
||||
(self - applicants).application_count = False
|
||||
|
||||
@api.depends_context('lang')
|
||||
@@ -487,16 +489,15 @@ class Applicant(models.Model):
|
||||
}
|
||||
|
||||
def action_applications_email(self):
|
||||
# Security rules will apply when loading the view, here we just fetch the ids
|
||||
mails = set()
|
||||
for applicant in self:
|
||||
if applicant.email_from:
|
||||
mails.add(applicant.email_from.lower())
|
||||
self.ensure_one()
|
||||
self.env.cr.execute("""
|
||||
SELECT id
|
||||
SELECT other.id
|
||||
FROM hr_applicant
|
||||
WHERE LOWER(email_from) in %s
|
||||
""", (tuple(mails),)
|
||||
JOIN hr_applicant other ON LOWER(other.email_from) = LOWER(hr_applicant.email_from)
|
||||
OR other.partner_phone = hr_applicant.partner_phone OR other.partner_phone = hr_applicant.partner_mobile
|
||||
OR other.partner_mobile = hr_applicant.partner_mobile OR other.partner_mobile = hr_applicant.partner_phone
|
||||
WHERE hr_applicant.id in %s
|
||||
""", (tuple(self.ids),)
|
||||
)
|
||||
ids = [res['id'] for res in self.env.cr.dictfetchall()]
|
||||
return {
|
||||
|
||||
@@ -26,3 +26,46 @@ class TestRecruitment(TransactionCase):
|
||||
self.assertEqual(dup1.application_count, 1)
|
||||
self.assertEqual(dup2.application_count, 1)
|
||||
self.assertEqual(no_dup.application_count, 0)
|
||||
|
||||
def test_application_count(self):
|
||||
""" Test that we find same applicants based on simmilar mail,
|
||||
phone or mobile phone.
|
||||
"""
|
||||
A, B, C, D, E, F = self.env['hr.applicant'].create([
|
||||
{
|
||||
'name': 'Application A',
|
||||
'email_from': 'abc@odoo.com',
|
||||
'partner_phone': '123',
|
||||
'partner_mobile': '14-15-16',
|
||||
},
|
||||
{
|
||||
'name': 'Application B',
|
||||
'partner_phone': '456',
|
||||
'partner_mobile': '11-12-13',
|
||||
},
|
||||
{
|
||||
'name': 'Application C',
|
||||
'email_from': 'def@odoo.com',
|
||||
'partner_phone': '123',
|
||||
'partner_mobile': '14-15-16',
|
||||
},
|
||||
{
|
||||
'name': 'Application D',
|
||||
'email_from': 'def@odoo.com',
|
||||
'partner_phone': '456',
|
||||
'partner_mobile': '14-15-16',
|
||||
},
|
||||
{
|
||||
'name': 'Application E',
|
||||
},
|
||||
{
|
||||
'name': 'Application F',
|
||||
'partner_phone': '11-12-13', # In case phone is configured in a wrong field
|
||||
}
|
||||
])
|
||||
self.assertEqual(A.application_count, 2) # C, D
|
||||
self.assertEqual(B.application_count, 2) # D, F
|
||||
self.assertEqual(C.application_count, 2) # A, D
|
||||
self.assertEqual(D.application_count, 3) # A, B, C
|
||||
self.assertEqual(E.application_count, 0)
|
||||
self.assertEqual(F.application_count, 1) # B
|
||||
|
||||
Reference in New Issue
Block a user