/** * Copyright (c) 2026 Niolla * All rights reserved. * * This source code is proprietary and confidential. * Unauthorized copying, modification, distribution, or use * of this file, via any medium, is strictly prohibited. */ // app/utills/validateExcel.utill.js const ExcelJS = require("exceljs"); exports.validateExcel = async (buffer, columns) => { const workbook = new ExcelJS.Workbook(); await workbook.xlsx.load(buffer); const worksheet = workbook.worksheets[0]; if (!worksheet) { throw { status: 400, message: "Excel sheet is empty" }; } const expectedHeaders = columns.map((col) => col.is_required ? `${col.column_name} *` : col.column_name ); const headerRow = worksheet.getRow(1); for (let i = 1; i <= expectedHeaders.length; i++) { const cellValue = (headerRow.getCell(i).value || "").toString().trim(); if (cellValue !== expectedHeaders[i - 1]) { throw { status: 400, message: `Invalid header in column ${i}`, expected: expectedHeaders[i - 1], received: cellValue, }; } } const errors = []; const validData = []; worksheet.eachRow((row, rowNumber) => { if (rowNumber === 1) return; let rowData = {}; let rowHasError = false; columns.forEach((col, index) => { let value = row.getCell(index + 1).value; if (value && typeof value === "object") { value = value.text || value.result || ""; } value = value?.toString().trim() || ""; if (col.is_required && !value) { errors.push({ row: rowNumber, column: col.column_name, message: "Required field is missing", }); rowHasError = true; } if (value) { if (col.validation_type === "number" && isNaN(value)) { errors.push({ row: rowNumber, column: col.column_name, message: "Must be a number", }); rowHasError = true; } if ( col.validation_type === "boolean" && !["true", "false"].includes(value.toLowerCase()) ) { errors.push({ row: rowNumber, column: col.column_name, message: "Must be true or false", }); rowHasError = true; } } rowData[col.column_name] = value; }); if (!rowHasError) { validData.push(rowData); } }); return { errors, validData }; };