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

Implement entity persistence for project creation #1326

Open
wants to merge 38 commits into
base: console
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
54cdeb3
Implement entity persistence for project creation
ashish-egov Jan 6, 2025
b527092
Made index changes
ashish-egov Jan 6, 2025
18f99d6
Fixed project update
ashish-egov Jan 6, 2025
2f5959c
Update logic fixed
ashish-egov Jan 7, 2025
8b1eddc
Campaign number fix
ashish-egov Jan 7, 2025
778f565
Merge branch 'console' into HCMPRE-1788-project-creation-entity-persi…
ashish-egov Jan 9, 2025
5a6f9d6
Implemented Bulk project creation
ashish-egov Jan 15, 2025
7bc6ebc
Merge branch 'console' into HCMPRE-1788-project-creation-entity-persi…
ashish-egov Jan 15, 2025
62a23b0
Refactor
ashish-egov Jan 15, 2025
a364bdf
Merge branch 'HCMPRE-1788-project-creation-entity-persistence' of htt…
ashish-egov Jan 15, 2025
f7ab7bc
Project bulk creation implemented
ashish-egov Jan 16, 2025
e20bcfe
Update Listener.ts
ashish-egov Jan 17, 2025
c04fdc2
Merge pull request #1342 from egovernments/ashish-egov-patch-4
ashish-egov Jan 17, 2025
c9e34e1
Refactored
ashish-egov Jan 17, 2025
836f8f3
Merge branch 'HCMPRE-1788-project-creation-entity-persistence' of htt…
ashish-egov Jan 17, 2025
f81c5ed
Project creation uuid fix
ashish-egov Jan 18, 2025
77c9119
Project fix
ashish-egov Jan 18, 2025
cea7a0f
fix for mapping
ashish-egov Jan 20, 2025
c2a01ad
Update campaignMappingUtils.ts
ashish-egov Jan 21, 2025
cdcec89
Merge pull request #1346 from egovernments/ashish-egov-patch-4
ashish-egov Jan 21, 2025
e4cbbc4
Update health-services/project-factory/src/server/utils/genericUtils.ts
ashish-egov Jan 21, 2025
aadd518
Merge remote-tracking branch 'origin/console' into HCMPRE-1788-projec…
ashish-egov Jan 22, 2025
fe71e0c
User Flow
ashish-egov Jan 29, 2025
1445208
Merge remote-tracking branch 'origin/console' into HCMPRE-1788-projec…
ashish-egov Jan 29, 2025
8b822e1
User Creation Flow Processing
ashish-egov Jan 31, 2025
3244244
Merge remote-tracking branch 'origin/console' into HCMPRE-1788-projec…
ashish-egov Jan 31, 2025
8c6bf87
User creation flow completed
ashish-egov Feb 3, 2025
10d37d3
Fixes
ashish-egov Feb 3, 2025
f817a2e
Fixes
ashish-egov Feb 3, 2025
1d664db
Fixes
ashish-egov Feb 3, 2025
4e74a54
Fix for string mobileNumber
ashish-egov Feb 3, 2025
bfce7db
Update campaignEmployeesUtils.ts
ashish-egov Feb 4, 2025
014d750
Merge pull request #1374 from egovernments/ashish-egov-patch-4
ashish-egov Feb 4, 2025
8ad62d5
Update excelUtils.ts
ashish-egov Feb 4, 2025
21824c7
Merge pull request #1377 from egovernments/ashish-egov-patch-4
ashish-egov Feb 4, 2025
67604b4
Update excelUtils.ts
ashish-egov Feb 4, 2025
02e50e2
Fixed for debugging
ashish-egov Feb 5, 2025
932d5e9
Merge branch 'HCMPRE-1788-project-creation-entity-persistence' of htt…
ashish-egov Feb 5, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
CREATE TABLE eg_cm_campaign_projects (
id CHARACTER VARYING(128) PRIMARY KEY,
projectid CHARACTER VARYING(128),
campaignnumber CHARACTER VARYING(128) NOT NULL,
boundarycode CHARACTER VARYING(128) NOT NULL,
boundarytype CHARACTER VARYING(128) NOT NULL,
parentBoundaryCode CHARACTER VARYING(128),
additionaldetails JSONB, -- Nullable JSONB column
isactive BOOLEAN NOT NULL,
createdby CHARACTER VARYING(128) NOT NULL,
lastmodifiedby CHARACTER VARYING(128) NOT NULL,
createdtime BIGINT NOT NULL,
lastmodifiedtime BIGINT NOT NULL,
CONSTRAINT unique_campaign_boundary_active UNIQUE (campaignnumber, boundarycode, isactive)
);

-- Adding index on campaignnumber
CREATE INDEX idx_campaignprojects_campaignnumber
ON eg_cm_campaign_projects (campaignnumber);

-- Adding index on combination of campaignnumber and boundarycode
CREATE INDEX idx_campaignprojects_campaignnumber_boundarycode
ON eg_cm_campaign_projects (campaignnumber, boundarycode);

-- Adding index on combination of campaignnumber and parentBoundaryCode
CREATE INDEX idx_campaignprojects_campaignnumber_parentboundarycode
ON eg_cm_campaign_projects (campaignnumber, parentBoundaryCode);
ashish-egov marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CREATE TABLE eg_cm_campaign_creation_process_status (
id CHARACTER VARYING(128) PRIMARY KEY,
campaignnumber VARCHAR(128) NOT NULL,
processname VARCHAR(128) NOT NULL,
status VARCHAR(64) NOT NULL,
additionaldetails JSONB,
createdby VARCHAR(128) NOT NULL,
lastmodifiedby VARCHAR(128) NOT NULL,
createdtime BIGINT NOT NULL,
lastmodifiedtime BIGINT NOT NULL,
CONSTRAINT unique_campaign_process UNIQUE (campaignnumber, processname)
);

-- Adding index on campaignnumber
CREATE INDEX idx_campaignprocessstatus_campaignnumber
ON eg_cm_campaign_creation_process_status (campaignnumber);

-- Adding index on combination of campaignnumber and processname
CREATE INDEX idx_campaignprocessstatus_campaignnumber_processname
ON eg_cm_campaign_creation_process_status (campaignnumber, processname);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- Create index if not exists on campaignnumber
CREATE INDEX IF NOT EXISTS idx_campaignnumber ON eg_cm_campaign_details (campaignnumber);
16 changes: 16 additions & 0 deletions health-services/project-factory/src/server/api/boundaryApis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import config from "../config";
import { logger } from "../utils/logger";
import { defaultheader, httpRequest } from "../utils/request";
import { defaultRequestInfo } from "./coreApis";

export async function getBoundaryRelationshipData(params: any) {
logger.info("Boundary relationship search initiated");
const url = `${config.host.boundaryHost}${config.paths.boundaryRelationship}`;
const header = {
...defaultheader,
cachekey: `boundaryRelationShipSearch${params?.hierarchyType}${params?.tenantId}${params.codes || ''}${params?.includeChildren || ''}`,
}
const boundaryRelationshipResponse = await httpRequest(url, defaultRequestInfo, params, undefined, undefined, header);
logger.info("Boundary relationship search response received");
return boundaryRelationshipResponse?.TenantBoundary?.[0]?.boundary;
}
24 changes: 15 additions & 9 deletions health-services/project-factory/src/server/api/campaignApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
checkIfSourceIsMicroplan,
createIdRequests,
createUniqueUserNameViaIdGen,
boundaryGeometryManagement,
boundaryGeometryManagement
} from "../utils/campaignUtils";
const _ = require("lodash");
import { produceModifiedMessages } from "../kafka/Producer";
Expand All @@ -50,7 +50,8 @@ import {
} from "../utils/microplanUtils";
import { getTransformedLocale } from "../utils/localisationUtils";
import { BoundaryModels } from "../models";
import { searchBoundaryRelationshipDefinition } from "./coreApis";
import { defaultRequestInfo, searchBoundaryRelationshipDefinition } from "./coreApis";
import { persistCampaignProject } from "../utils/projectCampaignUtils";

/**
* Enriches the campaign data with unique IDs and generates campaign numbers.
Expand Down Expand Up @@ -1747,23 +1748,26 @@ async function createProjectCampaignResourcData(request: any) {
);
}

async function confirmProjectParentCreation(request: any, projectId: any) {
async function confirmProjectParentCreation(projectId: any, tenantId: string) {
if(!projectId) {
return;
}
const searchBody = {
RequestInfo: request.body.RequestInfo,
RequestInfo: defaultRequestInfo?.RequestInfo,
Projects: [
{
id: projectId,
tenantId: request.body.CampaignDetails.tenantId,
tenantId
},
],
};
const params = {
tenantId: request.body.CampaignDetails.tenantId,
tenantId,
offset: 0,
limit: 5,
limit: 1,
};
var projectFound = false;
var retry = 6;
var retry = 20;
ashish-egov marked this conversation as resolved.
Show resolved Hide resolved
while (!projectFound && retry >= 0) {
const response = await httpRequest(
config.host.projectHost + config.paths.projectSearch,
Expand Down Expand Up @@ -1822,6 +1826,7 @@ async function projectCreate(projectCreateBody: any, request: any) {
request.body.boundaryProjectMapping[
projectCreateBody?.Projects?.[0]?.address?.boundary
].projectId = projectCreateResponse?.Project[0]?.id;
await persistCampaignProject(projectCreateResponse?.Project[0], request?.body?.CampaignDetails, request?.body?.RequestInfo);
} else {
throwError(
"PROJECT",
Expand All @@ -1833,7 +1838,7 @@ async function projectCreate(projectCreateBody: any, request: any) {
}
}

async function projectUpdateForTargets(projectUpdateBody: any, request: any, boundaryCode: any) {
async function projectUpdateForTargets(projectUpdateBody: any, request: any, boundaryCode: any, campaignProjectId : string) {
logger.info("Project Update For Targets started");

logger.debug("Project update request body: " + getFormattedStringForDebug(projectUpdateBody));
Expand All @@ -1848,6 +1853,7 @@ async function projectUpdateForTargets(projectUpdateBody: any, request: any, bou
);
logger.debug("Project update response: " + getFormattedStringForDebug(projectUpdateResponse));
logger.info(`Project update response for boundary code: ${boundaryCode} and project name: ${request?.body?.CampaignDetails?.campaignName}`);
await persistCampaignProject(projectUpdateResponse?.Project[0], request?.body?.CampaignDetails, request?.body?.RequestInfo, campaignProjectId);
} catch (error: any) {
logger.error("Project update failed", error);
throwError(
Expand Down
169 changes: 6 additions & 163 deletions health-services/project-factory/src/server/api/genericApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import config from "../config"; // Import configuration settings
import FormData from "form-data"; // Import FormData for handling multipart/form-data requests
import { defaultheader, httpRequest } from "../utils/request"; // Import httpRequest function for making HTTP requests
import { getFormattedStringForDebug, logger } from "../utils/logger"; // Import logger for logging
import { correctParentValues, findMapValue, getBoundaryRelationshipData, getDataSheetReady, getLocalizedHeaders, sortCampaignDetails, throwError } from "../utils/genericUtils"; // Import utility functions
import { correctParentValues, findMapValue,getDataSheetReady, getLocalizedHeaders, sortCampaignDetails, throwError } from "../utils/genericUtils"; // Import utility functions
ashish-egov marked this conversation as resolved.
Show resolved Hide resolved
import { extractCodesFromBoundaryRelationshipResponse, generateFilteredBoundaryData, getConfigurableColumnHeadersBasedOnCampaignType, getFiltersFromCampaignSearchResponse, getLocalizedName, processDataForTargetCalculation } from '../utils/campaignUtils'; // Import utility functions
import { getCampaignSearchResponse, getHierarchy } from './campaignApis';
const _ = require('lodash'); // Import lodash library
import { enrichTemplateMetaData, getExcelWorkbookFromFileURL } from "../utils/excelUtils";
import { processMapping } from "../utils/campaignMappingUtils";
import { getBoundaryRelationshipData } from "./boundaryApis";

//Function to get Workbook with different tabs (for type target)
const getTargetWorkbook = async (fileUrl: string, localizationMap?: any) => {
Expand Down Expand Up @@ -189,10 +190,8 @@ const getTargetSheetData = async (
};

const getTargetSheetDataAfterCode = async (
request: any,
campaignDetails: any,
fileUrl: string,
getRow = false,
getSheetName = false,
codeColumnName = "Boundary Code",
localizationMap?: any
) => {
Expand Down Expand Up @@ -221,10 +220,10 @@ const getTargetSheetDataAfterCode = async (
}

if (boundaryCodeColumnIndex === -1) {
console.warn(`Column "${codeColumnName}" not found in sheet "${sheetName}".`);
logger.warn(`Column "${codeColumnName}" not found in sheet "${sheetName}".`);
continue;
}
const processedData = await processDataForTargetCalculation(request, jsonData, codeColumnName, localizationMap);
const processedData = await processDataForTargetCalculation(campaignDetails, jsonData, codeColumnName, localizationMap);

workbookData[sheetName] = processedData;
}
Expand Down Expand Up @@ -314,117 +313,6 @@ const getCampaignNumber: any = async (
throwError("COMMON", 500, "IDGEN_ERROR");
};

// Function to generate a resource number
const getResouceNumber: any = async (
RequestInfo: any,
idFormat: String,
idName: string
) => {
// Construct request data
const data = {
RequestInfo,
idRequests: [
{
idName: idName,
tenantId: RequestInfo?.userInfo?.tenantId,
format: idFormat,
},
],
};

// Construct URL for ID generation service
const idGenUrl = config.host.idGenHost + config.paths.idGen;

try {
// Make HTTP request to ID generation service
const result = await httpRequest(
idGenUrl,
data,
undefined,
undefined,
undefined,
undefined
);

// Return generated resource number
if (result?.idResponses?.[0]?.id) {
return result?.idResponses?.[0]?.id;
}

// Return null if ID generation fails
return result;
} catch (error: any) {
// Log error if ID generation fails
logger.error("Error: " + error);

// Return error
return error;
}
};

// Function to get schema definition based on code and request info
const getSchema: any = async (code: string, RequestInfo: any) => {
const data = {
RequestInfo,
SchemaDefCriteria: {
tenantId: RequestInfo?.userInfo?.tenantId,
limit: 200,
codes: [code],
},
};
const mdmsSearchUrl = config.host.mdmsV2 + config.paths.mdmsSchema;

try {
const result = await httpRequest(
mdmsSearchUrl,
data,
undefined,
undefined,
undefined,
undefined
);
return result?.SchemaDefinitions?.[0]?.definition;
} catch (error: any) {
logger.error("Error: " + error);
return error;
}
};

// Function to get count from response data
const getCount: any = async (
responseData: any,
request: any,
response: any
) => {
try {
// Extract host and URL from response data
const host = responseData?.host;
const url = responseData?.searchConfig?.countUrl;

// Extract request information
const requestInfo = { RequestInfo: request?.body?.RequestInfo };

// Make HTTP request to get count
const result = await httpRequest(
host + url,
requestInfo,
undefined,
undefined,
undefined,
undefined
);

// Extract count from result using lodash
const count = _.get(result, responseData?.searchConfig?.countPath);

return count; // Return the count
} catch (error: any) {
// Log and throw error if any
logger.error("Error: " + error);
throw error;
}
};

// Function to create Excel sheet and upload it
async function createAndUploadFile(
updatedWorkbook: any,
Expand Down Expand Up @@ -540,47 +428,6 @@ function generateHierarchyList(data: any[], parentChain: any = []) {
return result; // Return the hierarchy list
}

// Function to generate hierarchy from boundaries
function generateHierarchy(boundaries: any[]) {
// Create an object to store boundary types and their parents
const parentMap: any = {};

// Populate the object with boundary types and their parents
for (const boundary of boundaries) {
parentMap[boundary.boundaryType] = boundary.parentBoundaryType;
}

// Traverse the hierarchy to generate the hierarchy list
const hierarchyList = [];
for (const boundaryType in parentMap) {
if (Object.prototype.hasOwnProperty.call(parentMap, boundaryType)) {
const parentBoundaryType = parentMap[boundaryType];
if (parentBoundaryType === null) {
// This boundary type has no parent, add it to the hierarchy list
hierarchyList.push(boundaryType);
// Traverse its children recursively
traverseChildren(boundaryType, parentMap, hierarchyList);
}
}
}
return hierarchyList; // Return the hierarchy list
}

// Recursive function to traverse children and generate hierarchy
function traverseChildren(parent: any, parentMap: any, hierarchyList: any[]) {
for (const boundaryType in parentMap) {
if (Object.prototype.hasOwnProperty.call(parentMap, boundaryType)) {
const parentBoundaryType = parentMap[boundaryType];
if (parentBoundaryType === parent) {
// This boundary type has the current parent, add it to the hierarchy list
hierarchyList.push(boundaryType);
// Traverse its children recursively
traverseChildren(boundaryType, parentMap, hierarchyList);
}
}
}
}

// Function to create an Excel sheet
async function createExcelSheet(data: any, headers: any) {
var rows = [headers, ...data];
Expand Down Expand Up @@ -740,7 +587,7 @@ async function getBoundarySheetData(
logger.info(
`processing boundary data generation for hierarchyType : ${hierarchyType}`
);
const boundaryData = await getBoundaryRelationshipData(request, params);
const boundaryData = await getBoundaryRelationshipData(params);
if (!boundaryData || boundaryData.length === 0) {
logger.info(`boundary data not found for hierarchyType : ${hierarchyType}`);
const hierarchy = await getHierarchy(
Expand Down Expand Up @@ -1431,14 +1278,10 @@ export {
getSheetData,
searchMDMS,
getCampaignNumber,
getSchema,
getResouceNumber,
getCount,
getBoundarySheetData,
createAndUploadFile,
createRelatedResouce,
createExcelSheet,
generateHierarchy,
generateHierarchyList,
getTargetWorkbook,
getTargetSheetData,
Expand Down
Loading
Loading