from datetime import datetime from odoo import http from odoo.http import request import json class website_hr_recruitment_applications(http.Controller): def _get_request_form(self, applicant_id, applicant_request_id, token=None, form_type=None, require_token=False): applicant_request = request.env['applicant.request.forms'].sudo().browse(applicant_request_id) if not applicant_request.exists(): return request.env['applicant.request.forms'] if applicant_request.applicant_id.id != applicant_id: return request.env['applicant.request.forms'] if form_type and applicant_request.form_type != form_type: return request.env['applicant.request.forms'] if require_token and not token: return request.env['applicant.request.forms'] if token and applicant_request.access_token != token: return request.env['applicant.request.forms'] return applicant_request @staticmethod def _is_submitted_for_token(applicant_request, token): return bool( applicant_request and applicant_request.status == 'done' and token and applicant_request.submitted_token == token ) @http.route(['/hr_recruitment/second_application_form//'], type='http', auth="public", website=True) def second_application_form(self, applicant_id, applicant_request_id, **kwargs): """Renders the website form for applicants to submit additional details.""" applicant_request_id = request.env['applicant.request.forms'].sudo().browse(applicant_request_id) if not applicant_request_id.exists(): return request.not_found() if applicant_request_id : if applicant_request_id.status == 'done': return request.render("hr_recruitment_extended.thank_you_template") else: return request.render("hr_recruitment_extended.applicant_form_template", { 'applicant': applicant_request_id.applicant_id, 'applicant_request_id': applicant_request_id }) else: return request.not_found() @http.route(['/hr_recruitment/submit_second_application///submit'], type='http', auth="public", methods=['POST'], website=True, csrf=False) def process_application_form(self, applicant_id, applicant_request_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) applicant_request_id = request.env['applicant.request.forms'].sudo().browse(applicant_request_id) if not applicant_request_id.exists() or not applicant.exists(): return request.not_found() # Return 404 if applicant doesn't exist if applicant_request_id.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_request_id.status = 'done' # Redirect to a Thank You page return request.render("hr_recruitment_extended.thank_you_template") @http.route(['/FTPROTECH/DocRequests//'], type='http', auth="public", website=True) def doc_request_form(self, applicant_id, applicant_request_id, **kwargs): request_token = kwargs.get('token') applicant_request = self._get_request_form( applicant_id, applicant_request_id, token=request_token, form_type='documents_request', require_token=True, ) if not applicant_request: raise request.not_found() if self._is_submitted_for_token(applicant_request, request_token): return request.render("hr_recruitment_extended.thank_you_template") return request.render("hr_recruitment_extended.doc_request_form_template", { 'applicant': applicant_request.applicant_id, 'applicant_request_id': applicant_request, 'request_token': request_token, }) @http.route(['/FTPROTECH/submit///docRequest'], type='http', auth="public", methods=['POST'], website=True, csrf=False) def process_applicant_doc_submission_form(self, applicant_id, applicant_request_id, **post): request_token = post.get('request_token') applicant_request = self._get_request_form( applicant_id, applicant_request_id, token=request_token, form_type='documents_request', require_token=True, ) if not applicant_request: raise request.not_found() applicant = applicant_request.applicant_id if self._is_submitted_for_token(applicant_request, request_token): 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', ''), } applicant_data = {k: v for k, v in applicant_data.items() if v != '' and v != 0} attachments_data_json = post.get('attachments_data_json', '[]') attachments_data = json.loads(attachments_data_json) if attachments_data_json else [] applicant.write(applicant_data) applicant.replace_joining_attachments(attachments_data) applicant_request.write({ 'status': 'done', 'applicant_submitted_date': datetime.now(), 'submitted_token': request_token, }) return request.render("hr_recruitment_extended.thank_you_template") @http.route(['/FTPROTECH/JoiningForm/'], 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: 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//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} 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') ] 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_data_json = post.get('attachments_data_json', '[]') attachments_data = json.loads(attachments_data_json) if attachments_data_json else [] applicant.write(applicant_data) applicant.replace_joining_attachments(attachments_data) template = request.env.ref('hr_recruitment_extended.email_template_post_onboarding_form_user_submit', raise_if_not_found=False) 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') ]) email_cc = ','.join([user.email for user in users]) email_values = { 'email_from': applicant.email_from, 'email_to': 'hr@ftprotech.com', 'email_cc': email_cc } template.sudo().send_mail( applicant.id, email_values=email_values, force_send=True ) 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