1131 lines
63 KiB
XML
1131 lines
63 KiB
XML
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<odoo>
|
|
<template id="applicants_list_partial_page">
|
|
<div class="ats-list-container">
|
|
<!-- Dynamic Job Stats Header -->
|
|
<!-- Job List and Details -->
|
|
<div class="ats-list-body">
|
|
<!-- Job List Panel -->
|
|
<div class="ats-list-left expanded" id="applicants-list-panel">
|
|
<t t-call="hr_recruitment_web_app.applicants_list"/>
|
|
<!-- Toggle Button -->
|
|
<i id="applicants-list-sidebar-toggle-btn" class="ats-list-toggle-btn"><<</i>
|
|
</div>
|
|
<!-- Job Detail Panel -->
|
|
<div id="applicants-detail" class="ats-detail">
|
|
<em>Select a Applicant to view details.</em>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<t t-call="hr_recruitment_web_app.applicant_image_modal"/>
|
|
<t t-call="hr_recruitment_web_app.create_new_application_template"/>
|
|
</template>
|
|
|
|
<template id="applicants_list">
|
|
<div class="ats-list-container">
|
|
<!-- Search -->
|
|
<div class="ats-list-search">
|
|
<input type="text" id="applicants-search" placeholder="🔍 Search applicants..."/>
|
|
</div>
|
|
<!-- Action Buttons Header -->
|
|
<div class="ats-actions-header">
|
|
<button class="btn" type="button" id="activeRecords" style="left:0;">
|
|
Active Records (
|
|
<span id="active-records-count">
|
|
<t t-esc="len(applicants)"/>
|
|
</span>
|
|
)
|
|
</button>
|
|
<button class="btn add-create-btn" type="button" id="add-application-create-btn" style="right:0;">
|
|
<span class="plus-icon">+</span>
|
|
Add New Applicant
|
|
</button>
|
|
</div>
|
|
<ul class="ats-list">
|
|
<t t-foreach="applicants" t-as="applicant">
|
|
<li class="ats-item applicants-item" t-att-data-id="applicant.id">
|
|
<div class="ats-item-content">
|
|
<div class="ats-info">
|
|
<div id="applicant_name" class="ats-title" style="padding-bottom:10px;">
|
|
<strong>
|
|
<t t-if="applicant.candidate_id.display_name">
|
|
<t t-esc="applicant.candidate_id.display_name"/>
|
|
</t>
|
|
<t t-else="">
|
|
<t t-esc="applicant.display_name"/>
|
|
</t>
|
|
</strong>
|
|
</div>
|
|
<div class="ats-meta" style="padding-bottom:10px;">
|
|
<span id="job_request" t-esc="applicant.hr_job_recruitment.display_name"/>
|
|
</div>
|
|
<div class="ats-meta">
|
|
<span id="applicant_stage"
|
|
t-esc="applicant.recruitment_stage_id.display_name"/>
|
|
</div>
|
|
<div style="display:none;">
|
|
<span id="create_date" t-esc="applicant.create_date"/>
|
|
<span id="applicant_email" t-esc="applicant.email_from"/>
|
|
<span id="applicant_phone" t-esc="applicant.partner_phone"/>
|
|
<span id="alternate_phone" t-esc="applicant.alternate_phone"/>
|
|
<span id="recruiter_id" t-esc="applicant.user_id.id"/>
|
|
<span id="recruiter_name" t-esc="applicant.user_id.display_name"/>
|
|
<span id="recruiter_image" t-esc="applicant.user_id.image_128"/>
|
|
</div>
|
|
</div>
|
|
<div class="ats-avatar">
|
|
<t t-if="applicant.candidate_id.candidate_image">
|
|
<img t-att-src="image_data_uri(applicant.candidate_id.candidate_image)"
|
|
class="ats-item-image"
|
|
alt="Applicant photo"/>
|
|
</t>
|
|
<t t-else="">
|
|
<div class="ats-item-initials">
|
|
<t t-if="applicant.candidate_id.display_name">
|
|
<t t-esc="applicant.candidate_id.display_name[0].upper()"/>
|
|
</t>
|
|
<t t-else="">
|
|
<t t-esc="applicant.display_name[0].upper()"/>
|
|
</t>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</t>
|
|
</ul>
|
|
</div>
|
|
</template>
|
|
|
|
<template id="applicant_image_modal">
|
|
<div class="applicant-detail-modal">
|
|
<div class="modal-overlay"></div>
|
|
<div class="applicant-modal-content">
|
|
<span class="applicant-close-modal">&times;</span>
|
|
<div class="applicant-status-ribbon new">
|
|
<span class="modal-applicant-stage">Stage</span>
|
|
</div>
|
|
<div class="modal-applicant-container">
|
|
<div class="modal-applicant-left">
|
|
<img class="modal-applicant-image" src="" alt="Applicant Photo" style="display: none;"/>
|
|
<div class="modal-applicant-initials" style="display: none;"></div>
|
|
</div>
|
|
<div class="modal-applicant-right">
|
|
<h2 class="modal-applicant-name">Applicant Name</h2>
|
|
<div class="modal-applicant-details">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Job Position:</span>
|
|
<span class="detail-value modal-applicant-job">Job Title</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Applied On:</span>
|
|
<span class="detail-value modal-applicant-date">Date</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Email:</span>
|
|
<span class="detail-value modal-applicant-email">Email</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Phone:</span>
|
|
<span class="detail-value modal-applicant-phone">Phone</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Alternate Phone:</span>
|
|
<span class="detail-value modal-applicant-altphone">Alternate Phone</span>
|
|
</div>
|
|
</div>
|
|
<!-- Recruiter Info -->
|
|
<div class="recruiter-info">
|
|
<div class="recruiter-avatar">
|
|
<img class="recruiter-image" src="" alt="Recruiter" style="display: none;"/>
|
|
<div class="recruiter-initials" style="display: none;"></div>
|
|
<span class="recruiter-tooltip">Recruiter Name</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
|
|
<template id="applicants_detail_partial">
|
|
<div class="ats-grid" id="ats-details-container">
|
|
<!-- Close button -->
|
|
<button type="button" class="close-detail" aria-label="Close">
|
|
<span aria-hidden="true">&times;</span>
|
|
</button>
|
|
|
|
<div class="ats-card span-3" style="grid-row: span 2;" id="ats-overview">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-list-ul me-2"></i>Quick Nav
|
|
</h4>
|
|
<div class="overview-nav">
|
|
<ul class="nav-list">
|
|
<li>
|
|
<a href="#ats-notice-period" class="nav-link smooth-scroll"><i
|
|
class="fa fa-calendar me-2"></i>Notice Period
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-resume" class="nav-link smooth-scroll"><i
|
|
class="fa fa-file-pdf me-2"></i>Resume
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-salary-details" class="nav-link smooth-scroll"><i
|
|
class="fa fa-money-bill-wave me-2"></i>Salary
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-basic-details" class="nav-link smooth-scroll"><i
|
|
class="fa fa-info-circle me-2"></i>Application
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-work-experience" class="nav-link smooth-scroll"><i
|
|
class="fa fa-briefcase me-2"></i>Experience
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-education-details" class="nav-link smooth-scroll"><i
|
|
class="fa fa-graduation-cap me-2"></i>Education
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-skills" class="nav-link smooth-scroll"><i class="fa fa-star me-2"></i>
|
|
Skills
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-attachments" class="nav-link smooth-scroll"><i
|
|
class="fa fa-paperclip me-2"></i>Attachments
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-current-organisation" class="nav-link smooth-scroll"><i
|
|
class="fa fa-building me-2"></i>Current Org
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-recruited-by" class="nav-link smooth-scroll"><i
|
|
class="fa fa-user-tie me-2"></i>Recruited By
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#ats-timeline" class="nav-link smooth-scroll"><i
|
|
class="fa fa-user-tie me-2"></i>Timeline
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-9" style="grid-row: span 1;" id="ats-profile">
|
|
<div class="ats-info">
|
|
<h1 class="ats-title">
|
|
<span t-esc="applicant.partner_name or 'Unnamed Applicant'"/>
|
|
</h1>
|
|
<div class="ats-meta">
|
|
<span class="me-3 meta-item">
|
|
<i class="fa fa-envelope me-1"></i>
|
|
<span t-esc="applicant.email_from or 'No email'"/>
|
|
</span>
|
|
<span class="me-3 meta-item">
|
|
<i class="fa fa-phone me-1"></i>
|
|
<span t-esc="applicant.partner_phone or 'No phone'"/>
|
|
</span>
|
|
<span class="me-3 meta-item">
|
|
<i class="fa fa-briefcase me-1"></i>
|
|
<span t-esc="applicant.job_id.display_name or 'No position'"/>
|
|
</span>
|
|
<span class="me-3 meta-item">
|
|
<i class="fa fa-map-marker me-1"></i>
|
|
<span t-esc="applicant.current_location or 'Location not specified'"/>
|
|
</span>
|
|
</div>
|
|
<div class="stage-selector btn-group" role="group" t-att-data-applicant-id="applicant.id">
|
|
<t t-foreach="applicant.hr_job_recruitment.recruitment_stage_ids" t-as="stage">
|
|
<button type="button"
|
|
class="btn btn-stage"
|
|
t-att-class="'btn btn-stage ' +
|
|
('btn-stage-current' if applicant.stage_id.id == stage.id else 'btn-stage-option')"
|
|
t-att-data-stage-id="stage.id"
|
|
t-esc="stage.display_name"/>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
<div class="ats-avatar">
|
|
<div class="avatar-wrapper">
|
|
<img t-if="applicant.candidate_image"
|
|
t-att-src="image_data_uri(applicant.candidate_id.candidate_image)"
|
|
class="rounded-circle avatar-img animate__animated animate__fadeIn"
|
|
width="120" height="120" alt="Applicant Photo"/>
|
|
<div t-else=""
|
|
class="avatar-placeholder rounded-circle animate__animated animate__fadeIn">
|
|
<div class="applicant-img-placeholder">
|
|
<t t-if="applicant.candidate_id.display_name">
|
|
<t t-esc="applicant.candidate_id.display_name[0].upper()"/>
|
|
</t>
|
|
<t t-else="">
|
|
<t t-esc="applicant.display_name[0].upper()"/>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
<div class="avatar-overlay">
|
|
<i class="fa fa-search-plus"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-4" style="grid-row: span 1;"
|
|
id="ats-personal-details">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-user-circle me-2"></i>Personal Details
|
|
</h4>
|
|
<div class="detail-grid">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Gender:</span>
|
|
<span class="detail-value" t-esc="applicant.gender or 'N/A'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Date of Birth:</span>
|
|
<span class="detail-value" t-esc="applicant.birthday or 'N/A'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Marital Status:</span>
|
|
<span class="detail-value" t-esc="applicant.marital or 'N/A'"/>
|
|
</div>
|
|
<div class="detail-row" t-if="applicant.marital != 'single'">
|
|
<span class="detail-label">Marriage Anniversary:</span>
|
|
<span class="detail-value" t-esc="applicant.marriage_anniversary_date or 'N/A'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Blood Group:</span>
|
|
<span class="detail-value" t-esc="applicant.blood_group or 'N/A'"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-5" style="grid-row: span 2;" id="ats-contact-details">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-address-book me-2"></i>Contact Details
|
|
</h4>
|
|
<div class="detail-grid">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Alternate Phone:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.alternate_phone or 'N/A'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">LinkedIn:</span>
|
|
<t t-if="applicant.linkedin_profile">
|
|
<a t-att-href="applicant.linkedin_profile" target="_blank"
|
|
class="detail-value social-link">
|
|
<i class="fa fa-linkedin-square me-1"></i>
|
|
<span>View Profile</span>
|
|
</a>
|
|
</t>
|
|
<t t-else="">
|
|
<span class="detail-value">N/A</span>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
<h5 class="mt-4 mb-3 section-subtitle">Current Address</h5>
|
|
<div class="address-box">
|
|
<div t-if="applicant.private_street" t-esc="applicant.private_street"/>
|
|
<div t-if="applicant.private_street2" t-esc="applicant.private_street2"/>
|
|
<div>
|
|
<span t-if="applicant.private_city" t-esc="applicant.private_city + ','"/>
|
|
<span t-if="applicant.private_state_id"
|
|
t-esc="applicant.private_state_id.display_name"/>
|
|
<span t-if="applicant.private_zip" t-esc="applicant.private_zip"/>
|
|
</div>
|
|
<div t-if="applicant.private_country_id"
|
|
t-esc="applicant.private_country_id.display_name"/>
|
|
<t t-if="not applicant.private_street">
|
|
<div class="text-muted">Not specified</div>
|
|
</t>
|
|
</div>
|
|
<h5 class="mt-4 mb-3 section-subtitle">Permanent Address</h5>
|
|
<div class="address-box">
|
|
<div t-if="applicant.permanent_street" t-esc="applicant.permanent_street"/>
|
|
<div t-if="applicant.permanent_street2" t-esc="applicant.permanent_street2"/>
|
|
<div>
|
|
<span t-if="applicant.permanent_city" t-esc="applicant.permanent_city + ','"/>
|
|
<span t-if="applicant.permanent_state_id"
|
|
t-esc="applicant.permanent_state_id.display_name"/>
|
|
<span t-if="applicant.permanent_zip" t-esc="applicant.permanent_zip"/>
|
|
</div>
|
|
<div t-if="applicant.permanent_country_id"
|
|
t-esc="applicant.permanent_country_id.display_name"/>
|
|
<t t-if="not applicant.permanent_street">
|
|
<div class="text-muted">Not specified</div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-4" style="grid-row: span 1;"
|
|
id="ats-notice-period">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-calendar me-2"></i>Notice Period
|
|
</h4>
|
|
<div class="detail-grid">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Notice Period:</span>
|
|
<span class="detail-value">
|
|
<t t-esc="applicant.notice_period or 'Not specified'"/>
|
|
<t t-if="applicant.notice_period_type">
|
|
<span t-esc="applicant.notice_period_type"/>
|
|
</t>
|
|
</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Negotiable:</span>
|
|
<span t-att-class="'badge ' + ('bg-success' if applicant.np_negotiable else 'bg-secondary')">
|
|
<t t-esc="'Yes' if applicant.np_negotiable else 'No'"/>
|
|
</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Holding Offer:</span>
|
|
<span t-att-class="'badge ' + ('bg-success' if applicant.holding_offer else 'bg-secondary') + ' animate__animated animate__pulse animate__infinite animate__slower'">
|
|
<t t-esc="'Yes' if applicant.holding_offer else 'No'"/>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-3" id="ats-resume">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-file-pdf me-2"></i>Resume
|
|
</h4>
|
|
<div class="attachment-item">
|
|
<div class="attachment-info">
|
|
<div class="attachment-name attachment-header" t-esc="resume.get('name')"/>
|
|
<div class="attachment-actions">
|
|
<!-- Preview Button -->
|
|
<a t-att-href="'/web/content/' + str(resume.get('attachment_id')) + '?download=false'"
|
|
class="btn btn-sm btn-outline-primary me-2 document-action-btn attachment-btn preview-btn"
|
|
target="_blank">
|
|
<i class="fa fa-eye me-1"></i>Preview
|
|
</a>
|
|
<!-- Download Button -->
|
|
<a t-att-href="'/web/content/' + str(resume.get('attachment_id')) + '?download=true'"
|
|
class="btn btn-sm btn-outline-success document-action-btn attachment-btn download-btn">
|
|
<i class="fa fa-download me-1"></i>Download
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-6" style="grid-row: span 2;" id="ats-salary-details">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-money-bill-wave me-2"></i>Salary Details
|
|
</h4>
|
|
<div class="detail-grid">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Current CTC:</span>
|
|
<span class="detail-value" t-esc="applicant.current_ctc or 'Not specified'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Expected Salary:</span>
|
|
<span class="detail-value">
|
|
<t t-esc="applicant.salary_expected or 'Not specified'"/>
|
|
<t t-if="applicant.salary_expected_extra">
|
|
+
|
|
<span t-esc="applicant.salary_expected_extra"/>
|
|
</t>
|
|
</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Proposed Salary:</span>
|
|
<span class="detail-value">
|
|
<t t-esc="applicant.salary_proposed or 'Not specified'"/>
|
|
<t t-if="applicant.salary_proposed_extra">
|
|
+
|
|
<span t-esc="applicant.salary_proposed_extra"/>
|
|
</t>
|
|
</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Salary Negotiable:</span>
|
|
<span t-att-class="'badge ' + ('bg-success' if applicant.salary_negotiable else 'bg-secondary') + ' animate__animated animate__pulse animate__infinite animate__slower'">
|
|
<t t-esc="'Yes' if applicant.salary_negotiable else 'No'"/>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-6" style="grid-row: span 2;"
|
|
id="ats-basic-details">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-file-text me-2"></i>Application Details
|
|
</h4>
|
|
<div class="detail-grid">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Applied for:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.job_id.display_name or 'Not specified'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Department:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.department_id.display_name or 'Not specified'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Recruiter:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.user_id.display_name or 'Not assigned'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Source:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.source_id.display_name or 'Not specified'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Medium:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.medium_id.display_name or 'Not specified'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Availability:</span>
|
|
<span class="detail-value" t-esc="applicant.availability or 'Not specified'"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-12" id="ats-work-experience">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-building me-2"></i>Work Experience
|
|
<small class="text-muted">Total:
|
|
<span t-esc="applicant.total_exp or '0'"/>
|
|
<span t-if="applicant.total_exp_type" t-esc="applicant.total_exp_type"/>
|
|
</small>
|
|
</h4>
|
|
<div t-if="applicant.employer_history and len(applicant.employer_history) > 0"
|
|
class="experience-list">
|
|
<t t-foreach="applicant.employer_history" t-as="exp">
|
|
<div class="experience-item animate__animated animate__fadeInLeft"
|
|
t-att-data-delay="exp_index * 100">
|
|
<div class="exp-header">
|
|
<h5 t-esc="exp.designation or 'No designation'"/>
|
|
<span class="exp-company" t-esc="exp.company_name or 'No company'"/>
|
|
</div>
|
|
<div class="exp-duration">
|
|
<i class="fa fa-calendar me-1"></i>
|
|
<span t-esc="exp.date_of_joining or 'Start date not specified'"/>
|
|
<span>to</span>
|
|
<span t-esc="exp.last_working_day or 'Present'"/>
|
|
</div>
|
|
<div class="exp-ctc" t-if="exp.ctc">
|
|
<i class="fa fa-money-bill-wave me-1"></i>
|
|
<span t-esc="exp.ctc"/>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<t t-else="">
|
|
<div class="alert alert-info animate__animated animate__fadeIn">No work experience
|
|
recorded
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<div class="ats-card span-12" id="ats-education-details">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-graduation-cap me-2"></i>Education
|
|
</h4>
|
|
<div t-if="applicant.education_history and len(applicant.education_history) > 0"
|
|
class="education-list">
|
|
<t t-foreach="applicant.education_history" t-as="edu">
|
|
<div class="education-item animate__animated animate__fadeInRight"
|
|
t-att-data-delay="edu_index * 100">
|
|
<div class="edu-header">
|
|
<h5 t-esc="edu.name or 'No degree'"/>
|
|
<span class="edu-type" t-esc="edu.education_type or 'No type'"/>
|
|
</div>
|
|
<div class="edu-university" t-esc="edu.university or 'No university'"/>
|
|
<div class="edu-duration">
|
|
<i class="fa fa-calendar me-1"></i>
|
|
<span t-esc="edu.start_year or 'Start year not specified'"/>
|
|
<span>to</span>
|
|
<span t-esc="edu.end_year or 'Present'"/>
|
|
</div>
|
|
<div class="edu-marks" t-if="edu.marks_or_grade">
|
|
<i class="fa fa-award me-1"></i>
|
|
<span t-esc="edu.marks_or_grade"/>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<t t-else="">
|
|
<div class="alert alert-info animate__animated animate__fadeIn">No education history
|
|
recorded
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<div class="ats-card span-12" id="ats-skills">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-star me-2"></i>Skills
|
|
<small class="text-muted float-end">
|
|
<span t-esc="len(applicant.candidate_skill_ids) or '0'"/>
|
|
skills recorded
|
|
</small>
|
|
</h4>
|
|
<div t-if="applicant.candidate_skill_ids and len(applicant.candidate_skill_ids) > 0"
|
|
class="skills-container">
|
|
<t t-foreach="applicant.candidate_skill_ids" t-as="skill">
|
|
<div class="skill-item animate__animated animate__fadeInUp"
|
|
t-att-data-delay="skill_index * 50">
|
|
<div class="skill-info">
|
|
<span class="skill-name" t-esc="skill.skill_id.display_name"/>
|
|
<span class="skill-type" t-esc="skill.skill_type_id.display_name"/>
|
|
</div>
|
|
<div class="skill-level">
|
|
<span class="skill-level-name"
|
|
t-esc="skill.skill_level_id.display_name"/>
|
|
<div class="progress">
|
|
<div class="progress-bar progress-bar-animated" role="progressbar"
|
|
t-att-style="'width: ' + str(skill.level_progress) + '%;'"
|
|
t-att-aria-valuenow="skill.level_progress"
|
|
aria-valuemin="0" aria-valuemax="100">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<t t-else="">
|
|
<div class="alert alert-info animate__animated animate__fadeIn">No skills recorded
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<div class="ats-card span-7" id="ats-attachments">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-paperclip me-2"></i>Attachments (Post On Boarding)
|
|
<small class="text-muted float-end">
|
|
<span t-esc="len(post_onboarding_attachments) or '0'"/>
|
|
attachments
|
|
</small>
|
|
</h4>
|
|
<div t-if="post_onboarding_attachments" class="attachments-list">
|
|
<t t-foreach="post_onboarding_attachments" t-as="attachment">
|
|
<div class="attachment-card attachment-item animate__animated animate__fadeInUp"
|
|
t-att-data-delay="attachment_index * 50">
|
|
<div class="attachment-info">
|
|
<div class="attachment-header">
|
|
<span class="attachment-title" t-esc="attachment.get('name')"/>
|
|
<span t-att-class="'attachment-badge ' + ('bg-success' if attachment.get('review_status') == 'pass' else 'bg-danger' if attachment.get('review_status') == 'fail' else 'bg-secondary')"
|
|
t-att-title="attachment.get('recruitment_attachment')"
|
|
t-esc="attachment.get('recruitment_attachment')"/>
|
|
</div>
|
|
<div class="attachment-actions">
|
|
<!-- Preview Button -->
|
|
<a t-if="attachment.get('attachment_id')"
|
|
t-att-href="'/web/content/' + str(attachment.get('attachment_id')) + '?download=false&filename=' + (attachment.get('name') or 'document') + (attachment.get('name') and '.' in attachment.get('name') and attachment.get('name').split('.')[-1] or '.pdf')"
|
|
class="btn btn-sm btn-outline-primary me-2 document-action-btn attachment-btn preview-btn"
|
|
target="_blank">
|
|
<i class="fa fa-eye me-1"></i>Preview
|
|
</a>
|
|
<!-- Download Button -->
|
|
<a t-if="attachment.get('attachment_id')"
|
|
t-att-href="'/web/content/' + str(attachment.get('attachment_id')) + '?download=true&filename=' + (attachment.get('name') or 'document') + (attachment.get('name') and '.' in attachment.get('name') and attachment.get('name').split('.')[-1] or '.pdf')"
|
|
class="btn btn-sm btn-outline-success document-action-btn attachment-btn download-btn">
|
|
<i class="fa fa-download me-1"></i>Download
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<t t-else="">
|
|
<div class="alert alert-info animate__animated animate__fadeIn">No Resume uploaded
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<div class="ats-card span-5" style="grid-row: span 1;" id="ats-current-organisation">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-briefcase me-2"></i>Current Organization
|
|
</h4>
|
|
<div class="detail-grid">
|
|
<div class="detail-row">
|
|
<span class="detail-label">Organization:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.current_organization or 'Not specified'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Location:</span>
|
|
<span class="detail-value"
|
|
t-esc="applicant.current_location or 'Not specified'"/>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label">Preferred Locations:</span>
|
|
<div class="skills-list">
|
|
<t t-foreach="applicant.preferred_location" t-as="loc">
|
|
<span class="location-badge animate__animated animate__fadeInUp"
|
|
t-att-data-delay="loc_index * 50"
|
|
t-esc="loc.display_name"/>
|
|
</t>
|
|
<t t-if="not applicant.preferred_location">
|
|
<span class="text-muted">Not specified</span>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-3" id="ats-recruited-by">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-user-tie me-2"></i>Recruited By
|
|
</h4>
|
|
<div class="recruiter-container">
|
|
<div class="recruiter-photo-wrapper" id="recruiter-photo-trigger">
|
|
<t t-if="applicant.user_id.image_128">
|
|
<img t-att-src="'/web/image/res.users/' + str(applicant.user_id.id) + '/image_128'"
|
|
class="rounded-circle recruiter-photo"
|
|
alt="Recruiter Photo"/>
|
|
</t>
|
|
<t t-else="">
|
|
<div class="recruiter-photo-placeholder">
|
|
<t t-if="applicant.user_id.display_name">
|
|
<t t-esc="applicant.user_id.display_name[0].upper()"/>
|
|
</t>
|
|
<t t-else="">
|
|
<t t-esc="applicant.display_name[0].upper()"/>
|
|
</t>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
<div class="recruiter-info" id="recruiter-info">
|
|
<div class="recruiter-name" t-esc="applicant.user_id.display_name or 'Not specified'"/>
|
|
<div class="recruiter-email" t-esc="applicant.user_id.email or ''"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="ats-card span-9" id="ats-timeline">
|
|
<h4 class="section-title">
|
|
<i class="fa fa-history me-2"></i>Application Timeline
|
|
</h4>
|
|
<div class="timeline">
|
|
<!-- Application Created -->
|
|
<div class="timeline-item animate__animated animate__fadeInLeft">
|
|
<div class="timeline-point"></div>
|
|
<div class="timeline-content">
|
|
<div class="timeline-header">
|
|
<h5>Application Created</h5>
|
|
<span class="timeline-date" t-esc="applicant.create_date"/>
|
|
</div>
|
|
<div class="timeline-body">
|
|
<p>Application was submitted for<span
|
|
t-esc="applicant.job_id.display_name or 'position'"/>.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Meetings/Interviews -->
|
|
<t t-foreach="applicant.meeting_ids" t-as="meeting">
|
|
<div class="timeline-item animate__animated animate__fadeInRight"
|
|
t-att-data-delay="meeting_index * 100">
|
|
<div class="timeline-point point-interview">
|
|
<i class="fa fa-calendar-check-o"></i>
|
|
</div>
|
|
<div class="timeline-content">
|
|
<div class="timeline-header">
|
|
<h5>
|
|
<span t-esc="meeting.name"/>
|
|
<!-- <span t-att-class="'badge ' + ('bg-success' if meeting.status == 'done' else 'bg-warning' if meeting.status == 'open' else 'bg-secondary')">-->
|
|
<!--<!– <t t-esc="meeting.state_id.capitalize()"/>–>-->
|
|
<!-- </span>-->
|
|
</h5>
|
|
<span class="timeline-date" t-esc="meeting.start"/>
|
|
</div>
|
|
<div class="timeline-body">
|
|
<p>With <span
|
|
t-esc="meeting.user_id.display_name or 'No organizer'"/>.
|
|
</p>
|
|
<p t-if="meeting.description" t-esc="meeting.description"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
<!-- Current Status -->
|
|
<div t-if="applicant.stage_id.stage_color"
|
|
class="timeline-item animate__animated animate__fadeInLeft">
|
|
<div t-att-class="'timeline-point point-' + applicant.stage_id.stage_color"></div>
|
|
<div class="timeline-content">
|
|
<div class="timeline-header">
|
|
<h5>Current Status:
|
|
<span t-esc="applicant.stage_id.display_name"/>
|
|
</h5>
|
|
<span class="timeline-date">Now</span>
|
|
</div>
|
|
<div class="timeline-body">
|
|
<p>The applicant is currently in this stage.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<template id="create_new_application_template">
|
|
<div id="application-creation-modal" class="application-creation-modal">
|
|
<div class="application-creation-content">
|
|
<div class="application-creation-header">
|
|
<div class="header-icon-container">
|
|
<i class="fas fa-user-plus header-icon"/>
|
|
<h3>Create New Applicant</h3>
|
|
</div>
|
|
<span class="application-creation-close">&times;</span>
|
|
</div>
|
|
|
|
<div class="application-creation-body">
|
|
<form id="new-applicant-form" class="application-creation-form">
|
|
<!-- Main Profile Section -->
|
|
|
|
<div class="form-section profile-section">
|
|
<h4 class="section-title">
|
|
<i class="fas fa-id-card"/>
|
|
Basic Information
|
|
</h4>
|
|
<div class="form-grid">
|
|
<t t-set="candidates" t-value="request.env['hr.candidate'].search([])"/>
|
|
<div class="form-group">
|
|
<label for="application-candidate-id">Candidate*</label>
|
|
<select id="application-candidate" class="form-select select2"
|
|
data-placeholder="Select Candidate" draggable="true">
|
|
<option value=""></option>
|
|
<t t-foreach="candidates" t-as="candidate" t-key="candidate.id">
|
|
<option t-att-value="candidate.id"
|
|
t-att-data-email="candidate.email_from"
|
|
t-att-data-phone="candidate.partner_phone"
|
|
t-att-data-alt-phone="candidate.alternate_phone"
|
|
t-att-data-linkedin="candidate.linkedin_profile"
|
|
t-att-data-skill-ids="candidate.candidate_skill_ids.skill_id.ids"
|
|
t-att-data-image="candidate.candidate_image and ('data:image/png;base64,' + candidate.candidate_image.decode('utf-8')) or '/web/static/img/placeholder.png'">
|
|
<t t-esc="candidate.display_name"/>
|
|
</option>
|
|
</t>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-email">Email*</label>
|
|
<input type="email" id="application-email" name="email" required="1"
|
|
placeholder="Enter email address" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-phone">Phone*</label>
|
|
<input type="tel" id="application-phone" name="phone" required="1"
|
|
placeholder="Enter phone number" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-alt-phone">Alternate Phone</label>
|
|
<input type="tel" id="application-alt-phone" name="alt_phone"
|
|
placeholder="Enter alternate phone" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-linkedin">LinkedIn Profile</label>
|
|
<input type="url" id="application-linkedin" name="linkedin"
|
|
placeholder="Enter LinkedIn URL" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<t t-set="job_recruitments" t-value="request.env['hr.job.recruitment'].sudo().search([])"/>
|
|
<label for="application-position">Position Applied For*</label>
|
|
<select id="application-position" class="form-select select2"
|
|
data-placeholder="Select Job">
|
|
<option value=""></option>
|
|
<t t-foreach="job_recruitments" t-as="job" t-key="job.id">
|
|
<option t-att-value="job.id">
|
|
<t t-esc="job.display_name"/>
|
|
</option>
|
|
</t>
|
|
</select>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Personal Details Section -->
|
|
<div class="form-section personal-section">
|
|
<h4 class="section-title">
|
|
<i class="fas fa-user-circle"/>
|
|
Personal Details
|
|
</h4>
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label for="application-gender">Gender</label>
|
|
<select id="application-gender" name="gender" class="form-select">
|
|
<option value="">Select gender</option>
|
|
<option value="male">Male</option>
|
|
<option value="female">Female</option>
|
|
<option value="other">Other</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-dob">Date of Birth</label>
|
|
<input type="date" id="application-dob" name="dob" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-marital">Marital Status</label>
|
|
<select id="application-marital" name="marital" class="form-select">
|
|
<option value="">Select status</option>
|
|
<option value="single">Single</option>
|
|
<option value="married">Married</option>
|
|
<option value="divorced">Divorced</option>
|
|
<option value="widowed">Widowed</option>
|
|
</select>
|
|
</div>
|
|
|
|
|
|
<div class="form-group marital-anniversary" id="marital-anniversary-field" style="display: none;">
|
|
<label for="application-anniversary">Marriage Anniversary</label>
|
|
<input type="date" id="application-anniversary" name="anniversary"
|
|
class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-blood">Blood Group</label>
|
|
<select id="application-blood" name="blood" class="form-select">
|
|
<option value="">Select blood group</option>
|
|
<option value="A+">A+</option>
|
|
<option value="A-">A-</option>
|
|
<option value="B+">B+</option>
|
|
<option value="B-">B-</option>
|
|
<option value="AB+">AB+</option>
|
|
<option value="AB-">AB-</option>
|
|
<option value="O+">O+</option>
|
|
<option value="O-">O-</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Professional Information -->
|
|
<div class="form-section professional-section">
|
|
<h4 class="section-title">
|
|
<i class="fas fa-briefcase"/>
|
|
Professional Information
|
|
</h4>
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label for="application-current-org">Current Organization</label>
|
|
<input type="text" id="application-current-org" name="current_org"
|
|
placeholder="Current company name" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-current-location">Current Location</label>
|
|
<input type="text" id="application-current-location" name="current_location"
|
|
placeholder="Current work location" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-notice-period">Notice Period (Days)</label>
|
|
<input type="number" id="application-notice-period" name="notice_period"
|
|
placeholder="Notice period in days" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-notice-negotiable">Notice Negotiable?</label>
|
|
<select id="application-notice-negotiable" name="notice_negotiable" class="form-select">
|
|
<option value="no">No</option>
|
|
<option value="yes">Yes</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-holding-offer">Holding Offer?</label>
|
|
<select id="application-holding-offer" name="holding_offer" class="form-select">
|
|
<option value="no">No</option>
|
|
<option value="yes">Yes</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-total-exp">Total Experience (Years)</label>
|
|
<input type="number" step="0.1" id="application-total-exp" name="total_exp"
|
|
placeholder="Total years of experience" class="form-input"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Salary Information -->
|
|
<div class="form-section salary-section">
|
|
<h4 class="section-title">
|
|
<i class="fas fa-money-bill-wave"/>
|
|
Salary Information
|
|
</h4>
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label for="application-current-ctc">Current CTC (₹)</label>
|
|
<input type="number" id="application-current-ctc" name="current_ctc"
|
|
placeholder="Current annual salary" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-expected-salary">Expected Salary (₹)</label>
|
|
<input type="number" id="application-expected-salary" name="expected_salary"
|
|
placeholder="Expected annual salary" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-salary-negotiable">Salary Negotiable?</label>
|
|
<select id="application-salary-negotiable" name="salary_negotiable" class="form-select">
|
|
<option value="no">No</option>
|
|
<option value="yes">Yes</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Education & Skills -->
|
|
<div class="form-section education-section">
|
|
<h4 class="section-title">
|
|
<i class="fas fa-graduation-cap"/>
|
|
Skills
|
|
</h4>
|
|
<div class="skills-container">
|
|
<t t-set="skills" t-value="request.env['hr.skill'].search([])"/>
|
|
<select id="application-skills" class="form-select select2" multiple="multiple"
|
|
data-placeholder="Select skills" draggable="true">
|
|
<t t-foreach="skills" t-as="skill" t-key="skill.id">
|
|
<option t-att-value="skill.id">
|
|
<t t-esc="skill.display_name"/>
|
|
</option>
|
|
</t>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Resume & Attachments -->
|
|
<div class="form-section attachments-section">
|
|
<h4 class="section-title">
|
|
<i class="fas fa-paperclip"/>
|
|
Resume & Attachments
|
|
</h4>
|
|
|
|
<div class="resume-upload-container">
|
|
<div class="upload-area" id="resume-dropzone">
|
|
<i class="fas fa-cloud-upload-alt upload-icon"/>
|
|
<h5>Upload Resume</h5>
|
|
<p>Drag & drop your resume here or click to browse</p>
|
|
<input type="file" id="resume-upload" name="resume" accept=".pdf,.doc,.docx,.jpg,.png,.jpeg,.txt"
|
|
class="file-input"/>
|
|
</div>
|
|
|
|
<div class="resume-preview" id="resume-preview">
|
|
<div class="resume-preview-placeholder">
|
|
<i class="fas fa-file-alt"></i>
|
|
<p>Resume preview will appear here</p>
|
|
</div>
|
|
<iframe id="resume-iframe" style="display: none;"></iframe>
|
|
<img id="resume-image" style="display: none; max-width: 100%; max-height: 400px;"/>
|
|
<div id="unsupported-format" style="display: none;">
|
|
<i class="fas fa-exclamation-triangle"></i>
|
|
<p>Preview not available for this file type</p>
|
|
<a id="download-resume" href="#" class="btn btn-primary mt-2">
|
|
<i class="fas fa-download"></i>
|
|
Download File
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="additional-attachments">
|
|
<label>Additional Documents</label>
|
|
<div class="attachments-list">
|
|
<!-- Additional attachments will be listed here -->
|
|
</div>
|
|
<button type="button" class="add-attachment btn-add">
|
|
<i class="fas fa-plus"/>
|
|
Add Attachment
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Application Details -->
|
|
<div class="form-section application-section">
|
|
<h4 class="section-title">
|
|
<i class="fas fa-file-alt"/>
|
|
Application Details
|
|
</h4>
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label for="application-source">Source</label>
|
|
<select id="application-source" name="source" class="form-select">
|
|
<option value="">Select source</option>
|
|
<option value="linkedin">LinkedIn</option>
|
|
<option value="naukri">Naukri</option>
|
|
<option value="referral">Referral</option>
|
|
<option value="website">Company Website</option>
|
|
<option value="other">Other</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-medium">Medium</label>
|
|
<select id="application-medium" name="medium" class="form-select">
|
|
<option value="">Select medium</option>
|
|
<option value="email">Email</option>
|
|
<option value="website">Website Form</option>
|
|
<option value="social">Social Media</option>
|
|
<option value="agency">Recruitment Agency</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-availability">Availability</label>
|
|
<input type="text" id="application-availability" name="availability"
|
|
placeholder="When can they join?" class="form-input"/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-department">Department</label>
|
|
<select id="application-department" name="department" class="form-select">
|
|
<option value="">Select department</option>
|
|
<!-- Departments will be populated dynamically -->
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-recruiter">Recruiter</label>
|
|
<select id="application-recruiter" name="recruiter" class="form-select">
|
|
<option value="">Select recruiter</option>
|
|
<!-- Recruiters will be populated dynamically -->
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="application-notes">Notes</label>
|
|
<textarea id="application-notes" name="notes"
|
|
placeholder="Any additional notes..." class="form-textarea"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="button" class="btn btn-application-primary" id="upload-resume">
|
|
<i class="fas fa-upload"></i>
|
|
Upload Resume
|
|
</button>
|
|
<div class="footer-right">
|
|
<button type="button" class="btn-cancel">Cancel</button>
|
|
<button type="submit" class="btn-application-primary btn-submit">
|
|
<i class="fas fa-save"/>
|
|
Create Applicant
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
</odoo> |