121 lines
4.7 KiB
TypeScript
121 lines
4.7 KiB
TypeScript
import db from '../../database/models/index.js';
|
|
const { ApplicationProgress } = db;
|
|
|
|
export const ONBOARDING_STAGES = [
|
|
{ name: 'Submitted', order: 1 },
|
|
{ name: 'Questionnaire', order: 2 },
|
|
{ name: 'Shortlist', order: 3 },
|
|
{ name: '1st Level Interview', order: 4 },
|
|
{ name: '2nd Level Interview', order: 5 },
|
|
{ name: '3rd Level Interview', order: 6 },
|
|
{ name: 'FDD', order: 7 },
|
|
{ name: 'LOI Approval', order: 8 },
|
|
{ name: 'Security Details', order: 9 },
|
|
{ name: 'LOI Issue', order: 10 },
|
|
{ name: 'Dealer Code Generation', order: 11 },
|
|
{ name: 'LOA', order: 12 },
|
|
{ name: 'EOR Complete', order: 13 },
|
|
{ name: 'Inauguration', order: 14 },
|
|
{ name: 'Onboarded', order: 15 }
|
|
];
|
|
|
|
/**
|
|
* Updates application progress for a specific stage
|
|
*/
|
|
export const updateApplicationProgress = async (applicationId: string, stageName: string, status: 'pending' | 'active' | 'completed', percentage: number = 0) => {
|
|
try {
|
|
const stage = ONBOARDING_STAGES.find(s => s.name === stageName);
|
|
if (!stage) return;
|
|
|
|
const [progress, created] = await ApplicationProgress.findOrCreate({
|
|
where: { applicationId, stageName },
|
|
defaults: {
|
|
stageOrder: stage.order,
|
|
status,
|
|
completionPercentage: percentage,
|
|
stageStartedAt: status === 'active' ? new Date() : null,
|
|
stageCompletedAt: status === 'completed' ? new Date() : null
|
|
}
|
|
});
|
|
|
|
if (!created) {
|
|
const updates: any = { status, completionPercentage: percentage };
|
|
if (status === 'active' && !progress.stageStartedAt) {
|
|
updates.stageStartedAt = new Date();
|
|
}
|
|
if (status === 'completed' && !progress.stageCompletedAt) {
|
|
updates.stageCompletedAt = new Date();
|
|
}
|
|
await progress.update(updates);
|
|
}
|
|
|
|
// Mark previous stages as completed if this one is completed
|
|
if (status === 'completed') {
|
|
await ApplicationProgress.update(
|
|
{ status: 'completed', completionPercentage: 100 },
|
|
{
|
|
where: {
|
|
applicationId,
|
|
stageOrder: { [db.Sequelize.Op.lt]: stage.order },
|
|
status: { [db.Sequelize.Op.ne]: 'completed' }
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
return progress;
|
|
} catch (error) {
|
|
console.error('Error updating application progress:', error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Syncs all progress stages based on current overall status
|
|
*/
|
|
export const syncApplicationProgress = async (applicationId: string, overallStatus: string) => {
|
|
// Map overallStatus to stage names
|
|
const statusToStageMap: Record<string, string> = {
|
|
'Submitted': 'Submitted',
|
|
'Questionnaire Completed': 'Questionnaire',
|
|
'Shortlisted': 'Shortlist',
|
|
'Level 1 Interview Pending': '1st Level Interview',
|
|
'Level 1 Approved': '1st Level Interview',
|
|
'Level 2 Interview Pending': '2nd Level Interview',
|
|
'Level 2 Approved': '2nd Level Interview',
|
|
'Level 2 Recommended': '2nd Level Interview',
|
|
'Level 3 Interview Pending': '3rd Level Interview',
|
|
'Level 3 Approved': '3rd Level Interview',
|
|
'FDD Verification': 'FDD',
|
|
'LOI In Progress': 'LOI Approval',
|
|
'Payment Pending': 'Security Details',
|
|
'LOI Issued': 'LOI Issue',
|
|
'Statutory LOI Ack': 'LOI Issue',
|
|
'Dealer Code Generation': 'Dealer Code Generation',
|
|
'Architecture Team Assigned': 'Dealer Code Generation',
|
|
'Architecture Document Upload': 'Dealer Code Generation',
|
|
'Architecture Team Completion': 'Dealer Code Generation',
|
|
'Statutory GST': 'Dealer Code Generation',
|
|
'LOA Pending': 'LOA',
|
|
'EOR In Progress': 'LOA',
|
|
'EOR Complete': 'EOR Complete',
|
|
'Inauguration': 'Inauguration',
|
|
'Approved': 'Inauguration',
|
|
'Onboarded': 'Onboarded'
|
|
};
|
|
|
|
const currentStageName = statusToStageMap[overallStatus];
|
|
if (currentStageName) {
|
|
const stage = ONBOARDING_STAGES.find(s => s.name === currentStageName);
|
|
if (stage) {
|
|
// Determine status for this stage
|
|
// If the status IS exactly the target "Complete" status for a stage, mark it as completed
|
|
const isCompleted = [
|
|
'Submitted', 'Questionnaire Completed', 'Shortlisted', 'Level 3 Approved',
|
|
'LOI Issued', 'EOR Complete', 'Approved', 'Onboarded'
|
|
].includes(overallStatus);
|
|
|
|
await updateApplicationProgress(applicationId, currentStageName, isCompleted ? 'completed' : 'active', isCompleted ? 100 : 50);
|
|
}
|
|
}
|
|
};
|