Loading application details...
;
+ const handleUpload = async () => {
+ if (!uploadFile || !uploadDocType) {
+ toast.warning('Please select a file and document type');
+ return;
}
- if (!application) {
- return Loading application details...
;
+ }
+
+ if (!application) {
+ return
-
+
+
+
+
No FDD Assignment
+
+ The Financial Due Diligence process has not been initiated for this application yet.
+
+
+
+ {(currentUser?.role === 'DD Admin' || currentUser?.role === 'Super Admin') && (
+
+
+
+
+ Initiate FDD Audit
+
+
+
+
+
+ Select FDD Agency
+ setSelectedAgencyId(e.target.value)}
+ >
+ Choose partner agency...
+ {fddAgencies && fddAgencies.map((agency: any) => (
+
+ {agency.fullName || agency.name} ({agency.email})
+
+ ))}
+
+
+
+ handleAssignAgency()}
+ disabled={isAssigningAgency || !selectedAgencyId}
+ >
+ {isAssigningAgency ? 'Assigning...' : 'Assign & Start Audit'}
+
+
+
+
+
+ )}
);
}
- if (!application) {
- return
Application not found
;
- }
-
- // Determine if current user has an active interview and if they have submitted feedback
- const interviewsList = Array.isArray(interviews) ? interviews : [];
-
- // For action buttons, we only care about pending interviews
- const activeInterviewForUser = interviewsList.find(i =>
- ['Scheduled', 'Rescheduled', 'Pending', 'In Progress'].includes(i.status) &&
- i.participants?.some((p: any) => p.userId === currentUser?.id)
- );
-
- // For checking if a decision was ALREADY made, we look at ANY interview the user participated in for the current level
- const lastInterviewForUser = [...interviewsList].reverse().find(i =>
- i.participants?.some((p: any) => p.userId === currentUser?.id)
- );
-
- const currentUserEvaluation = (activeInterviewForUser || lastInterviewForUser)?.evaluations?.find(
- (e: any) => e.evaluatorId === currentUser?.id
- );
-
- // Helper to check interview level completion
- const isInterviewCompleted = (level: number) => {
- return interviewsList.some(i => (Number(i.level) === level) && i.status === 'Completed');
- };
-
- const isInterviewActive = (level: number) => {
- return interviewsList.some(i => (Number(i.level) === level) && i.status === 'Scheduled');
- };
-
- // Robust checks for feedback and decision
- // 1. If there's an active interview, feedback is required before Approve/Reject
- // 2. hasMadeDecision should check if the evaluation has a recommendation
- const hasSubmittedFeedback = !!currentUserEvaluation;
-
- // Specific to the current active interview context
- const hasSubmittedFeedbackForActive = activeInterviewForUser && hasSubmittedFeedback;
- const policyManagedStages: { [key: string]: string } = {
- 'Level 1 Interview Pending': 'INTERVIEW_LEVEL_1',
- 'Level 2 Interview Pending': 'INTERVIEW_LEVEL_2',
- 'Level 2 Recommended': 'INTERVIEW_LEVEL_2',
- 'Level 3 Interview Pending': 'INTERVIEW_LEVEL_3',
- 'LOI In Progress': 'LOI_APPROVAL',
- 'LOA Pending': 'LOA_APPROVAL'
- };
-
- const currentStageCode = policyManagedStages[application.status];
- const currentUserStageAction = application.stageApprovals?.find(
- (a: any) =>
- a.stageCode === currentStageCode &&
- String(a.actorUserId) === String(currentUser?.id)
- );
-
- const hasMadeStageDecision = !!currentUserStageAction;
-
- const hasMadeDecisionForUser = !!currentUserStageAction ||
- currentUserEvaluation?.decision === 'Approved' ||
- currentUserEvaluation?.decision === 'Rejected' ||
- ['Approved', 'Rejected', 'Selected'].includes(currentUserEvaluation?.recommendation || '');
-
- // Centralized Permissions Utility (Consolidates 500 lines of fragmented logic)
- const getApplicationPermissions = () => {
- if (!application || !currentUser) {
- return { canApprove: false, canReject: false, canSchedule: false, canAssign: false, isLoaLocked: false, showDecisionMessage: false };
- }
-
- // 1. Core Flags
- const isAdminRole = ['DD Admin', 'Super Admin', 'NBH', 'DD Lead', 'DD Head', 'Finance', 'Finance Admin', 'FDD', 'ZBH', 'RBM'].includes(currentUser.role);
- const isAdministrativeStage = [
- 'Level 3 Approved', 'FDD Verification',
- 'LOI In Progress', 'LOI Issued', 'Statutory LOI Ack',
- 'Architecture Team Assigned', 'Architecture Document Upload', 'Architecture Team Completion',
- 'Statutory GST', 'Statutory PAN', 'Statutory Nodal', 'Statutory Check',
- 'Statutory Partnership', 'Statutory Firm Reg', 'Statutory Rental',
- 'Statutory Virtual Code', 'Statutory Domain', 'Statutory MSD',
- 'LOA Pending', 'EOR In Progress', 'EOR Complete', 'Inauguration'
- ].includes(application.status);
-
- const isLoaLocked = application.status === 'LOA Pending' && getDeposit('FIRST_FILL')?.status !== 'Verified';
- const isFinalState = application.status === 'Onboarded' || application.status === 'Rejected' || application.status === 'Approved';
-
- // 2. Interview Specific Logic
- const activeInterviewForUser = (interviews || []).find(i =>
- ['Scheduled', 'Rescheduled', 'Pending', 'In Progress'].includes(i.status) &&
- i.participants?.some((p: any) => p.userId === currentUser?.id)
- );
- const hasSubmittedFeedback = !!(activeInterviewForUser || lastInterviewForUser)?.evaluations?.find(
- (e: any) => e.evaluatorId === currentUser?.id
- );
-
- // 3. Sequential Sequence Check
- const ddHeadApproved = application.stageApprovals?.some((a: any) => a.stageCode === 'LOI_APPROVAL' && a.actorRole === 'DD Head' && a.decision === 'Approved');
- const ddHeadLoaApproved = application.stageApprovals?.some((a: any) => a.stageCode === 'LOA_APPROVAL' && a.actorRole === 'DD Head' && a.decision === 'Approved');
-
- let sequenceMet = true;
- if (!['Super Admin', 'DD Admin'].includes(currentUser.role)) {
- if (application.status === 'FDD Verification' || application.status === 'Level 3 Approved') sequenceMet = false;
- if (application.status === 'LOI In Progress') sequenceMet = (currentUser.role === 'NBH') ? !!ddHeadApproved : (currentUser.role === 'DD Head');
- if (application.status === 'LOA Pending') sequenceMet = (currentUser.role === 'NBH') ? !!ddHeadLoaApproved : (currentUser.role === 'DD Head');
- }
-
- // 4. Decision Tracking
- const hasMadeStageDecision = !!application.stageApprovals?.find(a => policyManagedStages[application.status] === a.stageCode && String(a.actorUserId) === String(currentUser.id));
- const hasMadeInterviewDecision = ['Approved', 'Rejected', 'Selected'].includes(currentUserEvaluation?.decision || currentUserEvaluation?.recommendation || '');
- const hasMadeDecisionTotal = hasMadeStageDecision || hasMadeInterviewDecision;
-
- // 5. Final Permission Bits
- const isDecisionMade = hasMadeDecisionTotal || hasMadeStageDecision;
- const canApproveReject = !isLoaLocked && !isFinalState && !isDecisionMade && (
- (!!activeInterviewForUser && !!hasSubmittedFeedback) ||
- (isAdminRole && isAdministrativeStage && sequenceMet)
- );
-
- return {
- canApprove: canApproveReject,
- canReject: canApproveReject,
- isLoaLocked,
- showDecisionMessage: isDecisionMade && (!isAdministrativeStage || hasMadeStageDecision),
- canSchedule: ['DD Admin', 'Super Admin', 'DD AM', 'ASM'].includes(currentUser.role) &&
- !isFinalState &&
- !([1, 2, 3].every(level => (interviews || []).some(i => i.level === level))),
- canAssign: ['DD Admin', 'Super Admin', 'DD AM'].includes(currentUser.role)
- };
- };
-
- const permissions = getApplicationPermissions();
-
-
-
-
- const renderFddAuditContent = () => {
- const assignments = application?.fddAssignments || [];
- const fddParticipants = application?.participants?.filter((p: any) =>
- p.user?.role === 'FDD' ||
- p.user?.roleCode === 'FDD' ||
- p.user?.allRoles?.includes('FDD')
- ) || [];
-
- const hasAssignment = assignments.length > 0 || fddParticipants.length > 0;
- const primaryFddUser = fddParticipants[0]?.user;
-
- const MANDATORY_FINANCIAL_DOCS = [
- { type: 'Bank Statement', label: 'Bank Statements' },
- { type: 'Income Tax Returns (ITR)', label: 'ITR (Last 3 Years)' },
- { type: 'CIBIL Report', label: 'CIBIL / Credit Reports' },
- { type: 'Property Documents', label: 'Property Documents' },
- { type: 'Business Valuation Report', label: 'Valuation Reports' }
- ];
-
- const getDocByTypeName = (typeName: string) => {
- if (!documents) return null;
- const target = typeName.toLowerCase();
- return documents.find((d: any) => {
- const docType = (d.documentType || '').toLowerCase();
- const fileName = (d.fileName || '').toLowerCase();
-
- if (docType === target) return true;
-
- if (target.includes('itr') && (docType.includes('itr') || fileName.includes('itr'))) return true;
- if (target.includes('bank statement') && (docType.includes('bank') || fileName.includes('bank'))) return true;
- if (target.includes('cibil') && (docType.includes('cibil') || fileName.includes('cibil') || docType.includes('credit'))) return true;
-
- return false;
- });
- };
-
- if (!hasAssignment && !['FDD Verification', 'LOI In Progress', 'Payment Pending'].includes(application.status)) {
- return (
-
-
-
-
No FDD Assignment
-
- The Financial Due Diligence process has not been initiated for this application yet.
-
+ return (
+
+ {/* FDD/Finance Audit Workspace */}
+ {/* FDD Status Header */}
+ {hasAssignment && (
+
+
+
+
+
+
+
FDD Assignment Active
+ {primaryFddUser &&
Assigned to: {primaryFddUser.name}
}
+
-
- {(currentUser?.role === 'DD Admin' || currentUser?.role === 'Super Admin') && (
-
-
-
-
- Initiate FDD Audit
-
-
-
-
-
- Select FDD Agency
- setSelectedAgencyId(e.target.value)}
- >
- Choose partner agency...
- {fddAgencies && fddAgencies.map((agency: any) => (
-
- {agency.fullName || agency.name} ({agency.email})
-
- ))}
-
-
-
- handleAssignAgency()}
- disabled={isAssigningAgency || !selectedAgencyId}
- >
- {isAssigningAgency ? 'Assigning...' : 'Assign & Start Audit'}
-
-
-
-
-
- )}
- );
- }
+ )}
- return (
-
- {/* FDD/Finance Audit Workspace */}
- {((currentUser?.role === 'FDD' || currentUser?.role === 'DD Admin' || currentUser?.role === 'Super Admin' || hasAssignment) &&
- (['FDD Verification', 'Level 3 Approved', 'LOI In Progress'].includes(application.status))) && (
-
-
-
-
-
-
- Audit Management Workspace {primaryFddUser && Assigned to: {primaryFddUser.name} }
-
-
Capture financial findings, upload reports, and provide your formal recommendation to progress the application.
-
-
- {
- const file = e.target.files?.[0];
- if (!file) return;
- try {
- setIsUploading(true);
- const formData = new FormData();
- formData.append('file', file);
- formData.append('documentType', 'FDD Final Audit Report');
- formData.append('stage', 'FDD');
- formData.append('applicationId', application.id);
- await onboardingService.uploadDocument(application.id, formData);
- toast.success('FDD Final Audit Report uploaded successfully');
- refreshDocuments();
- } catch (err) {
- toast.error('Upload failed');
- } finally {
- setIsUploading(false);
- }
- }}
- />
- document.getElementById('fdd-report-upload')?.click()}
- >
-
- {isUploading ? 'Uploading...' : 'Upload Report'}
-
- {(currentUser?.role === 'DD Admin' || currentUser?.role === 'Super Admin') && (
- <>
- setShowFddFlagModal(true)}
- >
- Flag Non-Responsive
-
- setShowFddFinalizeModal(true)}
- >
- Finalize Audit
-
- >
- )}
-
-
- )}
-
- {/* Financial Document Checklist Section */}
-
-
-
- Financial Artefacts Checklist
- Verify before sign-off
-
-
-
-
- {MANDATORY_FINANCIAL_DOCS.map((docType) => {
- const doc = getDocByTypeName(docType.type);
- return (
-
-
-
-
-
{docType.label}
-
- {doc ? `Uploaded: ${formatDateTime(doc.createdAt)}` : 'Missing in Documentation'}
-
-
-
- {doc ? (
-
- {
- setPreviewDoc(doc);
- setShowPreviewModal(true);
- }}
- >
-
- Preview
-
-
- ) : (
-
{
- const input = document.createElement('input');
- input.type = 'file';
- input.onchange = async (e: any) => {
- const file = e.target.files[0];
- if (!file) return;
- try {
- setIsUploading(true);
- const formData = new FormData();
- formData.append('file', file);
- formData.append('documentType', docType.type);
- formData.append('stage', 'FDD');
- formData.append('applicationId', application.id);
- await onboardingService.uploadDocument(application.id, formData);
- toast.success(`${docType.label} uploaded successfully`);
- refreshDocuments();
- } catch (err) {
- toast.error('Upload failed');
- } finally {
- setIsUploading(false);
- }
- };
- input.click();
- }}
- >
-
- Upload
-
- )}
-
- );
- })}
-
-
-
-
-
-
-
Financial Due Diligence Reports
-
- {assignments.length} Assignment(s)
-
-
-
- {assignments.map((assignment: any) => (
-
-
-
-
-
-
+ {/* Financial Document Checklist Section */}
+
+
+
+ Financial Artefacts Checklist
+ Verify before sign-off
+
+
+
+
+ {MANDATORY_FINANCIAL_DOCS.map((docType) => {
+ const doc = getDocByTypeName(docType.type);
+ return (
+
+
+
-
FDD Agency Audit
-
- Agency ID: {assignment.assignedToAgency || 'Assigned'} • Status: {assignment.status}
+
{docType.label}
+
+ {doc ? `Uploaded: ${formatDateTime(doc.createdAt)}` : 'Missing in Documentation'}
-
- {assignment.status}
-
-
-
-
- {(!assignment.reports || assignment.reports.length === 0) ? (
-
-
-
Waiting for internal or external agency to submit the final audit report...
-
- ) : (
-
- {assignment.reports.map((report: any) => (
-
-
-
- {/* Auditor Recommendation Hidden as per request */}
-
-
-
Findings Summary
-
- "{report.findings || 'No detail findings provided by the auditor.'}"
-
-
-
-
-
-
Report Document
- {report.reportDocument ? (
-
-
-
-
-
-
-
SUBMITTED {formatDateTime(report.createdAt)}
-
-
-
- {
- e.stopPropagation();
- window.open(`http://localhost:5000/${report.reportDocument.filePath}`, '_blank');
- }}
- >
-
-
- {
- e.stopPropagation();
- setPreviewDoc(report.reportDocument);
- setShowPreviewModal(true);
- }}
- >
-
-
-
-
- ) : (
-
- No audit report file attached
-
- )}
-
-
-
-
-
- Submitted by: {report.submitter?.fullName || 'Auditor'}
-
-
-
- {report.verifiedAt ? (
-
-
- Verified by {report.verifier?.fullName || 'Admin'}
-
- ) : (
-
-
- Pending Review
-
- )}
-
-
-
-
- ))}
-
- )}
-
-
- ))}
-
- {/* FDD Supporting Documents Section */}
-
-
-
Supporting Audit Documents
-
- {documents.filter(d => {
- const type = (d.documentType || '').toLowerCase();
- const stage = (d.stage || '').toLowerCase();
- return stage === 'fdd' ||
- type.includes('report') ||
- type.includes('itr') ||
- type.includes('bank') ||
- type.includes('cibil') ||
- type.includes('valuation');
- }).length} Document(s)
-
-
-
-
- {documents.filter(d => {
- const type = (d.documentType || '').toLowerCase();
- const stage = (d.stage || '').toLowerCase();
- return stage === 'fdd' ||
- type.includes('report') ||
- type.includes('itr') ||
- type.includes('bank') ||
- type.includes('cibil') ||
- type.includes('valuation');
- }).map((doc) => (
-
-
-
-
+ {doc ? (
+
+ {
+ setPreviewDoc(doc);
+ setShowPreviewModal(true);
+ }}
+ >
+
+ Preview
+
-
-
{doc.fileName}
-
{doc.documentType}
-
-
-
+ ) : (
window.open(`http://localhost:5000/${doc.filePath}`, '_blank')}
- >
-
-
- {
- setPreviewDoc(doc);
- setShowPreviewModal(true);
+ const input = document.createElement('input');
+ input.type = 'file';
+ input.onchange = async (e: any) => {
+ const file = e.target.files[0];
+ if (!file) return;
+ try {
+ setIsUploading(true);
+ const formData = new FormData();
+ formData.append('file', file);
+ formData.append('documentType', docType.type);
+ formData.append('stage', 'FDD');
+ formData.append('applicationId', application.id);
+ const res = await onboardingService.uploadDocument(application.id, formData);
+
+ // Auto-link if it's the final report
+ if (docType.type === 'FDD Final Audit Report') {
+ await onboardingService.submitFddReport({
+ applicationId: application.id,
+ reportDocumentId: res.data?.id || res.id,
+ findings: 'Final Audit Report uploaded via checklist.',
+ recommendation: 'REVIEW_PENDING'
+ });
+ fetchApplication();
+ }
+
+ toast.success(`${docType.label} uploaded successfully`);
+ refreshDocuments();
+ } catch (err) {
+ toast.error('Upload failed');
+ } finally {
+ setIsUploading(false);
+ }
+ };
+ input.click();
}}
>
-
+
+ Upload
-
+ )}
- ))}
+ );
+ })}
+
+
+
+
+ {/* Supporting documents and checklist are enough for simplified view */}
+
+ {/* FDD Supporting Documents Section */}
+
+
+
Supporting Audit Documents
+
{documents.filter(d => {
const type = (d.documentType || '').toLowerCase();
const stage = (d.stage || '').toLowerCase();
- return stage === 'fdd' ||
- type.includes('report') ||
- type.includes('itr') ||
- type.includes('bank') ||
- type.includes('cibil') ||
- type.includes('valuation');
- }).length === 0 && (
+ return stage === 'fdd' ||
+ type.includes('report') ||
+ type.includes('itr') ||
+ type.includes('bank') ||
+ type.includes('cibil') ||
+ type.includes('valuation');
+ }).length} Document(s)
+
+
+
+
+ {documents.filter(d => {
+ const type = (d.documentType || '').toLowerCase();
+ const stage = (d.stage || '').toLowerCase();
+ return stage === 'fdd' ||
+ type.includes('report') ||
+ type.includes('itr') ||
+ type.includes('bank') ||
+ type.includes('cibil') ||
+ type.includes('valuation');
+ }).map((doc) => (
+
+
+
+
+
+
+
{doc.fileName}
+
{doc.documentType}
+
+
+
+ window.open(`http://localhost:5000/${doc.filePath}`, '_blank')}
+ >
+
+
+ {
+ setPreviewDoc(doc);
+ setShowPreviewModal(true);
+ }}
+ >
+
+
+
+
+ ))}
+
+ {documents.filter(d => {
+ const type = (d.documentType || '').toLowerCase();
+ const stage = (d.stage || '').toLowerCase();
+ return stage === 'fdd' ||
+ type.includes('report') ||
+ type.includes('itr') ||
+ type.includes('bank') ||
+ type.includes('cibil') ||
+ type.includes('valuation');
+ }).length === 0 && (
No supporting audit documents uploaded yet.
)}
-
- );
- };
+
+ );
+ };
- return (
-
- {/* Header */}
-
+ return (
+
+ {isNonResponsive && (
+
-
-
-
-
-
{application.name}
-
{application.registrationNumber}
+
+
+
+
+
Applicant Flagged Non-Responsive
+
Audit process is currently on hold due to missing cooperation
-
+ {isAdmin && (
navigate(`/worknotes/application/${application.id}`, {
- state: {
- applicationName: application.name,
- registrationNumber: application.registrationNumber,
- participants: application.participants
- }
- })}
+ size="sm"
+ className="bg-white border-red-200 text-red-600 hover:bg-red-50 font-black text-[10px] uppercase tracking-widest hidden sm:block h-9"
+ onClick={() => {
+ const worknotesTab = document.querySelector('[value="worknotes"]') as HTMLElement;
+ worknotesTab?.click();
+ }}
>
-
- View Work Notes
+ Review Audit
+ )}
+
+ )}
+
+ {/* Header */}
+
+
+
+
+
+
+
{application.name}
+
{application.registrationNumber}
+
+ navigate(`/worknotes/application/${application.id}`, {
+ state: {
+ applicationName: application.name,
+ registrationNumber: application.registrationNumber,
+ participants: application.participants
+ }
+ })}
+ >
+
+ View Work Notes
+
+
+
-
- {/* Main Content */}
-
- {/* Core Details Card */}
-
-
- Applicant Information
-
-
-
-
-
-
-
Full Name
-
{application.name}
-
+
+ {/* Main Content */}
+
+ {/* Core Details Card */}
+
+
+ Applicant Information
+
+
+
+
+
+
+
Full Name
+
{application.name}
+
-
-
-
-
Email
-
{application.email}
-
+
+
+
+
Email
+
{application.email}
+
-
-
-
-
Phone
-
{application.phone}
-
+
+
+
+
Phone
+
{application.phone}
+
-
-
-
-
Age
-
{application.age ? `${application.age} years` : 'N/A'}
-
+
+
+
+
Age
+
{application.age ? `${application.age} years` : 'N/A'}
+
-
-
-
-
Education
-
{application.education || 'N/A'}
-
+
+
+
+
Education
+
{application.education || 'N/A'}
+
-
-
-
-
Preferred Location
-
{application.preferredLocation || 'N/A'}
-
+
+
+
+
Preferred Location
+
{application.preferredLocation || 'N/A'}
+
-
-
-
-
Location Type
-
{application.locationType || 'N/A'}
-
+
+
+
+
Location Type
+
{application.locationType || 'N/A'}
+
-
-
-
-
{
- setTempFirmType(application.constitutionType || '');
- setShowFirmTypeModal(true);
- }}>
- Proposed Firm Type
-
-
-
- {application.constitutionType || 'Not Provided'}
-
-
+
+
+
+
{
+ setTempFirmType(application.constitutionType || '');
+ setShowFirmTypeModal(true);
+ }}>
+ Proposed Firm Type
+
+
+
+ {application.constitutionType || 'Not Provided'}
+
+
+
+
+
+
Owns Bike
+
{application.ownRoyalEnfield === 'yes' ? 'Yes' : 'No'}
+
+
+
+ {application.ownRoyalEnfield === 'yes' && (
-
Owns Bike
-
{application.ownRoyalEnfield === 'yes' ? 'Yes' : 'No'}
+
Bike Model
+
{application.royalEnfieldModel || 'N/A'}
+ )}
- {application.ownRoyalEnfield === 'yes' && (
-
-
-
-
Bike Model
-
{application.royalEnfieldModel || 'N/A'}
-
-
- )}
+
+
+
+
Existing Dealer
+
{application.existingDealer === 'yes' ? 'Yes' : 'No'}
+
+
+ {application.existingDealer === 'yes' && (
-
Existing Dealer
-
{application.existingDealer === 'yes' ? 'Yes' : 'No'}
+
Company Name
+
{application.companyName || 'N/A'}
+ )}
- {application.existingDealer === 'yes' && (
-
-
-
-
Company Name
-
{application.companyName || 'N/A'}
-
-
- )}
+
+
+
+
Source
+
{application.source || 'N/A'}
+
+
+ {application.questionnaireMarks !== undefined && (
-
+
-
Source
-
{application.source || 'N/A'}
+
Questionnaire Score
+
{application.questionnaireMarks}/100
+ )}
+
- {application.questionnaireMarks !== undefined && (
-
-
-
-
Questionnaire Score
-
{application.questionnaireMarks}/100
-
-
+
+
+
+
Address
+
{application.address || 'N/A'}
+
+
+
+
Pincode
+
{application.pincode || 'N/A'}
+
+
+
+
Description
+
{application.description || 'N/A'}
+
+
+
+
Past Experience
+
{application.pastExperience || 'N/A'}
+
+
+
+
+
+ Statutory & Bank Information
+
+ {canEditStatutory && !isEditingStatutory && (
+
+
+ Edit Details
+
)}
-
-
-
-
Address
-
{application.address || 'N/A'}
-
-
-
-
Pincode
-
{application.pincode || 'N/A'}
-
-
-
-
Description
-
{application.description || 'N/A'}
-
-
-
-
Past Experience
-
{application.pastExperience || 'N/A'}
-
-
-
-
-
- Statutory & Bank Information
-
- {canEditStatutory && !isEditingStatutory && (
-
+
+
+
setIsEditingStatutory(false)}
+ disabled={isSavingStatutory}
>
-
- Edit Details
+ Cancel
- )}
+
+ {isSavingStatutory ? : 'Save Details'}
+
+
-
- {isEditingStatutory ? (
-
-
-
- setIsEditingStatutory(false)}
- disabled={isSavingStatutory}
- >
- Cancel
-
-
- {isSavingStatutory ? : 'Save Details'}
-
-
+ ) : (
+
+
+
Legal Entity Name
+
{application.accountHolderName || 'Pending'}
- ) : (
-
-
-
Legal Entity Name
-
{application.accountHolderName || 'Pending'}
-
-
-
PAN Number
-
{application.panNumber || 'Pending'}
-
-
-
GST Number
-
{application.gstNumber || 'Pending'}
-
-
-
Registered Address
-
{application.registeredAddress || 'Pending'}
-
-
-
Bank Details
-
{application.bankName || 'N/A'}
-
A/C: {application.accountNumber || 'N/A'}
-
IFSC: {application.ifscCode || 'N/A'}
-
+
+
PAN Number
+
{application.panNumber || 'Pending'}
- )}
-
-
-
-
- {/* Tabs Section */}
- {/* Only show tabs for shortlisted applications (opportunity requests and regular dealership requests) */}
- {/* Hide tabs for non-opportunity requests (lead generation) */}
- {application.isShortlisted !== false && (
-
-
-
-
-
- Questionnaire
- Progress
- Documents
- Interviews
- FDD Audit
- EOR Checklist
- Payments
- Audit Trail
-
+
+
GST Number
+
{application.gstNumber || 'Pending'}
-
+
+
Registered Address
+
{application.registeredAddress || 'Pending'}
+
+
+
Bank Details
+
{application.bankName || 'N/A'}
+
A/C: {application.accountNumber || 'N/A'}
+
IFSC: {application.ifscCode || 'N/A'}
+
+
+ )}
+
+
+
-
- {/* Questionnaire Response Tab */}
-
-
-
+ {/* Tabs Section */}
+ {/* Only show tabs for shortlisted applications (opportunity requests and regular dealership requests) */}
+ {/* Hide tabs for non-opportunity requests (lead generation) */}
+ {application.isShortlisted !== false && (
+
+
+
+
+
+ Questionnaire
+ Progress
+ Documents
+ Interviews
+ FDD Audit
+ EOR Checklist
+ Payments
+ Audit Trail
+
+
+
- {/* Progress Tab */}
-
-
-
-
Application Journey
- {application.progress}% Complete
-
-
+
+ {/* Questionnaire Response Tab */}
+
+
+
+
+ {/* Progress Tab */}
+
+
+
+
Application Journey
+ {application.progress}% Complete
+
+
-
- {(() => {
- const getApproverStatus = (stageCode: string | number) => {
- const stageParticipants = (application.participants || []).filter((p: any) =>
- p.metadata?.stageCode === stageCode ||
- p.metadata?.allAssignments?.includes(stageCode) ||
- (typeof stageCode === 'number' && (p.metadata?.interviewLevel === stageCode || p.metadata?.allAssignments?.includes(stageCode))) ||
- (typeof stageCode === 'string' && !isNaN(Number(stageCode)) && (p.metadata?.interviewLevel === Number(stageCode) || p.metadata?.allAssignments?.includes(Number(stageCode))))
+
+ {(() => {
+ const getApproverStatus = (stageCode: string | number) => {
+ const stageParticipants = (application.participants || []).filter((p: any) =>
+ p.metadata?.stageCode === stageCode ||
+ p.metadata?.allAssignments?.includes(stageCode) ||
+ (typeof stageCode === 'number' && (p.metadata?.interviewLevel === stageCode || p.metadata?.allAssignments?.includes(stageCode))) ||
+ (typeof stageCode === 'string' && !isNaN(Number(stageCode)) && (p.metadata?.interviewLevel === Number(stageCode) || p.metadata?.allAssignments?.includes(Number(stageCode))))
+ );
+
+ return stageParticipants.map((p: any) => {
+ const saCode = typeof stageCode === 'number' ? `INTERVIEW_LEVEL_${stageCode}` : stageCode;
+ const approval = (application.stageApprovals || []).find((sa: any) =>
+ sa.stageCode === saCode &&
+ String(sa.actorUserId) === String(p.userId)
);
- return stageParticipants.map((p: any) => {
- const saCode = typeof stageCode === 'number' ? `INTERVIEW_LEVEL_${stageCode}` : stageCode;
- const approval = (application.stageApprovals || []).find((sa: any) =>
- sa.stageCode === saCode &&
- String(sa.actorUserId) === String(p.userId)
- );
-
- return {
- name: p.user?.name || 'Unknown',
- role: p.user?.role || 'Reviewer',
- status: approval ? (approval.decision === 'Approved' ? 'approved' : 'rejected') : 'pending'
- };
- });
- };
-
- const renderApprovers = (stageName: string) => {
- const stageMapping: Record
= {
- '1st Level Interview': 1,
- '2nd Level Interview': 2,
- '3rd Level Interview': 3,
- 'LOI Approval': 'LOI_APPROVAL',
- 'LOA': 'LOA_APPROVAL'
+ return {
+ name: p.user?.name || 'Unknown',
+ role: p.user?.role || 'Reviewer',
+ status: approval ? (approval.decision === 'Approved' ? 'approved' : 'rejected') : 'pending'
};
+ });
+ };
- const stageCode = stageMapping[stageName];
- if (!stageCode) return null;
-
- const approvers = getApproverStatus(stageCode);
- if (approvers.length === 0) return null;
-
- return (
-
- {approvers.map((approver, i) => (
-
-
- {approver.name.split(' ').map((n: string) => n[0]).join('').substring(0, 2).toUpperCase()}
-
-
- {approver.name}
- {approver.role}
-
-
- {/* Status Dot Overlay */}
-
-
- {/* Tooltip */}
-
- {approver.role}: {approver.status.toUpperCase()}
-
-
- ))}
-
- );
+ const renderApprovers = (stageName: string) => {
+ const stageMapping: Record = {
+ '1st Level Interview': 1,
+ '2nd Level Interview': 2,
+ '3rd Level Interview': 3,
+ 'LOI Approval': 'LOI_APPROVAL',
+ 'LOA': 'LOA_APPROVAL'
};
- return processStages.map((stage, index) => (
-
-
-
-
- {stage.isParallel ? (
-
- ) : stage.isLocked ? (
-
-
-
-
-
- Stage Locked
-
-
{stage.lockMessage}
-
-
-
-
- ) : (
- <>
- {stage.status === 'completed' ? (
-
- ) : stage.status === 'active' ? (
-
- ) : (
-
- )}
- >
- )}
+ const stageCode = stageMapping[stageName];
+ if (!stageCode) return null;
+
+ const approvers = getApproverStatus(stageCode);
+ if (approvers.length === 0) return null;
+
+ return (
+
+ {approvers.map((approver, i) => (
+
+
+ {approver.name.split(' ').map((n: string) => n[0]).join('').substring(0, 2).toUpperCase()}
- {index < processStages.length - 1 && !stage.isParallel && (
-
- )}
-
-
-
{stage.name}
- {stage.description && (
-
{stage.description}
- )}
-
- {renderApprovers(stage.name as string)}
-
- {stage.evaluators && stage.evaluators.length > 0 && !['LOI Approval', 'LOA', '1st Level Interview', '2nd Level Interview', '3rd Level Interview'].includes(stage.name as string) && (
-
-
- Evaluators: {stage.evaluators.join(' + ')}
-
- )}
-
- {(() => {
- const expectedMap: Record
= {
- 3: 2, // Shortlist (Expected to have auto-mapped interviewers for next steps)
- 4: 2, // L1 Interview (ZM + RBM)
- 5: 2, // L2 Interview (ZBH + DD Lead)
- 6: 2, // L3 Interview (NBH + DD Head)
- 8: 2, // LOI Approval (DD Head + NBH)
- 12: 2 // LOA Approval (DD Head + NBH)
- };
- const stageId = Number(stage.id);
- const expectedCount = expectedMap[stageId];
-
- // For Shortlist step, check if Interview Level 1 evaluators are missing
- let actualCount = stage.evaluators?.length || 0;
- if (stageId === 3) {
- const l1Evaluators = (application.participants || []).filter((p: any) => p.metadata?.interviewLevel === 1 || p.metadata?.interviewLevel === '1');
- actualCount = l1Evaluators.length;
- }
-
- // Only show warning if stage is active/completed
- // For Shortlist (3), show ONLY after it's finished to avoid clutter during earlier steps
- const isEligibleForWarning = stageId === 3 ? (stage.status === 'completed') : (stage.status !== 'pending');
-
- if (expectedCount && actualCount < expectedCount && application.status !== 'Rejected' && isEligibleForWarning) {
- return (
-
-
-
- Missing Evaluators
-
- {actualCount === 0
- ? "Respective role users were not found for this location."
- : `Some roles (${actualCount}/${expectedCount}) are missing for this location.`
- }
-
-
- Re-trigger Assignment
-
-
-
-
- );
- }
- return null;
- })()}
-
- {(() => {
- const stageDocsCount = documents.filter(doc =>
- doc.stage === stage.name ||
- (!doc.stage && doc.documentType?.toLowerCase().includes(stage.name.toLowerCase().split(' ')[0]))
- ).length;
-
- return (
-
-
{
- setSelectedStage(stage.name);
- setShowDocumentsModal(true);
- if (stageDocsCount === 0) setShowUploadForm(true);
- }}
- className="text-xs font-semibold text-blue-600 hover:text-blue-800 flex items-center gap-1.5 px-3 py-1 rounded-full bg-blue-50 border border-blue-100 hover:bg-blue-100 transition-all shadow-sm"
- >
-
- {stageDocsCount > 0 ? `${stageDocsCount} Documents` : 'Upload'}
-
+
+ {approver.name}
+ {approver.role}
- );
- })()}
-
- {stage.status === 'completed' && stage.date && `Completed: ${formatDateTime(stage.date)}`}
- {stage.status === 'active' && 'In Progress'}
- {stage.status === 'pending' && 'Pending'}
-
+ {/* Status Dot Overlay */}
+
+
+ {/* Tooltip */}
+
+ {approver.role}: {approver.status.toUpperCase()}
+
-
-
- {stage.isParallel && stage.branches && (
-
- {stage.branches.map((branch, branchIndex) => {
- const branchKey = branch.name.toLowerCase().replace(/\s+/g, '-');
- const isExpanded = expandedBranches[branchKey];
- const branchColor = branch.color === 'blue' ? 'blue' : 'green';
-
- return (
-
-
-
setExpandedBranches(prev => ({
- ...prev,
- [branchKey]: !prev[branchKey]
- }))}
- className={`flex-1 flex items-center gap-3 p-4 rounded-lg border-2 transition-all hover:shadow-md ${branchColor === 'blue'
- ? 'border-blue-300 bg-blue-50 hover:bg-blue-100'
- : 'border-green-300 bg-green-50 hover:bg-green-100'
- }`}
- >
- {isExpanded ? (
-
- ) : (
-
- )}
-
-
-
-
-
- {branch.name}
-
-
- {branch.stages.length} SUB-STEPS
-
-
-
-
-
-
-
- {isExpanded && (
-
- {branch.stages.map((branchStage) => (
-
-
- {(() => {
- const stageDocs = documents.filter(doc =>
- doc.documentType?.toLowerCase().includes(branchStage.name.toLowerCase().split(' ')[0]) ||
- doc.stage === branchStage.name
- );
- const isDone = branchStage.status === 'completed' || stageDocs.length > 0;
-
- return (
- <>
-
-
- {isDone ? (
-
- ) : branchStage.status === 'active' ? (
-
- ) : (
-
- )}
-
-
-
-
{branchStage.name}
- {branchStage.description && (
-
{branchStage.description}
- )}
-
-
- {
- setSelectedStage(branchStage.name);
- setShowDocumentsModal(true);
- if (stageDocs.length === 0) setShowUploadForm(true);
- }}
- className="text-[10px] font-medium text-blue-600 hover:text-blue-800 flex items-center gap-1 transition-colors"
- >
-
- {stageDocs.length > 0 ? `${stageDocs.length} Docs` : 'Upload'}
-
-
-
- {isDone && branchStage.date ? `Done: ${formatDateTime(branchStage.date)}` : isDone && stageDocs.length > 0 ? `Uploaded: ${formatDateTime(stageDocs[0].updatedAt || stageDocs[0].createdAt)}` : branchStage.status === 'active' ? 'Evaluating' : 'Pending'}
-
-
- >
- );
- })()}
-
-
- ))}
-
- )}
-
- );
- })}
-
-
- )}
+ ))}
- ))
- })()}
-
-
+ );
+ };
- {/* Documents Tab */}
-
-
-
Uploaded Documents
- {
- setSelectedStage(null);
- setShowDocumentsModal(true);
- setShowUploadForm(true);
- }}>
-
- Upload Document
-
-
+ return processStages.map((stage, index) => (
+
+
+
+
+ {stage.isParallel ? (
+
+ ) : stage.isLocked ? (
+
+
+
+
+
+ Stage Locked
+
+
{stage.lockMessage}
+
+
+
+
+ ) : (
+ <>
+ {stage.status === 'completed' ? (
+
+ ) : stage.status === 'active' ? (
+
+ ) : (
+
+ )}
+ >
+ )}
+
+ {index < processStages.length - 1 && !stage.isParallel && (
+
+ )}
+
+
+
{stage.name}
+ {stage.description && (
+
{stage.description}
+ )}
+ {renderApprovers(stage.name as string)}
+
+ {stage.evaluators && stage.evaluators.length > 0 && !['LOI Approval', 'LOA', '1st Level Interview', '2nd Level Interview', '3rd Level Interview'].includes(stage.name as string) && (
+
+
+ Evaluators: {stage.evaluators.join(' + ')}
+
+ )}
+
+ {(() => {
+ const expectedMap: Record
= {
+ 3: 2, // Shortlist (Expected to have auto-mapped interviewers for next steps)
+ 4: 2, // L1 Interview (ZM + RBM)
+ 5: 2, // L2 Interview (ZBH + DD Lead)
+ 6: 2, // L3 Interview (NBH + DD Head)
+ 8: 2, // LOI Approval (DD Head + NBH)
+ 12: 2 // LOA Approval (DD Head + NBH)
+ };
+ const stageId = Number(stage.id);
+ const expectedCount = expectedMap[stageId];
+
+ // For Shortlist step, check if Interview Level 1 evaluators are missing
+ let actualCount = stage.evaluators?.length || 0;
+ if (stageId === 3) {
+ const l1Evaluators = (application.participants || []).filter((p: any) => p.metadata?.interviewLevel === 1 || p.metadata?.interviewLevel === '1');
+ actualCount = l1Evaluators.length;
+ }
+
+ // Only show warning if stage is active/completed
+ // For Shortlist (3), show ONLY after it's finished to avoid clutter during earlier steps
+ const isEligibleForWarning = stageId === 3 ? (stage.status === 'completed') : (stage.status !== 'pending');
+
+ if (expectedCount && actualCount < expectedCount && application.status !== 'Rejected' && isEligibleForWarning) {
+ return (
+
+
+
+ Missing Evaluators
+
+ {actualCount === 0
+ ? "Respective role users were not found for this location."
+ : `Some roles (${actualCount}/${expectedCount}) are missing for this location.`
+ }
+
+
+ Re-trigger Assignment
+
+
+
+
+ );
+ }
+ return null;
+ })()}
+
+ {(() => {
+ const stageDocsCount = documents.filter(doc =>
+ doc.stage === stage.name ||
+ (!doc.stage && doc.documentType?.toLowerCase().includes(stage.name.toLowerCase().split(' ')[0]))
+ ).length;
+
+ return (
+
+ {
+ setSelectedStage(stage.name);
+ setShowDocumentsModal(true);
+ if (stageDocsCount === 0) setShowUploadForm(true);
+ }}
+ className="text-xs font-semibold text-blue-600 hover:text-blue-800 flex items-center gap-1.5 px-3 py-1 rounded-full bg-blue-50 border border-blue-100 hover:bg-blue-100 transition-all shadow-sm"
+ >
+
+ {stageDocsCount > 0 ? `${stageDocsCount} Documents` : 'Upload'}
+
+
+ );
+ })()}
+
+
+ {stage.status === 'completed' && stage.date && `Completed: ${formatDateTime(stage.date)}`}
+ {stage.status === 'active' && 'In Progress'}
+ {stage.status === 'pending' && 'Pending'}
+
+
+
+
+ {stage.isParallel && stage.branches && (
+
+ {stage.branches.map((branch, branchIndex) => {
+ const branchKey = branch.name.toLowerCase().replace(/\s+/g, '-');
+ const isExpanded = expandedBranches[branchKey];
+ const branchColor = branch.color === 'blue' ? 'blue' : 'green';
+
+ return (
+
+
+
setExpandedBranches(prev => ({
+ ...prev,
+ [branchKey]: !prev[branchKey]
+ }))}
+ className={`flex-1 flex items-center gap-3 p-4 rounded-lg border-2 transition-all hover:shadow-md ${branchColor === 'blue'
+ ? 'border-blue-300 bg-blue-50 hover:bg-blue-100'
+ : 'border-green-300 bg-green-50 hover:bg-green-100'
+ }`}
+ >
+ {isExpanded ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ {branch.name}
+
+
+ {branch.stages.length} SUB-STEPS
+
+
+
+
+
+
+
+ {isExpanded && (
+
+ {branch.stages.map((branchStage) => (
+
+
+ {(() => {
+ const stageDocs = documents.filter(doc =>
+ doc.documentType?.toLowerCase().includes(branchStage.name.toLowerCase().split(' ')[0]) ||
+ doc.stage === branchStage.name
+ );
+ const isDone = branchStage.status === 'completed' || stageDocs.length > 0;
+
+ return (
+ <>
+
+
+ {isDone ? (
+
+ ) : branchStage.status === 'active' ? (
+
+ ) : (
+
+ )}
+
+
+
+
{branchStage.name}
+ {branchStage.description && (
+
{branchStage.description}
+ )}
+
+
+ {
+ setSelectedStage(branchStage.name);
+ setShowDocumentsModal(true);
+ if (stageDocs.length === 0) setShowUploadForm(true);
+ }}
+ className="text-[10px] font-medium text-blue-600 hover:text-blue-800 flex items-center gap-1 transition-colors"
+ >
+
+ {stageDocs.length > 0 ? `${stageDocs.length} Docs` : 'Upload'}
+
+
+
+ {isDone && branchStage.date ? `Done: ${formatDateTime(branchStage.date)}` : isDone && stageDocs.length > 0 ? `Uploaded: ${formatDateTime(stageDocs[0].updatedAt || stageDocs[0].createdAt)}` : branchStage.status === 'active' ? 'Evaluating' : 'Pending'}
+
+
+ >
+ );
+ })()}
+
+
+ ))}
+
+ )}
+
+ );
+ })}
+
+
+ )}
+
+ ))
+ })()}
+
+
+
+ {/* Documents Tab */}
+
+
+
Uploaded Documents
+ {
+ setSelectedStage(null);
+ setShowDocumentsModal(true);
+ setShowUploadForm(true);
+ }}>
+
+ Upload Document
+
+
+
+
+
+
+
+ File Name
+ Type
+ Upload Date
+ Uploader
+ Actions
+
+
+
+ {documents.length === 0 ? (
+
+
+ No documents uploaded yet
+
+
+ ) : (
+ documents.map((doc) => (
+
+
+
+ {doc.fileName}
+
+ {doc.documentType}
+ {formatDateTime(doc.createdAt)}
+
+ {doc.uploader?.fullName || (doc.uploadedBy ? 'Unknown User' : 'Applicant')}
+
+
+
+ window.open(`http://localhost:5000/${doc.filePath}`, '_blank')}>
+
+
+
+
+
+ )))}
+
+
+
+
+
+ {/* Interviews Tab */}
+
+
+
Scheduled Interviews
- File Name
- Type
- Upload Date
- Uploader
- Actions
+ Level
+ Date & Time
+ Type
+ Location/Link
+ Status
+ Scheduled By
+ Actions
- {documents.length === 0 ? (
+ {(!interviews || interviews.length === 0) ? (
-
- No documents uploaded yet
+
+ No interviews scheduled yet
) : (
- documents.map((doc) => (
-
-
-
- {doc.fileName}
-
- {doc.documentType}
- {formatDateTime(doc.createdAt)}
+ (Array.isArray(interviews) ? interviews : []).map((interview) => (
+
+ Level {interview.level}
+ {interview.scheduleDate ? new Date(interview.scheduleDate).toLocaleString() : 'N/A'}
+ {interview.interviewType}
- {doc.uploader?.fullName || (doc.uploadedBy ? 'Unknown User' : 'Applicant')}
+ {interview.interviewType?.toLowerCase().includes('virtual') ? (
+
+ Join Meeting
+
+ ) : (
+ interview.linkOrLocation
+ )}
-
-
window.open(`http://localhost:5000/${doc.filePath}`, '_blank')}>
-
+
+ {interview.status}
+
+
+ {interview.scheduler?.fullName || interview.scheduledBy || 'N/A'}
+
+ {(interview.status === 'Scheduled' || interview.status === 'scheduled') && (
+ handleCancelInterview(interview.id)}
+ >
+ Cancel
-
+ )}
- )))}
+ ))
+ )}
-
+
- {/* Interviews Tab */}
-
+
+
Interview Feedback
+ {(!interviews || interviews.length === 0) ? (
+
No interviews scheduled.
+ ) : (
+ (Array.isArray(interviews) ? interviews : []).map((interview) => (
+
+
+ Level {interview.level} Interview
+
+ ({formatDateTime(interview.scheduleDate)} - {interview.interviewType})
+
+
+ {interview.evaluations && interview.evaluations.length > 0 ? (
+
+
+
+ Interviewer
+ Role
+
+ {interview.level === 1 ? 'Score (KT Matrix)' : 'Overall Score'}
+
+ Remarks
+ Recommendation
+
+
+
+ {interview.evaluations.map((evalItem: any) => (
+
+ {evalItem.evaluator?.fullName}
+ {evalItem.evaluator?.role?.roleName || 'N/A'}
+
+ {evalItem.ktMatrixScore ? (
+ = 50 ? 'outline' : 'destructive')
+ : (Number(evalItem.ktMatrixScore) >= 5 ? 'outline' : 'destructive')
+ }>
+ {evalItem.ktMatrixScore}/{interview.level === 1 ? '100' : '10'}
+
+ ) : 'N/A'}
+
+
+ {evalItem.remarks ? (
+
+ {evalItem.remarks}
+ {evalItem.feedbackDetails && evalItem.feedbackDetails.length > 0 && (
+ {
+ setSelectedEvaluationForView({ ...evalItem, interview });
+ setShowFeedbackDetailsModal(true);
+ }}
+ >
+ View Detailed Feedback
+
+ )}
+
+ ) : evalItem.feedbackDetails && evalItem.feedbackDetails.length > 0 ? (
+ {
+ setSelectedEvaluationForView({ ...evalItem, interview });
+ setShowFeedbackDetailsModal(true);
+ }}
+ >
+ View Detailed Feedback
+
+ ) : (
+ evalItem.qualitativeFeedback || '-'
+ )}
+
+ {evalItem.recommendation || '-'}
+
+ ))}
+
+
+ ) : (
+
No feedback recorded yet.
+ )}
+
+ ))
+ )}
+
+
+ {['Level 2 Approved', 'Level 3 Interview Pending', 'Approved', 'Onboarded'].includes(application.status) && (
-
Scheduled Interviews
-
-
-
-
- Level
- Date & Time
- Type
- Location/Link
- Status
- Scheduled By
- Actions
-
-
-
- {(!interviews || interviews.length === 0) ? (
-
-
- No interviews scheduled yet
-
-
- ) : (
- (Array.isArray(interviews) ? interviews : []).map((interview) => (
-
- Level {interview.level}
- {interview.scheduleDate ? new Date(interview.scheduleDate).toLocaleString() : 'N/A'}
- {interview.interviewType}
-
- {interview.interviewType?.toLowerCase().includes('virtual') ? (
-
- Join Meeting
-
- ) : (
- interview.linkOrLocation
- )}
-
-
-
- {interview.status}
-
-
- {interview.scheduler?.fullName || interview.scheduledBy || 'N/A'}
-
- {(interview.status === 'Scheduled' || interview.status === 'scheduled') && (
+ Level 2 Interview Summary
+
+
Decision: Approved by both ZBH and DD Lead
+
Overall Assessment: Strong candidate with excellent business plan
+
+
+ )}
+
+
+
+ {renderFddAuditContent()}
+
+
+ {/* EOR Checklist Tab */}
+
+
+
Essential Operating Requirements
+ {Math.round(eorProgress)}% Complete
+
+
+
+
+ {(eorData?.items || eorChecklist).map((item: any) => {
+ const docType = item.description || item.item;
+ const hasDocument = !!item.proofDocument;
+
+ return (
+
+
+
+ {/* Clickable Info Area */}
+
{
+ setSelectedStage(`EOR: ${docType}`);
+ setUploadDocType(docType);
+ setShowDocumentsModal(true);
+ if (!hasDocument) setShowUploadForm(true);
+ else setShowUploadForm(false);
+ }}
+ >
+
+
+ {docType}
+
+ {hasDocument && !item.isCompliant && (
+
+ Needs Verification
+
+ )}
+
+ {hasDocument && (
+
+
+ {item.proofDocument.fileName}
+
+ )}
+ {!hasDocument && (
+
Click to upload proof
+ )}
+
+
+ {/* Separate Action Area (No modal trigger) */}
+
+ {hasDocument && !item.isCompliant && isAdmin && (
+
+ {
+ await eorService.updateItem(eorData.id, {
+ ...item,
+ isCompliant: true
+ });
+ fetchEorData();
+ toast.success(`${docType} verified!`);
+ }}
+ >
+ Verify
+
+ {
+ await eorService.updateItem(eorData.id, {
+ ...item,
+ isCompliant: false,
+ proofDocumentId: null
+ });
+ fetchEorData();
+ toast.success(`${docType} rejected.`);
+ }}
+ >
+ Reject
+
+
+ )}
+
+ {(item.isCompliant || item.completed) && (
+
+
+
+ )}
+
+ {!hasDocument && (
+
+
+
+ )}
+
+
+ );
+ })}
+
+
+ {eorProgress === 100 && isAdmin && (application.status === 'EOR In Progress' || application.status === 'LOA Pending') && (
+
+
+
+
+
+
+
EOR Checklist Complete
+
All 12 mandatory requirements have been verified. You can now complete the audit and move to final inauguration.
+
+
{
+ try {
+ const checklistId = eorData?.id || eorChecklist?.id;
+ if (!checklistId) throw new Error('Checklist ID not found');
+
+ await eorService.submitAudit(checklistId, {
+ status: 'Completed',
+ overallComments: 'EOR Checklist verified and audit completed.'
+ });
+ toast.success('EOR Audit completed successfully!');
+ fetchApplication();
+ fetchEorData();
+ } catch (error: any) {
+ toast.error(error.message || 'Failed to complete EOR audit');
+ }
+ }}
+ >
+ Complete Audit & Proceed
+
+
+
+ )}
+
+
+ {/* Payments Tab */}
+
+
+
Security Deposits
+
+ {deposits.length} Payment Record(s)
+
+
+
+
+ {/* Initial Security Deposit */}
+ {(() => {
+ const deposit = getDeposit('SECURITY_DEPOSIT');
+ const config = paymentConfigs.SECURITY_DEPOSIT;
+ const expectedAmount = config?.amount || 500000;
+
+ return (
+
+
+
+
+
+
+
+
Security Deposit
+
+
+ {deposit?.status || 'Awaiting'}
+
+
+
+
+
+ Amount Received
+ ₹{Number(deposit?.amount || 0).toLocaleString()}
+
+
+ Expected Total
+ ₹{expectedAmount.toLocaleString()}
+
+
+ {deposit?.paymentReference && (
+
+ Ref: {deposit.paymentReference}
+ {deposit.verifiedAt && {formatDateTime(deposit.verifiedAt)} }
+
+ )}
+
+ {deposit?.remarks && (
+
+ "{deposit.remarks}"
+
+ )}
+
+ {/* Respective Documents */}
+
+
Verification Documents
+
+ {documents.filter((d: any) => d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')).map((doc: any, idx: number) => (
+
+
+
+ {doc.fileName || doc.name}
+
handleCancelInterview(interview.id)}
+ className="h-6 px-2 text-[10px] text-amber-600 hover:text-amber-700 hover:bg-amber-50"
+ onClick={() => { setPreviewDoc(doc); setShowPreviewModal(true); }}
>
- Cancel
+ View
- )}
-
-
- ))
- )}
-
-
-
-
-
-
-
Interview Feedback
- {(!interviews || interviews.length === 0) ? (
-
No interviews scheduled.
- ) : (
- (Array.isArray(interviews) ? interviews : []).map((interview) => (
-
-
- Level {interview.level} Interview
-
- ({formatDateTime(interview.scheduleDate)} - {interview.interviewType})
-
-
- {interview.evaluations && interview.evaluations.length > 0 ? (
-
-
-
- Interviewer
- Role
-
- {interview.level === 1 ? 'Score (KT Matrix)' : 'Overall Score'}
-
- Remarks
- Recommendation
-
-
-
- {interview.evaluations.map((evalItem: any) => (
-
- {evalItem.evaluator?.fullName}
- {evalItem.evaluator?.role?.roleName || 'N/A'}
-
- {evalItem.ktMatrixScore ? (
- = 50 ? 'outline' : 'destructive')
- : (Number(evalItem.ktMatrixScore) >= 5 ? 'outline' : 'destructive')
- }>
- {evalItem.ktMatrixScore}/{interview.level === 1 ? '100' : '10'}
-
- ) : 'N/A'}
-
-
- {evalItem.remarks ? (
-
- {evalItem.remarks}
- {evalItem.feedbackDetails && evalItem.feedbackDetails.length > 0 && (
- {
- setSelectedEvaluationForView({ ...evalItem, interview });
- setShowFeedbackDetailsModal(true);
- }}
- >
- View Detailed Feedback
-
- )}
-
- ) : evalItem.feedbackDetails && evalItem.feedbackDetails.length > 0 ? (
- {
- setSelectedEvaluationForView({ ...evalItem, interview });
- setShowFeedbackDetailsModal(true);
- }}
- >
- View Detailed Feedback
-
- ) : (
- evalItem.qualitativeFeedback || '-'
- )}
-
- {evalItem.recommendation || '-'}
-
+
))}
-
-
- ) : (
-
No feedback recorded yet.
- )}
+ {documents.filter((d: any) => d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')).length === 0 && (
+
No proof uploaded
+ )}
+
+
+
+
+
+ );
+ })()}
+
+ {/* Final Security Deposit */}
+ {(() => {
+ const deposit = getDeposit('FIRST_FILL');
+ const config = paymentConfigs.FIRST_FILL;
+ const expectedAmount = config?.amount || 1500000;
+
+ return (
+
+
+
+
+
+ {deposit?.status || 'Awaiting'}
+
+
+
+
+
+ Amount Received
+ ₹{Number(deposit?.amount || 0).toLocaleString()}
+
+
+ Expected Total
+ ₹{expectedAmount.toLocaleString()}
+
+
+ {deposit?.paymentReference && (
+
+ Ref: {deposit.paymentReference}
+ {deposit.verifiedAt && {formatDateTime(deposit.verifiedAt)} }
+
+ )}
+
+ {deposit?.remarks && (
+
+ "{deposit.remarks}"
+
+ )}
+
+ {/* Respective Documents */}
+
+
Verification Documents
+
+ {documents.filter((d: any) => d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')).map((doc: any, idx: number) => (
+
+
+
+ {doc.fileName || doc.name}
+
+
{ setPreviewDoc(doc); setShowPreviewModal(true); }}
+ >
+ View
+
+
+ ))}
+ {documents.filter((d: any) => d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')).length === 0 && (
+
No proof uploaded
+ )}
+
+
+
+
+
+ );
+ })()}
+
+
+
+
+ {/* Audit Trail Tab */}
+
+
+
+ {auditLoading ? (
+
+
+
Loading audit trail...
+
+ ) : auditLogs.length === 0 ? (
+
+ No audit logs recorded yet for this application.
+
+ ) : (
+ auditLogs.map((log: any) => (
+
+
+
+
+
{log.description || log.action}
+
+ {formatDateTime(log.timestamp)}
+
+
+
by {log.userName || 'System'}
+ {log.remarks && (
+
+ "{log.remarks}"
+
+ )}
+ {log.changes && log.changes.length > 0 && (
+
+ {log.changes.map((change: string, idx: number) => (
+
{change}
+ ))}
+
+ )}
+
))
)}
+
+
+
+
+
+ )}
+
- {['Level 2 Approved', 'Level 3 Interview Pending', 'Approved', 'Onboarded'].includes(application.status) && (
-
-
Level 2 Interview Summary
-
-
Decision: Approved by both ZBH and DD Lead
-
Overall Assessment: Strong candidate with excellent business plan
-
-
- )}
-
+ {/* Right Sidebar - Summary and Actions */}
+
+ {/* Summary Card */}
+
+
+ Summary
+
+
+
+
Registration ID
+
{application.registrationNumber}
+
+
+
Current Status
+
+ {application.status}
+
+
+ {application.rank && (
+
+
Rank
+
+ {application.rank} of {application.totalApplicantsAtLocation}
+ in {application.preferredLocation}
+
+
+ )}
+
+
Progress
+
+
+
{application.progress}%
+
+
+ {application.deadline && (
+
+
Questionnaire Deadline
+
{formatDateTime(application.deadline)}
+
+ )}
+
+
-
- {renderFddAuditContent()}
-
-
- {/* EOR Checklist Tab */}
-
-
-
Essential Operating Requirements
- {Math.round(eorProgress)}% Complete
-
-
-
-
- {(eorData?.items || eorChecklist).map((item: any) => {
- const docType = item.description || item.item;
- const hasDocument = !!item.proofDocument;
-
- return (
-
-
-
- {/* Clickable Info Area */}
-
{
- setSelectedStage(`EOR: ${docType}`);
- setUploadDocType(docType);
- setShowDocumentsModal(true);
- if (!hasDocument) setShowUploadForm(true);
- else setShowUploadForm(false);
- }}
- >
-
-
- {docType}
-
- {hasDocument && !item.isCompliant && (
-
- Needs Verification
-
- )}
-
- {hasDocument && (
-
-
- {item.proofDocument.fileName}
-
- )}
- {!hasDocument && (
-
Click to upload proof
- )}
-
-
- {/* Separate Action Area (No modal trigger) */}
-
- {hasDocument && !item.isCompliant && isAdmin && (
-
- {
- await eorService.updateItem(eorData.id, {
- ...item,
- isCompliant: true
- });
- fetchEorData();
- toast.success(`${docType} verified!`);
- }}
- >
- Verify
-
- {
- await eorService.updateItem(eorData.id, {
- ...item,
- isCompliant: false,
- proofDocumentId: null
- });
- fetchEorData();
- toast.success(`${docType} rejected.`);
- }}
- >
- Reject
-
-
- )}
-
- {(item.isCompliant || item.completed) && (
-
-
-
- )}
-
- {!hasDocument && (
-
-
-
- )}
-
-
- );
- })}
-
-
- {eorProgress === 100 && isAdmin && (application.status === 'EOR In Progress' || application.status === 'LOA Pending') && (
-
-
-
-
-
-
-
EOR Checklist Complete
-
All 12 mandatory requirements have been verified. You can now complete the audit and move to final inauguration.
-
-
{
- try {
- await onboardingService.updateApplicationStatus(application.id, {
- status: 'EOR Complete',
- remarks: 'EOR Checklist verified and audit completed.'
- });
- toast.success('EOR Audit completed successfully!');
- fetchApplication();
- } catch (error) {
- toast.error('Failed to complete EOR audit');
- }
- }}
- >
- Complete Audit & Proceed
-
-
-
- )}
-
-
- {/* Payments Tab */}
-
-
-
Security Deposits
-
- {deposits.length} Payment Record(s)
-
-
-
-
- {/* Initial Security Deposit */}
- {(() => {
- const deposit = getDeposit('SECURITY_DEPOSIT');
- const config = paymentConfigs.SECURITY_DEPOSIT;
- const expectedAmount = config?.amount || 500000;
-
- return (
-
-
-
-
-
-
-
-
Security Deposit
-
-
- {deposit?.status || 'Awaiting'}
-
-
-
-
-
- Amount Received
- ₹{Number(deposit?.amount || 0).toLocaleString()}
-
-
- Expected Total
- ₹{expectedAmount.toLocaleString()}
-
-
- {deposit?.paymentReference && (
-
- Ref: {deposit.paymentReference}
- {deposit.verifiedAt && {formatDateTime(deposit.verifiedAt)} }
-
- )}
-
- {deposit?.remarks && (
-
- "{deposit.remarks}"
-
- )}
-
- {/* Respective Documents */}
-
-
Verification Documents
-
- {documents.filter((d: any) => d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')).map((doc: any, idx: number) => (
-
-
-
- {doc.fileName || doc.name}
-
-
{ setPreviewDoc(doc); setShowPreviewModal(true); }}
- >
- View
-
-
- ))}
- {documents.filter((d: any) => d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')).length === 0 && (
-
No proof uploaded
- )}
-
-
-
-
-
- );
- })()}
-
- {/* Final Security Deposit */}
- {(() => {
- const deposit = getDeposit('FIRST_FILL');
- const config = paymentConfigs.FIRST_FILL;
- const expectedAmount = config?.amount || 1500000;
-
- return (
-
-
-
-
-
- {deposit?.status || 'Awaiting'}
-
-
-
-
-
- Amount Received
- ₹{Number(deposit?.amount || 0).toLocaleString()}
-
-
- Expected Total
- ₹{expectedAmount.toLocaleString()}
-
-
- {deposit?.paymentReference && (
-
- Ref: {deposit.paymentReference}
- {deposit.verifiedAt && {formatDateTime(deposit.verifiedAt)} }
-
- )}
-
- {deposit?.remarks && (
-
- "{deposit.remarks}"
-
- )}
-
- {/* Respective Documents */}
-
-
Verification Documents
-
- {documents.filter((d: any) => d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')).map((doc: any, idx: number) => (
-
-
-
- {doc.fileName || doc.name}
-
-
{ setPreviewDoc(doc); setShowPreviewModal(true); }}
- >
- View
-
-
- ))}
- {documents.filter((d: any) => d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')).length === 0 && (
-
No proof uploaded
- )}
-
-
-
-
-
- );
- })()}
-
-
-
-
- {/* Audit Trail Tab */}
-
-
-
- {auditLoading ? (
-
-
-
Loading audit trail...
-
- ) : auditLogs.length === 0 ? (
-
- No audit logs recorded yet for this application.
-
- ) : (
- auditLogs.map((log: any) => (
-
-
-
-
-
{log.description || log.action}
-
- {formatDateTime(log.timestamp)}
-
-
-
by {log.userName || 'System'}
- {log.changes && log.changes.length > 0 && (
-
- {log.changes.map((change: string, idx: number) => (
-
{change}
- ))}
-
- )}
-
-
- ))
- )}
-
-
-
-
-
-
- )}
-
-
- {/* Right Sidebar - Summary and Actions */}
-
- {/* Summary Card */}
+ {/* Actions Card */}
+ {/* Only show Actions card for shortlisted applications (opportunity requests and regular dealership requests) */}
+ {/* Hide Actions for non-opportunity requests (lead generation) - these are read-only records */}
+ {application.isShortlisted !== false && (
- Summary
+ Actions
-
-
-
Registration ID
-
{application.registrationNumber}
-
-
-
Current Status
-
- {application.status}
-
-
- {application.rank && (
-
-
Rank
-
- {application.rank} of {application.totalApplicantsAtLocation}
- in {application.preferredLocation}
-
+
+ {/* Show Approve/Reject block */}
+ {permissions.isLoaLocked && (
+
+
+ Stage Locked
+
+ First Fill (₹15L) must be verified by Finance before LOA Approval can proceed.
+
+
+ )}
+
+ {isNonResponsive && isAdmin && (
+
+
+ ⚠️ Non-Responsive Flag
+
+ FDD Audit has flagged this applicant. Review audit logs before approval.
+
+
+ )}
+
+ {isAdmin && (application.status === 'Level 3 Approved' || application.status === 'FDD Verification') && (!application.fddAssignments || application.fddAssignments.length === 0) && (
+
+
+ FDD Assignment Required
+
+ This application is pending financial due diligence. Please assign an FDD Agency to proceed with the audit.
+
+
+ )}
+
+ {permissions.canApprove && (
+ <>
+ setShowApproveModal(true)}
+ >
+
+ {['Inauguration', 'Approved'].includes(application.status) ? 'Onboard Dealer' : 'Approve'}
+
+
+ setShowRejectModal(true)}
+ >
+
+ Reject
+
+ >
+ )}
+
+ {permissions.showDecisionMessage && (
+
+ You have {(currentUserStageAction?.decision === 'Approved' || currentUserEvaluation?.decision === 'Approved' || currentUserEvaluation?.recommendation === 'Approved' || currentUserEvaluation?.decision === 'Selected') ? 'Approved' : 'Rejected'}
)}
-
-
Progress
-
-
-
{application.progress}%
-
-
- {application.deadline && (
-
-
Questionnaire Deadline
-
{formatDateTime(application.deadline)}
-
- )}
-
-
- {/* Actions Card */}
- {/* Only show Actions card for shortlisted applications (opportunity requests and regular dealership requests) */}
- {/* Hide Actions for non-opportunity requests (lead generation) - these are read-only records */}
- {application.isShortlisted !== false && (
-
-
- Actions
-
-
- {/* Show Approve/Reject block */}
- {permissions.isLoaLocked && (
-
-
- Stage Locked
-
- First Fill (₹15L) must be verified by Finance before LOA Approval can proceed.
-
-
- )}
+
- {permissions.canApprove && (
- <>
- setShowApproveModal(true)}
- >
-
- Approve
-
-
- setShowRejectModal(true)}
- >
-
- Reject
-
- >
- )}
-
- {permissions.showDecisionMessage && (
-
- You have {(currentUserStageAction?.decision === 'Approved' || currentUserEvaluation?.decision === 'Approved' || currentUserEvaluation?.recommendation === 'Approved' || currentUserEvaluation?.decision === 'Selected') ? 'Approved' : 'Rejected'}
-
- )}
-
-
+ navigate(`/worknotes/application/${application.id}`, {
+ state: {
+ applicationName: application.name,
+ registrationNumber: application.registrationNumber,
+ participants: application.participants
+ }
+ })}
+ >
+
+ Work Note
+
+ {permissions.canSchedule && (
navigate(`/worknotes/application/${application.id}`, {
- state: {
- applicationName: application.name,
- registrationNumber: application.registrationNumber,
- participants: application.participants
- }
- })}
+ onClick={() => setShowScheduleModal(true)}
>
-
- Work Note
+
+ Schedule Interview
+ )}
- {permissions.canSchedule && (
- setShowScheduleModal(true)}
- >
-
- Schedule Interview
-
- )}
-
- {currentUser && ['DD Admin', 'Super Admin'].includes(currentUser.role) && application.status === 'Dealer Code Generation' && (
- <>
- {!application.dealerCode && (
-
-
- Generate Dealer Codes
-
- )}
-
- {application.dealerCode && (
- setShowAssignArchitectureModal(true)}
- >
-
- Assign Architecture Team
-
- )}
- >
- )}
-
- {((currentUser && currentUser.id === application.architectureAssignedTo) || (currentUser && ['DD Admin', 'Super Admin'].includes(currentUser.role))) &&
- application.architectureStatus === 'IN_PROGRESS' && (
+ {currentUser && ['DD Admin', 'Super Admin'].includes(currentUser.role) &&
+ ['Dealer Code Generation', 'LOA Pending', 'Architecture Team Assigned', 'Architecture Document Upload', 'Architecture Team Completion'].includes(application.status) && (
+ <>
+ {!application.dealerCode && (
setShowArchitectureStatusModal(true)}
+ onClick={handleGenerateDealerCodes}
>
-
- Complete Architecture Work
+
+ Generate Dealer Codes
)}
- {/* Show Interview Feedback only if active interview exists AND feedback NOT submitted */}
- {activeInterviewForUser && !hasSubmittedFeedback && (
-
-
-
-
- Interview Feedback
-
-
-
-
- {
- setSelectedInterviewForFeedback(activeInterviewForUser);
- if (activeInterviewForUser.level === 1) setShowKTMatrixModal(true);
- else if (activeInterviewForUser.level === 2) setShowLevel2FeedbackModal(true);
- else setShowLevel3FeedbackModal(true);
- }}
- >
- Level {activeInterviewForUser.level} - {activeInterviewForUser.interviewType}
-
-
-
- )}
-
- {application.status === 'Questionnaire Pending' && (
- <>
-
-
- Send Reminder
-
-
-
-
- Extend Deadline
-
- >
- )}
-
- {/* Dedicated Onboarding Button - Appears ONLY when everything is ready (last step) */}
- {isAdmin && application.status === 'Inauguration' && !application.dealer && (
-
- {eorProgress < 100 && (
-
-
-
- EOR Checklist must be 100% complete before onboarding. (Current: {eorProgress.toFixed(0)}%)
-
-
- )}
+ {application.dealerCode && !application.architectureAssignedTo && (
setShowOnboardModal(true)}
- disabled={eorProgress < 100}
+ variant="outline"
+ className="w-full border-blue-200 hover:bg-blue-50 text-blue-700"
+ onClick={() => setShowAssignArchitectureModal(true)}
>
-
- Onboard as Dealer (Final Step)
+
+ Assign Architecture Team
-
- )}
-
- {/* Dealer Onboarded Status & Link */}
- {application.dealer && (
-
-
-
- Dealer Profile Active
-
-
- This application has been successfully onboarded as a dealer. A user account has been created for the dealer.
-
- {application.dealerCode && (
-
- Dealer Code:
- {application.dealerCode.code}
-
- )}
-
navigate('/dashboard')}
- >
-
- Go to Dealer Dashboard
-
-
- )}
-
- {currentUser && ['DD Admin', 'Super Admin'].includes(currentUser.role) && (
-
-
-
-
- Assign User
-
-
-
-
- Assign User to Application
-
- Select a user and their role for this application.
-
-
-
-
- Select User
-
-
-
-
-
- {users.map((u) => (
-
- {u.fullName} ({u.email})
-
- ))}
-
-
-
-
- Assignment Role
-
-
-
-
-
- Owner
- Contributor
- Reviewer
-
-
-
-
- {isAssigningParticipant ? (
- <>
-
- Assigning...
- >
- ) : (
- 'Assign User'
- )}
-
-
-
-
- )}
-
-
- )}
-
-
- {/* Approve Modal */}
-
-
-
- Approve Application
-
- Provide approval remarks and optionally attach supporting documents.
-
-
-
-
- Remark (Required)
-
-
- Attach File (Optional)
- setApprovalFile(e.target.files ? e.target.files[0] : null)}
- />
-
-
- setShowApproveModal(false)}
- disabled={isApproving}
- >
- Cancel
-
-
- {isApproving ? (
- <>
-
- Approving...
- >
- ) : (
- 'Submit Approval'
- )}
-
-
-
-
-
-
- {/* Onboard Confirmation Modal */}
-
-
-
-
-
-
- Finalize Onboarding
-
- You are about to officially onboard {application.name} as a Royal Enfield dealer.
-
-
-
-
-
-
-
Official dealer profile will be created.
-
-
-
-
User account will be activated with role Dealer .
-
-
-
-
Primary outlet will be registered in the system.
-
-
-
-
- {
- setIsOnboarding(true);
- try {
- await onboardingService.createDealer({ applicationId: application.id });
- toast.success('Dealer profile and login account created successfully!');
- setShowOnboardModal(false);
- fetchApplication();
- } catch (error) {
- toast.error('Failed to create dealer profile');
- } finally {
- setIsOnboarding(false);
- }
- }}
- disabled={isOnboarding}
- >
- {isOnboarding ? (
- <>
-
- Processing Onboarding...
+ )}
>
- ) : (
- 'Confirm & Onboard Dealer'
)}
-
- setShowOnboardModal(false)}
- disabled={isOnboarding}
- >
- Cancel
-
-
-
-
- {/* Reject Modal */}
-
-
-
- Reject Application
-
- Please provide a clear reason for rejecting this application.
-
-
-
-
-
Reason for Rejection (Required)
-