diff --git a/health-services/plan-service/src/main/java/digit/web/models/Resource.java b/health-services/plan-service/src/main/java/digit/web/models/Resource.java index d0d8ce2500b..2a614db0ba6 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Resource.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Resource.java @@ -29,7 +29,6 @@ public class Resource { private String resourceType = null; @JsonProperty("estimatedNumber") - @NotNull private BigDecimal estimatedNumber = null; @JsonProperty("activityCode") diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/config/Configuration.java b/health-services/resource-generator/src/main/java/org/egov/processor/config/Configuration.java index 1f49dc085e1..c0e08a02aa2 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/config/Configuration.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/config/Configuration.java @@ -112,11 +112,11 @@ public class Configuration { private String resourceCensusCreateTopic; //Default - @Value("${resource.default.offset}") - private Integer defaultOffset; + @Value("${default.offset.for.mdms.data}") + private Integer defaultOffsetForMdms; - @Value("${resource.default.limit}") - private Integer defaultLimit; + @Value("${default.limit.for.mdms.data}") + private Integer defaultLimitForMdms; //census additonal field configs @Value("${census.additional.field.override.keys}") 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 6e0a864c102..09ba679d818 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 @@ -71,6 +71,8 @@ public class ServiceConstants { "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 DISTRIBUTION_PROCESS = "DistributionProcess"; + public static final String REGISTRATION_PROCESS = "RegistrationProcess"; public static final String FILE_NAME = "output.xls"; public static final String FILE_TYPE = "boundaryWithTarget"; public static final String FILE_TEMPLATE_IDENTIFIER_POPULATION = "Population"; @@ -86,6 +88,7 @@ public class ServiceConstants { public static final String MDMS_MASTER_ADMIN_SCHEMA = "adminSchema"; public static final String MDMS_CAMPAIGN_TYPE = "campaignType"; public static final String MDMS_SCHEMA_ADMIN_SCHEMA = "adminSchema"; + public static final String MDMS_MASTER_MIXED_STRATEGY = "MixedStrategyOperationLogic"; public static final String MDMS_ADMIN_CONSOLE_MODULE_NAME = "HCM-ADMIN-CONSOLE"; public static final String BOUNDARY = "boundary"; public static final String DOT_SEPARATOR = "."; @@ -93,6 +96,8 @@ public class ServiceConstants { public static final Double BRIGHTEN_FACTOR = 1.1; public static final String ACCESSIBILITY_DETAILS = "accessibilityDetails"; public static final String SECURITY_DETAILS = "securityDetails"; + public static final String EMPTY_STRING = ""; + public static final String FIXED_POST_YES = "yes"; //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 7b5a52234b2..f892f5a4053 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 @@ -18,6 +18,7 @@ import org.egov.processor.web.models.campaignManager.Boundary; import org.egov.processor.web.models.campaignManager.CampaignResources; import org.egov.processor.web.models.campaignManager.CampaignResponse; +import org.egov.processor.web.models.mdmsV2.MixedStrategyOperationLogic; import org.egov.processor.web.models.planFacility.PlanFacility; import org.egov.processor.web.models.planFacility.PlanFacilityResponse; import org.egov.processor.web.models.planFacility.PlanFacilitySearchCriteria; @@ -26,6 +27,7 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.io.File; import java.io.FileNotFoundException; @@ -69,11 +71,13 @@ public class ExcelParser implements FileParser { private OutputEstimationGenerationUtil outputEstimationGenerationUtil; + private MixedStartegyUtil mixedStartegyUtil; + private PlanFacilityUtil planFacilityUtil; 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, OutputEstimationGenerationUtil outputEstimationGenerationUtil, PlanFacilityUtil planFacilityUtil) { + Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil, EnrichmentUtil enrichmentUtil, PlanConfigurationUtil planConfigurationUtil, OutputEstimationGenerationUtil outputEstimationGenerationUtil, MixedStartegyUtil mixedStartegyUtil, PlanFacilityUtil planFacilityUtil) { this.objectMapper = objectMapper; this.parsingUtil = parsingUtil; this.filestoreUtil = filestoreUtil; @@ -88,6 +92,7 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore this.enrichmentUtil = enrichmentUtil; this.planConfigurationUtil = planConfigurationUtil; this.outputEstimationGenerationUtil = outputEstimationGenerationUtil; + this.mixedStartegyUtil = mixedStartegyUtil; this.planFacilityUtil = planFacilityUtil; } @@ -243,10 +248,6 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, processRowsForCensusRecords(request, excelWorkbookSheet, fileStoreId, attributeNameVsDataTypeMap, boundaryCodeList, campaign.getCampaign().get(0).getHierarchyType()); } else if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigUpdatePlanEstimatesIntoOutputFileStatus())) { - - // Create a Map of Boundary Code to Facility's fixed post detail. - Map boundaryCodeToFixedPostMap = fetchFixedPostDetails(request, excelWorkbook, fileStoreId); - enrichmentUtil.enrichsheetWithApprovedPlanEstimates(excelWorkbookSheet, request, fileStoreId, mappedValues); } } @@ -256,17 +257,14 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, /** * This method makes plan facility search call and creates a map of boundary code to it's fixed post facility details. * - * @param request the plan configuration request. - * @param excelWorkbook the Excel workbook to be processed. - * @param fileStoreId the fileStore id of the file. + * @param request the plan configuration request. + * @param sheet the Excel sheet to be processed. + * @param fileStoreId the fileStore id of the file. * @return returns a map of boundary code to it's fixed post facility details. */ - private Map fetchFixedPostDetails(PlanConfigurationRequest request, Workbook excelWorkbook, String fileStoreId) { + private Map fetchFixedPostDetails(PlanConfigurationRequest request, Sheet sheet, String fileStoreId) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - // Create the map of boundary code to the facility assigned to that boundary. - Map boundaryCodeToFacilityNameMap = outputEstimationGenerationUtil.getBoundaryCodeToFacilityMap(excelWorkbook, request, fileStoreId); - //Create plan facility search request PlanFacilitySearchRequest searchRequest = PlanFacilitySearchRequest.builder() .requestInfo(request.getRequestInfo()) @@ -283,19 +281,24 @@ private Map fetchFixedPostDetails(PlanConfigurationRequest reque } // Create a Boundary Code to Facility's fixed post detail map. - Map boundaryCodeToFixedPostMap = new HashMap<>(); + Map boundaryCodeToFixedPostMap = new HashMap<>(); for (PlanFacility planFacility : planFacilityResponse.getPlanFacility()) { - // Find the boundary code corresponding to the facility name. - String boundaryCode = findByValue(boundaryCodeToFacilityNameMap, planFacility.getFacilityName()); + // Ensure serviceBoundaries are not empty + if (!CollectionUtils.isEmpty(planFacility.getServiceBoundaries())) { - // Extract the 'FIXED_POST' field from additional details. - String fixedPostValue = (String) parsingUtil.extractFieldsFromJsonObject(planFacility.getAdditionalDetails(), FIXED_POST); + // Extract the 'FIXED_POST' field from additional details. + String fixedPostValue = (String) parsingUtil.extractFieldsFromJsonObject(planFacility.getAdditionalDetails(), FIXED_POST); - // Populate the map. - boundaryCodeToFixedPostMap.put(boundaryCode, fixedPostValue); - } + // Normalize the value and determine boolean equivalent. + Boolean isFixedPost = !ObjectUtils.isEmpty(fixedPostValue) && fixedPostValue.trim().equalsIgnoreCase(FIXED_POST_YES); + // Populate the map with boundary code and isFixedPost. + planFacility.getServiceBoundaries().forEach((String boundary) -> + boundaryCodeToFixedPostMap.put(boundary, isFixedPost) + ); + } + } return boundaryCodeToFixedPostMap; } @@ -318,8 +321,10 @@ private Map fetchFixedPostDetails(PlanConfigurationRequest reque * @throws IOException If an I/O error occurs. */ private void processRows(PlanConfigurationRequest planConfigurationRequest, Sheet sheet, DataFormatter dataFormatter, String fileStoreId, List campaignBoundaryList, Map attributeNameVsDataTypeMap, List boundaryCodeList, Map boundaryCodeToCensusAdditionalDetails) { - PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); - performRowLevelCalculations(planConfigurationRequest, sheet, dataFormatter, fileStoreId, campaignBoundaryList, planConfig, attributeNameVsDataTypeMap, boundaryCodeList, boundaryCodeToCensusAdditionalDetails); + + // Create a Map of Boundary Code to Facility's fixed post detail. + Map boundaryCodeToFixedPostMap = fetchFixedPostDetails(planConfigurationRequest, sheet, fileStoreId); + performRowLevelCalculations(planConfigurationRequest, sheet, dataFormatter, fileStoreId, campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList, boundaryCodeToFixedPostMap, boundaryCodeToCensusAdditionalDetails); } private void processRowsForCensusRecords(PlanConfigurationRequest planConfigurationRequest, Sheet sheet, String fileStoreId, Map attributeNameVsDataTypeMap, List boundaryCodeList, String hierarchyType) { @@ -401,14 +406,15 @@ private Map prepareAttributeVsIndexMap(PlanConfigurationRequest * @param dataFormatter The data formatter for formatting cell values. * @param fileStoreId The ID of the uploaded file in the file store. * @param campaignBoundaryList List of boundary objects related to the campaign. - * @param planConfig The configuration details specific to the plan. * @param attributeNameVsDataTypeMap Mapping of attribute names to their data types. * @param boundaryCodeList List of boundary codes. */ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurationRequest, Sheet sheet, DataFormatter dataFormatter, String fileStoreId, List campaignBoundaryList, - PlanConfiguration planConfig, Map attributeNameVsDataTypeMap, List boundaryCodeList, Map boundaryCodeToCensusAdditionalDetails) { + Map attributeNameVsDataTypeMap, List boundaryCodeList, + Map boundaryCodeToFixedPostMap, Map boundaryCodeToCensusAdditionalDetails) { Row firstRow = null; + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); Map mappedValues = planConfig.getResourceMapping().stream() .filter(f -> f.getFilestoreId().equals(fileStoreId)) .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); @@ -419,6 +425,9 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + List mixedStrategyOperationLogicList = mixedStartegyUtil + .fetchMixedStrategyOperationLogicFromMDMS(planConfigurationRequest); + for (Row row : sheet) { if(parsingUtil.isRowEmpty(row)) continue; @@ -434,9 +443,10 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat JsonNode feature = createFeatureNodeFromRow(row, mapOfColumnNameAndIndex); performCalculationsOnOperations(sheet, planConfig, row, resultMap, mappedValues, assumptionValueMap, feature); - if (config.isIntegrateWithAdminConsole()) - campaignIntegrationUtil.updateCampaignBoundary(planConfig, feature, assumptionValueMap, mappedValues, - mapOfColumnNameAndIndex, campaignBoundaryList, resultMap); + + // Get Boundary Code for the current row. + String boundaryCode = row.getCell(indexOfBoundaryCode).getStringCellValue(); + mixedStartegyUtil.processResultMap(resultMap, planConfig.getOperations(), mixedStartegyUtil.getCategoriesNotAllowed(boundaryCodeToFixedPostMap.get(boundaryCode), planConfig, mixedStrategyOperationLogicList)); planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues, boundaryCodeToCensusAdditionalDetails); } @@ -787,6 +797,6 @@ public List getAllBoundaryPresentforHierarchyType(List } return boundaryList; } - + } \ No newline at end of file diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java index 9bfbe7cb62c..aa394c5a338 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; import org.egov.processor.repository.ServiceRequestRepository; @@ -14,10 +13,7 @@ import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; -import java.io.IOException; -import java.math.BigDecimal; import java.util.*; -import java.util.Map.Entry; import static org.egov.processor.config.ServiceConstants.*; @@ -28,15 +24,11 @@ public class CampaignIntegrationUtil { private ServiceRequestRepository serviceRequestRepository; private Configuration config; private ObjectMapper mapper; - private ParsingUtil parsingUtil; - - public CampaignIntegrationUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, - ObjectMapper mapper, FilestoreUtil filestoreUtil, ParsingUtil parsingUtil) { + public CampaignIntegrationUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.mapper = mapper; - this.parsingUtil= parsingUtil; } /** @@ -82,34 +74,6 @@ private MicroplanDetailsRequest buildMicroplanDetailsForUpdate(PlanConfiguration } - /** - * Updates campaign details based on the provided plan configuration request and response data. - * This method integrates the campaign details obtained from the response into the provided plan configuration request. - * It also updates the campaign boundaries and resources accordingly. - * - * @param planConfigurationRequest The plan configuration request containing the execution plan details. - * @param response The response object containing campaign details. - * @param campaignBoundaryList The list of campaign boundaries. - * @param campaignResourcesList The list of campaign resources. - */ - public void updateCampaignDetails(PlanConfigurationRequest planConfigurationRequest,Object response,List campaignBoundaryList,List campaignResourcesList) { - CampaignResponse campaignResponse = null; - try { - campaignResponse = mapper.convertValue(response, CampaignResponse.class); - campaignResponse.getCampaign().get(0).setResources(campaignResourcesList); - Boundary[] array = campaignBoundaryList.toArray(new Boundary[0]); - campaignResponse.getCampaign().get(0).setBoundaries(campaignBoundaryList.toArray(new Boundary[0])); - serviceRequestRepository.fetchResult( - new StringBuilder(config.getProjectFactoryHostEndPoint() + config.getCampaignIntegrationUpdateEndPoint()), - buildCampaignRequestForUpdate(planConfigurationRequest, campaignResponse)); - log.info("Campaign Integration successful."); - } catch (Exception e) { - log.error(ServiceConstants.ERROR_WHILE_SEARCHING_CAMPAIGN - + planConfigurationRequest.getPlanConfiguration().getCampaignId(), e); - throw new CustomException("Failed to update campaign details in CampaignIntegration class within method updateCampaignDetails.", e.toString()); - } - } - /** * Sends a data creation request to the Project Factory service using the provided * plan and campaign details. @@ -131,41 +95,6 @@ public void createProjectFactoryDataCall(PlanConfigurationRequest planConfigurat } } - /** - * Updates the campaign resources in the given campaign response based on the files specified in the plan configuration request. - * - * @param campaignResponse The campaign response object to be updated with resources. - * @param planConfigurationRequest The plan configuration request containing file information. - * @param fileStoreId The file store ID. - */ - public void updateResources(CampaignResponse campaignResponse, PlanConfigurationRequest planConfigurationRequest, - String fileStoreId) { - List campaignResourcesList = new ArrayList<>(); - List files = planConfigurationRequest.getPlanConfiguration().getFiles(); - for (File file : files) { - CampaignResources campaignResource = new CampaignResources(); - campaignResource.setFilename(ServiceConstants.FILE_NAME); - campaignResource.setFilestoreId(fileStoreId); - campaignResource.setType(ServiceConstants.FILE_TYPE); - campaignResourcesList.add(campaignResource); - } - campaignResponse.getCampaign().get(0).setResources(campaignResourcesList); - } - - /** - * Builds a campaign request object for updating campaign details based on the provided plan configuration request and campaign response. - * - * @param planConfigurationRequest The plan configuration request containing necessary information for updating the campaign. - * @param campaignResponse The campaign response containing the updated campaign details. - * @return The campaign request object built for updating campaign details. - */ - private CampaignRequest buildCampaignRequestForUpdate(PlanConfigurationRequest planConfigurationRequest, - CampaignResponse campaignResponse) { - return CampaignRequest.builder().requestInfo(planConfigurationRequest.getRequestInfo()) - .campaignDetails(campaignResponse.getCampaign().get(0)).build(); - - } - /** * Builds a {@link ResourceDetailsRequest} object for facility creation using the provided * plan configuration and campaign details. @@ -202,121 +131,6 @@ private ResourceDetailsRequest buildResourceDetailsObjectForFacilityCreate(PlanC } - /** - * Updates campaign boundary based on the provided plan configuration, feature, assumption values, mapped values, column index map, boundary list, and result map. - * - * @param planConfig The plan configuration containing relevant details. - * @param feature The JSON node representing the feature. - * @param assumptionValueMap The map containing assumption values. - * @param mappedValues The map containing mapped values. - * @param mapOfColumnNameAndIndex The map containing column names and their indices. - * @param boundaryList The list of campaign boundaries to update. - * @param resultMap The map containing result values. - * @throws IOException If an I/O error occurs. - */ - public void updateCampaignBoundary(PlanConfiguration planConfig, JsonNode feature, - Map assumptionValueMap, Map mappedValues, - Map mapOfColumnNameAndIndex, List boundaryList, - Map resultMap) { - Integer indexOfType = null; - boolean validToAdd = false; - Integer indexValue = 0; - Boundary boundary = new Boundary(); - List> sortedColumnList = parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex); - indexValue = parsingUtil.getIndexOfBoundaryCode(indexValue, sortedColumnList, mappedValues); - prepareBoundary(indexOfType, indexValue, sortedColumnList, feature, boundary, mappedValues); - if (isValidToAdd(boundaryList, resultMap, validToAdd, boundary)) - boundaryList.add(boundary); - } - - - /** - * Prepares a campaign boundary based on the provided index values, sorted column list, feature, and mapped values. - * - * @param indexOfType The index of the boundary type. - * @param indexValue The index value. - * @param sortedColumnList The sorted list of column names and indices. - * @param feature The JSON node representing the feature. - * @param boundary The boundary object to be prepared. - * @param mappedValues The map containing mapped values. - * @return The index of the boundary type after preparation. - */ - private Integer prepareBoundary(Integer indexOfType, Integer indexValue, - List> sortedColumnList, JsonNode feature, Boundary boundary,Map mappedValues) { - String codeValue = getBoundaryCodeValue(ServiceConstants.BOUNDARY_CODE, feature, mappedValues); - boundary.setCode(codeValue); - for (int j = 0; j < indexValue; j++) { - Map.Entry entry = sortedColumnList.get(j); - String value = String.valueOf(feature.get(PROPERTIES).get(entry.getKey())); - if (StringUtils.isNotBlank(value) && value.length() > 2) { - boundary.setType(entry.getKey()); - indexOfType = entry.getValue(); - } - } - if (indexOfType == 0) { - boundary.setRoot(true); - boundary.setIncludeAllChildren(true); - } - return indexOfType; - } - - /** - * Checks if the provided boundary is valid to add to the boundary list based on the result map. - * - * @param boundaryList The list of existing boundaries. - * @param resultMap The map containing result values. - * @param validToAdd The flag indicating whether the boundary is valid to add. - * @param boundary The boundary to be checked for validity. - * @return True if the boundary is valid to add, false otherwise. - */ - private boolean isValidToAdd(List boundaryList, Map resultMap, boolean validToAdd, - Boundary boundary) { - for (Entry entry : resultMap.entrySet()) { - if (entry.getValue().compareTo(new BigDecimal(0)) > 0) { - validToAdd = true; - } else { - validToAdd = false; - break; - } - } - return validToAdd; - } - - - - /** - * Retrieves the value of the boundary code from the feature JSON node based on the mapped values. - * - * @param input The input key. - * @param feature The JSON node representing the feature. - * @param mappedValues The map containing mapped values. - * @return The value of the boundary code. - * @throws CustomException If the input value is not found in the feature JSON node. - */ - private String getBoundaryCodeValue(String input, JsonNode feature, Map mappedValues) { - if (feature.get(PROPERTIES).get(mappedValues.get(input)) != null) { - String value = String.valueOf(feature.get(PROPERTIES).get(mappedValues.get(input))); - return ((value != null && value.length() > 2) ? value.substring(1, value.length() - 1) : value); - } else { - throw new CustomException("INPUT_VALUE_NOT_FOUND", "Input value not found: " + input); - } - } - - /** - * Updates campaign resources with the provided file store ID. - * - * @param fileStoreId The file store ID. - * @param campaignResourcesList The list of campaign resources to update. - */ - public void updateCampaignResources(String fileStoreId,List campaignResourcesList,String fileName) { - CampaignResources campaignResource = new CampaignResources(); - campaignResource.setFilename(fileName); - campaignResource.setFilestoreId(fileStoreId); - campaignResource.setType(ServiceConstants.FILE_TYPE); - campaignResourcesList.add(campaignResource); - - } - /** * Builds a campaign search request based on the provided plan configuration request. * 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 218df737916..2ca5b2c5c70 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 @@ -22,6 +22,7 @@ import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -246,8 +247,10 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR Plan planEstimate = planMap.get(boundaryCode); if (planEstimate != null) { - Map resourceTypeToEstimatedNumberMap = planEstimate.getResources().stream() - .collect(Collectors.toMap(Resource::getResourceType, Resource::getEstimatedNumber)); + Map resourceTypeToEstimatedNumberMap = new HashMap<>(); + planEstimate.getResources().forEach(resource -> + resourceTypeToEstimatedNumberMap.put(resource.getResourceType(), resource.getEstimatedNumber())); + // Iterate over each output column to update the row cells with resource values for (String resourceType : outputColumnList) { @@ -264,6 +267,17 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR } cell.setCellValue(estimatedValue.doubleValue()); } + } else { + // If estimatedValue is null, set the cell to empty + Integer columnIndex = mapOfColumnNameAndIndex.get(resourceType); + if (columnIndex != null) { + // Ensure the cell is empty + Cell cell = row.getCell(columnIndex); + if (cell == null) { + cell = row.createCell(columnIndex); + } + cell.setCellValue(EMPTY_STRING); // Set as empty string + } } } } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsV2Util.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsV2Util.java index 85b87872658..5430e0e55c6 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsV2Util.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsV2Util.java @@ -67,9 +67,10 @@ private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenan MdmsCriteriaV2 mdmsCriteriaV2 = MdmsCriteriaV2.builder() .tenantId(tenantId) .schemaCode(schemaCode) - .uniqueIdentifiers(Collections.singletonList(uniqueIdentifier)) - .limit(config.getDefaultLimit()) - .offset(config.getDefaultOffset()).build(); + .uniqueIdentifiers(uniqueIdentifier != null ? Collections.singletonList(uniqueIdentifier) : null) + .limit(config.getDefaultLimitForMdms()) + .offset(config.getDefaultOffsetForMdms()) + .build(); return MdmsCriteriaReqV2.builder() .requestInfo(requestInfo) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/MixedStartegyUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/MixedStartegyUtil.java new file mode 100644 index 00000000000..0bfc1c49b5f --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/MixedStartegyUtil.java @@ -0,0 +1,105 @@ +package org.egov.processor.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.egov.processor.web.models.Operation; +import org.egov.processor.web.models.PlanConfiguration; +import org.egov.processor.web.models.PlanConfigurationRequest; +import org.egov.processor.web.models.mdmsV2.Mdms; +import org.egov.processor.web.models.mdmsV2.MixedStrategyOperationLogic; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.math.BigDecimal; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.egov.processor.config.ServiceConstants.*; +import static org.egov.processor.config.ServiceConstants.MDMS_SCHEMA_ADMIN_SCHEMA; + +@Component +public class MixedStartegyUtil { + + private MdmsV2Util mdmsV2Util; + + private ParsingUtil parsingUtil; + + private ObjectMapper mapper; + + public MixedStartegyUtil(MdmsV2Util mdmsV2Util, ParsingUtil parsingUtil, ObjectMapper mapper) { + this.mdmsV2Util = mdmsV2Util; + this.parsingUtil = parsingUtil; + this.mapper = mapper; + } + + /** + * Fetches a list of MixedStrategyOperationLogic objects from MDMS based on the provided planConfigurationRequest. + * + * @param request The PlanConfigurationRequest containing the plan configuration and request info. + * @return A list of MixedStrategyOperationLogic objects fetched from MDMS. + */ + public List fetchMixedStrategyOperationLogicFromMDMS(PlanConfigurationRequest request) { + String rootTenantId = request.getPlanConfiguration().getTenantId().split("\\.")[0]; + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_MIXED_STRATEGY, null); + + return mdmsV2Data.stream() + .map(mdms -> mapper.convertValue(mdms.getData(), MixedStrategyOperationLogic.class)) + .collect(Collectors.toList()); + + } + + /** + * Retrieves a list of categories that are restricted based on the provided details. + * Returns an empty list if no match is found. + * + * @param isFixedPost A boolean indicating whether the mapped facility is fixed post. + * @param planConfiguration The plan configuration containing additional details. + * @param logicList A list of MixedStrategyOperationLogic objects to filter against. + * @return A list of categories not allowed to have output value or an empty list if no matching logic is found. + */ + public List getCategoriesNotAllowed(boolean isFixedPost, PlanConfiguration planConfiguration, List logicList) { + + return logicList.stream() + .filter(logic -> logic.isFixedPost() == isFixedPost && + logic.getRegistrationProcess().equalsIgnoreCase((String) parsingUtil.extractFieldsFromJsonObject(planConfiguration.getAdditionalDetails(), REGISTRATION_PROCESS)) && + logic.getDistributionProcess().equalsIgnoreCase((String) parsingUtil.extractFieldsFromJsonObject(planConfiguration.getAdditionalDetails(), DISTRIBUTION_PROCESS))) + .map(MixedStrategyOperationLogic::getCategoriesNotAllowed) + .findAny() // Returns any matching element since there is only one match + .orElse(List.of()); + + } + + /** + * Nullifies result values in the map for outputs belonging to the categories not allowed. + * Exits early if no restrictions are specified. + * + * @param resultMap A map containing output keys and their corresponding result values. + * @param operations A list of operations. + * @param categoriesNotAllowed A list of categories that are restricted and should not have associated outputs. + */ + public void processResultMap(Map resultMap, List operations, List categoriesNotAllowed) { + + // If all te categories are allowed, don't process further. + if(CollectionUtils.isEmpty(categoriesNotAllowed)) + return; + + // Map categories not allowed to its corresponding list of output keys + Map> categoryNotAllowedToOutputMap = operations.stream() + .filter(op -> op.getActive() && categoriesNotAllowed.contains(op.getCategory())) + .collect(Collectors.groupingBy( + Operation::getCategory, + Collectors.mapping(Operation::getOutput, Collectors.toList()))); + + + // Iterate through categories in the categoriesNotAllowed list and set their result values to null + for (String category : categoriesNotAllowed) { + List outputKeys = categoryNotAllowedToOutputMap.getOrDefault(category, Collections.emptyList()); + for (String outputKey : outputKeys) { + if (resultMap.containsKey(outputKey)) { + resultMap.put(outputKey, null); + } + } + } + } +} 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 8ec8f595bd6..f3b80492acb 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 @@ -64,7 +64,9 @@ public void processOutputFile(Workbook workbook, PlanConfigurationRequest reques } // 3. Adding facility information for each boundary code - addAssignedFacility(workbook, request, filestoreId); + for(Sheet sheet: workbook) { + addAssignedFacility(sheet, request, filestoreId); + } } @@ -117,11 +119,11 @@ public void processSheetForHeaderLocalization(Sheet sheet, LocaleResponse locale * 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 sheet the sheet 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) { + public void addAssignedFacility(Sheet sheet, PlanConfigurationRequest request, String fileStoreId) { LocaleResponse localeResponse = localeUtil.searchLocale(request); // Get the localized column header name for assigned facilities. @@ -141,16 +143,11 @@ public void addAssignedFacility(Workbook workbook, PlanConfigurationRequest requ )); // Create 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); + Map boundaryCodeToFacility = getBoundaryCodeToFacilityMap(sheet, request, fileStoreId); - if (isSheetAllowedToProcess(request, sheet.getSheetName(), localeResponse)) { - // Add facility names to the sheet. - addFacilityNameToSheet(sheet, assignedFacilityColHeader, boundaryCodeToFacility, mappedValues); - } + if (isSheetAllowedToProcess(request, sheet.getSheetName(), localeResponse)) { + // Add facility names to the sheet. + addFacilityNameToSheet(sheet, assignedFacilityColHeader, boundaryCodeToFacility, mappedValues); } } @@ -158,21 +155,18 @@ public void addAssignedFacility(Workbook workbook, PlanConfigurationRequest requ * 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 sheet the sheet to be processed. * @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. */ - public Map getBoundaryCodeToFacilityMap(Workbook workbook, PlanConfigurationRequest request, String fileStoreId) { + public Map getBoundaryCodeToFacilityMap(Sheet sheet, 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 (isSheetAllowedToProcess(request, sheet.getSheetName(), localeUtil.searchLocale(request))) { - // Extract boundary codes from the sheet. - boundaryCodes.addAll(enrichmentUtil.getBoundaryCodesFromTheSheet(sheet, request, fileStoreId)); - } + + if (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. diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Resource.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Resource.java index 693ba12ef32..c33fd233ec9 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Resource.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Resource.java @@ -29,7 +29,6 @@ public class Resource { private String resourceType = null; @JsonProperty("estimatedNumber") - @NotNull private BigDecimal estimatedNumber = null; @JsonProperty("activityCode") diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MixedStrategyOperationLogic.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MixedStrategyOperationLogic.java new file mode 100644 index 00000000000..d48f5077a75 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MixedStrategyOperationLogic.java @@ -0,0 +1,30 @@ +package org.egov.processor.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class MixedStrategyOperationLogic { + + @JsonProperty("isFixedPost") + private boolean isFixedPost; + + @JsonProperty("RegistrationProcess") + private String registrationProcess; + + @JsonProperty("DistributionProcess") + private String distributionProcess; + + @JsonProperty("CategoriesNotAllowed") + private List categoriesNotAllowed; +} diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index ce74288a820..f5f8ba1c4f1 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -98,8 +98,8 @@ plan.config.trigger.plan.facility.mappings.status=EXECUTION_TO_BE_DONE plan.config.update.plan.estimates.into.output.file.status=RESOURCE_ESTIMATIONS_APPROVED # Pagination config -resource.default.offset=0 -resource.default.limit=10 +default.offset.for.mdms.data=0 +default.limit.for.mdms.data=10 # Census egov.census.host=https://unified-dev.digit.org