diff --git a/utilities/project-factory/src/server/api/genericApis.ts b/utilities/project-factory/src/server/api/genericApis.ts index fe0ebcba109..4cb3583d975 100644 --- a/utilities/project-factory/src/server/api/genericApis.ts +++ b/utilities/project-factory/src/server/api/genericApis.ts @@ -138,6 +138,69 @@ const getTargetSheetData = async ( return workbookData; }; +const getTargetSheetDataAfterCode = async ( + fileUrl: string, + getRow = false, + getSheetName = false, + codeColumnName = "Boundary Code", + localizationMap?: any +) => { + const workbook = await getTargetWorkbook(fileUrl, localizationMap); + const sheetNames: string[] = []; + workbook.eachSheet((worksheet: any) => { + sheetNames.push(worksheet.name); + }); + const localizedSheetNames = getLocalizedHeaders(sheetNames, localizationMap); + + const workbookData: { [key: string]: any[] } = {}; // Object to store data from each sheet + + for (const sheetName of localizedSheetNames) { + const worksheet = workbook.getWorksheet(sheetName); + const sheetData = worksheet.getSheetValues({ includeEmpty: true }); + + // Find the target column index where the first row value matches codeColumnName + const firstRow = sheetData[1]; + let targetColumnIndex = -1; + for (let colIndex = 1; colIndex < firstRow.length; colIndex++) { + if (firstRow[colIndex] === codeColumnName) { + targetColumnIndex = colIndex; + break; + } + } + + if (targetColumnIndex === -1) { + console.warn(`Column "${codeColumnName}" not found in sheet "${sheetName}".`); + continue; + } + + // Process data from sheet + const processedData = sheetData.map((row: any, rowIndex: any) => { + if (rowIndex === 0) return null; // Skip header row + + let rowData = getJsonData([row], getRow, getSheetName, sheetName)[0]; + if (!rowData) return null; + + // Add integer values in the target column for the current row + let sum = 0; + for (let colIndex = targetColumnIndex + 1; colIndex < row.length; colIndex++) { + const value = row[colIndex]; + if (typeof value === 'number' && Number.isInteger(value)) { + sum += value; + } + } + + // Add the sum to the row data + rowData['Target at the Selected Boundary level'] = sum; + return rowData; + }).filter(Boolean); // Remove null entries + + workbookData[sheetName] = processedData; + } + + return workbookData; +}; + + // Function to search MDMS for specific unique identifiers const searchMDMS: any = async ( uniqueIdentifiers: any[], @@ -1111,6 +1174,7 @@ export { generateHierarchyList, getTargetWorkbook, getTargetSheetData, + getTargetSheetDataAfterCode, callMdmsData, getMDMSV1Data, callMdmsV2Data, diff --git a/utilities/project-factory/src/server/utils/campaignUtils.ts b/utilities/project-factory/src/server/utils/campaignUtils.ts index 7747c3cdc1f..0e1a4792677 100644 --- a/utilities/project-factory/src/server/utils/campaignUtils.ts +++ b/utilities/project-factory/src/server/utils/campaignUtils.ts @@ -4,7 +4,7 @@ import config from "../config/index"; import { v4 as uuidv4 } from 'uuid'; import { produceModifiedMessages } from '../kafka/Listener' import { confirmProjectParentCreation, createProjectCampaignResourcData, getCampaignSearchResponse, getHierarchy, handleResouceDetailsError, projectCreate } from "../api/campaignApis"; -import { getCampaignNumber, createAndUploadFile, getSheetData, createExcelSheet, getAutoGeneratedBoundaryCodesHandler, getTargetSheetData, createBoundaryEntities, createBoundaryRelationship, getMDMSV1Data, callMdmsV2Data } from "../api/genericApis"; +import { getCampaignNumber, createAndUploadFile, getSheetData, createExcelSheet, getAutoGeneratedBoundaryCodesHandler, createBoundaryEntities, createBoundaryRelationship, getMDMSV1Data, callMdmsV2Data, getTargetSheetDataAfterCode } from "../api/genericApis"; import { getFormattedStringForDebug, logger } from "./logger"; import createAndSearch from "../config/createAndSearch"; import { addDataToSheet, changeFirstRowColumnColour, createBoundaryDataMainSheet, createReadMeSheet, findMapValue, getBoundaryRelationshipData, getConfigurableColumnHeadersFromSchemaForTargetSheet, getLocalizedHeaders, getLocalizedMessagesHandler, modifyBoundaryData, replicateRequest, throwError } from "./genericUtils"; @@ -1231,9 +1231,9 @@ async function getCodesTarget(request: any, localizationMap?: any) { if (!fileResponse?.fileStoreIds?.[0]?.url) { throwError("FILE", 500, "DOWNLOAD_URL_NOT_FOUND"); } - const targetData = await getTargetSheetData(fileResponse?.fileStoreIds?.[0]?.url, true, true); - const boundaryTargetMapping: any = {}; const codeColumnName = getLocalizedName(createAndSearch?.boundaryWithTarget?.boundaryValidation?.column, localizationMap) + const targetData = await getTargetSheetDataAfterCode(fileResponse?.fileStoreIds?.[0]?.url, true, true, codeColumnName); + const boundaryTargetMapping: any = {}; // Iterate through each key in targetData for (const key in targetData) { // Iterate through each entry in the array under the current key diff --git a/utilities/project-factory/src/server/utils/genericUtils.ts b/utilities/project-factory/src/server/utils/genericUtils.ts index 89299ea208b..8bb639bcc0e 100644 --- a/utilities/project-factory/src/server/utils/genericUtils.ts +++ b/utilities/project-factory/src/server/utils/genericUtils.ts @@ -15,6 +15,7 @@ import { getLocaleFromRequest, getLocalisationModuleName } from "./localisationU import { getBoundaryColumnName, getBoundaryTabName } from "./boundaryUtils"; import { getBoundaryDataService } from "../service/dataManageService"; import { addDataToSheet, formatWorksheet, getNewExcelWorkbook } from "./excelUtils"; +import createAndSearch from "../config/createAndSearch"; const NodeCache = require("node-cache"); const updateGeneratedResourceTopic = config?.kafka?.KAFKA_UPDATE_GENERATED_RESOURCE_DETAILS_TOPIC; @@ -562,10 +563,16 @@ function changeFirstRowColumnColour(facilitySheet: any, color: any, columnNumber firstHeaderCell.fill = { type: 'pattern', pattern: 'solid', - fgColor: { argb: color } // Orange color + fgColor: { argb: color } }; } +function hideUniqueIdentifierColumn(sheet: any, column: any) { + if (column) { + sheet.getColumn(column).hidden = true + } +} + async function createFacilityAndBoundaryFile(facilitySheetData: any, boundarySheetData: any, request: any, localizationMap?: any) { const workbook = getNewExcelWorkbook(); @@ -582,6 +589,7 @@ async function createFacilityAndBoundaryFile(facilitySheetData: any, boundaryShe // Add facility sheet data const facilitySheet = workbook.addWorksheet(localizedFacilityTab); addDataToSheet(facilitySheet, facilitySheetData, undefined, undefined, true); + hideUniqueIdentifierColumn(facilitySheet, createAndSearch?.["facility"]?.uniqueIdentifierColumn); changeFirstRowColumnColour(facilitySheet, 'E06666'); // Add boundary sheet to the workbook diff --git a/utilities/project-factory/src/server/validators/campaignValidators.ts b/utilities/project-factory/src/server/validators/campaignValidators.ts index a02711cd2fc..68a5a32b9c2 100644 --- a/utilities/project-factory/src/server/validators/campaignValidators.ts +++ b/utilities/project-factory/src/server/validators/campaignValidators.ts @@ -330,6 +330,16 @@ async function validateViaSchema(data: any, schema: any, request: any, localizat } if (data?.length > 0) { data.forEach((item: any) => { + if (activeColumnName) { + if (!item?.[activeColumnName]) { + throwError("COMMON", 400, "VALIDATION_ERROR", `Data at row ${item?.["!row#number!"]} have missing value in ${activeColumnName}`); + } + if (item?.[activeColumnName] != "Active" && item?.[activeColumnName] != "Inactive") { + { + throwError("COMMON", 400, "VALIDATION_ERROR", `Data at row ${item?.["!row#number!"]} have invalid value in ${activeColumnName}, Allowed values are Active or Inactive`); + } + } + } const active = activeColumnName ? item[activeColumnName] : "Active"; if (active == "Active" || !item?.[uniqueIdentifierColumnName]) if (!validate(item)) {