From dba50acfee0c69b7c12755d315c3c0bb579fdf3b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 3 Jan 2025 14:24:09 +0530 Subject: [PATCH 1/7] Removed readme sheet, localised estimation sheet and added facility name --- .../processor/config/ServiceConstants.java | 11 + .../egov/processor/service/ExcelParser.java | 58 ++---- .../egov/processor/util/EnrichmentUtil.java | 11 +- .../egov/processor/util/ExcelStylingUtil.java | 78 +++++++ .../util/OutputEstimationGenerationUtil.java | 196 ++++++++++++++++++ .../org/egov/processor/util/ParsingUtil.java | 73 ++++++- 6 files changed, 385 insertions(+), 42 deletions(-) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java b/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java index 7200f29cec..41e9144856 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java @@ -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."; @@ -116,8 +119,16 @@ 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_"; public static final String CONFIRMED_KEY = "CONFIRMED_"; + + //Excel header row styling constants + public static final String HEX_BACKGROUND_COLOR = "93C47D"; // Constant background color + public static final boolean FREEZE_CELL = true; // Constant to lock cell + public static final int COLUMN_WIDTH = 40; // Column width in characters + } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java index 6f2326d628..2faa00b43f 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java @@ -13,7 +13,6 @@ import org.egov.processor.config.ServiceConstants; import org.egov.processor.util.*; import org.egov.processor.web.models.*; -import org.egov.processor.web.models.Locale; import org.egov.processor.web.models.boundary.BoundarySearchResponse; import org.egov.processor.web.models.boundary.EnrichedBoundary; import org.egov.processor.web.models.campaignManager.Boundary; @@ -31,9 +30,6 @@ import java.util.*; import java.util.stream.Collectors; -import static org.egov.processor.config.ServiceConstants.HCM_ADMIN_CONSOLE_BOUNDARY_DATA; -import static org.egov.processor.config.ServiceConstants.READ_ME_SHEET_NAME; - @Slf4j @Service public class ExcelParser implements FileParser { @@ -64,9 +60,11 @@ public class ExcelParser implements FileParser { private PlanConfigurationUtil planConfigurationUtil; + private OutputEstimationGenerationUtil outputEstimationGenerationUtil; + public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, FilestoreUtil filestoreUtil, CalculationUtil calculationUtil, PlanUtil planUtil, CampaignIntegrationUtil campaignIntegrationUtil, - Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil, EnrichmentUtil enrichmentUtil, PlanConfigurationUtil planConfigurationUtil) { + Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil, EnrichmentUtil enrichmentUtil, PlanConfigurationUtil planConfigurationUtil, OutputEstimationGenerationUtil outputEstimationGenerationUtil) { this.objectMapper = objectMapper; this.parsingUtil = parsingUtil; this.filestoreUtil = filestoreUtil; @@ -80,6 +78,7 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore this.censusUtil = censusUtil; this.enrichmentUtil = enrichmentUtil; this.planConfigurationUtil = planConfigurationUtil; + this.outputEstimationGenerationUtil = outputEstimationGenerationUtil; } /** @@ -128,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."); @@ -153,7 +152,7 @@ private void processExcelFile(PlanConfigurationRequest planConfigurationRequest, */ private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigurationRequest, Object campaignResponse, Workbook workbook, - List campaignBoundaryList, List campaignResourcesList) { + List campaignBoundaryList, List campaignResourcesList, String filestoreId) { File fileToUpload = null; try { PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); @@ -164,9 +163,21 @@ private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigu planUtil.update(planConfigurationRequest); } if (planConfig.getStatus().equals(config.getPlanConfigUpdatePlanEstimatesIntoOutputFileStatus()) && config.isIntegrateWithAdminConsole()) { + //Upload the processed output file into project factory String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); - } + + 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); + uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); + planUtil.setFileStoreIdForPopulationTemplate(planConfigurationRequest, uploadedFileStoreId); + planUtil.update(planConfigurationRequest); + } } finally { try { if (fileToUpload != null && !fileToUpload.delete()) { @@ -189,7 +200,7 @@ private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigu * @param campaignBoundaryList List of boundary objects related to the campaign. * @param dataFormatter The data formatter for formatting cell values. */ - + //TODO: processsheetforestimate and processsheetforcensus private void processSheets(PlanConfigurationRequest request, String fileStoreId, Object campaignResponse, Workbook excelWorkbook, List campaignBoundaryList, @@ -213,7 +224,7 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, LinkedHashMap::new )); excelWorkbook.forEach(excelWorkbookSheet -> { - if (isSheetAllowedToProcess(request, excelWorkbookSheet.getSheetName(), localeResponse)) { + if (parsingUtil.isSheetAllowedToProcess(request, excelWorkbookSheet.getSheetName(), localeResponse)) { if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { enrichmentUtil.enrichsheetWithApprovedCensusRecords(excelWorkbookSheet, request, fileStoreId, mappedValues); processRows(request, excelWorkbookSheet, dataFormatter, fileStoreId, @@ -312,7 +323,6 @@ private List getBoundaryCodeList(PlanConfigurationRequest planConfigurat * @return A map of attribute names to their corresponding indices or data types. */ - //TODO: fetch from adminSchema master private Map prepareAttributeVsIndexMap(PlanConfigurationRequest planConfigurationRequest, String fileStoreId, CampaignResponse campaign, PlanConfiguration planConfig, Object mdmsData) { @@ -370,7 +380,8 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat campaignIntegrationUtil.updateCampaignBoundary(planConfig, feature, assumptionValueMap, mappedValues, mapOfColumnNameAndIndex, campaignBoundaryList, resultMap); planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); - + // TODO: remove after testing + parsingUtil.printRow(sheet, row); } } @@ -718,28 +729,5 @@ public List getAllBoundaryPresentforHierarchyType(List return boundaryList; } - /** - * Checks if a sheet is allowed to be processed based on MDMS constants and locale-specific configuration. - * - * @param planConfigurationRequest The request containing configuration details including request info and tenant ID. - * @param sheetName The name of the sheet to be processed. - * @return true if the sheet is allowed to be processed, false otherwise. - * @throws JsonMappingException If there's an issue mapping JSON response to Java objects. - * @throws JsonProcessingException If there's an issue processing JSON during conversion. - */ - private boolean isSheetAllowedToProcess(PlanConfigurationRequest planConfigurationRequest, String sheetName, LocaleResponse localeResponse) { - Map mdmsDataConstants = mdmsUtil.fetchMdmsDataForCommonConstants( - planConfigurationRequest.getRequestInfo(), - planConfigurationRequest.getPlanConfiguration().getTenantId()); - - for (Locale locale : localeResponse.getMessages()) { - if ((locale.getCode().equalsIgnoreCase((String) mdmsDataConstants.get(READ_ME_SHEET_NAME))) - || locale.getCode().equalsIgnoreCase(HCM_ADMIN_CONSOLE_BOUNDARY_DATA)) { - if (sheetName.equals(locale.getMessage())) - return false; - } - } - return true; - } } \ No newline at end of file diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java index 89f0a89511..e543dd062a 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java @@ -144,6 +144,9 @@ public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationR } } } + //TODO: remove after testing + log.info("After updating values in sheet -> "); + parsingUtil.printRow(sheet, row); log.info("Successfully update file with approved census data."); } @@ -220,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 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 planMap = planList.stream() .collect(Collectors.toMap(Plan::getLocality, plan -> plan)); @@ -233,6 +236,7 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR for(Row row: sheet) { + parsingUtil.printRow(sheet, row); // Skip the header row and empty rows if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { continue; @@ -265,6 +269,9 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR } } } + //TODO: remove after testing + log.info("After updating values in sheet -> "); + parsingUtil.printRow(sheet, row); log.info("Successfully update file with approved census data."); } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java new file mode 100644 index 0000000000..c8da424ea1 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java @@ -0,0 +1,78 @@ +package org.egov.processor.util; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.*; +import org.springframework.stereotype.Component; + +import java.awt.Color; + +import static org.egov.processor.config.ServiceConstants.*; + +@Component +public class ExcelStylingUtil { + + public void styleCell(Cell cell) { + Sheet sheet = cell.getSheet(); + Workbook workbook = sheet.getWorkbook(); + XSSFWorkbook xssfWorkbook = (XSSFWorkbook) workbook; + + // Create a cell style + XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle(); + + // Set background color + XSSFColor backgroundColor = hexToXSSFColor(HEX_BACKGROUND_COLOR, xssfWorkbook); + cellStyle.setFillForegroundColor(backgroundColor); + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + // Set font style (bold) + XSSFFont font = (XSSFFont) workbook.createFont(); + font.setBold(true); + cellStyle.setFont(font); + + // Set alignment and wrap text + cellStyle.setAlignment(HorizontalAlignment.LEFT); + cellStyle.setVerticalAlignment(VerticalAlignment.TOP); + cellStyle.setWrapText(true); + + // Lock the cell if FREEZE_CELL is true + if (FREEZE_CELL) { + cellStyle.setLocked(true); + } + + // Apply the style to the cell + cell.setCellStyle(cellStyle); + + // Adjust the column width + int columnIndex = cell.getColumnIndex(); + sheet.setColumnWidth(columnIndex, COLUMN_WIDTH * 256); // Width is measured in units of 1/256 of a character + } + + /** + * Converts a HEX color string to XSSFColor using the XSSFWorkbook context. + * + * @param hexColor The HEX color string (e.g., "93C47D"). + * @param xssfWorkbook The XSSFWorkbook context for styles. + * @return XSSFColor The corresponding XSSFColor object. + */ + public static XSSFColor hexToXSSFColor(String hexColor, XSSFWorkbook xssfWorkbook) { + // Convert HEX to RGB + int red = Integer.valueOf(hexColor.substring(0, 2), 16); + int green = Integer.valueOf(hexColor.substring(2, 4), 16); + int blue = Integer.valueOf(hexColor.substring(4, 6), 16); + + red = (int) (red * 1.1); // increase red component by 10% + green = (int) (green * 1.1); // increase green component by 10% + blue = (int) (blue * 1.1); // increase blue component by 10% + + // Clamp the values to be between 0 and 255 + red = Math.min(255, Math.max(0, red)); + green = Math.min(255, Math.max(0, green)); + blue = Math.min(255, Math.max(0, blue)); + + // Create IndexedColorMap from the workbook's styles source + IndexedColorMap colorMap = xssfWorkbook.getStylesSource().getIndexedColors(); + + // Create XSSFColor using the XSSFWorkbook context and colorMap + return new XSSFColor(new Color(red, green, blue), colorMap); + } +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java new file mode 100644 index 0000000000..71b3ac8b65 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java @@ -0,0 +1,196 @@ +package org.egov.processor.util; + +import org.apache.poi.ss.usermodel.*; +import org.egov.processor.web.models.Locale; +import org.egov.processor.web.models.LocaleResponse; +import org.egov.processor.web.models.PlanConfigurationRequest; +import org.egov.processor.web.models.ResourceMapping; +import org.egov.processor.web.models.census.Census; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +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; + + private ExcelStylingUtil excelStylingUtil; + + private EnrichmentUtil enrichmentUtil; + + public OutputEstimationGenerationUtil(LocaleUtil localeUtil, ParsingUtil parsingUtil, EnrichmentUtil enrichmentUtil, ExcelStylingUtil excelStylingUtil) { + this.localeUtil = localeUtil; + this.parsingUtil = parsingUtil; + this.excelStylingUtil = excelStylingUtil; + this.enrichmentUtil = enrichmentUtil; + } + + public void processOutputFile(Workbook workbook, PlanConfigurationRequest request) { + LocaleResponse localeResponse = localeUtil.searchLocale(request); + //removing readme sheet + for (int i = workbook.getNumberOfSheets() - 1; i >= 0; i--) { + Sheet sheet = workbook.getSheetAt(i); + if (!parsingUtil.isSheetAllowedToProcess(request, sheet.getSheetName(), localeResponse)) { + workbook.removeSheetAt(i); + } + } + + Map localizationCodeAndMessageMap = localeResponse.getMessages().stream() + .collect(Collectors.toMap( + Locale::getCode, + Locale::getMessage, + (existingValue, newValue) -> existingValue // Keep the existing value in case of duplicates + )); + + for(Sheet sheet: workbook) { + processSheetForHeaderLocalization(sheet, localizationCodeAndMessageMap); + } + } + + public void processSheetForHeaderLocalization(Sheet sheet, Map localizationCodeAndMessageMap) { + // Fetch the header row from sheet + Row row = sheet.getRow(0); + if (parsingUtil.isRowEmpty(row)) throw new CustomException(); + + + //Iterate from the end, for every cell localize the header value + for (int i = row.getLastCellNum() - 1; i >= 0; i--) { + Cell headerColumn = row.getCell(i); + + if (headerColumn == null || headerColumn.getCellType() != CellType.STRING) { + continue; + } + String headerColumnValue = headerColumn.getStringCellValue(); + + // Exit the loop if the header column value is not in the localization map + if (!localizationCodeAndMessageMap.containsKey(headerColumnValue)) { + break; + } + + // Update the cell value with the localized message + excelStylingUtil.styleCell(headerColumn); + headerColumn.setCellValue(localizationCodeAndMessageMap.get(headerColumnValue)); + } + + } + + /** + * This is the main method responsible for adding an assigned facility name column to each sheet in the workbook. + * It iterates through all the sheets, verifies if they are eligible for processing, retrieves required mappings + * and boundary codes, and populates the new column with facility names based on these mappings. + * + * @param workbook the workbook containing the sheets to be processed. + * @param request the plan configuration request containing the resource mapping and other configurations. + * @param fileStoreId the associated file store ID used to filter resource mappings. + */ + 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; + + // Creating a map of MappedTo and MappedFrom values from resource mapping + Map mappedValues = request.getPlanConfiguration().getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap( + ResourceMapping::getMappedTo, + ResourceMapping::getMappedFrom, + (existing, replacement) -> existing, + LinkedHashMap::new + )); + + // Get the map of boundary code to the facility assigned to that boundary. + Map boundaryCodeToFacility = getBoundaryCodeToFacilityMap(workbook, request, fileStoreId); + + for (int i = 0; i < workbook.getNumberOfSheets(); i++) { + Sheet sheet = workbook.getSheetAt(i); + if (parsingUtil.isSheetAllowedToProcess(request, sheet.getSheetName(), localeResponse)) { + addFacilityNameToSheet(sheet, assignedFacilityColHeader, boundaryCodeToFacility, mappedValues); + } + } + } + + /** + * Collects boundary codes from all eligible sheets in the workbook, fetches census records for these boundaries, + * and maps each boundary code to its assigned facility name obtained from the census data. + * + * @param workbook the workbook containing the sheets. + * @param request the plan configuration request with boundary code details. + * @param fileStoreId the associated file store ID for filtering. + * @return a map of boundary codes to their assigned facility names. + */ + private Map getBoundaryCodeToFacilityMap(Workbook workbook, PlanConfigurationRequest request, String fileStoreId) { + List boundaryCodes = new ArrayList<>(); + + for (int i = 0; i < workbook.getNumberOfSheets(); i++) { + Sheet sheet = workbook.getSheetAt(i); + if (parsingUtil.isSheetAllowedToProcess(request, sheet.getSheetName(), localeUtil.searchLocale(request))) { + boundaryCodes.addAll(enrichmentUtil.getBoundaryCodesFromTheSheet(sheet, request, fileStoreId)); + } + } + + List censusList = enrichmentUtil.getCensusRecordsForEnrichment(request, boundaryCodes); + return censusList.stream() + .collect(Collectors.toMap( + Census::getBoundaryCode, + census -> (String) parsingUtil.extractFieldsFromJsonObject(census.getAdditionalDetails(), FACILITY_NAME))); + } + + /** + * Processes a given sheet by adding a new column for assigned facilities and populating + * each row with the corresponding facility name based on the boundary code. + * + * @param sheet the sheet being processed. + * @param assignedFacilityColHeader the header for the new assigned facility column. + * @param boundaryCodeToFacility the mapping of boundary codes to assigned facilities. + * @param mappedValues a map of 'MappedTo' to 'MappedFrom' values. + */ + private void addFacilityNameToSheet(Sheet sheet, String assignedFacilityColHeader, Map boundaryCodeToFacility, Map mappedValues) { + int indexOfFacility = createAssignedFacilityColumn(sheet, assignedFacilityColHeader); + Map columnNameIndexMap = parsingUtil.getAttributeNameIndexFromExcel(sheet); + int indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, parsingUtil.sortColumnByIndex(columnNameIndexMap), mappedValues); + + for (Row row : sheet) { + if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { + continue; + } + + String boundaryCode = row.getCell(indexOfBoundaryCode).getStringCellValue(); + + Cell facilityCell = row.getCell(indexOfFacility); + if (facilityCell == null) { + facilityCell = row.createCell(indexOfFacility, CellType.STRING); + } + + facilityCell.setCellValue(boundaryCodeToFacility.getOrDefault(boundaryCode, "")); + } + } + + /** + * Adds a new column for the assigned facility name in the provided sheet, styles the header cell, + * and returns the index of the newly created column. + * + * @param sheet the sheet where the column is to be added. + * @param assignedFacilityColHeader the header for the new column. + * @return the index of the newly created column. + */ + private int createAssignedFacilityColumn(Sheet sheet, String assignedFacilityColHeader) { + int indexOfFacility = (int) sheet.getRow(0).getLastCellNum(); + Cell facilityColHeader = sheet.getRow(0).createCell(indexOfFacility, CellType.STRING); + excelStylingUtil.styleCell(facilityColHeader); + facilityColHeader.setCellValue(assignedFacilityColHeader); + return indexOfFacility; + } +} + diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java index ba10327e4c..756252b562 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java @@ -7,8 +7,8 @@ import org.apache.commons.io.FileUtils; import org.apache.poi.ss.usermodel.*; import org.egov.processor.config.ServiceConstants; -import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.ResourceMapping; +import org.egov.processor.web.models.Locale; +import org.egov.processor.web.models.*; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; @@ -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.*; @@ -24,7 +25,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import static org.egov.processor.config.ServiceConstants.PROPERTIES; +import static org.egov.processor.config.ServiceConstants.*; @Slf4j @Component @@ -36,10 +37,16 @@ public class ParsingUtil { private CalculationUtil calculationUtil; - public ParsingUtil(PlanConfigurationUtil planConfigurationUtil, FilestoreUtil filestoreUtil, CalculationUtil calculationUtil) { + private 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 fetchAttributeNamesFromJson(JsonNode jsonNode) @@ -314,7 +321,7 @@ public List extractPropertyNamesFromAdminSchema(JsonNode rootNode) { * @param row the Row to check * @return true if the row is empty, false otherwise */ - public static boolean isRowEmpty(Row row) { + public boolean isRowEmpty(Row row) { if (row == null) { return true; } @@ -392,4 +399,60 @@ public void printRow(Sheet sheet, Row row) { System.out.println(); // Move to the next line after printing the row } + /** + * Checks if a sheet is allowed to be processed based on MDMS constants and locale-specific configuration. + * + * @param planConfigurationRequest The request containing configuration details including request info and tenant ID. + * @param sheetName The name of the sheet to be processed. + * @return true if the sheet is allowed to be processed, false otherwise. + */ + public boolean isSheetAllowedToProcess(PlanConfigurationRequest planConfigurationRequest, String sheetName, LocaleResponse localeResponse) { + Map mdmsDataConstants = mdmsUtil.fetchMdmsDataForCommonConstants( + planConfigurationRequest.getRequestInfo(), + planConfigurationRequest.getPlanConfiguration().getTenantId()); + + for (Locale locale : localeResponse.getMessages()) { + if ((locale.getCode().equalsIgnoreCase((String) mdmsDataConstants.get(READ_ME_SHEET_NAME))) + || locale.getCode().equalsIgnoreCase(HCM_ADMIN_CONSOLE_BOUNDARY_DATA)) { + if (sheetName.equals(locale.getMessage())) + return false; + } + } + return true; + + } + + /** + * 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); + } + } } From ffa7974b3dabc602c5b567885ce7a36d8b1ac75d Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 3 Jan 2025 15:16:15 +0530 Subject: [PATCH 2/7] Resolved code rabbit review comments --- .../org/egov/processor/config/ServiceConstants.java | 5 +++++ .../java/org/egov/processor/service/ExcelParser.java | 3 +-- .../java/org/egov/processor/util/EnrichmentUtil.java | 7 ------- .../java/org/egov/processor/util/ExcelStylingUtil.java | 10 +++++++--- .../processor/util/OutputEstimationGenerationUtil.java | 6 +++--- .../main/java/org/egov/processor/util/ParsingUtil.java | 1 + 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java b/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java index 41e9144856..f13f37ceca 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java @@ -42,6 +42,9 @@ public class ServiceConstants { 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 EMPTY_HEADER_ROW_CODE = "EMPTY_HEADER_ROW"; + public static final String EMPTY_HEADER_ROW_MESSAGE = "The header row is empty for the given sheet"; + 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."; @@ -60,6 +63,7 @@ public class ServiceConstants { public static final String ERROR_WHILE_DATA_CREATE_CALL = "Exception occurred while creating data for campaign - "; public static final String ERROR_WHILE_CALLING_MICROPLAN_API = "Unexpected error while calling fetch from Microplan API for plan config Id: "; + public static final String INVALID_HEX = "Invalid hex color specified: "; public static final String FILE_NAME = "output.xls"; public static final String FILE_TYPE = "boundaryWithTarget"; @@ -77,6 +81,7 @@ public class ServiceConstants { public static final String BOUNDARY = "boundary"; public static final String DOT_SEPARATOR = "."; public static final String MICROPLAN_PREFIX = "MP-"; + public static final Double BRIGHTEN_FACTOR = 1.1; //MDMS field Constants public static final String DATA = "data"; diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java index 2faa00b43f..b951270f8d 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java @@ -380,8 +380,7 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat campaignIntegrationUtil.updateCampaignBoundary(planConfig, feature, assumptionValueMap, mappedValues, mapOfColumnNameAndIndex, campaignBoundaryList, resultMap); planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); - // TODO: remove after testing - parsingUtil.printRow(sheet, row); + } } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java index e543dd062a..330a391484 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java @@ -144,9 +144,6 @@ public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationR } } } - //TODO: remove after testing - log.info("After updating values in sheet -> "); - parsingUtil.printRow(sheet, row); log.info("Successfully update file with approved census data."); } @@ -236,7 +233,6 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR for(Row row: sheet) { - parsingUtil.printRow(sheet, row); // Skip the header row and empty rows if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { continue; @@ -269,9 +265,6 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR } } } - //TODO: remove after testing - log.info("After updating values in sheet -> "); - parsingUtil.printRow(sheet, row); log.info("Successfully update file with approved census data."); } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java index c8da424ea1..39e5fd75de 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java @@ -55,14 +55,18 @@ public void styleCell(Cell cell) { * @return XSSFColor The corresponding XSSFColor object. */ public static XSSFColor hexToXSSFColor(String hexColor, XSSFWorkbook xssfWorkbook) { + + if (hexColor == null || hexColor.length() < 6) + throw new IllegalArgumentException(INVALID_HEX + hexColor); + // Convert HEX to RGB int red = Integer.valueOf(hexColor.substring(0, 2), 16); int green = Integer.valueOf(hexColor.substring(2, 4), 16); int blue = Integer.valueOf(hexColor.substring(4, 6), 16); - red = (int) (red * 1.1); // increase red component by 10% - green = (int) (green * 1.1); // increase green component by 10% - blue = (int) (blue * 1.1); // increase blue component by 10% + red = (int) (red * BRIGHTEN_FACTOR); // increase red component by 10% + green = (int) (green * BRIGHTEN_FACTOR); // increase green component by 10% + blue = (int) (blue * BRIGHTEN_FACTOR); // increase blue component by 10% // Clamp the values to be between 0 and 255 red = Math.min(255, Math.max(0, red)); diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java index 71b3ac8b65..eb2dd82baa 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java @@ -15,8 +15,7 @@ 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; +import static org.egov.processor.config.ServiceConstants.*; @Component public class OutputEstimationGenerationUtil { @@ -61,7 +60,8 @@ public void processOutputFile(Workbook workbook, PlanConfigurationRequest reques public void processSheetForHeaderLocalization(Sheet sheet, Map localizationCodeAndMessageMap) { // Fetch the header row from sheet Row row = sheet.getRow(0); - if (parsingUtil.isRowEmpty(row)) throw new CustomException(); + if (parsingUtil.isRowEmpty(row)) + throw new CustomException(EMPTY_HEADER_ROW_CODE, EMPTY_HEADER_ROW_MESSAGE); //Iterate from the end, for every cell localize the header value diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java index 756252b562..ec20dbd2bd 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java @@ -449,6 +449,7 @@ public Object extractFieldsFromJsonObject(Object additionalDetails, String field return node.asText(); } } + log.debug("The field to be extracted - " + fieldToExtract + " is not present in additional details."); return null; } catch (Exception e) { log.error(e.getMessage() + fieldToExtract); From f6f02d178ebe0c2ec142d18220cd960344a31012 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 6 Jan 2025 16:02:48 +0530 Subject: [PATCH 3/7] HCMPRE-1801 setting dynamic column width for column headers --- .../egov/processor/util/ExcelStylingUtil.java | 26 +++++++++++++++++-- .../util/OutputEstimationGenerationUtil.java | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java index 39e5fd75de..63d38d6654 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/ExcelStylingUtil.java @@ -42,9 +42,31 @@ public void styleCell(Cell cell) { // Apply the style to the cell cell.setCellStyle(cellStyle); - // Adjust the column width + } + + /** + * Adjusts the column width to fit the content of the given cell, adding padding for readability. + * + * @param cell the cell whose column width is to be adjusted; does nothing if null. + */ + public void adjustColumnWidthForCell(Cell cell) { + if (cell == null) { + return; + } + + Sheet sheet = cell.getSheet(); int columnIndex = cell.getColumnIndex(); - sheet.setColumnWidth(columnIndex, COLUMN_WIDTH * 256); // Width is measured in units of 1/256 of a character + int maxWidth = sheet.getColumnWidth(columnIndex); + + // Calculate the width needed for the current cell content + String cellValue = cell.toString(); // Convert cell content to string + int cellWidth = cellValue.length() * 256; // Approximate width (1/256th of character width) + + // Use the maximum width seen so far, including padding for readability + int padding = 512; // Adjust padding as needed + int newWidth = Math.max(maxWidth, cellWidth + padding); + + sheet.setColumnWidth(columnIndex, newWidth); } /** diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java index eb2dd82baa..e687c32dc9 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java @@ -81,6 +81,7 @@ public void processSheetForHeaderLocalization(Sheet sheet, Map l // Update the cell value with the localized message excelStylingUtil.styleCell(headerColumn); headerColumn.setCellValue(localizationCodeAndMessageMap.get(headerColumnValue)); + excelStylingUtil.adjustColumnWidthForCell(headerColumn); } } @@ -190,6 +191,7 @@ private int createAssignedFacilityColumn(Sheet sheet, String assignedFacilityCol Cell facilityColHeader = sheet.getRow(0).createCell(indexOfFacility, CellType.STRING); excelStylingUtil.styleCell(facilityColHeader); facilityColHeader.setCellValue(assignedFacilityColHeader); + excelStylingUtil.adjustColumnWidthForCell(facilityColHeader); return indexOfFacility; } } From 308cd0b0eed85c78b1971c423492779de20df782 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 8 Jan 2025 12:20:04 +0530 Subject: [PATCH 4/7] HCMPRE-1577 Updating comments --- .../egov/processor/service/ExcelParser.java | 8 ++-- .../util/OutputEstimationGenerationUtil.java | 41 +++++++++++++++---- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java index b951270f8d..9913ed6a83 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java @@ -167,12 +167,10 @@ private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigu String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); - outputEstimationGenerationUtil.processOutputFile(workbook, planConfigurationRequest); + //process output file for localized header columns and addition of new columns + outputEstimationGenerationUtil.processOutputFile(workbook, planConfigurationRequest, filestoreId); - // Adding facility information for each boundary code - outputEstimationGenerationUtil.addAssignedFacility(workbook, planConfigurationRequest, filestoreId); - - //update processed output file into plan configuration file object + //upload the processed output file and update the same into plan configuration file object fileToUpload = convertWorkbookToXls(workbook); uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); planUtil.setFileStoreIdForPopulationTemplate(planConfigurationRequest, uploadedFileStoreId); diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java index e687c32dc9..bb1a34c14d 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java @@ -35,9 +35,19 @@ public OutputEstimationGenerationUtil(LocaleUtil localeUtil, ParsingUtil parsing this.enrichmentUtil = enrichmentUtil; } - public void processOutputFile(Workbook workbook, PlanConfigurationRequest request) { + /** + * Processes an output Excel workbook by removing unnecessary sheets, localizing header columns, + * and adding facility information for each boundary code. The configuration for processing + * is based on the provided PlanConfigurationRequest. + * + * @param workbook the Excel workbook to process + * @param request the PlanConfigurationRequest containing processing configuration + * @param filestoreId the identifier of the file store for additional processing requirements + */ + public void processOutputFile(Workbook workbook, PlanConfigurationRequest request, String filestoreId) { LocaleResponse localeResponse = localeUtil.searchLocale(request); - //removing readme sheet + + // 1. removing readme sheet for (int i = workbook.getNumberOfSheets() - 1; i >= 0; i--) { Sheet sheet = workbook.getSheetAt(i); if (!parsingUtil.isSheetAllowedToProcess(request, sheet.getSheetName(), localeResponse)) { @@ -45,6 +55,25 @@ public void processOutputFile(Workbook workbook, PlanConfigurationRequest reques } } + // 2. Stylize and localize output column headers + for(Sheet sheet: workbook) { + processSheetForHeaderLocalization(sheet, localeResponse); + } + + // 3. Adding facility information for each boundary code + addAssignedFacility(workbook, request, filestoreId); + + } + + /** + * Localizes the header row in the given sheet using the provided localization map. + * Applies styling and adjusts column widths for each localized header cell. + * + * @param sheet the Excel sheet whose header row needs localization + * @param localeResponse localization search call response + */ + public void processSheetForHeaderLocalization(Sheet sheet, LocaleResponse localeResponse) { + // create localization code and message map Map localizationCodeAndMessageMap = localeResponse.getMessages().stream() .collect(Collectors.toMap( Locale::getCode, @@ -52,12 +81,6 @@ public void processOutputFile(Workbook workbook, PlanConfigurationRequest reques (existingValue, newValue) -> existingValue // Keep the existing value in case of duplicates )); - for(Sheet sheet: workbook) { - processSheetForHeaderLocalization(sheet, localizationCodeAndMessageMap); - } - } - - public void processSheetForHeaderLocalization(Sheet sheet, Map localizationCodeAndMessageMap) { // Fetch the header row from sheet Row row = sheet.getRow(0); if (parsingUtil.isRowEmpty(row)) @@ -189,6 +212,8 @@ private void addFacilityNameToSheet(Sheet sheet, String assignedFacilityColHeade private int createAssignedFacilityColumn(Sheet sheet, String assignedFacilityColHeader) { int indexOfFacility = (int) sheet.getRow(0).getLastCellNum(); Cell facilityColHeader = sheet.getRow(0).createCell(indexOfFacility, CellType.STRING); + + //stylize cell and set cell value as the localized value excelStylingUtil.styleCell(facilityColHeader); facilityColHeader.setCellValue(assignedFacilityColHeader); excelStylingUtil.adjustColumnWidthForCell(facilityColHeader); From 2988c15f07eb8600876f6d2fd3bb8e662e988b2d Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 8 Jan 2025 12:22:23 +0530 Subject: [PATCH 5/7] Adding comments --- .../util/OutputEstimationGenerationUtil.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java index e687c32dc9..bd6f2e899e 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java @@ -98,7 +98,10 @@ public void processSheetForHeaderLocalization(Sheet sheet, Map l public void addAssignedFacility(Workbook workbook, PlanConfigurationRequest request, String fileStoreId) { LocaleResponse localeResponse = localeUtil.searchLocale(request); + // Get the localized column header name for assigned facilities. String assignedFacilityColHeader = localeUtil.localeSearch(localeResponse.getMessages(), HCM_MICROPLAN_SERVING_FACILITY); + + // Default to a constant value if no localized value is found. assignedFacilityColHeader = assignedFacilityColHeader != null ? assignedFacilityColHeader : HCM_MICROPLAN_SERVING_FACILITY; // Creating a map of MappedTo and MappedFrom values from resource mapping @@ -114,9 +117,12 @@ public void addAssignedFacility(Workbook workbook, PlanConfigurationRequest requ // Get the map of boundary code to the facility assigned to that boundary. Map boundaryCodeToFacility = getBoundaryCodeToFacilityMap(workbook, request, fileStoreId); + // Iterate through all sheets in the workbook. for (int i = 0; i < workbook.getNumberOfSheets(); i++) { Sheet sheet = workbook.getSheetAt(i); + if (parsingUtil.isSheetAllowedToProcess(request, sheet.getSheetName(), localeResponse)) { + // Add facility names to the sheet. addFacilityNameToSheet(sheet, assignedFacilityColHeader, boundaryCodeToFacility, mappedValues); } } @@ -134,13 +140,16 @@ public void addAssignedFacility(Workbook workbook, PlanConfigurationRequest requ private Map getBoundaryCodeToFacilityMap(Workbook workbook, PlanConfigurationRequest request, String fileStoreId) { List boundaryCodes = new ArrayList<>(); + // Iterate through all sheets in the workbook. for (int i = 0; i < workbook.getNumberOfSheets(); i++) { Sheet sheet = workbook.getSheetAt(i); if (parsingUtil.isSheetAllowedToProcess(request, sheet.getSheetName(), localeUtil.searchLocale(request))) { + // Extract boundary codes from the sheet. boundaryCodes.addAll(enrichmentUtil.getBoundaryCodesFromTheSheet(sheet, request, fileStoreId)); } } + // Fetch census records for the extracted boundary codes. List censusList = enrichmentUtil.getCensusRecordsForEnrichment(request, boundaryCodes); return censusList.stream() .collect(Collectors.toMap( @@ -159,9 +168,14 @@ private Map getBoundaryCodeToFacilityMap(Workbook workbook, Plan */ private void addFacilityNameToSheet(Sheet sheet, String assignedFacilityColHeader, Map boundaryCodeToFacility, Map mappedValues) { int indexOfFacility = createAssignedFacilityColumn(sheet, assignedFacilityColHeader); + + // Get column index mappings from the sheet. Map columnNameIndexMap = parsingUtil.getAttributeNameIndexFromExcel(sheet); + + // Get the index of the boundary code column based on the provided mappings. int indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, parsingUtil.sortColumnByIndex(columnNameIndexMap), mappedValues); + // Iterate over each row in the sheet and set the facility name for each row. for (Row row : sheet) { if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { continue; @@ -169,11 +183,13 @@ private void addFacilityNameToSheet(Sheet sheet, String assignedFacilityColHeade String boundaryCode = row.getCell(indexOfBoundaryCode).getStringCellValue(); + // Get or create the facility cell in the row. Cell facilityCell = row.getCell(indexOfFacility); if (facilityCell == null) { facilityCell = row.createCell(indexOfFacility, CellType.STRING); } + // Assign the facility name based on the boundary code. facilityCell.setCellValue(boundaryCodeToFacility.getOrDefault(boundaryCode, "")); } } @@ -188,7 +204,11 @@ private void addFacilityNameToSheet(Sheet sheet, String assignedFacilityColHeade */ private int createAssignedFacilityColumn(Sheet sheet, String assignedFacilityColHeader) { int indexOfFacility = (int) sheet.getRow(0).getLastCellNum(); + + // Create a new cell for the column header. Cell facilityColHeader = sheet.getRow(0).createCell(indexOfFacility, CellType.STRING); + + // Apply styling to the header cell, adjust width and set column header for facility. excelStylingUtil.styleCell(facilityColHeader); facilityColHeader.setCellValue(assignedFacilityColHeader); excelStylingUtil.adjustColumnWidthForCell(facilityColHeader); From 2670e269d745e92f1d87b3530a9e2e6bb3dd1599 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 8 Jan 2025 12:27:20 +0530 Subject: [PATCH 6/7] HCMPRE-1577 Updating comments --- .../src/main/java/org/egov/processor/service/ExcelParser.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java index 9913ed6a83..adbed6b243 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java @@ -198,7 +198,6 @@ private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigu * @param campaignBoundaryList List of boundary objects related to the campaign. * @param dataFormatter The data formatter for formatting cell values. */ - //TODO: processsheetforestimate and processsheetforcensus private void processSheets(PlanConfigurationRequest request, String fileStoreId, Object campaignResponse, Workbook excelWorkbook, List campaignBoundaryList, From 89f4046f62ad5766b4f4179a5cba95aa8a3e10e8 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 8 Jan 2025 12:28:34 +0530 Subject: [PATCH 7/7] HCMPRE-1577 Removing todo --- .../src/main/java/org/egov/processor/service/ExcelParser.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java index adbed6b243..26f7735067 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java @@ -320,7 +320,6 @@ private List getBoundaryCodeList(PlanConfigurationRequest planConfigurat * @return A map of attribute names to their corresponding indices or data types. */ - //TODO: fetch from adminSchema master private Map prepareAttributeVsIndexMap(PlanConfigurationRequest planConfigurationRequest, String fileStoreId, CampaignResponse campaign, PlanConfiguration planConfig, Object mdmsData) { org.egov.processor.web.models.File file = planConfig.getFiles().stream()