pagination and filters addd for tjhe location data. front end start aligning to brand ui theme like font family and colors
This commit is contained in:
parent
d6426f705b
commit
837be9bce1
@ -78,6 +78,16 @@ export const getAreas = async (req: Request, res: Response) => {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stateId = req.query.stateId as string;
|
||||||
|
const zoneId = req.query.zoneId as string;
|
||||||
|
const regionId = req.query.regionId as string;
|
||||||
|
const isActive = req.query.isActive as string;
|
||||||
|
|
||||||
|
if (stateId) where['$district.stateId$'] = stateId;
|
||||||
|
if (zoneId) where['$district.zoneId$'] = zoneId;
|
||||||
|
if (regionId) where['$district.regionId$'] = regionId;
|
||||||
|
if (isActive !== undefined) where.isActive = isActive === 'true';
|
||||||
|
|
||||||
const { count, rows: areas } = await db.Location.findAndCountAll({
|
const { count, rows: areas } = await db.Location.findAndCountAll({
|
||||||
where,
|
where,
|
||||||
include: [
|
include: [
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import db from '../../database/models/index.js';
|
import db from '../../database/models/index.js';
|
||||||
const { Application, Opportunity, ApplicationStatusHistory, ApplicationProgress, AuditLog, District, State, Region, Zone, SecurityDeposit, FddAssignment, FddReport, OnboardingDocument, Worknote, StageApprovalAction, DealerCode, Dealer, RequestParticipant, QuestionnaireResponse, QuestionnaireQuestion, QuestionnaireOption, User } = db;
|
const { Application, Opportunity, ApplicationStatusHistory, ApplicationProgress, AuditLog, District, State, Region, Zone, SecurityDeposit, FddAssignment, FddReport, OnboardingDocument, Worknote, StageApprovalAction, DealerCode, Dealer, RequestParticipant, QuestionnaireResponse, QuestionnaireQuestion, QuestionnaireOption, Questionnaire, User } = db;
|
||||||
import { AUDIT_ACTIONS, APPLICATION_STAGES, APPLICATION_STATUS } from '../../common/config/constants.js';
|
import { AUDIT_ACTIONS, APPLICATION_STAGES, APPLICATION_STATUS } from '../../common/config/constants.js';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { Op } from 'sequelize';
|
import { Op } from 'sequelize';
|
||||||
@ -1121,3 +1121,72 @@ export const updateApplication = async (req: AuthRequest, res: Response) => {
|
|||||||
return res.status(500).json({ success: false, message: 'Internal server error' });
|
return res.status(500).json({ success: false, message: 'Internal server error' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
export const exportApplicationResponses = async (req: AuthRequest, res: Response) => {
|
||||||
|
try {
|
||||||
|
const { applicationIds } = req.query;
|
||||||
|
if (!applicationIds) return res.status(400).json({ success: false, message: 'No applications selected' });
|
||||||
|
|
||||||
|
const ids = (applicationIds as string).split(',');
|
||||||
|
|
||||||
|
// 1. Fetch Applications with their identification details
|
||||||
|
const applications = await Application.findAll({
|
||||||
|
where: {
|
||||||
|
id: { [Op.in]: ids },
|
||||||
|
overallStatus: { [Op.ne]: APPLICATION_STATUS.QUESTIONNAIRE_PENDING }
|
||||||
|
},
|
||||||
|
attributes: ['id', 'applicationId', 'applicantName', 'preferredLocation', 'email', 'phone']
|
||||||
|
});
|
||||||
|
|
||||||
|
if (applications.length === 0 && ids.length > 0) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'No applications found with completed questionnaires among the selected records.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Fetch all unique questions involved in these applications
|
||||||
|
// For consistency, let's get all questions from the active questionnaire
|
||||||
|
const activeQuestionnaire = await Questionnaire.findOne({ where: { isActive: true }, order: [['version', 'DESC']] });
|
||||||
|
if (!activeQuestionnaire) return res.status(404).json({ success: false, message: 'Active questionnaire not found' });
|
||||||
|
|
||||||
|
const allQuestions = await QuestionnaireQuestion.findAll({
|
||||||
|
where: { questionnaireId: activeQuestionnaire.id },
|
||||||
|
order: [['order', 'ASC']]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Fetch all responses for these applications
|
||||||
|
const responses = await QuestionnaireResponse.findAll({
|
||||||
|
where: { applicationId: { [Op.in]: ids } },
|
||||||
|
attributes: ['applicationId', 'questionId', 'responseValue']
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. Map responses for quick lookup: applicationid -> questionid -> responseValue
|
||||||
|
const responsesMap: any = {};
|
||||||
|
responses.forEach((r: any) => {
|
||||||
|
if (!responsesMap[r.applicationId]) responsesMap[r.applicationId] = {};
|
||||||
|
responsesMap[r.applicationId][r.questionId] = r.responseValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 5. Construct rows
|
||||||
|
const rows = applications.map((app: any) => {
|
||||||
|
const data: any = {
|
||||||
|
'Application ID': app.applicationId,
|
||||||
|
'Applicant Name': app.applicantName,
|
||||||
|
'Email': app.email,
|
||||||
|
'Phone': app.phone,
|
||||||
|
'Preferred Location': app.preferredLocation
|
||||||
|
};
|
||||||
|
|
||||||
|
allQuestions.forEach((q: any) => {
|
||||||
|
data[q.questionText] = responsesMap[app.id]?.[q.id] || 'Not Answered';
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json({ success: true, data: rows });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Export error:', error);
|
||||||
|
res.status(500).json({ success: false, message: 'Error exporting data' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import {
|
|||||||
uploadDocuments, getApplicationDocuments, bulkShortlist,
|
uploadDocuments, getApplicationDocuments, bulkShortlist,
|
||||||
assignArchitectureTeam, updateArchitectureStatus, generateDealerCodes,
|
assignArchitectureTeam, updateArchitectureStatus, generateDealerCodes,
|
||||||
retriggerEvaluators, getDocumentConfigs, getDocumentConfigMetadata,
|
retriggerEvaluators, getDocumentConfigs, getDocumentConfigMetadata,
|
||||||
createDocumentConfig, updateDocumentConfig, deleteDocumentConfig, updateApplication
|
createDocumentConfig, updateDocumentConfig, deleteDocumentConfig, updateApplication,
|
||||||
|
exportApplicationResponses
|
||||||
} from './onboarding.controller.js';
|
} from './onboarding.controller.js';
|
||||||
import { authenticate } from '../../common/middleware/auth.js';
|
import { authenticate } from '../../common/middleware/auth.js';
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ router.put('/document-configs/:id', updateDocumentConfig);
|
|||||||
router.delete('/document-configs/:id', deleteDocumentConfig);
|
router.delete('/document-configs/:id', deleteDocumentConfig);
|
||||||
|
|
||||||
router.get('/applications', getApplications);
|
router.get('/applications', getApplications);
|
||||||
|
router.get('/applications/export-responses', exportApplicationResponses);
|
||||||
router.get('/document-configs/metadata', getDocumentConfigMetadata);
|
router.get('/document-configs/metadata', getDocumentConfigMetadata);
|
||||||
router.get('/document-configs', getDocumentConfigs);
|
router.get('/document-configs', getDocumentConfigs);
|
||||||
router.post('/applications/shortlist', bulkShortlist); // Existing route, updated to named import
|
router.post('/applications/shortlist', bulkShortlist); // Existing route, updated to named import
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user