Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat : added user mapping for multiple boundaries with common parent #1005

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions utilities/project-factory/src/server/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const getDBSchemaName = (dbSchema = "") => {
}
// Configuration object containing various environment variables
const config = {
excludeHierarchyTypeFromBoundaryCodes:false,
excludeBoundaryNameAtLastFromBoundaryCodes:false,
excludeHierarchyTypeFromBoundaryCodes: false,
excludeBoundaryNameAtLastFromBoundaryCodes: false,
masterNameForSchemaOfColumnHeaders: "adminSchema",
masterNameForSplitBoundariesOn: "hierarchyConfig",
boundary: {
Expand All @@ -38,6 +38,7 @@ const config = {
userSchemaMasterName: process.env.USER_SCHEMA_MASTER || "userSchema",
userDefaultPassword: process.env.USER_DEFAULT_PASSWORD || "eGov@123",
userPasswordAutoGenerate: process.env.USER_PASSWORD_AUTO_GENERATE || "true",
mapUserViaCommonParent: process.env.MAP_USER_VIA_COMMON_PARENT || false,
},
cacheValues: {
cacheEnabled: process.env.CACHE_ENABLED,
Expand Down
116 changes: 101 additions & 15 deletions utilities/project-factory/src/server/utils/campaignMappingUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import createAndSearch from "../config/createAndSearch";
import config from "../config";
import { getDataFromSheet, throwError } from "./genericUtils";
import { getFormattedStringForDebug, logger } from "./logger";
import { httpRequest } from "./request";
import { defaultheader, httpRequest } from "./request";
import { produceModifiedMessages } from "../kafka/Listener";
import { getLocalizedName } from "./campaignUtils";
import { campaignStatuses, resourceDataStatuses } from "../config/constants";
Expand Down Expand Up @@ -36,8 +36,107 @@ function getPvarIds(messageObject: any) {
return Array.from(uniquePvarIds); // Convert Set to array before returning
}

function trimBoundaryCodes(root: any) {
if (root) {
root.code = root.code.trim(); // Trim the code

// Recursively trim the codes in the children
for (const child of root.children) {
trimBoundaryCodes(child);
}
}
}

async function getAllBoundaries(messageObject: any, tenantId: any, rootBoundary: any, hierarchyType: any) {
const BoundarySearchBody = {
RequestInfo: messageObject?.RequestInfo,
}
const params = {
tenantId,
codes: rootBoundary,
hierarchyType,
includeChildren: true
}
const header = {
...defaultheader,
cachekey: `boundaryRelationShipSearch${params?.hierarchyType}${params?.tenantId}${params.codes || ''}${params?.includeChildren || ''}`,
}
const boundaryResponse = await httpRequest(config.host.boundaryHost + config.paths.boundaryRelationship, BoundarySearchBody, params, undefined, undefined, header);
trimBoundaryCodes(boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0]);
return boundaryResponse?.TenantBoundary?.[0]?.boundary?.[0]
}

// Function to find the path to a given boundary code
function findPath(root: any, code: string, path: any[] = []) {
if (root.code === code) {
return [...path, root];
}
for (const child of root.children) {
const result: any = findPath(child, code, [...path, root]);
if (result) return result;
}
return null;
}

// Function to find the common parent for multiple codes
function findCommonParent(codes: string[], root: any) {
if (codes.length === 0) return null;

// Find paths for all codes
const paths = codes.map(code => findPath(root, code)).filter(path => path !== null);

if (paths.length === 0) return null;

// Compare paths to find the common ancestor
let commonParent: any = null;

for (let i = 0; i < Math.min(...paths.map(path => path.length)); i++) {
const currentParent = paths[0][i];
if (paths.every(path => path[i] && path[i].code === currentParent.code)) {
commonParent = currentParent;
} else {
break;
}
}

return commonParent?.code;
}

function mapBoundaryCodes(resource: any, code: string, boundaryCode: string, boundaryCodes: any, allBoundaries: any) {
// Split boundary codes if they have comma separated values
const boundaryCodesArray = boundaryCode.split(',').map((bc: string) => bc.trim());
if (resource?.type == "user" && boundaryCodesArray?.length > 1 && config.user.mapUserViaCommonParent) {
const commonParent = findCommonParent(boundaryCodesArray, allBoundaries);
if (commonParent) {
logger.info(`Boundary Codes Array ${boundaryCodesArray.join(",")} for resource ${resource?.type} has common parent ${commonParent}`)
if (!boundaryCodes[resource?.type]) {
boundaryCodes[resource?.type] = {};
}
if (!boundaryCodes[resource?.type][commonParent]) {
boundaryCodes[resource?.type][commonParent] = [];
}
boundaryCodes[resource?.type][commonParent].push(code);
logger.info(`Common Parent Boundary code ${commonParent} mapped to resource ${resource?.type} with code ${code}`)
}
}
else {
boundaryCodesArray.forEach((trimmedBC: string) => {
// Trim any leading or trailing spaces
if (!boundaryCodes[resource?.type]) {
boundaryCodes[resource?.type] = {};
}
if (!boundaryCodes[resource?.type][trimmedBC]) {
boundaryCodes[resource?.type][trimmedBC] = [];
}
boundaryCodes[resource?.type][trimmedBC].push(code);
logger.info(`Boundary code ${trimmedBC} mapped to resource ${resource?.type} with code ${code}`)
});
}
}

async function enrichBoundaryCodes(resources: any[], messageObject: any, boundaryCodes: any, sheetName: any) {
const localizationMap: any = messageObject?.localizationMap
const allBoundaries = await getAllBoundaries(messageObject, messageObject?.Campaign?.tenantId, messageObject?.Campaign?.boundaryCode, messageObject?.Campaign?.hierarchyType);
for (const resource of resources) {
const processedFilestoreId = resource?.processedFilestoreId;
if (processedFilestoreId) {
Expand All @@ -54,20 +153,7 @@ async function enrichBoundaryCodes(resources: any[], messageObject: any, boundar
active = data[activeColumn];
}
if (boundaryCode && active == "Active") {
// Split boundary codes if they have comma separated values
const boundaryCodesArray = boundaryCode.split(',');
boundaryCodesArray.forEach((bc: string) => {
// Trim any leading or trailing spaces
const trimmedBC = bc.trim();
if (!boundaryCodes[resource?.type]) {
boundaryCodes[resource?.type] = {};
}
if (!boundaryCodes[resource?.type][trimmedBC]) {
boundaryCodes[resource?.type][trimmedBC] = [];
}
boundaryCodes[resource?.type][trimmedBC].push(code);
logger.info(`Boundary code ${trimmedBC} mapped to resource ${resource?.type} with code ${code}`)
});
mapBoundaryCodes(resource, code, boundaryCode, boundaryCodes, allBoundaries);
}
}
else {
Expand Down
Loading