Skip to content

Commit

Permalink
Target enrichment
Browse files Browse the repository at this point in the history
  • Loading branch information
ashish-egov committed Dec 26, 2024
1 parent 24630cb commit 879e645
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 89 deletions.
75 changes: 49 additions & 26 deletions health-services/project-factory/src/server/api/genericApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getCampaignSearchResponse, getHierarchy } from './campaignApis';
const _ = require('lodash'); // Import lodash library
import { getExcelWorkbookFromFileURL } from "../utils/excelUtils";
import { processMapping } from "../utils/campaignMappingUtils";
import { targetConfigs } from "../config/targetConfigs";


//Function to get Workbook with different tabs (for type target)
Expand Down Expand Up @@ -209,6 +210,7 @@ const getTargetSheetDataAfterCode = async (
for (const sheetName of localizedSheetNames) {
const worksheet = workbook.getWorksheet(sheetName);
const sheetData = getSheetDataFromWorksheet(worksheet);
const jsonData = getJsonData(sheetData,true,true, sheetName);

// Find the target column index where the first row value matches codeColumnName
const firstRow = sheetData[0];
Expand All @@ -225,43 +227,64 @@ const getTargetSheetDataAfterCode = async (
continue;
}

// Process data from sheet
const processedData = sheetData.map((row: any, rowIndex: any) => {
if (rowIndex <= 0) return null; // Skip header row
// Process each row of the sheet data
const processedData = jsonData.map((row: any, rowIndex: any) => {
// Skip the header row (rowIndex 0)
if (rowIndex <= 0) return null;

let rowData: any = { [codeColumnName]: row[boundaryCodeColumnIndex] };
// Initialize an object to hold row-specific data
let rowData: any = { [codeColumnName]: row[codeColumnName] };

// Add integer values in the target column for the current row
let sumOfCurrentTargets = 0;
let sumOfParentTargets = 0;
const remainingColumns = row.length - boundaryCodeColumnIndex - 1;
const halfPoint = Math.floor(remainingColumns / 2);
let startColIndex = boundaryCodeColumnIndex + 1;
// Add placeholder fields for Parent Target and Current Target data
rowData['Parent Target at the Selected Boundary level'] = {};
rowData['Target at the Selected Boundary level'] = {};
const beneficiaries = targetConfigs?.[request?.body?.CampaignDetails?.projectType]?.beneficiaries;

// Check if a parent campaign exists in the request body
if (request?.body?.parentCampaign) {
for (let colIndex = startColIndex; colIndex < startColIndex + halfPoint; colIndex++) {
const value = row[colIndex];
if (typeof value === 'number' && Number.isInteger(value)) {
sumOfParentTargets += value;
// Loop through the beneficiaries for the specified campaign type
if (beneficiaries?.length > 0) {
for (const beneficiary of beneficiaries) {
const beneficiaryType = beneficiary?.beneficiaryType;
const columns = beneficiary?.columns;
let totalParentValue = 0;

// Loop through each column to calculate the total parent value
for (const col of columns) {
// Get the parent value from the column and add it if it's an integer
const parentValue = row[`${getLocalizedName(col, localizationMap)}(OLD)`];
if (typeof parentValue === 'number' && Number.isInteger(parentValue)) {
totalParentValue += parentValue;
}
}
// Assign the total parent value to the corresponding beneficiary type
rowData['Parent Target at the Selected Boundary level'][beneficiaryType] = totalParentValue;
}
}
// Add the sum to the row data
rowData['Parent Target at the Selected Boundary level'] = sumOfParentTargets;

// Calculate middle point of remaining columns
startColIndex = boundaryCodeColumnIndex + 1 + halfPoint;
}
for (let colIndex = startColIndex; colIndex < row.length; colIndex++) {
const value = row[colIndex];
if (typeof value === 'number' && Number.isInteger(value)) {
sumOfCurrentTargets += value;

// Loop through the beneficiaries again to calculate the current target values
if (beneficiaries?.length > 0) {
for (const beneficiary of beneficiaries) {
const beneficiaryType = beneficiary?.beneficiaryType;
const columns = beneficiary?.columns;
let totalCurrentValue = 0;

// Loop through each column to calculate the total current value
for (const col of columns) {
const currentValue = row[getLocalizedName(col, localizationMap)];
if (typeof currentValue === 'number' && Number.isInteger(currentValue)) {
totalCurrentValue += currentValue;
}
}
// Assign the total current value to the corresponding beneficiary type
rowData['Target at the Selected Boundary level'][beneficiaryType] = totalCurrentValue;
}
}

// Add the sum to the row data
rowData['Target at the Selected Boundary level'] = sumOfCurrentTargets;
// Return the processed row data
return rowData;
}).filter(Boolean); // Remove null entries
}).filter(Boolean); // Remove any null entries from the map (i.e., skip the header row)

workbookData[sheetName] = processedData;
}
Expand Down
50 changes: 50 additions & 0 deletions health-services/project-factory/src/server/config/targetConfigs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export const targetConfigs: any = {
"LLIN-mz": {
"beneficiaries": [
{
"beneficiaryType": "INDIVIDUAL",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_BEDNET_COLUMN_2"]
},
{
"beneficiaryType": "HOUSEHOLD",
"columns": ["HCM_ADMIN_CONSOLE_TARGET"]
},
{
"beneficiaryType": "PRODUCT",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_BEDNET_COLUMN_3"]
}
]
},
"MR-DN": {
"beneficiaries": [
{
"beneficiaryType": "INDIVIDUAL",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_SMC_AGE_3_TO_11", "HCM_ADMIN_CONSOLE_TARGET_SMC_AGE_12_TO_59"]
},
{
"beneficiaryType": "HOUSEHOLD",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_SMC_COLUUM_3"]
},
{
"beneficiaryType": "PRODUCT",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_SMC_COLUUM_4"]
}
]
},
"IRS-mz": {
"beneficiaries": [
{
"beneficiaryType": "INDIVIDUAL",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_IRS_4"]
},
{
"beneficiaryType": "HOUSEHOLD",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_IRS_1"]
},
{
"beneficiaryType": "PRODUCT",
"columns": ["HCM_ADMIN_CONSOLE_TARGET_IRS_3"]
}
]
}
}
116 changes: 53 additions & 63 deletions health-services/project-factory/src/server/utils/campaignUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1695,21 +1695,37 @@ function mapBoundariesParent(boundaryResponse: any, request: any, parent: any) {
function mapTargets(boundaryResponses: any, codesTargetMapping: any) {
if (!boundaryResponses || !codesTargetMapping) return;

for (const boundaryResponse of boundaryResponses) {
const mapBoundary = (boundary: any) => {
if (!boundary.children || boundary.children.length === 0) {
const targetValue = codesTargetMapping[boundary.code];
return targetValue ? targetValue : 0;
// Helper function to map individual boundaries
const mapBoundary = (boundary: any) => {
if (!boundary.children || boundary.children.length === 0) {
// If no children, simply return the target value object or default to empty object
const targetValue = codesTargetMapping[boundary.code];
return targetValue || {};
}

// Initialize a new object to accumulate total target values from children
let totalTargetValue: any = {};

// Iterate through each child and accumulate their target values
for (const child of boundary.children) {
const childTargetValue = mapBoundary(child);

// Accumulate the child target values into the total target value
for (const key in childTargetValue) {
if (childTargetValue.hasOwnProperty(key)) {
// Initialize key in totalTargetValue if it doesn't exist
totalTargetValue[key] = (totalTargetValue[key] || 0) + childTargetValue[key];
}
}
}

let totalTargetValue = 0;
for (const child of boundary.children) {
const childTargetValue = mapBoundary(child);
totalTargetValue += childTargetValue;
}
codesTargetMapping[boundary.code] = totalTargetValue;
return totalTargetValue;
};
// Store the accumulated total target value for the current boundary
codesTargetMapping[boundary.code] = totalTargetValue;
return totalTargetValue;
};

// Map each boundary response
for (const boundaryResponse of boundaryResponses) {
mapBoundary(boundaryResponse);
}
}
Expand Down Expand Up @@ -2169,13 +2185,14 @@ async function getCodesTarget(request: any, localizationMap?: any) {
fileResponse?.fileStoreIds?.[0]?.url,
true,
true,
codeColumnName
codeColumnName,
localizationMap
);
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
targetData[key].forEach((entry) => {
targetData[key].forEach((entry : any) => {
// Check if the entry has both "Boundary Code" and "Target at the Selected Boundary level"
if (
entry[codeColumnName] !== undefined &&
Expand All @@ -2185,7 +2202,7 @@ async function getCodesTarget(request: any, localizationMap?: any) {
boundaryTargetMapping[entry[codeColumnName]] =
entry["Target at the Selected Boundary level"];
if (
entry["Parent Target at the Selected Boundary level"] !== 0 &&
Object.keys(entry["Parent Target at the Selected Boundary level"]).length > 0 &&
entry["Parent Target at the Selected Boundary level"] !==
entry["Target at the Selected Boundary level"]
) {
Expand Down Expand Up @@ -2236,6 +2253,7 @@ async function createProject(
Projects,
};
boundaries = await reorderBoundaries(request, localizationMap);
const codesTargetMapping = request?.body?.CampaignDetails?.codesTargetMapping;
let boundariesAlreadyWithProjects: any;
if (request?.body?.parentCampaign) {
// make search to project with parent campaign root project id
Expand Down Expand Up @@ -2267,38 +2285,7 @@ async function createProject(
);
const projectToUpdate = projectSearchResponse?.Project?.[0];
if (projectToUpdate) {
const filteredTargets = projectToUpdate.targets.filter(
(e: any) =>
e.beneficiaryType ==
request?.body?.CampaignDetails?.additionalDetails
?.beneficiaryType
);
if (filteredTargets.length == 0) {
projectToUpdate.targets = [
{
beneficiaryType:
request?.body?.CampaignDetails?.additionalDetails
?.beneficiaryType,
totalNo:
request?.body?.CampaignDetails?.codesTargetMapping[
boundary
],
targetNo:
request?.body?.CampaignDetails?.codesTargetMapping[
boundary
],
},
];
} else {
const targetobj = filteredTargets[0];
(targetobj.totalNo =
request?.body?.CampaignDetails?.codesTargetMapping[boundary]),
(targetobj.targetNo =
request?.body?.CampaignDetails?.codesTargetMapping[
boundary
]);
projectToUpdate.targets = [targetobj];
}
enrichTargetForProject(projectToUpdate, codesTargetMapping, boundary);
const projectUpdateBody = {
RequestInfo: request?.body?.RequestInfo,
Projects: [projectToUpdate],
Expand Down Expand Up @@ -2344,21 +2331,7 @@ async function createProject(

// Set the reference ID and project targets
Projects[0].referenceID = request?.body?.CampaignDetails?.campaignNumber;
(Projects[0].targets = [
{
beneficiaryType:
request?.body?.CampaignDetails?.additionalDetails
?.beneficiaryType,
totalNo:
request?.body?.CampaignDetails?.codesTargetMapping[
boundaryCode
],
targetNo:
request?.body?.CampaignDetails?.codesTargetMapping[
boundaryCode
],
},
]);
enrichTargetForProject(Projects[0], codesTargetMapping, boundaryCode);
await projectCreate(projectCreateBody, request);
}
}
Expand All @@ -2385,6 +2358,23 @@ async function createProject(
);
}

const enrichTargetForProject = (project: any, codesTargetMapping: any, boundaryCode: any) => {
if ( codesTargetMapping && Object.keys(codesTargetMapping?.[boundaryCode]).length > 0) {
let targets = [];
for (const key in codesTargetMapping?.[boundaryCode]) {
let targetNo = parseInt(codesTargetMapping?.[boundaryCode][key]);
let beneficiaryType = key;
targets.push({
beneficiaryType: beneficiaryType,
targetNo: targetNo,
});
}
if(targets.length > 0){
project.targets = targets;
}
}
}

async function processAfterPersist(request: any, actionInUrl: any) {
try {
const localizationMap = await getLocalizedMessagesHandler(
Expand Down

0 comments on commit 879e645

Please sign in to comment.