Skip to content

Commit

Permalink
Merge pull request #1314 from egovernments/download-estimation-1578
Browse files Browse the repository at this point in the history
HCMPRE-1576,1577,1578: Removed readme sheet, localised estimation sheet and added facility name
  • Loading branch information
Priyanka-eGov authored Jan 8, 2025
2 parents 4fbf404 + 89f4046 commit 656f733
Show file tree
Hide file tree
Showing 6 changed files with 450 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ 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 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.";

Expand All @@ -57,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";
Expand All @@ -74,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";
Expand Down Expand Up @@ -116,8 +124,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

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -80,6 +78,7 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore
this.censusUtil = censusUtil;
this.enrichmentUtil = enrichmentUtil;
this.planConfigurationUtil = planConfigurationUtil;
this.outputEstimationGenerationUtil = outputEstimationGenerationUtil;
}

/**
Expand Down Expand Up @@ -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.");
Expand All @@ -153,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 @@ -164,9 +163,19 @@ 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);
}

//process output file for localized header columns and addition of new columns
outputEstimationGenerationUtil.processOutputFile(workbook, planConfigurationRequest, filestoreId);

//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);
planUtil.update(planConfigurationRequest);
}
} finally {
try {
if (fileToUpload != null && !fileToUpload.delete()) {
Expand All @@ -189,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.
*/

private void processSheets(PlanConfigurationRequest request, String fileStoreId,
Object campaignResponse, Workbook excelWorkbook,
List<Boundary> campaignBoundaryList,
Expand All @@ -213,7 +221,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,
Expand Down Expand Up @@ -312,8 +320,6 @@ private List<String> getBoundaryCodeList(PlanConfigurationRequest planConfigurat
* @return A map of attribute names to their corresponding indices or data types.
*/


//TODO: fetch from adminSchema master
private Map<String, Object> prepareAttributeVsIndexMap(PlanConfigurationRequest planConfigurationRequest,
String fileStoreId, CampaignResponse campaign, PlanConfiguration planConfig, Object mdmsData) {
org.egov.processor.web.models.File file = planConfig.getFiles().stream()
Expand Down Expand Up @@ -718,28 +724,5 @@ public List<String> getAllBoundaryPresentforHierarchyType(List<EnrichedBoundary>
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<String, Object> 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;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,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
@@ -0,0 +1,104 @@
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);

}

/**
* 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();
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);
}

/**
* 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) {

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 * 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));
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);
}
}
Loading

0 comments on commit 656f733

Please sign in to comment.