From 1298bdea16d662ce14c6db6e3f2c1c5380dc4034 Mon Sep 17 00:00:00 2001 From: nitish-egov <137176807+nitish-egov@users.noreply.github.com> Date: Thu, 23 May 2024 12:25:58 +0530 Subject: [PATCH] Uat signoff (#678) * change in filter recursive * lowest level * added validation related to target sheet headers * HLM-5916 --- .../src/server/api/genericApis.ts | 390 +++++++++--------- .../src/server/utils/genericUtils.ts | 25 +- .../server/validators/campaignValidators.ts | 53 ++- 3 files changed, 258 insertions(+), 210 deletions(-) diff --git a/utilities/project-factory/src/server/api/genericApis.ts b/utilities/project-factory/src/server/api/genericApis.ts index f034a90917e..15761ea9187 100644 --- a/utilities/project-factory/src/server/api/genericApis.ts +++ b/utilities/project-factory/src/server/api/genericApis.ts @@ -176,10 +176,14 @@ const getTargetSheetData = async ( const rowData: any = {}; if (Object.keys(row).length > 0) { Object.keys(row).forEach((key) => { - rowData[key] = - row[key] === undefined || row[key] === "" ? "" : row[key]; + // Check if the value is a numerical string + rowData[key] = isNumeric(row[key]) + ? Number(row[key]) + : row[key] === undefined || row[key] === "" + ? "" + : row[key]; }); - if (getRow) rowData["!row#number!"] = index + 1; // Adding row number + if (getRow) rowData["!row#number!"] = index + 1; if (getSheetName) rowData["!sheet#name!"] = sheetName; return rowData; } @@ -521,16 +525,16 @@ async function createExcelSheet( // Function to handle getting boundary codes async function getAutoGeneratedBoundaryCodesHandler(boundaryList: any, childParentMap: Map<{ key: string; value: string; }, { key: string; value: string; } | null>, elementCodesMap: any, countMap: any, request: any) { - try { - // Get updated element codes map - logger.info("Auto Generation of Boundary code begins for the user uploaded sheet") - const updatedelementCodesMap = await getAutoGeneratedBoundaryCodes(boundaryList, childParentMap, elementCodesMap, countMap, request); - return updatedelementCodesMap; // Return the updated element codes map - } catch (error) { - // Log and propagate the error - console.error("Error in getBoundaryCodesHandler:", error); - throw error; - } + try { + // Get updated element codes map + logger.info("Auto Generation of Boundary code begins for the user uploaded sheet") + const updatedelementCodesMap = await getAutoGeneratedBoundaryCodes(boundaryList, childParentMap, elementCodesMap, countMap, request); + return updatedelementCodesMap; // Return the updated element codes map + } catch (error) { + // Log and propagate the error + console.error("Error in getBoundaryCodesHandler:", error); + throw error; + } } /** @@ -544,50 +548,50 @@ async function getAutoGeneratedBoundaryCodesHandler(boundaryList: any, childPare * @returns Updated element codes map */ async function getAutoGeneratedBoundaryCodes(boundaryList: any, childParentMap: any, elementCodesMap: any, countMap: any, request: any) { - // Initialize an array to store column data - const columnsData: { key: string, value: string }[][] = []; - // Extract unique elements from each column - for (const row of boundaryList) { - row.forEach((element: any, index: any) => { - if (!columnsData[index]) { - columnsData[index] = []; - } - const existingElement = columnsData[index].find((existing: any) => _.isEqual(existing, element)); - if (!existingElement) { - columnsData[index].push(element); - } - }); - } + // Initialize an array to store column data + const columnsData: { key: string, value: string }[][] = []; + // Extract unique elements from each column + for (const row of boundaryList) { + row.forEach((element: any, index: any) => { + if (!columnsData[index]) { + columnsData[index] = []; + } + const existingElement = columnsData[index].find((existing: any) => _.isEqual(existing, element)); + if (!existingElement) { + columnsData[index].push(element); + } + }); + } - // Iterate over columns to generate boundary codes - for (let i = 0; i < columnsData.length; i++) { - const column = columnsData[i]; - for (const element of column) { - if (!findMapValue(elementCodesMap, element)) { - const parentCode = findMapValue(childParentMap, element) - if (parentCode !== undefined && parentCode !== null) { - countMap.set(parentCode, (findMapValue(countMap, parentCode) || 0) + 1); - let code; - const grandParentCode = findMapValue(childParentMap, parentCode); - if (grandParentCode != null && grandParentCode != undefined) { - const parentBoundaryCode = findMapValue(elementCodesMap, parentCode) - const lastUnderscoreIndex = parentBoundaryCode.lastIndexOf('_'); - const parentBoundaryCodeTrimmed = lastUnderscoreIndex !== -1 ? parentBoundaryCode.substring(0, lastUnderscoreIndex) : parentBoundaryCode; - code = generateElementCode(countMap.get(parentCode), parentBoundaryCodeTrimmed, element.value); - } else { - code = generateElementCode(countMap.get(parentCode), findMapValue(elementCodesMap, parentCode), element.value); - } - elementCodesMap.set(element, code); // Store the code of the element in the map - } else { - // Generate default code if parent code is not found - elementCodesMap.set(element, (request?.body?.ResourceDetails?.hierarchyType + "_").toUpperCase() + element.value.toString().substring(0, 2).toUpperCase()); - } - } else { - continue; - } + // Iterate over columns to generate boundary codes + for (let i = 0; i < columnsData.length; i++) { + const column = columnsData[i]; + for (const element of column) { + if (!findMapValue(elementCodesMap, element)) { + const parentCode = findMapValue(childParentMap, element) + if (parentCode !== undefined && parentCode !== null) { + countMap.set(parentCode, (findMapValue(countMap, parentCode) || 0) + 1); + let code; + const grandParentCode = findMapValue(childParentMap, parentCode); + if (grandParentCode != null && grandParentCode != undefined) { + const parentBoundaryCode = findMapValue(elementCodesMap, parentCode) + const lastUnderscoreIndex = parentBoundaryCode.lastIndexOf('_'); + const parentBoundaryCodeTrimmed = lastUnderscoreIndex !== -1 ? parentBoundaryCode.substring(0, lastUnderscoreIndex) : parentBoundaryCode; + code = generateElementCode(countMap.get(parentCode), parentBoundaryCodeTrimmed, element.value); + } else { + code = generateElementCode(countMap.get(parentCode), findMapValue(elementCodesMap, parentCode), element.value); + } + elementCodesMap.set(element, code); // Store the code of the element in the map + } else { + // Generate default code if parent code is not found + elementCodesMap.set(element, (request?.body?.ResourceDetails?.hierarchyType + "_").toUpperCase() + element.value.toString().substring(0, 2).toUpperCase()); } + } else { + continue; + } } - return elementCodesMap; // Return the updated element codes map + } + return elementCodesMap; // Return the updated element codes map } /** @@ -691,7 +695,7 @@ async function createStaff(resouceBody: any) { logger.info("Project Staff mapping created"); logger.debug( "Project Staff mapping response " + - getFormattedStringForDebug(staffResponse) + getFormattedStringForDebug(staffResponse) ); validateStaffResponse(staffResponse); } @@ -719,7 +723,7 @@ async function createProjectResource(resouceBody: any) { logger.debug("Project Resource Created"); logger.debug( "Project Resource Creation response :: " + - getFormattedStringForDebug(projectResourceResponse) + getFormattedStringForDebug(projectResourceResponse) ); validateProjectResourceResponse(projectResourceResponse); } @@ -747,7 +751,7 @@ async function createProjectFacility(resouceBody: any) { logger.info("Project Facility Created"); logger.debug( "Project Facility Creation response" + - getFormattedStringForDebug(projectFacilityResponse) + getFormattedStringForDebug(projectFacilityResponse) ); validateProjectFacilityResponse(projectFacilityResponse); } @@ -852,61 +856,61 @@ async function createRelatedResouce(requestBody: any) { * @param boundaryMap Map of boundary names to codes. */ async function createBoundaryEntities(request: any, boundaryMap: Map) { - try { - const updatedBoundaryMap: Array<{ key: string, value: string }> = Array.from(boundaryMap).map(([key, value]) => ({ key: key.value, value: value })); - // Create boundary entities - const requestBody = { "RequestInfo": request.body.RequestInfo } as { RequestInfo: any; Boundary?: any }; - const boundaries: any[] = []; - const codesFromResponse: any = []; - const boundaryCodes: any[] = []; - Array.from(boundaryMap.entries()).forEach(([, boundaryCode]) => { - boundaryCodes.push(boundaryCode); - }); - const boundaryEntitiesCreated: any[] = []; - const boundaryEntityCreateChunkSize = 200; - const chunkSize = 20; - const boundaryCodeChunks = []; - for (let i = 0; i < boundaryCodes.length; i += chunkSize) { - boundaryCodeChunks.push(boundaryCodes.slice(i, i + chunkSize)); - } + try { + const updatedBoundaryMap: Array<{ key: string, value: string }> = Array.from(boundaryMap).map(([key, value]) => ({ key: key.value, value: value })); + // Create boundary entities + const requestBody = { "RequestInfo": request.body.RequestInfo } as { RequestInfo: any; Boundary?: any }; + const boundaries: any[] = []; + const codesFromResponse: any = []; + const boundaryCodes: any[] = []; + Array.from(boundaryMap.entries()).forEach(([, boundaryCode]) => { + boundaryCodes.push(boundaryCode); + }); + const boundaryEntitiesCreated: any[] = []; + const boundaryEntityCreateChunkSize = 200; + const chunkSize = 20; + const boundaryCodeChunks = []; + for (let i = 0; i < boundaryCodes.length; i += chunkSize) { + boundaryCodeChunks.push(boundaryCodes.slice(i, i + chunkSize)); + } - for (const chunk of boundaryCodeChunks) { - const string = chunk.join(', '); - const boundaryEntityResponse = await httpRequest(config.host.boundaryHost + config.paths.boundaryServiceSearch, request.body, { tenantId: request?.body?.ResourceDetails?.tenantId, codes: string }); - const boundaryCodesFromResponse = boundaryEntityResponse.Boundary.flatMap((boundary: any) => boundary.code.toString()); - codesFromResponse.push(...boundaryCodesFromResponse); - } + for (const chunk of boundaryCodeChunks) { + const string = chunk.join(', '); + const boundaryEntityResponse = await httpRequest(config.host.boundaryHost + config.paths.boundaryServiceSearch, request.body, { tenantId: request?.body?.ResourceDetails?.tenantId, codes: string }); + const boundaryCodesFromResponse = boundaryEntityResponse.Boundary.flatMap((boundary: any) => boundary.code.toString()); + codesFromResponse.push(...boundaryCodesFromResponse); + } - const codeSet = new Set(codesFromResponse);// Creating a set and filling it with the codes from the response - for (const { key: boundaryName, value: boundaryCode } of updatedBoundaryMap) { - if (!codeSet.has(boundaryCode.toString())) { - const boundary = { - tenantId: request?.body?.ResourceDetails?.tenantId, - code: boundaryCode, - geometry: null, - additionalDetails: { - name: boundaryName - } - }; - boundaries.push(boundary); - } + const codeSet = new Set(codesFromResponse);// Creating a set and filling it with the codes from the response + for (const { key: boundaryName, value: boundaryCode } of updatedBoundaryMap) { + if (!codeSet.has(boundaryCode.toString())) { + const boundary = { + tenantId: request?.body?.ResourceDetails?.tenantId, + code: boundaryCode, + geometry: null, + additionalDetails: { + name: boundaryName + } }; - if (!(boundaries.length === 0)) { - for (let i = 0; i < boundaries.length; i += boundaryEntityCreateChunkSize) { - requestBody.Boundary = boundaries.slice(i, i + boundaryEntityCreateChunkSize); - const response = await httpRequest(`${config.host.boundaryHost}boundary-service/boundary/_create`, requestBody, {}, 'POST',); - boundaryEntitiesCreated.push(response) - } - logger.info('Boundary entities created'); - logger.debug('Boundary entities response: ' + getFormattedStringForDebug(boundaryEntitiesCreated)); - } - else { - // throwError("COMMON", 400, "VALIDATION_ERROR", "Boundary entity already present in the system"); - logger.info("Boundary Entities are already in the system") - } - } catch (error) { - throwError("COMMMON", 500, "INTERNAL_SERVER_ERROR", "Error while Boundary Entity Creation") + boundaries.push(boundary); + } + }; + if (!(boundaries.length === 0)) { + for (let i = 0; i < boundaries.length; i += boundaryEntityCreateChunkSize) { + requestBody.Boundary = boundaries.slice(i, i + boundaryEntityCreateChunkSize); + const response = await httpRequest(`${config.host.boundaryHost}boundary-service/boundary/_create`, requestBody, {}, 'POST',); + boundaryEntitiesCreated.push(response) + } + logger.info('Boundary entities created'); + logger.debug('Boundary entities response: ' + getFormattedStringForDebug(boundaryEntitiesCreated)); + } + else { + // throwError("COMMON", 400, "VALIDATION_ERROR", "Boundary entity already present in the system"); + logger.info("Boundary Entities are already in the system") } + } catch (error) { + throwError("COMMMON", 500, "INTERNAL_SERVER_ERROR", "Error while Boundary Entity Creation") + } } /** @@ -916,74 +920,74 @@ async function createBoundaryEntities(request: any, boundaryMap: Map) * @param modifiedChildParentMap Modified child-parent map. */ async function createBoundaryRelationship(request: any, boundaryMap: Map<{ key: string, value: string }, string>, modifiedChildParentMap: Map) { - try { - - const updatedBoundaryMap: Array<{ key: string, value: string }> = Array.from(boundaryMap).map(([key, value]) => ({ key: value, value: key.key })); - - let activityMessage: any[] = []; - const requestBody = { "RequestInfo": request.body.RequestInfo } as { RequestInfo: any; BoundaryRelationship?: any }; - const url = `${config.host.boundaryHost}${config.paths.boundaryRelationship}`; - const params = { - "type": request?.body?.ResourceDetails?.type, - "tenantId": request?.body?.ResourceDetails?.tenantId, - "boundaryType": null, - "codes": null, - "includeChildren": true, - "hierarchyType": request?.body?.ResourceDetails?.hierarchyType - }; + try { - const boundaryRelationshipResponse = await httpRequest(url, request.body, params); - const boundaryData = boundaryRelationshipResponse?.TenantBoundary?.[0]?.boundary; - const allCodes = extractCodesFromBoundaryRelationshipResponse(boundaryData); - - let flag = 1; - - for (const { key: boundaryCode, value: boundaryType } of updatedBoundaryMap) { - if (!allCodes.has(boundaryCode)) { - const boundary = { - tenantId: request?.body?.ResourceDetails?.tenantId, - boundaryType: boundaryType, - code: boundaryCode, - hierarchyType: request?.body?.ResourceDetails?.hierarchyType, - parent: modifiedChildParentMap.get(boundaryCode) ? modifiedChildParentMap.get(boundaryCode) : null - }; - - flag = 0; - requestBody.BoundaryRelationship = boundary; - // Introducing a delay of 1 second - await new Promise(resolve => setTimeout(resolve, 1000)); - try { - const response = await httpRequest(`${config.host.boundaryHost}${config.paths.boundaryRelationshipCreate}`, requestBody, {}, 'POST', undefined, undefined, true); - - if (!response.TenantBoundary || !Array.isArray(response.TenantBoundary) || response.TenantBoundary.length === 0) { - throwError("BOUNDARY", 500, "BOUNDARY_RELATIONSHIP_CREATE_ERROR"); - } - logger.info(`Boundary relationship created for boundaryType :: ${boundaryType} & boundaryCode :: ${boundaryCode} `); - - const newRequestBody = JSON.parse(JSON.stringify(request.body)); - activityMessage.push(await generateActivityMessage(request?.body?.ResourceDetails?.tenantId, request.body, newRequestBody, response, request?.body?.ResourceDetails?.type, url, response?.statusCode)); - } catch (error) { - // Log the error and rethrow to be caught by the outer try...catch block - logger.error(`Error creating boundary relationship for boundaryType :: ${boundaryType} & boundaryCode :: ${boundaryCode} :: `, error); - throw error; - } - } + const updatedBoundaryMap: Array<{ key: string, value: string }> = Array.from(boundaryMap).map(([key, value]) => ({ key: value, value: key.key })); + + let activityMessage: any[] = []; + const requestBody = { "RequestInfo": request.body.RequestInfo } as { RequestInfo: any; BoundaryRelationship?: any }; + const url = `${config.host.boundaryHost}${config.paths.boundaryRelationship}`; + const params = { + "type": request?.body?.ResourceDetails?.type, + "tenantId": request?.body?.ResourceDetails?.tenantId, + "boundaryType": null, + "codes": null, + "includeChildren": true, + "hierarchyType": request?.body?.ResourceDetails?.hierarchyType + }; + + const boundaryRelationshipResponse = await httpRequest(url, request.body, params); + const boundaryData = boundaryRelationshipResponse?.TenantBoundary?.[0]?.boundary; + const allCodes = extractCodesFromBoundaryRelationshipResponse(boundaryData); + + let flag = 1; + + for (const { key: boundaryCode, value: boundaryType } of updatedBoundaryMap) { + if (!allCodes.has(boundaryCode)) { + const boundary = { + tenantId: request?.body?.ResourceDetails?.tenantId, + boundaryType: boundaryType, + code: boundaryCode, + hierarchyType: request?.body?.ResourceDetails?.hierarchyType, + parent: modifiedChildParentMap.get(boundaryCode) ? modifiedChildParentMap.get(boundaryCode) : null }; - if (flag === 1) { - throwError("COMMON", 400, "VALIDATION_ERROR", "Boundary already present in the system"); + flag = 0; + requestBody.BoundaryRelationship = boundary; + // Introducing a delay of 1 second + await new Promise(resolve => setTimeout(resolve, 1000)); + try { + const response = await httpRequest(`${config.host.boundaryHost}${config.paths.boundaryRelationshipCreate}`, requestBody, {}, 'POST', undefined, undefined, true); + + if (!response.TenantBoundary || !Array.isArray(response.TenantBoundary) || response.TenantBoundary.length === 0) { + throwError("BOUNDARY", 500, "BOUNDARY_RELATIONSHIP_CREATE_ERROR"); + } + logger.info(`Boundary relationship created for boundaryType :: ${boundaryType} & boundaryCode :: ${boundaryCode} `); + + const newRequestBody = JSON.parse(JSON.stringify(request.body)); + activityMessage.push(await generateActivityMessage(request?.body?.ResourceDetails?.tenantId, request.body, newRequestBody, response, request?.body?.ResourceDetails?.type, url, response?.statusCode)); + } catch (error) { + // Log the error and rethrow to be caught by the outer try...catch block + logger.error(`Error creating boundary relationship for boundaryType :: ${boundaryType} & boundaryCode :: ${boundaryCode} :: `, error); + throw error; } + } + }; - request.body = { - ...request.body, - Activities: activityMessage - }; - } catch (error: any) { - const errorCode = error.code || "INTERNAL_SERVER_ERROR"; - const errorMessage = error.description || "Error while boundary relationship create"; - logger.error(`Error in createBoundaryRelationship: ${errorMessage}`, error); - throwError("COMMON", 500, errorCode, errorMessage); + if (flag === 1) { + throwError("COMMON", 400, "VALIDATION_ERROR", "Boundary already present in the system"); } + + request.body = { + ...request.body, + Activities: activityMessage + }; + } catch (error: any) { + const errorCode = error.code || "INTERNAL_SERVER_ERROR"; + const errorMessage = error.description || "Error while boundary relationship create"; + logger.error(`Error in createBoundaryRelationship: ${errorMessage}`, error); + throwError("COMMON", 500, errorCode, errorMessage); + } } @@ -1017,30 +1021,30 @@ async function callMdmsData( } async function getMDMSV1Data(request: any, moduleName: string, masterName: string, tenantId: string) { - const resp=await callMdmsData(request, moduleName, masterName, tenantId); - return resp; + const resp = await callMdmsData(request, moduleName, masterName, tenantId); + return resp; } export { - getAutoGeneratedBoundaryCodes, - getAutoGeneratedBoundaryCodesHandler, - createBoundaryEntities, - createBoundaryRelationship, - getWorkbook, - getSheetData, - searchMDMS, - getCampaignNumber, - getSchema, - getResouceNumber, - getCount, - getBoundarySheetData, - createAndUploadFile, - createRelatedResouce, - createExcelSheet, - generateHierarchy, - generateHierarchyList, - getTargetWorkbook, - getTargetSheetData, - callMdmsData, - getMDMSV1Data + getAutoGeneratedBoundaryCodes, + getAutoGeneratedBoundaryCodesHandler, + createBoundaryEntities, + createBoundaryRelationship, + getWorkbook, + getSheetData, + searchMDMS, + getCampaignNumber, + getSchema, + getResouceNumber, + getCount, + getBoundarySheetData, + createAndUploadFile, + createRelatedResouce, + createExcelSheet, + generateHierarchy, + generateHierarchyList, + getTargetWorkbook, + getTargetSheetData, + callMdmsData, + getMDMSV1Data } diff --git a/utilities/project-factory/src/server/utils/genericUtils.ts b/utilities/project-factory/src/server/utils/genericUtils.ts index 222c26ded8b..97e7fcda321 100644 --- a/utilities/project-factory/src/server/utils/genericUtils.ts +++ b/utilities/project-factory/src/server/utils/genericUtils.ts @@ -961,6 +961,28 @@ function findMapValue(map: Map, key: any): any | null { return foundValue; } +function getDifferentDistrictTabs(boundaryData: any, differentTabsBasedOnLevel: any) { + const uniqueDistrictsForMainSheet: string[] = []; + const differentDistrictTabs: any[] = []; + for (const data of boundaryData) { + const rowData = Object.values(data); + const districtValue = data[differentTabsBasedOnLevel]; + const districtIndex = districtValue !== '' ? rowData.indexOf(districtValue) : -1; + + if (districtIndex != -1) { + const districtLevelRow = rowData.slice(0, districtIndex + 1); + const districtKey = districtLevelRow.join('_'); + + if (!uniqueDistrictsForMainSheet.includes(districtKey)) { + uniqueDistrictsForMainSheet.push(districtKey); + } + } + } + for (const uniqueData of uniqueDistrictsForMainSheet) { + differentDistrictTabs.push(uniqueData.slice(uniqueData.lastIndexOf('_') + 1)); + } + return differentDistrictTabs; +} @@ -1006,7 +1028,8 @@ export { getLocalizedHeaders, createReadMeSheet, findMapValue, - replicateRequest + replicateRequest, + getDifferentDistrictTabs }; diff --git a/utilities/project-factory/src/server/validators/campaignValidators.ts b/utilities/project-factory/src/server/validators/campaignValidators.ts index 72c27080c83..6542b3ba461 100644 --- a/utilities/project-factory/src/server/validators/campaignValidators.ts +++ b/utilities/project-factory/src/server/validators/campaignValidators.ts @@ -5,7 +5,7 @@ import { httpRequest } from "../utils/request"; import { getHeadersOfBoundarySheet, getHierarchy, handleResouceDetailsError } from "../api/campaignApis"; import { campaignDetailsSchema } from "../config/models/campaignDetails"; import Ajv from "ajv"; -import { calculateKeyIndex, getLocalizedHeaders, getLocalizedMessagesHandler, modifyTargetData, replicateRequest, throwError } from "../utils/genericUtils"; +import { calculateKeyIndex, getDifferentDistrictTabs, getLocalizedHeaders, getLocalizedMessagesHandler, modifyTargetData, replicateRequest, throwError } from "../utils/genericUtils"; import { createBoundaryMap, generateProcessedFileAndPersist, getLocalizedName } from "../utils/campaignUtils"; import { validateBodyViaSchema, validateCampaignBodyViaSchema, validateHierarchyType } from "./genericValidator"; import { searchCriteriaSchema } from "../config/models/SearchCriteria"; @@ -403,26 +403,28 @@ async function validateCreateRequest(request: any) { const targetWorkbook: any = await getTargetWorkbook(fileUrl); // const mainSheetName = targetWorkbook.SheetNames[1]; // const sheetData = await getSheetData(fileUrl, mainSheetName, true, undefined, localizationMap); - // const hierachy = await getHierarchy(request, request?.body?.ResourceDetails?.tenantId, request?.body?.ResourceDetails?.hierarchyType); + const hierarchy = await getHierarchy(request, request?.body?.ResourceDetails?.tenantId, request?.body?.ResourceDetails?.hierarchyType); + const modifiedHierarchy = hierarchy.map(ele => `${request?.body?.ResourceDetails?.hierarchyType}_${ele}`.toUpperCase()); + const localizedHierarchy = getLocalizedHeaders(modifiedHierarchy, localizationMap); + const index = localizedHierarchy.indexOf(getLocalizedName(config.generateDifferentTabsOnBasisOf, localizationMap)); + let expectedHeadersForTargetSheet = index !== -1 ? localizedHierarchy.slice(index) : throwError("COMMON", 400, "VALIDATION_ERROR", `${getLocalizedName(config.generateDifferentTabsOnBasisOf, localizationMap)} level not present in the hierarchy`); + expectedHeadersForTargetSheet = [...expectedHeadersForTargetSheet, getLocalizedName(config.boundaryCode, localizationMap), getLocalizedName("HCM_ADMIN_CONSOLE_TARGET", localizationMap)] // validateForRootElementExists(sheetData, hierachy, mainSheetName); - validateTabsWithTargetInTargetSheet(request, targetWorkbook); + validateTabsWithTargetInTargetSheet(request, targetWorkbook, expectedHeadersForTargetSheet); } } } -function validateTabsWithTargetInTargetSheet(request: any, targetWorkbook: any) { - const sheet = targetWorkbook.Sheets[targetWorkbook.SheetNames[2]]; - const expectedHeaders = XLSX.utils.sheet_to_json(sheet, { - header: 1, - })[0]; +function validateTabsWithTargetInTargetSheet(request: any, targetWorkbook: any, expectedHeadersForTargetSheet: any) { for (let i = 2; i < targetWorkbook.SheetNames.length; i++) { const sheetName = targetWorkbook?.SheetNames[i]; const sheet = targetWorkbook?.Sheets[sheetName]; // Convert the sheet to JSON to extract headers - const headersToValidate = XLSX.utils.sheet_to_json(sheet, { + let headersToValidate: any = XLSX.utils.sheet_to_json(sheet, { header: 1, })[0]; - if (!_.isEqual(expectedHeaders, headersToValidate)) { + headersToValidate = headersToValidate.map((header: any) => header.trim()); + if (!_.isEqual(expectedHeadersForTargetSheet, headersToValidate)) { throwError("COMMON", 400, "VALIDATION_ERROR", `Headers not according to the template in target sheet ${sheetName}`) } } @@ -966,13 +968,14 @@ async function validateDownloadRequest(request: any) { } function immediateValidationForTargetSheet(dataFromSheet: any, localizationMap: any) { + validateAllDistrictTabsPresentOrNot(dataFromSheet, localizationMap); for (const key in dataFromSheet) { - if (Object.prototype.hasOwnProperty.call(dataFromSheet, key)) { - const dataArray = (dataFromSheet as { [key: string]: any[] })[key]; - if (dataArray.length === 0) { - throwError("COMMON", 400, "VALIDATION_ERROR", `The Target Sheet ${key} you have uploaded is empty`) - } - if (key != getLocalizedName(getBoundaryTabName(), localizationMap) && key != getLocalizedName(config?.readMeTab, localizationMap)) { + if (key != getLocalizedName(getBoundaryTabName(), localizationMap) && key != getLocalizedName(config?.readMeTab, localizationMap)) { + if (Object.prototype.hasOwnProperty.call(dataFromSheet, key)) { + const dataArray = (dataFromSheet as { [key: string]: any[] })[key]; + if (dataArray.length === 0) { + throwError("COMMON", 400, "VALIDATION_ERROR", `The Target Sheet ${key} you have uploaded is empty`) + } const root = getLocalizedName(config.generateDifferentTabsOnBasisOf, localizationMap); for (const boundaryRow of dataArray) { for (const columns in boundaryRow) { @@ -990,6 +993,24 @@ function immediateValidationForTargetSheet(dataFromSheet: any, localizationMap: } +function validateAllDistrictTabsPresentOrNot(dataFromSheet: any, localizationMap?: any) { + let tabsIndex = 2; + const tabsOfDistrict = getDifferentDistrictTabs(modifyTargetData(dataFromSheet), getLocalizedName(config.generateDifferentTabsOnBasisOf, localizationMap)); + const tabsFromTargetSheet = Object.keys(dataFromSheet); + for (let tab of tabsOfDistrict) { + if (tabsIndex >= tabsFromTargetSheet.length) { + throwError("COMMON", 400, "VALIDATION_ERROR", `District tab ${tab} not present in the Target Sheet Uploaded`); + } + if (tabsFromTargetSheet[tabsIndex] === tab) { + tabsIndex++; + } + else { + throwError("COMMON", 400, "VALIDATION_ERROR", `District tab ${tab} not present in the Target Sheet Uploaded`) + } + } +} + + export { fetchBoundariesInChunks, validateSheetData,