205 lines
11 KiB
TypeScript
205 lines
11 KiB
TypeScript
import { Request, Response } from 'express';
|
|
import { CpcHistoryService } from '../services/cpc-cdc/CpcHistoryService';
|
|
import { CpcDocument } from '../models/CpcDocument';
|
|
import { appendCpcDocumentFilters, cpcWhereFromAndParts } from '../services/cpc-cdc/utils';
|
|
import ExcelJS from 'exceljs';
|
|
import { ResponseHandler } from '../utils/responseHandler';
|
|
|
|
import { Op } from 'sequelize';
|
|
|
|
export class CpcReportController {
|
|
/**
|
|
* Download Excel report for a specific claim
|
|
*/
|
|
async downloadReport(req: Request, res: Response) {
|
|
try {
|
|
const { claimId } = req.params;
|
|
const { attempt } = req.query;
|
|
|
|
const where: any = {
|
|
[Op.or]: [
|
|
{ claimId: claimId },
|
|
{ bookingId: claimId }
|
|
]
|
|
};
|
|
if (attempt) where.attemptNo = parseInt(attempt as string);
|
|
|
|
const docs = await CpcDocument.findAll({
|
|
where,
|
|
order: [['createdAt', 'DESC']]
|
|
});
|
|
|
|
if (!docs || docs.length === 0) {
|
|
return ResponseHandler.error(res, "No records found for this claim", 404);
|
|
}
|
|
|
|
const workbook = new ExcelJS.Workbook();
|
|
const sheet = workbook.addWorksheet('Validation Report');
|
|
|
|
// HEADERS
|
|
const row1 = sheet.getRow(1);
|
|
row1.values = [
|
|
'Booking Type', 'Booking Number', 'Document Count', 'Document Name',
|
|
'Customer Name', '', '', '', '',
|
|
'PO Number /Authorisation Letter Number', '', '', '', '',
|
|
'Aadhar Number', '', '', '', '',
|
|
'PO Amount / Authorisation Letter Amount', '', '', '', '',
|
|
'Signature & Stamp Availability', '', '', '', '',
|
|
'Final Validation'
|
|
];
|
|
|
|
const row2 = sheet.getRow(2);
|
|
row2.values = [
|
|
'', '', '', '',
|
|
'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy',
|
|
'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy',
|
|
'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy',
|
|
'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy',
|
|
'Expected', 'OCR', 'Accuracy Matching Availability', 'Accuracy Criteria', 'Success Ratio',
|
|
''
|
|
];
|
|
|
|
sheet.mergeCells('E1:I1');
|
|
sheet.mergeCells('J1:N1');
|
|
sheet.mergeCells('O1:S1');
|
|
sheet.mergeCells('T1:X1');
|
|
sheet.mergeCells('Y1:AC1');
|
|
sheet.mergeCells('A1:A2'); sheet.mergeCells('B1:B2'); sheet.mergeCells('C1:C2'); sheet.mergeCells('D1:D2');
|
|
sheet.mergeCells('AD1:AD2');
|
|
|
|
[row1, row2].forEach((r: any) => {
|
|
r.font = { bold: true, size: 9 };
|
|
r.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true };
|
|
r.eachCell((cell: any) => {
|
|
cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFD9D9D9' } };
|
|
cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } };
|
|
});
|
|
});
|
|
|
|
docs.forEach((doc: any, idx: number) => {
|
|
|
|
const rowData = CpcHistoryService.getSummaryRow(doc, idx);
|
|
const values = [
|
|
rowData.booking_type,
|
|
rowData.booking_number,
|
|
rowData.document_count,
|
|
rowData.document_name,
|
|
rowData.customer_name_group.msd, rowData.customer_name_group.ocr, rowData.customer_name_group.accuracy_pct, rowData.customer_name_group.criteria, rowData.customer_name_group.is_match,
|
|
rowData.po_or_auth_number_group.msd, rowData.po_or_auth_number_group.ocr, rowData.po_or_auth_number_group.accuracy_pct, rowData.po_or_auth_number_group.criteria, rowData.po_or_auth_number_group.is_match,
|
|
rowData.aadhaar_number_group.msd, rowData.aadhaar_number_group.ocr, rowData.aadhaar_number_group.accuracy_pct, rowData.aadhaar_number_group.criteria, rowData.aadhaar_number_group.is_match,
|
|
rowData.amount_group.msd, rowData.amount_group.ocr, rowData.amount_group.accuracy_pct, rowData.amount_group.criteria, rowData.amount_group.is_match,
|
|
rowData.stamp_group.msd, rowData.stamp_group.ocr, rowData.stamp_group.accuracy_pct, rowData.stamp_group.criteria, rowData.stamp_group.is_match,
|
|
rowData.final_validation
|
|
];
|
|
const row = sheet.addRow(values);
|
|
row.eachCell((cell: any, colNum: number) => {
|
|
cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } };
|
|
cell.font = { size: 8 };
|
|
cell.alignment = { vertical: 'middle', horizontal: 'center' };
|
|
|
|
if (cell.value === 'N.A.' && colNum > 4) {
|
|
cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFF0000' } };
|
|
cell.font = { color: { argb: 'FFFFFFFF' }, size: 8, bold: true };
|
|
}
|
|
});
|
|
});
|
|
|
|
sheet.addRow([]);
|
|
sheet.addRow([]);
|
|
const detailHeader = sheet.addRow(['Detailed Field-Wise Comparison']);
|
|
detailHeader.font = { bold: true, size: 12 };
|
|
|
|
docs.forEach((doc: any) => {
|
|
const docHeader = sheet.addRow([`Document: ${doc.documentType?.replace(/_/g, ' ')}`]);
|
|
docHeader.font = { bold: true, size: 10 };
|
|
|
|
|
|
const subHeader = sheet.addRow(['Field', 'Expected', 'Extracted (OCR)', 'Accuracy %', 'Criteria', 'Status', 'Message']);
|
|
const finalResults = CpcHistoryService.getDetailedFieldResults(doc);
|
|
|
|
finalResults.forEach((f: any) => {
|
|
sheet.addRow([
|
|
f.field.replace(/_/g, ' '),
|
|
f.expected || '-',
|
|
f.extracted || 'Not extracted',
|
|
f.accuracy,
|
|
f.criteria,
|
|
f.pass ? 'PASS' : 'FAIL',
|
|
f.message
|
|
]);
|
|
});
|
|
|
|
sheet.addRow([]);
|
|
});
|
|
|
|
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
|
res.setHeader('Content-Disposition', `attachment; filename=Report_${claimId}.xlsx`);
|
|
await workbook.xlsx.write(res);
|
|
res.end();
|
|
} catch (error: any) {
|
|
return ResponseHandler.error(res, error.message || "Report generation failed", 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Download Master Audit Report for all filtered documents
|
|
*/
|
|
async downloadAllReport(req: Request, res: Response) {
|
|
try {
|
|
const { search, status, type } = req.query;
|
|
const andParts: Record<string, unknown>[] = [];
|
|
appendCpcDocumentFilters(andParts, {
|
|
type: type as string,
|
|
status: status as string,
|
|
search: search as string,
|
|
searchIncludeId: false
|
|
});
|
|
const where = cpcWhereFromAndParts(andParts);
|
|
|
|
const docs = await CpcDocument.findAll({
|
|
where,
|
|
order: [['createdAt', 'DESC']]
|
|
});
|
|
|
|
const workbook = new ExcelJS.Workbook();
|
|
const sheet = workbook.addWorksheet('Master Audit Trail');
|
|
|
|
const row1 = sheet.getRow(1);
|
|
row1.values = ['Booking Type', 'Booking Number', 'Doc ID', 'Document Name', 'Customer Name', '', '', '', '', 'PO Number /Authorisation Letter Number', '', '', '', '', 'Aadhar Number', '', '', '', '', 'PO Amount / Authorisation Letter Amount', '', '', '', '', 'Signature & Stamp Availability', '', '', '', '', 'Final Validation'];
|
|
|
|
const row2 = sheet.getRow(2);
|
|
row2.values = ['', '', '', '', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching %', 'Accuracy Criteria', 'Is Match the Accuracy', 'Expected', 'OCR', 'Accuracy Matching Availability', 'Accuracy Criteria', 'Success Ratio', ''];
|
|
|
|
sheet.mergeCells('E1:I1'); sheet.mergeCells('J1:N1'); sheet.mergeCells('O1:S1'); sheet.mergeCells('T1:X1'); sheet.mergeCells('Y1:AC1'); sheet.mergeCells('A1:A2'); sheet.mergeCells('B1:B2'); sheet.mergeCells('C1:C2'); sheet.mergeCells('D1:D2'); sheet.mergeCells('AD1:AD2');
|
|
|
|
[row1, row2].forEach((r: any) => {
|
|
r.font = { bold: true, size: 9 };
|
|
r.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true };
|
|
r.eachCell((cell: any) => { cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFD9D9D9' } }; cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }; });
|
|
});
|
|
|
|
docs.forEach((doc: any, idx: number) => {
|
|
|
|
const rowData = CpcHistoryService.getSummaryRow(doc, idx);
|
|
const values = [
|
|
rowData.booking_type, rowData.booking_number, String(doc.id).slice(0, 8), rowData.document_name,
|
|
rowData.customer_name_group.msd, rowData.customer_name_group.ocr, rowData.customer_name_group.accuracy_pct, rowData.customer_name_group.criteria, rowData.customer_name_group.is_match,
|
|
rowData.po_or_auth_number_group.msd, rowData.po_or_auth_number_group.ocr, rowData.po_or_auth_number_group.accuracy_pct, rowData.po_or_auth_number_group.criteria, rowData.po_or_auth_number_group.is_match,
|
|
rowData.aadhaar_number_group.msd, rowData.aadhaar_number_group.ocr, rowData.aadhaar_number_group.accuracy_pct, rowData.aadhaar_number_group.criteria, rowData.aadhaar_number_group.is_match,
|
|
rowData.amount_group.msd, rowData.amount_group.ocr, rowData.amount_group.accuracy_pct, rowData.amount_group.criteria, rowData.amount_group.is_match,
|
|
rowData.stamp_group.msd, rowData.stamp_group.ocr, rowData.stamp_group.accuracy_pct, rowData.stamp_group.criteria, rowData.stamp_group.is_match,
|
|
rowData.final_validation
|
|
];
|
|
const row = sheet.addRow(values);
|
|
});
|
|
|
|
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
|
res.setHeader('Content-Disposition', `attachment; filename=Master_Audit_Report.xlsx`);
|
|
await workbook.xlsx.write(res);
|
|
res.end();
|
|
} catch (error: any) {
|
|
return ResponseHandler.error(res, error.message || "Master report failed", 500);
|
|
}
|
|
}
|
|
}
|