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

HCMPRE-1578: Adding facility information for each village in estimation sheet #1284

Open
wants to merge 9 commits into
base: download-estimation-feature
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public class ServiceConstants {
public static final String FILE_NOT_FOUND_CODE = "FILE_NOT_FOUND";
public static final String FILE_NOT_FOUND_MESSAGE = "No file with the specified templateIdentifier found - ";

public static final String PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_CODE = "PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT";
public static final String PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_MESSAGE = "Key is not present in json object - ";

public static final String UNABLE_TO_CREATE_ADDITIONAL_DETAILS_CODE = "UNABLE_TO_CREATE_ADDITIONAL_DETAILS";
public static final String UNABLE_TO_CREATE_ADDITIONAL_DETAILS_MESSAGE = "Unable to create additional details for facility creation.";

Expand Down Expand Up @@ -116,6 +119,8 @@ public class ServiceConstants {
public static final String SOURCE_KEY = "source";
public static final String MICROPLAN_SOURCE_KEY = "microplan";
public static final String MICROPLAN_ID_KEY = "microplanId";
public static final String FACILITY_NAME = "facilityName";
public static final String HCM_MICROPLAN_SERVING_FACILITY = "HCM_MICROPLAN_SERVING_FACILITY";

//Census additional field constants
public static final String UPLOADED_KEY = "UPLOADED_";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ private void processExcelFile(PlanConfigurationRequest planConfigurationRequest,
processSheets(planConfigurationRequest, fileStoreId, campaignResponse, workbook,
campaignBoundaryList, dataFormatter);
uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse,
workbook, campaignBoundaryList, campaignResourcesList);
workbook, campaignBoundaryList, campaignResourcesList, fileStoreId);
} catch (FileNotFoundException e) {
log.error("File not found: {}", e.getMessage());
throw new CustomException("FileNotFound", "The specified file was not found.");
Expand All @@ -152,7 +152,7 @@ private void processExcelFile(PlanConfigurationRequest planConfigurationRequest,
*/
private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigurationRequest,
Object campaignResponse, Workbook workbook,
List<Boundary> campaignBoundaryList, List<CampaignResources> campaignResourcesList) {
List<Boundary> campaignBoundaryList, List<CampaignResources> campaignResourcesList, String filestoreId) {
File fileToUpload = null;
try {
PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration();
Expand All @@ -169,6 +169,8 @@ private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigu

outputEstimationGenerationUtil.processOutputFile(workbook, planConfigurationRequest);

// Adding facility information for each boundary code
outputEstimationGenerationUtil.addAssignedFacility(workbook, planConfigurationRequest, filestoreId);

//update processed output file into plan configuration file object
fileToUpload = convertWorkbookToXls(workbook);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR
Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0,
parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues);

//Getting census records for the list of boundaryCodes
//Getting plan records for the list of boundaryCodes
List<Plan> planList = getPlanRecordsForEnrichment(planConfigurationRequest, boundaryCodes);

// Create a map from boundaryCode to Census for quick lookups
// Create a map from boundaryCode to Plan for quick lookups
Map<String, Plan> planMap = planList.stream()
.collect(Collectors.toMap(Plan::getLocality, plan -> plan));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,32 @@
import org.egov.processor.web.models.Locale;
import org.egov.processor.web.models.LocaleResponse;
import org.egov.processor.web.models.PlanConfigurationRequest;
import org.egov.tracer.model.CustomException;
import org.egov.processor.web.models.ResourceMapping;
import org.egov.processor.web.models.census.Census;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.egov.tracer.model.CustomException;

import static org.egov.processor.config.ServiceConstants.FACILITY_NAME;
import static org.egov.processor.config.ServiceConstants.HCM_MICROPLAN_SERVING_FACILITY;

@Component
public class OutputEstimationGenerationUtil {

private LocaleUtil localeUtil;

private ParsingUtil parsingUtil;

public OutputEstimationGenerationUtil(LocaleUtil localeUtil, ParsingUtil parsingUtil) {
private EnrichmentUtil enrichmentUtil;

public OutputEstimationGenerationUtil(LocaleUtil localeUtil, ParsingUtil parsingUtil, EnrichmentUtil enrichmentUtil) {
this.localeUtil = localeUtil;
this.parsingUtil = parsingUtil;
this.enrichmentUtil = enrichmentUtil;
}

public void processOutputFile(Workbook workbook, PlanConfigurationRequest request) {
Expand Down Expand Up @@ -63,4 +75,77 @@ public void processSheetForHeaderLocalization(Sheet sheet, Map<String, String> l
}

}

/**
* For each boundary code in the sheet being processed, adds the name of the facility mapped to that boundary code.
*
* @param workbook the workbook.
* @param request the plan configuration request.
* @param fileStoreId the associated file store ID.
*/
public void addAssignedFacility(Workbook workbook, PlanConfigurationRequest request, String fileStoreId) {
LocaleResponse localeResponse = localeUtil.searchLocale(request);

String assignedFacilityColHeader = localeUtil.localeSearch(localeResponse.getMessages(), HCM_MICROPLAN_SERVING_FACILITY);

assignedFacilityColHeader = assignedFacilityColHeader != null ? assignedFacilityColHeader : HCM_MICROPLAN_SERVING_FACILITY;

for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
Sheet sheet = workbook.getSheetAt(i);
if (parsingUtil.isSheetAllowedToProcess(request, sheet.getSheetName(), localeResponse)) {

// Get column index of assigned facility name in the sheet being processed
Integer indexOfFacility = sheet.getRow(0).getLastCellNum() + 1;

// Create a new column for assigned facility name
Cell cell = sheet.getRow(0).createCell(indexOfFacility, CellType.STRING);
cell.setCellValue(assignedFacilityColHeader);

// Creating a map of MappedTo and MappedFrom values from resource mapping
Map<String, String> mappedValues = request.getPlanConfiguration().getResourceMapping().stream()
.filter(f -> f.getFilestoreId().equals(fileStoreId))
.collect(Collectors.toMap(
ResourceMapping::getMappedTo,
ResourceMapping::getMappedFrom,
(existing, replacement) -> existing,
LinkedHashMap::new
));

// Get column index of boundary code in the sheet being processed
Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, sheet, mappedValues);

// Get a list of boundary codes
List<String> boundaryCodes = enrichmentUtil.getBoundaryCodesFromTheSheet(sheet, request, fileStoreId);

//Getting census records for the list of boundaryCodes
List<Census> censusList = enrichmentUtil.getCensusRecordsForEnrichment(request, boundaryCodes);

// Create a map of boundary code to facility assigned for the boundary
Map<String, String> boundaryCodeToFacility = censusList.stream()
.collect(Collectors.toMap(Census::getBoundaryCode, census -> (String) parsingUtil.extractFieldsFromJsonObject(census.getAdditionalDetails(), FACILITY_NAME)));

// for each boundary code in the sheet add the name of the facility assigned to it.
for (Row row : sheet) {

// Skip the header row and empty rows
if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) {
continue;
}

// Get the boundaryCode in the current row
Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode);
String boundaryCode = boundaryCodeCell.getStringCellValue();

String facility = boundaryCodeToFacility.get(boundaryCode);

Cell facilityCell = row.getCell(indexOfFacility);
if (facilityCell == null) {
facilityCell = row.createCell(indexOfFacility, CellType.STRING);
}
facilityCell.setCellValue(facility);
}
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;
Expand All @@ -38,11 +39,14 @@ public class ParsingUtil {

private MdmsUtil mdmsUtil;

public ParsingUtil(PlanConfigurationUtil planConfigurationUtil, FilestoreUtil filestoreUtil, CalculationUtil calculationUtil, MdmsUtil mdmsUtil) {
private ObjectMapper objectMapper;

public ParsingUtil(PlanConfigurationUtil planConfigurationUtil, FilestoreUtil filestoreUtil, CalculationUtil calculationUtil, MdmsUtil mdmsUtil, ObjectMapper objectMapper) {
this.planConfigurationUtil = planConfigurationUtil;
this.filestoreUtil = filestoreUtil;
this.calculationUtil = calculationUtil;
this.mdmsUtil = mdmsUtil;
this.objectMapper = objectMapper;
}

public List<String> fetchAttributeNamesFromJson(JsonNode jsonNode)
Expand Down Expand Up @@ -346,6 +350,23 @@ public Integer getIndexOfBoundaryCode(Integer indexValue, List<Map.Entry<String,
return indexValue;
}

public Integer getIndexOfBoundaryCode(Integer indexValue, Sheet sheet, Map<String, String> mappedValues) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reuse already existing function


DataFormatter dataFormatter = new DataFormatter();

// Assuming the first row contains column headers
Row headerRow = sheet.getRow(0);
for (int i = 0; i < headerRow.getLastCellNum(); i++) {
Cell cell = headerRow.getCell(i);
String columnHeader = dataFormatter.formatCellValue(cell);
if (columnHeader.equals(mappedValues.get(ServiceConstants.BOUNDARY_CODE))) {
indexValue = i;
break;
}
}
return indexValue;
}

/**
* Sorts the column names and indices based on the provided map of column names and indices.
*
Expand Down Expand Up @@ -418,4 +439,37 @@ public boolean isSheetAllowedToProcess(PlanConfigurationRequest planConfiguratio

}

/**
* Extracts provided field from the additional details object
*
* @param additionalDetails the additionalDetails object from PlanConfigurationRequest
* @param fieldToExtract the name of the field to be extracted from the additional details
* @return the value of the specified field as a string
* @throws CustomException if the field does not exist
*/
public Object extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract) {
try {
String jsonString = objectMapper.writeValueAsString(additionalDetails);
JsonNode rootNode = objectMapper.readTree(jsonString);

JsonNode node = rootNode.get(fieldToExtract);
if (node != null && !node.isNull()) {

// Check for different types of JSON nodes
if (node.isDouble() || node.isFloat()) {
return BigDecimal.valueOf(node.asDouble()); // Convert Double to BigDecimal
} else if (node.isLong() || node.isInt()) {
return BigDecimal.valueOf(node.asLong()); // Convert Long to BigDecimal
} else if (node.isBoolean()) {
return node.asBoolean();
} else if (node.isTextual()) {
return node.asText();
}
}
return null;
} catch (Exception e) {
log.error(e.getMessage() + fieldToExtract);
throw new CustomException(PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_CODE, PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_MESSAGE + fieldToExtract);
}
}
}