Re_Backend/src/controllers/CpcReportController.ts
2026-04-17 19:58:45 +05:30

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);
}
}
}