odoo18/addons_extensions/hr_recruitment_extended/controllers/controllers.py

338 lines
16 KiB
Python

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
import base64
from odoo.exceptions import UserError
from PIL import Image
from io import BytesIO
import re
import json
class website_hr_recruitment_applications(http.Controller):
@http.route(['/hr_recruitment/second_application_form/<int:applicant_id>'], type='http', auth="public", website=True)
def second_application_form(self, applicant_id, **kwargs):
"""Renders the website form for applicants to submit additional details."""
applicant = request.env['hr.applicant'].sudo().browse(applicant_id)
if not applicant.exists():
return request.not_found()
if applicant and applicant.send_second_application_form:
if applicant.second_application_form_status == 'done':
return request.render("hr_recruitment_extended.thank_you_template")
else:
return request.render("hr_recruitment_extended.applicant_form_template", {
'applicant': applicant
})
else:
return request.not_found()
@http.route(['/hr_recruitment/submit_second_application/<int:applicant_id>/submit'], type='http', auth="public",
methods=['POST'], website=True, csrf=False)
def process_application_form(self, applicant_id, **kwargs):
# Get the applicant
candidate_image_base64 = kwargs.pop('candidate_image_base64')
candidate_image = kwargs.pop('candidate_image')
experience_years = kwargs.pop('experience_years', 0)
experience_months = kwargs.pop('experience_months', 0)
if not len(str(experience_months)) > 0:
experience_months = 0
if not len(str(experience_years)) > 0:
experience_years = 0
# If there are months, convert everything to months
if int(experience_months) > 0:
kwargs['total_exp'] = (int(experience_years) * 12) + int(experience_months)
kwargs['total_exp_type'] = 'month'
else:
kwargs['total_exp'] = int(experience_years)
kwargs['total_exp_type'] = 'year'
applicant = request.env['hr.applicant'].sudo().browse(applicant_id)
if not applicant.exists():
return request.not_found() # Return 404 if applicant doesn't exist
if applicant.second_application_form_status == 'done':
return request.render("hr_recruitment_extended.thank_you_template")
kwargs['candidate_image'] = candidate_image_base64
applicant.write(kwargs)
applicant.candidate_id.candidate_image = candidate_image_base64
template = request.env.ref('hr_recruitment_extended.email_template_second_application_submitted',
raise_if_not_found=False)
if template and applicant.user_id.email:
template.sudo().send_mail(applicant.id, force_send=True)
applicant.second_application_form_status = 'done'
# Redirect to a Thank You page
return request.render("hr_recruitment_extended.thank_you_template")
@http.route(['/FTPROTECH/DocRequests/<int:applicant_id>'], type='http', auth="public",
website=True)
def doc_request_form(self, applicant_id, **kwargs):
"""Renders the website form for applicants to submit additional details."""
applicant = request.env['hr.applicant'].sudo().browse(applicant_id)
if not applicant.exists():
return request.not_found()
if applicant:
if applicant.doc_requests_form_status == 'done':
return request.render("hr_recruitment_extended.thank_you_template")
else:
return request.render("hr_recruitment_extended.doc_request_form_template", {
'applicant': applicant
})
else:
return request.not_found()
@http.route(['/FTPROTECH/submit/<int:applicant_id>/docRequest'], type='http', auth="public",
methods=['POST'], website=True, csrf=False)
def process_applicant_doc_submission_form(self, applicant_id, **post):
applicant = request.env['hr.applicant'].sudo().browse(applicant_id)
if not applicant.exists():
return request.not_found() # Return 404 if applicant doesn't exist
if applicant.doc_requests_form_status == 'done':
return request.render("hr_recruitment_extended.thank_you_template")
applicant_data = {
'applicant_id': int(post.get('applicant_id', 0)),
'candidate_image': post.get('candidate_image_base64', ''),
'doc_requests_form_status': 'done'
}
applicant_data = {k: v for k, v in applicant_data.items() if v != '' and v != 0}
# attachments
attachments_data_json = post.get('attachments_data_json', '[]')
attachments_data = json.loads(attachments_data_json) if attachments_data_json else []
if attachments_data:
applicant_data['joining_attachment_ids'] = [
(4, existing_id) for existing_id in
(applicant.joining_attachment_ids).ids
] + [
(0, 0, {
'name': attachment.get('file_name', ''),
'recruitment_attachment_id': attachment.get(
'attachment_rec_id', ''),
'file': attachment.get('file_content', '')
}) for attachment in attachments_data if
attachment.get('attachment_rec_id')
]
applicant.write(applicant_data)
return request.render("hr_recruitment_extended.thank_you_template")
@http.route(['/FTPROTECH/JoiningForm/<int:applicant_id>'], type='http', auth="public",
website=True)
def post_onboarding_form(self, applicant_id, **kwargs):
"""Renders the website form for applicants to submit additional details."""
applicant = request.env['hr.applicant'].sudo().browse(applicant_id)
if not applicant.exists():
return request.not_found()
if applicant and applicant.send_post_onboarding_form:
if applicant.post_onboarding_form_status == 'done':
return request.render("hr_recruitment_extended.thank_you_template")
else:
return request.render("hr_recruitment_extended.post_onboarding_form_template", {
'applicant': applicant
})
else:
return request.not_found()
@http.route(['/FTPROTECH/submit/<int:applicant_id>/JoinForm'], type='http', auth="public",
methods=['POST'], website=True, csrf=False)
def process_employee_joining_form(self,applicant_id,**post):
applicant = request.env['hr.applicant'].sudo().browse(applicant_id)
if not applicant.exists():
return request.not_found() # Return 404 if applicant doesn't exist
if applicant.post_onboarding_form_status == 'done':
return request.render("hr_recruitment_extended.thank_you_template",{
'applicant': applicant
})
private_state_id = request.env['res.country.state'].sudo().browse(int(post.get('present_state', 0)))
permanent_state_id = request.env['res.country.state'].sudo().browse(int(post.get('permanent_state', 0)))
applicant_data = {
'applicant_id': int(post.get('applicant_id', 0)),
'employee_id': int(post.get('employee_id', 0)),
'candidate_image': post.get('candidate_image_base64', ''),
'doj': datetime.strptime(post.get('doj'), '%Y-%m-%d').date() if post.get('doj', None) else '',
'email_from': post.get('email_from', ''),
'gender': post.get('gender', ''),
'partner_phone': post.get('partner_phone', ''),
'alternate_phone': post.get('alternate_phone', ''),
'birthday': post.get('birthday', ''),
'blood_group': post.get('blood_group', ''),
'private_street': post.get('present_street', ''),
'private_street2': post.get('present_street2', ''),
'private_city': post.get('present_city', ''),
'private_state_id': private_state_id.id if private_state_id else '',
'private_country_id': private_state_id.country_id.id if private_state_id else '',
'private_zip': post.get('present_zip', ''),
'permanent_street': post.get('permanent_street', ''),
'permanent_street2': post.get('permanent_street2', ''),
'permanent_city': post.get('permanent_city', ''),
'permanent_state_id': permanent_state_id.id if permanent_state_id else '',
'permanent_country_id': permanent_state_id.country_id.id if permanent_state_id else '',
'permanent_zip': post.get('permanent_zip', ''),
'marital': post.get('marital', ''),
'marriage_anniversary_date': post.get('marriage_anniversary_date', ''),
'full_name_as_in_bank': post.get('full_name_as_in_bank', ''),
'bank_name': post.get('bank_name', ''),
'bank_branch': post.get('bank_branch', ''),
'bank_account_no': post.get('bank_account_no', ''),
'bank_ifsc_code': post.get('bank_ifsc_code', ''),
'passport_no': post.get('passport_no', ''),
'passport_start_date': datetime.strptime(post.get('passport_start_date'), '%Y-%m-%d').date() if post.get('passport_start_date', None) else '',
'passport_end_date': datetime.strptime(post.get('passport_end_date'), '%Y-%m-%d').date() if post.get('passport_end_date', None) else '',
'passport_issued_location': post.get('passport_issued_location', ''),
'pan_no': post.get('pan_no', ''),
'identification_id': post.get('identification_id', ''),
'previous_company_pf_no': post.get('previous_company_pf_no', ''),
'previous_company_uan_no': post.get('previous_company_uan_no', ''),
'post_onboarding_form_status': 'done'
}
applicant_data = {k: v for k, v in applicant_data.items() if v != '' and v != 0}
# Get family details data from JSON
family_data_json = post.get('family_data_json', '[]')
family_data = json.loads(family_data_json) if family_data_json else []
if family_data:
applicant_data['family_details'] = [
(0, 0, {
'relation_type': member.get('relation', ''),
'name': str(member.get('name', '')),
'contact_no': member.get('contact', ''),
'dob': datetime.strptime(member.get('dob'), '%Y-%m-%d').date() if member.get('dob') else None,
'location': member.get('location', ''),
}) for member in family_data if member.get('name') and member.get('relation') # Optional filter to avoid empty members
]
# education details
education_data_json = post.get('education_data_json', '[]')
education_data = json.loads(education_data_json) if education_data_json else []
if education_data:
applicant_data['education_history'] = [
(0,0,{
'education_type': education.get('education_type',''),
'name': education.get('specialization', ''),
'university': education.get('university', ''),
'start_year': education.get('start_year', ''),
'end_year': education.get('end_year', ''),
'marks_or_grade': education.get('marks_or_grade','')
}) for education in education_data
]
employer_history_data_json = post.get('employer_history_data_json', '[]')
employer_data = json.loads(employer_history_data_json) if employer_history_data_json else []
if employer_data:
applicant_data['employer_history'] = [
(0, 0, {
'company_name': company.get('company_name', ''),
'designation': company.get('designation', ''),
'date_of_joining': self.safe_date_parse(company.get('date_of_joining')),
'last_working_day': self.safe_date_parse(company.get('last_working_day')),
'ctc': company.get('ctc', ''),
}) for company in employer_data
]
#attachments
attachments_data_json = post.get('attachments_data_json', '[]')
attachments_data = json.loads(attachments_data_json) if attachments_data_json else []
if attachments_data:
applicant_data['joining_attachment_ids'] = [
(4, existing_id) for existing_id in
(applicant.joining_attachment_ids).ids
] + [
(0, 0, {
'name': attachment.get('file_name', ''),
'recruitment_attachment_id': attachment.get(
'attachment_rec_id', ''),
'file': attachment.get('file_content', '')
}) for attachment in attachments_data if
attachment.get('attachment_rec_id')
]
applicant.write(applicant_data)
template = request.env.ref('hr_recruitment_extended.email_template_post_onboarding_form_user_submit',
raise_if_not_found=False)
# Get HR managers with HR department
group = request.env.ref('hr.group_hr_manager')
users = request.env['res.users'].sudo().search([
('groups_id', 'in', group.ids),
('email', '!=', False),
('email', '!=', 'hr@ftprotech.com'),
('employee_id.department_id.name', '=', 'Human Resource')
])
# Extract emails and join them into a comma-separated string
email_cc = ','.join([user.email for user in users])
# Prepare email values
email_values = {
'email_from': applicant.email_from,
'email_to': 'hr@ftprotech.com',
'email_cc': email_cc
}
# Debug: Print the email_cc value to verify
print(f"Email CC value: {email_values['email_cc']}")
# Send email
template.sudo().send_mail(
applicant.id,
email_values=email_values,
force_send=True
)
# Render thank you page
return request.render("hr_recruitment_extended.thank_you_template", {
'applicant': applicant
})
def safe_date_parse(self,date_str):
try:
return datetime.strptime(date_str, '%Y-%m-%d').date() if date_str else None
except (ValueError, TypeError):
return None
@http.route('/hr_recruitment_extended/fetch_related_state_ids', type='json', auth="public", website=True)
def fetch_preferred_state_ids(self, country_id=None):
state_ids = {}
states = http.request.env['res.country.state'].sudo()
if country_id:
for state_id in states.search([('country_id', '=?', country_id)]):
state_ids[state_id.id] = state_id.name
return state_ids