import warnings from datetime import datetime from dateutil.relativedelta import relativedelta from operator import itemgetter from werkzeug.urls import url_encode from odoo import http, _ from odoo.addons.website_hr_recruitment.controllers.main import WebsiteHrRecruitment from odoo.osv.expression import AND from odoo.http import request from odoo.tools import email_normalize from odoo.tools.misc import groupby class WebsiteRecruitmentApplication(WebsiteHrRecruitment): @http.route('/hr_recruitment_extended/fetch_hr_recruitment_degree', type='json', auth="public", website=True) def fetch_recruitment_degrees(self): degrees = {} all_degrees = http.request.env['hr.recruitment.degree'].sudo().search([]) if all_degrees: for degree in all_degrees: degrees[degree.id] = degree.name return degrees @http.route('/hr_recruitment_extended/fetch_preferred_locations', type='json', auth="public", website=True) def fetch_preferred_locations(self, loc_ids): locations = {} for id in loc_ids: location = http.request.env['hr.location'].sudo().browse(id) if location: locations[location.id] = location.location_name return locations @http.route('/website_hr_recruitment/check_recent_application', type='json', auth="public", website=True) def check_recent_application(self, field, value, job_id): def refused_applicants_condition(applicant): return not applicant.active \ and applicant.job_id.id == int(job_id) \ and applicant.create_date >= (datetime.now() - relativedelta(months=6)) field_domain = { 'name': [('partner_name', '=ilike', value)], 'email': [('email_normalized', '=', email_normalize(value))], 'phone': [('partner_phone', '=', value)], 'linkedin': [('linkedin_profile', '=ilike', value)], }.get(field, []) applications_by_status = http.request.env['hr.applicant'].sudo().search(AND([ field_domain, [ ('job_id.website_id', 'in', [http.request.website.id, False]), '|', ('application_status', '=', 'ongoing'), '&', ('application_status', '=', 'refused'), ('active', '=', False), ] ]), order='create_date DESC').grouped('application_status') refused_applicants = applications_by_status.get('refused', http.request.env['hr.applicant']) if any(applicant for applicant in refused_applicants if refused_applicants_condition(applicant)): return { 'message': _( 'We\'ve found a previous closed application in our system within the last 6 months.' ' Please consider before applying in order not to duplicate efforts.' ) } if 'ongoing' not in applications_by_status: return {'message': None} ongoing_application = applications_by_status.get('ongoing')[0] if ongoing_application.job_id.id == int(job_id): recruiter_contact = "" if not ongoing_application.user_id else _( ' In case of issue, contact %(contact_infos)s', contact_infos=", ".join( [value for value in itemgetter('name', 'email', 'phone')(ongoing_application.user_id) if value] )) return { 'message': _( 'An application already exists for %(value)s.' ' Duplicates might be rejected. %(recruiter_contact)s', value=value, recruiter_contact=recruiter_contact ) } return { 'message': _( 'We found a recent application with a similar name, email, phone number.' ' You can continue if it\'s not a mistake.' ) } def _should_log_authenticate_message(self, record): if record._name == "hr.applicant" and not request.session.uid: return False return super()._should_log_authenticate_message(record) def extract_data(self, model, values): candidate = False current_ctc = values.pop('current_ctc', None) expected_ctc = values.pop('expected_ctc', None) exp_type = values.pop('exp_type', None) current_location = values.pop('current_location', None) preferred_locations_str = values.pop('preferred_locations', '') preferred_locations = [int(x) for x in preferred_locations_str.split(',')] if len(preferred_locations_str) > 0 else [] current_organization = values.pop('current_organization', None) notice_period = values.pop('notice_period',0) notice_period_type = values.pop('notice_period_type', 'day') if model.model == 'hr.applicant': # pop the fields since there are only useful to generate a candidate record # partner_name = values.pop('partner_name') first_name = values.pop('first_name', None) middle_name = values.pop('middle_name', None) last_name = values.pop('last_name', None) partner_phone = values.pop('partner_phone', None) alternate_phone = values.pop('alternate_phone', None) partner_email = values.pop('email_from', None) degree = values.pop('degree',None) if partner_phone and partner_email: candidate = request.env['hr.candidate'].sudo().search([ ('email_from', '=', partner_email), ('partner_phone', '=', partner_phone), ], limit=1) if candidate: candidate.sudo().write({ 'partner_name': f"{first_name + ' '+ ((middle_name + ' ') if middle_name else '') + last_name}", 'first_name': first_name, 'middle_name': middle_name, 'last_name': last_name, 'alternate_phone': alternate_phone, 'type_id': int(degree) if degree.isdigit() else False }) if not candidate: candidate = request.env['hr.candidate'].sudo().create({ 'partner_name': f"{first_name + ' '+ ((middle_name + ' ') if middle_name else '') + last_name}", 'email_from': partner_email, 'partner_phone': partner_phone, 'first_name': first_name, 'middle_name': middle_name, 'last_name': last_name, 'alternate_phone': alternate_phone, 'type_id': int(degree) if degree.isdigit() else False }) values['partner_name'] = f"{first_name + ' '+ ((middle_name + ' ') if middle_name else '') + last_name}" if partner_phone: values['partner_phone'] = partner_phone if partner_email: values['email_from'] = partner_email data = super().extract_data(model, values) data['record']['current_ctc'] = float(current_ctc if current_ctc else 0) data['record']['salary_expected'] = float(expected_ctc if expected_ctc else 0) data['record']['exp_type'] = exp_type if exp_type else 'fresher' data['record']['current_location'] =current_location if current_location else '' data['record']['current_organization'] = current_organization if current_organization else '' data['record']['notice_period'] = notice_period if notice_period else 0 data['record']['notice_period_type'] = notice_period_type if notice_period_type else 'day' if len(preferred_locations_str) > 0: data['record']['preferred_location'] = preferred_locations if candidate: data['record']['candidate_id'] = candidate.id data['record']['type_id'] = candidate.type_id.id return data