From cd486281e8f78eb4166c7e3454f857bf7aed280e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 29 Aug 2024 16:50:43 +0530 Subject: [PATCH 001/351] Plan config name-implemented fuzzy search --- .../digit/repository/querybuilder/PlanConfigQueryBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 6dc4449b55f..74deaa36dac 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -105,8 +105,8 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter if (criteria.getName() != null) { addClauseIfRequired(preparedStmtList, builder); - builder.append(" pc.name = ?"); - preparedStmtList.add(criteria.getName()); + builder.append(" pc.name LIKE ?"); + preparedStmtList.add(criteria.getName() + '%'); } if (criteria.getStatus() != null) { From b4f561a3ae96ee5a1b87028d564b653ca8d8a028 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 30 Aug 2024 11:46:27 +0530 Subject: [PATCH 002/351] HCMPRE-172 adding additional details to plan configuration --- .../java/digit/config/ServiceConstants.java | 3 ++ .../validator/PlanConfigurationValidator.java | 29 ++++++++++++++++++- .../digit/web/models/PlanConfiguration.java | 3 ++ ...nfiguration_add_additional_details_ddl.sql | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 2266c82de93..743348aa25d 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -84,6 +84,7 @@ public class ServiceConstants { public static final String MDMS_MASTER_SCHEMAS = "Schemas"; public static final String MDMS_MASTER_METRIC = "Metric"; public static final String MDMS_MASTER_UOM = "Uom"; + public static final String MDMS = "mdms"; public static final String DOT_SEPARATOR = "."; @@ -110,4 +111,6 @@ public class ServiceConstants { public static final String MDMS_SCHEMA_PROPERTIES_IS_REQUIRED = "isRequired"; public static final String BOUNDARY_CODE = "boundaryCode"; + public static final String VEHICLE_IDS = "vehicleIds"; + } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 115c19855d8..ac36af9ea32 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -1,5 +1,6 @@ package digit.service.validator; +import com.fasterxml.jackson.databind.JsonNode; import com.jayway.jsonpath.JsonPath; import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; @@ -48,6 +49,7 @@ public void validateCreate(PlanConfigurationRequest request) { validateOperationsInputAgainstMDMS(request, mdmsData); validateResourceMappingAgainstMDMS(request, mdmsData); validateMappedToUniqueness(planConfiguration.getResourceMapping()); + validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsData); } /** @@ -81,7 +83,7 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; + final String jsonPathForAssumption = "$." + MDMS + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; List assumptionListFromMDMS = null; try { @@ -406,6 +408,31 @@ public static List getIsTruePropertyFromSchema(List schemas, Lis return new ArrayList<>(finalData); } + public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) + { + List vehicleIds = extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); + } + + public static List extractVehicleIdsFromAdditionalDetails(Object additionalDetails) { + try { + String jsonString = objectMapper.writeValueAsString(additionalDetails); + JsonNode rootNode = objectMapper.readTree(jsonString); + + List vehicleIds = new ArrayList<>(); + JsonNode vehicleIdsNode = rootNode.get(VEHICLE_IDS); + if (vehicleIdsNode != null && vehicleIdsNode.isArray()) { + for (JsonNode idNode : vehicleIdsNode) { + vehicleIds.add(idNode.asText()); + } + } + + return vehicleIds; + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + } + public void validateFilesActive(PlanConfiguration planConfigurationFromDB, PlanConfiguration planConfiguration) { // Create a map of files from planConfigurationFromDB using the file ID as the key diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index dbf9ed7f139..11f43e194f7 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -79,6 +79,9 @@ public class PlanConfiguration { @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + /** * The status used in the Plan Configuration */ diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql new file mode 100644 index 00000000000..3437a0862d4 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE plan_configuration ADD additional_details JSONB; From 1dc3c4346bb7a254e8bde515ddb0f32d68492145 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 2 Sep 2024 12:31:47 +0530 Subject: [PATCH 003/351] added vehicleId validation for plan config --- .../main/java/digit/config/Configuration.java | 2 + .../java/digit/config/ServiceConstants.java | 5 ++ .../validator/PlanConfigurationValidator.java | 41 ++++++++-- .../src/main/java/digit/util/MdmsV2Util.java | 76 +++++++++++++++++++ .../web/models/mdmsV2/MdmsV2Criteria.java | 62 +++++++++++++++ .../web/models/mdmsV2/MdmsV2CriteriaReq.java | 23 ++++++ .../src/main/resources/application.properties | 1 + 7 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2Criteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaReq.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 7cf4b3549f7..03ea5c05d16 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -28,6 +28,8 @@ public class Configuration { @Value("${egov.mdms.search.endpoint}") private String mdmsEndPoint; + @Value("${egov.mdms.search.v2.endpoint}") + private String mdmsV2EndPoint; //Persister Topic @Value("${plan.configuration.create.topic}") diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 743348aa25d..69dbfee0339 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -28,6 +28,9 @@ public class ServiceConstants { public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE = "ASSUMPTION_KEY_NOT_FOUND_IN_MDMS"; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS"; + public static final String VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE = "VEHICLE_ID_NOT_FOUND_IN_MDMS"; + public static final String VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE = "Vehicle Id is not present in MDMS"; + public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_CODE = "TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS"; public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE = "Template Identifier is not present in MDMS"; @@ -113,4 +116,6 @@ public class ServiceConstants { public static final String VEHICLE_IDS = "vehicleIds"; + public static final String SCHEMA_CODE_VEHICLE = "hcm-microplanning.VehicleDetails"; + } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index ac36af9ea32..430ee94f9f6 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -1,10 +1,12 @@ package digit.service.validator; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; import digit.util.MdmsUtil; +import digit.util.MdmsV2Util; import digit.web.models.*; import java.util.*; @@ -14,6 +16,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -26,11 +29,18 @@ public class PlanConfigurationValidator { private MdmsUtil mdmsUtil; + private MdmsV2Util mdmsV2Util; + private PlanConfigurationRepository planConfigRepository; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository) { + private ObjectMapper objectMapper; + + @Autowired + public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, ObjectMapper objectMapper) { this.mdmsUtil = mdmsUtil; + this.mdmsV2Util = mdmsV2Util; this.planConfigRepository = planConfigRepository; + this.objectMapper = objectMapper; } /** @@ -41,6 +51,7 @@ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, SCHEMA_CODE_VEHICLE); validateAssumptionKeyAgainstMDMS(request, mdmsData); validateAssumptionValue(planConfiguration); @@ -49,7 +60,7 @@ public void validateCreate(PlanConfigurationRequest request) { validateOperationsInputAgainstMDMS(request, mdmsData); validateResourceMappingAgainstMDMS(request, mdmsData); validateMappedToUniqueness(planConfiguration.getResourceMapping()); - validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsData); + validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); } /** @@ -83,7 +94,7 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = "$." + MDMS + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; + final String jsonPathForAssumption = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; List assumptionListFromMDMS = null; try { @@ -408,12 +419,32 @@ public static List getIsTruePropertyFromSchema(List schemas, Lis return new ArrayList<>(finalData); } - public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) + public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, Object mdmsV2Data) { List vehicleIds = extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); + + String jsonPathForVehicleIds = "$." + MDMS + DOT_SEPARATOR + "*.id"; + + List vehicleIdsFromMdms = null; + try { + log.info(jsonPathForVehicleIds); + vehicleIdsFromMdms = JsonPath.read(mdmsV2Data, jsonPathForVehicleIds); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + for(String vehicleId : vehicleIds) + { + if(!vehicleIdsFromMdms.contains(vehicleId)) + { + log.error(" Vehicle Id " + vehicleId + " is not present in MDMS"); + throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForVehicleIds); + } + } } - public static List extractVehicleIdsFromAdditionalDetails(Object additionalDetails) { + public List extractVehicleIdsFromAdditionalDetails(Object additionalDetails) { try { String jsonString = objectMapper.writeValueAsString(additionalDetails); JsonNode rootNode = objectMapper.readTree(jsonString); diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java new file mode 100644 index 00000000000..25e1864e51a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -0,0 +1,76 @@ +package digit.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.config.Configuration; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import org.springframework.web.client.RestTemplate; +import digit.web.models.mdmsV2.*; + +import java.util.*; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class MdmsV2Util { + + private RestTemplate restTemplate; + + private ObjectMapper objectMapper; + + private Configuration configs; + + @Autowired + public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configuration configs) + { + this.restTemplate = restTemplate; + this.objectMapper = objectMapper; + this.configs = configs; + } + + public Object fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode) + { + StringBuilder uri = getMdmsV2Uri(); + MdmsV2CriteriaReq mdmsV2CriteriaReq = getMdmsV2Request(requestInfo, tenantId, schemaCode); + Object mdmsResponseMap = new HashMap<>(); + try{ + mdmsResponseMap = restTemplate.postForObject(uri.toString(), mdmsV2CriteriaReq, Map.class); + } catch (Exception e) + { + log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); + } + + if(mdmsResponseMap == null || ObjectUtils.isEmpty(mdmsResponseMap)) + { + log.error(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE + " - " + tenantId); + throw new CustomException(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE, NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE); + } + + return mdmsResponseMap; + } + + private StringBuilder getMdmsV2Uri() + { + StringBuilder uri = new StringBuilder(); + return uri.append(configs.getMdmsHost()).append(configs.getMdmsV2EndPoint()); + } + + private MdmsV2CriteriaReq getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode) + { + MdmsV2Criteria mdmsV2Criteria = MdmsV2Criteria.builder() + .tenantId(tenantId) + .schemaCode(schemaCode) + .limit(configs.getDefaultLimit()) + .offset(configs.getDefaultOffset()).build(); + + return MdmsV2CriteriaReq.builder() + .requestInfo(requestInfo) + .mdmsV2Criteria(mdmsV2Criteria).build(); + } + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2Criteria.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2Criteria.java new file mode 100644 index 00000000000..b1ab701ed45 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2Criteria.java @@ -0,0 +1,62 @@ +package digit.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +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 javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Data +@Validated +@AllArgsConstructor +@NoArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class MdmsV2Criteria { + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + @NotNull + private String tenantId; + + @JsonProperty("ids") + private Set ids; + + @JsonProperty("uniqueIdentifier") + @Size(min = 1, max = 64) + private String uniqueIdentifier; + + @JsonProperty("uniqueIdentifiers") + private List uniqueIdentifiers; + + @JsonProperty("schemaCode") + private String schemaCode; + + @JsonProperty("filters") + private Map filterMap; + + @JsonProperty("isActive") + private Boolean isActive; + + @JsonIgnore + private Map schemaCodeFilterMap; + + @JsonIgnore + private Set uniqueIdentifiersForRefVerification; + + @JsonProperty("offset") + private Integer offset; + + @JsonProperty("limit") + private Integer limit; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaReq.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaReq.java new file mode 100644 index 00000000000..c0264560928 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaReq.java @@ -0,0 +1,23 @@ +package digit.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class MdmsV2CriteriaReq { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo; + + @JsonProperty("MdmsCriteria") + @Valid + private MdmsV2Criteria mdmsV2Criteria; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 03ee3da916d..25456401843 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -52,6 +52,7 @@ plan.update.topic=update-plan #mdms urls egov.mdms.host=https://unified-dev.digit.org egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search # Pagination config plan.default.offset=0 From 9cbf836fb6b1fb329687ab3181374f82dac1c01c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 2 Sep 2024 16:21:30 +0530 Subject: [PATCH 004/351] Validation for vehicleId in plan config update --- .../digit/service/validator/PlanConfigurationValidator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 430ee94f9f6..5f257553181 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -295,6 +295,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, SCHEMA_CODE_VEHICLE); // Validate plan existence PlanConfiguration planConfigurationFromDB = validatePlanConfigExistence(request); @@ -308,7 +309,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { validateOperationDependencies(planConfiguration); validateResourceMappingAgainstMDMS(request, mdmsData); validateMappedToUniqueness(planConfiguration.getResourceMapping()); - + validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); } /** From 623d0969503c0909fb3c2e1393eea79582e9b334 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 3 Sep 2024 11:43:09 +0530 Subject: [PATCH 005/351] chnaged mdms constant name --- .../src/main/java/digit/config/ServiceConstants.java | 2 +- .../digit/service/validator/PlanConfigurationValidator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 69dbfee0339..a3c2964191b 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -87,7 +87,7 @@ public class ServiceConstants { public static final String MDMS_MASTER_SCHEMAS = "Schemas"; public static final String MDMS_MASTER_METRIC = "Metric"; public static final String MDMS_MASTER_UOM = "Uom"; - public static final String MDMS = "mdms"; + public static final String MDMS_CODE = "mdms"; public static final String DOT_SEPARATOR = "."; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 5f257553181..73fca185531 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -424,7 +424,7 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration { List vehicleIds = extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); - String jsonPathForVehicleIds = "$." + MDMS + DOT_SEPARATOR + "*.id"; + String jsonPathForVehicleIds = "$." + MDMS_CODE + DOT_SEPARATOR + "*.id"; List vehicleIdsFromMdms = null; try { From cbc5ec88b6aa65c7a04cdebb5c204cb564bc9417 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 3 Sep 2024 17:55:34 +0530 Subject: [PATCH 006/351] resolved comments --- .../java/digit/config/ServiceConstants.java | 8 +++-- .../validator/PlanConfigurationValidator.java | 30 +++++++++++-------- .../src/main/java/digit/util/MdmsV2Util.java | 1 - 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index a3c2964191b..062ffae51aa 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -97,6 +97,8 @@ public class ServiceConstants { public static final String FILTER_ID = "$.*.id"; + public static final String GET_ALL_IDS = "*.id"; + public static final String FILTER_DATA = "$.*.data"; public static final String LOCALITY_CODE = "Locality"; @@ -112,10 +114,10 @@ public class ServiceConstants { public static final String MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT = "isRuleConfigureInputs"; public static final String MDMS_SCHEMA_PROPERTIES_IS_REQUIRED = "isRequired"; - public static final String BOUNDARY_CODE = "boundaryCode"; - public static final String VEHICLE_IDS = "vehicleIds"; + public static final String MDMS_SCHEMA_VEHICLE = "VehicleDetails"; - public static final String SCHEMA_CODE_VEHICLE = "hcm-microplanning.VehicleDetails"; + public static final String BOUNDARY_CODE = "boundaryCode"; + public static final String VEHICLE_ID_FIELD = "vehicleIds"; } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 73fca185531..7e6c5f6839b 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -35,7 +35,6 @@ public class PlanConfigurationValidator { private ObjectMapper objectMapper; - @Autowired public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, ObjectMapper objectMapper) { this.mdmsUtil = mdmsUtil; this.mdmsV2Util = mdmsV2Util; @@ -51,7 +50,7 @@ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, SCHEMA_CODE_VEHICLE); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE); validateAssumptionKeyAgainstMDMS(request, mdmsData); validateAssumptionValue(planConfiguration); @@ -295,7 +294,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, SCHEMA_CODE_VEHICLE); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE); // Validate plan existence PlanConfiguration planConfigurationFromDB = validatePlanConfigExistence(request); @@ -420,11 +419,16 @@ public static List getIsTruePropertyFromSchema(List schemas, Lis return new ArrayList<>(finalData); } + /** + * Validates Vehicle ids from additional details against MDMS V2 + * @param request plan configuration request + * @param mdmsV2Data mdms v2 data object + */ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, Object mdmsV2Data) { List vehicleIds = extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); - String jsonPathForVehicleIds = "$." + MDMS_CODE + DOT_SEPARATOR + "*.id"; + String jsonPathForVehicleIds = "$." + MDMS_CODE + DOT_SEPARATOR + GET_ALL_IDS; List vehicleIdsFromMdms = null; try { @@ -435,14 +439,14 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - for(String vehicleId : vehicleIds) - { - if(!vehicleIdsFromMdms.contains(vehicleId)) - { - log.error(" Vehicle Id " + vehicleId + " is not present in MDMS"); - throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForVehicleIds); - } - } + + List finalVehicleIdsFromMdms = vehicleIdsFromMdms; + vehicleIds.stream() + .filter(vehicleId -> !finalVehicleIdsFromMdms.contains(vehicleId)) + .forEach(vehicleId -> { + log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); + throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForVehicleIds); + }); } public List extractVehicleIdsFromAdditionalDetails(Object additionalDetails) { @@ -451,7 +455,7 @@ public List extractVehicleIdsFromAdditionalDetails(Object additionalDeta JsonNode rootNode = objectMapper.readTree(jsonString); List vehicleIds = new ArrayList<>(); - JsonNode vehicleIdsNode = rootNode.get(VEHICLE_IDS); + JsonNode vehicleIdsNode = rootNode.get(VEHICLE_ID_FIELD); if (vehicleIdsNode != null && vehicleIdsNode.isArray()) { for (JsonNode idNode : vehicleIdsNode) { vehicleIds.add(idNode.asText()); diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index 25e1864e51a..db42bf5c512 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -25,7 +25,6 @@ public class MdmsV2Util { private Configuration configs; - @Autowired public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configuration configs) { this.restTemplate = restTemplate; From 1bb8b78c708a288705407211439230eedec99de1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 4 Sep 2024 12:31:53 +0530 Subject: [PATCH 007/351] Added comments for validateVehicleIds function --- .../digit/service/validator/PlanConfigurationValidator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 7e6c5f6839b..ac3f804346d 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -59,6 +59,8 @@ public void validateCreate(PlanConfigurationRequest request) { validateOperationsInputAgainstMDMS(request, mdmsData); validateResourceMappingAgainstMDMS(request, mdmsData); validateMappedToUniqueness(planConfiguration.getResourceMapping()); + + // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); } @@ -308,6 +310,8 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { validateOperationDependencies(planConfiguration); validateResourceMappingAgainstMDMS(request, mdmsData); validateMappedToUniqueness(planConfiguration.getResourceMapping()); + + // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); } From 17749d39f2f4c3a8bf114167f1a0c359062189c0 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 4 Sep 2024 14:01:51 +0530 Subject: [PATCH 008/351] renamed service constants --- .../java/digit/config/ServiceConstants.java | 4 ++-- .../validator/PlanConfigurationValidator.java | 17 ++++++++--------- .../src/main/java/digit/util/MdmsV2Util.java | 3 +-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 062ffae51aa..2f1b62a0ba8 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -97,7 +97,7 @@ public class ServiceConstants { public static final String FILTER_ID = "$.*.id"; - public static final String GET_ALL_IDS = "*.id"; + public static final String FILTER_TO_GET_ALL_IDS = "*.id"; public static final String FILTER_DATA = "$.*.data"; @@ -115,7 +115,7 @@ public class ServiceConstants { public static final String MDMS_SCHEMA_PROPERTIES_IS_REQUIRED = "isRequired"; - public static final String MDMS_SCHEMA_VEHICLE = "VehicleDetails"; + public static final String MDMS_SCHEMA_VEHICLE_DETAILS = "VehicleDetails"; public static final String BOUNDARY_CODE = "boundaryCode"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index ac3f804346d..16d81d187fb 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -11,12 +11,10 @@ import java.util.*; import java.util.stream.Collectors; -import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -26,7 +24,6 @@ @Slf4j public class PlanConfigurationValidator { - private MdmsUtil mdmsUtil; private MdmsV2Util mdmsV2Util; @@ -50,7 +47,7 @@ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); validateAssumptionKeyAgainstMDMS(request, mdmsData); validateAssumptionValue(planConfiguration); @@ -296,7 +293,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); // Validate plan existence PlanConfiguration planConfigurationFromDB = validatePlanConfigExistence(request); @@ -432,7 +429,7 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration { List vehicleIds = extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); - String jsonPathForVehicleIds = "$." + MDMS_CODE + DOT_SEPARATOR + GET_ALL_IDS; + String jsonPathForVehicleIds = "$." + MDMS_CODE + DOT_SEPARATOR + FILTER_TO_GET_ALL_IDS; List vehicleIdsFromMdms = null; try { @@ -446,10 +443,12 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration List finalVehicleIdsFromMdms = vehicleIdsFromMdms; vehicleIds.stream() - .filter(vehicleId -> !finalVehicleIdsFromMdms.contains(vehicleId)) .forEach(vehicleId -> { - log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); - throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForVehicleIds); + if(!finalVehicleIdsFromMdms.contains(vehicleId)) + { + log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); + throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForVehicleIds); + } }); } diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index db42bf5c512..5c4196f0d24 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import org.springframework.web.client.RestTemplate; @@ -44,7 +43,7 @@ public Object fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String s log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); } - if(mdmsResponseMap == null || ObjectUtils.isEmpty(mdmsResponseMap)) + if(ObjectUtils.isEmpty(mdmsResponseMap)) { log.error(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE + " - " + tenantId); throw new CustomException(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE, NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE); From c795b57ff5250019986a858d16f9de1acc156bfd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 9 Sep 2024 15:04:51 +0530 Subject: [PATCH 009/351] changed json path for HypothesisAssumption --- .../src/main/java/digit/config/ServiceConstants.java | 2 +- .../digit/service/validator/PlanConfigurationValidator.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 0c67eb2ea0a..a33d542b44b 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -133,7 +133,7 @@ public class ServiceConstants { //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; - public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions"; + public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumption"; public static final String MDMS_MASTER_UPLOAD_CONFIGURATION = "UploadConfiguration"; public static final String MDMS_MASTER_RULE_CONFIGURE_INPUTS = "RuleConfigureInputs"; public static final String MDMS_MASTER_SCHEMAS = "Schemas"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 04b07bddcd6..0726dc1946d 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -1,7 +1,5 @@ package digit.service.validator; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; @@ -152,7 +150,7 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; + final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptionCategories[*].assumptions[*]"; List assumptionListFromMDMS = null; try { From b5ea674895565da25f3fec009fd053cd7cd1fff6 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 9 Sep 2024 16:47:06 +0530 Subject: [PATCH 010/351] Changed the name of master --- .../src/main/java/digit/config/ServiceConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index a33d542b44b..0c67eb2ea0a 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -133,7 +133,7 @@ public class ServiceConstants { //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; - public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumption"; + public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions"; public static final String MDMS_MASTER_UPLOAD_CONFIGURATION = "UploadConfiguration"; public static final String MDMS_MASTER_RULE_CONFIGURE_INPUTS = "RuleConfigureInputs"; public static final String MDMS_MASTER_SCHEMAS = "Schemas"; From 5310d515dcdd020d1d4947a6003dd0b7741dd153 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 9 Sep 2024 17:28:52 +0530 Subject: [PATCH 011/351] added filter_all_assumptions constant --- .../src/main/java/digit/config/ServiceConstants.java | 2 ++ .../digit/service/validator/PlanConfigurationValidator.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 0c67eb2ea0a..1528951de9c 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -174,6 +174,8 @@ public class ServiceConstants { public static final String BOUNDARY_CODE = "boundaryCode"; + public static final String FILTER_ALL_ASSUMPTIONS = "[*].assumptionCategories[*].assumptions[*]"; + public static final String NAME_VALIDATION_DATA = "Data"; public static final String VEHICLE_ID_FIELD = "vehicleIds"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 0726dc1946d..13e17188953 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -150,7 +150,7 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptionCategories[*].assumptions[*]"; + final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + FILTER_ALL_ASSUMPTIONS; List assumptionListFromMDMS = null; try { From e12af11e1c00a129bc7335ca70985f287579cb9c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 10 Sep 2024 12:10:43 +0530 Subject: [PATCH 012/351] added null and empty checks on functions --- .../java/digit/config/ServiceConstants.java | 12 + .../service/enrichment/EnrichmentService.java | 137 ++++--- .../validator/PlanConfigurationValidator.java | 364 +++++++++++------- .../digit/web/models/PlanConfiguration.java | 12 +- 4 files changed, 324 insertions(+), 201 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 2266c82de93..e703a10e4b6 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -76,6 +76,18 @@ public class ServiceConstants { public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE = "BOUNDARY_CODE_MAPPING_NOT_FOUND"; public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE = "Boundary Code Mapping is required column is not found."; + public static final String FILES_NOT_FOUND_CODE = "FILES_NOT_FOUND"; + public static final String FILES_NOT_FOUND_MESSAGE = "Files are not present in Plan Configuration."; + + public static final String RESOURCE_MAPPING_NOT_FOUND_CODE = "RESOURCE_MAPPING_NOT_FOUND"; + public static final String RESOURCE_MAPPING_NOT_FOUND_MESSAGE = "Resource mapping is not present in Plan Configuration."; + + public static final String ASSUMPTIONS_NOT_FOUND_CODE = "ASSUMPTIONS_NOT_FOUND"; + public static final String ASSUMPTIONS_NOT_FOUND_MESSAGE = "Assumptions are not present in Plan Configuration."; + + public static final String OPERATIONS_NOT_FOUND_CODE = "OPERATIONS_NOT_FOUND"; + public static final String OPERATIONS_NOT_FOUND_MESSAGE = "Operations are not present in Plan Configuration."; + //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions"; diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index 787e5ce2766..8b4a37cdb89 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java @@ -14,6 +14,8 @@ import java.util.List; import static digit.config.ServiceConstants.USERINFO_MISSING_CODE; import static digit.config.ServiceConstants.USERINFO_MISSING_MESSAGE; + +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @Component @@ -50,20 +52,33 @@ public void enrichPlanConfiguration(PlanConfiguration planConfiguration) { UUIDEnrichmentUtil.enrichRandomUuid(planConfiguration, "id"); // Generate id for files - planConfiguration.getFiles().forEach(file -> { - UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); - enrichActiveForResourceMapping(file, planConfiguration.getResourceMapping()); - }); - + if(!CollectionUtils.isEmpty(planConfiguration.getFiles())) + { + planConfiguration.getFiles().forEach(file -> { + UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); + enrichActiveForResourceMapping(file, planConfiguration.getResourceMapping()); + }); + } // Generate id for assumptions - planConfiguration.getAssumptions().forEach(assumption -> UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id")); + if(!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) + { + planConfiguration.getAssumptions().forEach(assumption -> UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id")); + } + // Generate id for operations - planConfiguration.getOperations().forEach(operation -> UUIDEnrichmentUtil.enrichRandomUuid(operation, "id")); + if(!CollectionUtils.isEmpty(planConfiguration.getOperations())) + { + planConfiguration.getOperations().forEach(operation -> UUIDEnrichmentUtil.enrichRandomUuid(operation, "id")); + } // Generate id for resource mappings - planConfiguration.getResourceMapping().forEach(resourceMapping -> UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id")); + if(!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) + { + planConfiguration.getResourceMapping().forEach(resourceMapping -> UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id")); + } + } /** @@ -99,33 +114,45 @@ public void enrichPlanConfigurationForUpdate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); // For Files - planConfiguration.getFiles().forEach(file -> { - if (ObjectUtils.isEmpty(file.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); - } - enrichActiveForResourceMapping(file, request.getPlanConfiguration().getResourceMapping()); - }); + if(!CollectionUtils.isEmpty(planConfiguration.getFiles())) + { + planConfiguration.getFiles().forEach(file -> { + if (ObjectUtils.isEmpty(file.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); + } + enrichActiveForResourceMapping(file, request.getPlanConfiguration().getResourceMapping()); + }); + } // For Assumptions - planConfiguration.getAssumptions().forEach(assumption -> { - if (ObjectUtils.isEmpty(assumption.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id"); - } - }); + if(!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) + { + planConfiguration.getAssumptions().forEach(assumption -> { + if (ObjectUtils.isEmpty(assumption.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id"); + } + }); + } // For Operations - planConfiguration.getOperations().forEach(operation -> { - if (ObjectUtils.isEmpty(operation.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(operation, "id"); - } - }); + if(!CollectionUtils.isEmpty(planConfiguration.getOperations())) + { + planConfiguration.getOperations().forEach(operation -> { + if (ObjectUtils.isEmpty(operation.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(operation, "id"); + } + }); + } // For ResourceMappings - planConfiguration.getResourceMapping().forEach(resourceMapping -> { - if (ObjectUtils.isEmpty(resourceMapping.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); - } - }); + if(!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) + { + planConfiguration.getResourceMapping().forEach(resourceMapping -> { + if (ObjectUtils.isEmpty(resourceMapping.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); + } + }); + } } @@ -158,29 +185,41 @@ public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest req PlanConfiguration planConfiguration = request.getPlanConfiguration(); // For Files, Operations, Assumptions and Resource Mappings override active to be True - planConfiguration.getFiles().forEach(file -> { - if (ObjectUtils.isEmpty(file.getId())) { - file.setActive(Boolean.TRUE); - } - }); + if(!CollectionUtils.isEmpty(planConfiguration.getFiles())) + { + planConfiguration.getFiles().forEach(file -> { + if (ObjectUtils.isEmpty(file.getId())) { + file.setActive(Boolean.TRUE); + } + }); + } - planConfiguration.getOperations().forEach(operation -> { - if (ObjectUtils.isEmpty(operation.getId())) { - operation.setActive(Boolean.TRUE); - } - }); + if(!CollectionUtils.isEmpty(planConfiguration.getOperations())) + { + planConfiguration.getOperations().forEach(operation -> { + if (ObjectUtils.isEmpty(operation.getId())) { + operation.setActive(Boolean.TRUE); + } + }); + } - planConfiguration.getAssumptions().forEach(assumption -> { - if (ObjectUtils.isEmpty(assumption.getId())) { - assumption.setActive(Boolean.TRUE); - } - }); + if(!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) + { + planConfiguration.getAssumptions().forEach(assumption -> { + if (ObjectUtils.isEmpty(assumption.getId())) { + assumption.setActive(Boolean.TRUE); + } + }); + } - planConfiguration.getResourceMapping().forEach(resourceMapping -> { - if (ObjectUtils.isEmpty(resourceMapping.getId())) { - resourceMapping.setActive(Boolean.TRUE); - } - }); + if(!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) + { + planConfiguration.getResourceMapping().forEach(resourceMapping -> { + if (ObjectUtils.isEmpty(resourceMapping.getId())) { + resourceMapping.setActive(Boolean.TRUE); + } + }); + } } } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 115c19855d8..e4a9414dca7 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -57,18 +57,24 @@ public void validateCreate(PlanConfigurationRequest request) { * @param planConfiguration The plan configuration to validate. */ public void validateAssumptionValue(PlanConfiguration planConfiguration) { - // Collect all active assumption keys - Set activeAssumptionKeys = planConfiguration.getAssumptions().stream() - .filter(Assumption::getActive) - .map(Assumption::getKey) - .collect(Collectors.toSet()); - - List operations = planConfiguration.getOperations(); - for (Operation operation : operations) { - // Check if the operation is using an assumption key that is not in the set of active assumption keys - if (operation.getActive() && !activeAssumptionKeys.contains(operation.getAssumptionValue())) { - log.error("Assumption Value " + operation.getAssumptionValue() + " is not present in the list of active Assumption Keys"); - throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + operation.getAssumptionValue()); + if(isSetupCompleted(planConfiguration)) + { + checkForEmptyAssumption(planConfiguration); + checkForEmptyOperation(planConfiguration); + + // Collect all active assumption keys + Set activeAssumptionKeys = planConfiguration.getAssumptions().stream() + .filter(Assumption::getActive) + .map(Assumption::getKey) + .collect(Collectors.toSet()); + + List operations = planConfiguration.getOperations(); + for (Operation operation : operations) { + // Check if the operation is using an assumption key that is not in the set of active assumption keys + if (operation.getActive() && !activeAssumptionKeys.contains(operation.getAssumptionValue())) { + log.error("Assumption Value " + operation.getAssumptionValue() + " is not present in the list of active Assumption Keys"); + throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + operation.getAssumptionValue()); + } } } } @@ -81,23 +87,26 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; - - List assumptionListFromMDMS = null; - try { - log.info(jsonPathForAssumption); - assumptionListFromMDMS = JsonPath.read(mdmsData, jsonPathForAssumption); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - for(Assumption assumption : planConfiguration.getAssumptions()) + if(!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { - if(!assumptionListFromMDMS.contains(assumption.getKey())) + final String jsonPathForAssumption = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; + + List assumptionListFromMDMS = null; + try { + log.info(jsonPathForAssumption); + assumptionListFromMDMS = JsonPath.read(mdmsData, jsonPathForAssumption); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + for(Assumption assumption : planConfiguration.getAssumptions()) { - log.error("Assumption Key " + assumption.getKey() + " is not present in MDMS"); - throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); + if(!assumptionListFromMDMS.contains(assumption.getKey())) + { + log.error("Assumption Key " + assumption.getKey() + " is not present in MDMS"); + throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); + } } } } @@ -107,15 +116,21 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O * @param planConfiguration The PlanConfiguration to validate. */ public void validateFilestoreId(PlanConfiguration planConfiguration) { - Set fileStoreIds = planConfiguration.getFiles().stream() - .map(File::getFilestoreId) - .collect(Collectors.toSet()); - - List resourceMappingList = planConfiguration.getResourceMapping(); - for (ResourceMapping mapping : resourceMappingList) { - if (!fileStoreIds.contains(mapping.getFilestoreId())) { - log.error("Resource Mapping " + mapping.getMappedTo() + " does not have valid fileStoreId " + mapping.getFilestoreId()); - throw new CustomException(FILESTORE_ID_INVALID_CODE, FILESTORE_ID_INVALID_MESSAGE); + if(isSetupCompleted(planConfiguration)) + { + checkForEmptyFiles(planConfiguration); + checkForEmptyResourceMapping(planConfiguration); + + Set fileStoreIds = planConfiguration.getFiles().stream() + .map(File::getFilestoreId) + .collect(Collectors.toSet()); + + List resourceMappingList = planConfiguration.getResourceMapping(); + for (ResourceMapping mapping : resourceMappingList) { + if (!fileStoreIds.contains(mapping.getFilestoreId())) { + log.error("Resource Mapping " + mapping.getMappedTo() + " does not have valid fileStoreId " + mapping.getFilestoreId()); + throw new CustomException(FILESTORE_ID_INVALID_CODE, FILESTORE_ID_INVALID_MESSAGE); + } } } } @@ -129,49 +144,51 @@ public void validateFilestoreId(PlanConfiguration planConfiguration) { */ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForTemplateIdentifier = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + ".*.id"; - final String jsonPathForTemplateIdentifierIsRequired = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + "[?(@.required == true)].id"; - - List templateIdentifierListFromMDMS = null; - List requiredTemplateIdentifierFromMDMS = null; - Set activeRequiredTemplates = new HashSet<>(); - - try { - log.info(jsonPathForTemplateIdentifier); - templateIdentifierListFromMDMS = JsonPath.read(mdmsData, jsonPathForTemplateIdentifier); - requiredTemplateIdentifierFromMDMS = JsonPath.read(mdmsData, jsonPathForTemplateIdentifierIsRequired); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - for(File file : planConfiguration.getFiles()) + if(!CollectionUtils.isEmpty(planConfiguration.getFiles())) { - if(!templateIdentifierListFromMDMS.contains(file.getTemplateIdentifier())) - { - log.error("Template Identifier " + file.getTemplateIdentifier() + " is not present in MDMS"); - throw new CustomException(TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_CODE, TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE); + final String jsonPathForTemplateIdentifier = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + ".*.id"; + final String jsonPathForTemplateIdentifierIsRequired = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + "[?(@.required == true)].id"; + + List templateIdentifierListFromMDMS = null; + List requiredTemplateIdentifierFromMDMS = null; + Set activeRequiredTemplates = new HashSet<>(); + + try { + log.info(jsonPathForTemplateIdentifier); + templateIdentifierListFromMDMS = JsonPath.read(mdmsData, jsonPathForTemplateIdentifier); + requiredTemplateIdentifierFromMDMS = JsonPath.read(mdmsData, jsonPathForTemplateIdentifierIsRequired); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - if (file.getActive()) { // Check if the file is active - String templateIdentifier = file.getTemplateIdentifier(); - if (requiredTemplateIdentifierFromMDMS.contains(templateIdentifier)) { // Check if the template identifier is required - if (!activeRequiredTemplates.add(templateIdentifier)) { // Ensure only one active file per required template identifier - log.error("Only one file with the required Template Identifier should be present " + file.getTemplateIdentifier()); - throw new CustomException(ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_CODE, ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE); + for(File file : planConfiguration.getFiles()) + { + if(!templateIdentifierListFromMDMS.contains(file.getTemplateIdentifier())) + { + log.error("Template Identifier " + file.getTemplateIdentifier() + " is not present in MDMS"); + throw new CustomException(TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_CODE, TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE); + } + + if (file.getActive()) { // Check if the file is active + String templateIdentifier = file.getTemplateIdentifier(); + if (requiredTemplateIdentifierFromMDMS.contains(templateIdentifier)) { // Check if the template identifier is required + if (!activeRequiredTemplates.add(templateIdentifier)) { // Ensure only one active file per required template identifier + log.error("Only one file with the required Template Identifier should be present " + file.getTemplateIdentifier()); + throw new CustomException(ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_CODE, ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE); + } } } } - } - // Ensure at least one active file for each required template identifier - for (Object requiredTemplate : requiredTemplateIdentifierFromMDMS) { - if (!activeRequiredTemplates.contains(requiredTemplate)) { - log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); - throw new CustomException(REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE, REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE); + // Ensure at least one active file for each required template identifier + for (Object requiredTemplate : requiredTemplateIdentifierFromMDMS) { + if (!activeRequiredTemplates.contains(requiredTemplate)) { + log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); + throw new CustomException(REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE, REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE); + } } } - } @@ -183,32 +200,39 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque */ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - List files = planConfiguration.getFiles(); - List templateIds = files.stream() - .map(File::getTemplateIdentifier) - .collect(Collectors.toList()); - List inputFileTypes = files.stream() - .map(File::getInputFileType) - .map(File.InputFileTypeEnum::toString) - .collect(Collectors.toList()); - - final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS; - List ruleInputsListFromMDMS = null; - try { - log.info(jsonPathForRuleInputs); - ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - List allowedColumns = getRuleConfigInputsFromSchema(ruleInputsListFromMDMS, templateIds, inputFileTypes); - planConfiguration.getOperations().stream() - .map(Operation::getOutput) - .forEach(allowedColumns::add); - for (Operation operation : planConfiguration.getOperations()) { - if (!allowedColumns.contains(operation.getInput())) { - log.error("Input Value " + operation.getInput() + " is not present in MDMS Input List"); - throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE); + + if(isSetupCompleted(planConfiguration)) + { + checkForEmptyFiles(planConfiguration); + checkForEmptyOperation(planConfiguration); + + List files = planConfiguration.getFiles(); + List templateIds = files.stream() + .map(File::getTemplateIdentifier) + .collect(Collectors.toList()); + List inputFileTypes = files.stream() + .map(File::getInputFileType) + .map(File.InputFileTypeEnum::toString) + .collect(Collectors.toList()); + + final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS; + List ruleInputsListFromMDMS = null; + try { + log.info(jsonPathForRuleInputs); + ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + List allowedColumns = getRuleConfigInputsFromSchema(ruleInputsListFromMDMS, templateIds, inputFileTypes); + planConfiguration.getOperations().stream() + .map(Operation::getOutput) + .forEach(allowedColumns::add); + for (Operation operation : planConfiguration.getOperations()) { + if (!allowedColumns.contains(operation.getInput())) { + log.error("Input Value " + operation.getInput() + " is not present in MDMS Input List"); + throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE); + } } } } @@ -243,13 +267,16 @@ public static List getRuleConfigInputsFromSchema(List schemas, L * @throws CustomException If a duplicate 'mappedTo' value is found. */ public static void validateMappedToUniqueness(List resourceMappings) { - Set uniqueMappedToSet = new HashSet<>(); - for (ResourceMapping mapping : resourceMappings) { - String uniqueKey = mapping.getFilestoreId() + "-" + mapping.getMappedTo(); - if (!uniqueMappedToSet.add(uniqueKey)) { - log.error("Duplicate MappedTo " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - throw new CustomException(DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE, - DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE + " - " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); + if(!CollectionUtils.isEmpty(resourceMappings)) + { + Set uniqueMappedToSet = new HashSet<>(); + for (ResourceMapping mapping : resourceMappings) { + String uniqueKey = mapping.getFilestoreId() + "-" + mapping.getMappedTo(); + if (!uniqueMappedToSet.add(uniqueKey)) { + log.error("Duplicate MappedTo " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); + throw new CustomException(DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE, + DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE + " - " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); + } } } } @@ -323,17 +350,20 @@ public PlanConfiguration validatePlanConfigExistence(PlanConfigurationRequest re * @throws CustomException If an inactive operation's output is used as input in any other active operation. */ public static void validateOperationDependencies(PlanConfiguration planConfiguration) { - // Collect all active operations' inputs - Set activeInputs = planConfiguration.getOperations().stream() - .filter(Operation::getActive) - .map(Operation::getInput) - .collect(Collectors.toSet()); - - // Check for each inactive operation - for (Operation operation : planConfiguration.getOperations()) { - if (!operation.getActive() && activeInputs.contains(operation.getOutput())) { - log.error(INACTIVE_OPERATION_USED_AS_INPUT_MESSAGE + operation.getOutput()); - throw new CustomException(INACTIVE_OPERATION_USED_AS_INPUT_CODE, INACTIVE_OPERATION_USED_AS_INPUT_MESSAGE + operation.getOutput()); + if(!CollectionUtils.isEmpty(planConfiguration.getOperations())) + { + // Collect all active operations' inputs + Set activeInputs = planConfiguration.getOperations().stream() + .filter(Operation::getActive) + .map(Operation::getInput) + .collect(Collectors.toSet()); + + // Check for each inactive operation + for (Operation operation : planConfiguration.getOperations()) { + if (!operation.getActive() && activeInputs.contains(operation.getOutput())) { + log.error(INACTIVE_OPERATION_USED_AS_INPUT_MESSAGE + operation.getOutput()); + throw new CustomException(INACTIVE_OPERATION_USED_AS_INPUT_CODE, INACTIVE_OPERATION_USED_AS_INPUT_MESSAGE + operation.getOutput()); + } } } } @@ -346,39 +376,45 @@ public static void validateOperationDependencies(PlanConfiguration planConfigura */ public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - List files = planConfiguration.getFiles(); - List templateIds = files.stream() - .map(File::getTemplateIdentifier) - .collect(Collectors.toList()); - List inputFileTypes = files.stream() - .map(File::getInputFileType) - .map(File.InputFileTypeEnum::toString) - .collect(Collectors.toList()); - - final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS; - List ruleInputsListFromMDMS = null; - try { - log.info(jsonPathForRuleInputs); - ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - List requiredColumns = getIsTruePropertyFromSchema(ruleInputsListFromMDMS, templateIds, inputFileTypes); - List resourceMappings = planConfiguration.getResourceMapping(); - // Throw a custom exception if no active mappings with BOUNDARY_CODE are found - if(requiredColumns.contains(ServiceConstants.BOUNDARY_CODE)) { - boolean exists = resourceMappings.stream() - .anyMatch(mapping -> mapping.getActive() && mapping.getMappedTo().equals(ServiceConstants.BOUNDARY_CODE)); + if(isSetupCompleted(planConfiguration)) + { + checkForEmptyFiles(planConfiguration); + checkForEmptyResourceMapping(planConfiguration); + + List files = planConfiguration.getFiles(); + List templateIds = files.stream() + .map(File::getTemplateIdentifier) + .collect(Collectors.toList()); + List inputFileTypes = files.stream() + .map(File::getInputFileType) + .map(File.InputFileTypeEnum::toString) + .collect(Collectors.toList()); + + final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS; + List ruleInputsListFromMDMS = null; + try { + log.info(jsonPathForRuleInputs); + ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + List requiredColumns = getIsTruePropertyFromSchema(ruleInputsListFromMDMS, templateIds, inputFileTypes); + List resourceMappings = planConfiguration.getResourceMapping(); + + // Throw a custom exception if no active mappings with BOUNDARY_CODE are found + if(requiredColumns.contains(ServiceConstants.BOUNDARY_CODE)) { + boolean exists = resourceMappings.stream() + .anyMatch(mapping -> mapping.getActive() && mapping.getMappedTo().equals(ServiceConstants.BOUNDARY_CODE)); - if (!exists) { - throw new CustomException(BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE, BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE); + if (!exists) { + throw new CustomException(BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE, BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE); + } } } - } - + } /** * Return all properties that has isTrue flag as a true. * @param schemas schema object. @@ -421,4 +457,48 @@ public void validateFilesActive(PlanConfiguration planConfigurationFromDB, PlanC } } } + + + public boolean isSetupCompleted(PlanConfiguration planConfiguration) + { + return planConfiguration.getStatus() == PlanConfiguration.StatusEnum.SETUP_COMPLETED; + } + + // Checks for whether file, assumption, operation or resource mapping is empty or null at a certain status + private void checkForEmptyFiles(PlanConfiguration planConfiguration) + { + if(CollectionUtils.isEmpty(planConfiguration.getFiles())) + { + log.error("Files cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + throw new CustomException(FILES_NOT_FOUND_CODE, FILES_NOT_FOUND_MESSAGE); + } + } + + private void checkForEmptyAssumption(PlanConfiguration planConfiguration) + { + if(CollectionUtils.isEmpty(planConfiguration.getAssumptions())) + { + log.error("Assumptions cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + throw new CustomException(ASSUMPTIONS_NOT_FOUND_CODE,ASSUMPTIONS_NOT_FOUND_MESSAGE); + } + } + + private void checkForEmptyOperation(PlanConfiguration planConfiguration) + { + if(CollectionUtils.isEmpty(planConfiguration.getOperations())) + { + log.error("Operations cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + throw new CustomException(OPERATIONS_NOT_FOUND_CODE, OPERATIONS_NOT_FOUND_MESSAGE); + } + } + + private void checkForEmptyResourceMapping(PlanConfiguration planConfiguration) + { + if(CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) + { + log.error("Resource mapping cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + throw new CustomException(RESOURCE_MAPPING_NOT_FOUND_CODE, RESOURCE_MAPPING_NOT_FOUND_MESSAGE); + } + } + } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index dbf9ed7f139..f8b6b953361 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -53,26 +53,18 @@ public class PlanConfiguration { private StatusEnum status = null; @JsonProperty("files") - @NotNull - @NotEmpty @Valid private List files = new ArrayList<>(); @JsonProperty("assumptions") - @NotNull - @NotEmpty @Valid private List assumptions = new ArrayList<>(); @JsonProperty("operations") - @NotNull - @NotEmpty @Valid private List operations = new ArrayList<>(); @JsonProperty("resourceMapping") - @NotNull - @NotEmpty @Valid private List resourceMapping = new ArrayList<>(); @@ -85,7 +77,7 @@ public class PlanConfiguration { public enum StatusEnum { DRAFT , GENERATED, - INVALID_DATA + INVALID_DATA, + SETUP_COMPLETED } - } From c8ee52366e2e39bb897dddd4629a6134e4fa9486 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 12 Sep 2024 17:11:33 +0530 Subject: [PATCH 013/351] HCMPRE-503, HCMPRE-513 renaming executionPlanId to campaignId and adding showOnEstimationDashboard to operations. --- .../querybuilder/PlanConfigQueryBuilder.java | 10 +++++----- .../repository/querybuilder/PlanQueryBuilder.java | 8 ++++---- .../repository/rowmapper/PlanConfigRowMapper.java | 3 ++- .../java/digit/repository/rowmapper/PlanRowMapper.java | 2 +- .../src/main/java/digit/service/PlanValidator.java | 4 ++-- .../service/validator/PlanConfigurationValidator.java | 2 +- .../src/main/java/digit/web/models/Operation.java | 4 ++++ .../src/main/java/digit/web/models/Plan.java | 4 ++-- .../main/java/digit/web/models/PlanConfiguration.java | 6 +++--- .../web/models/PlanConfigurationSearchCriteria.java | 4 ++-- .../main/java/digit/web/models/PlanSearchCriteria.java | 4 ++-- ...1109150000__rename_execution_id_campaign_id_ddl.sql | 8 ++++++++ 12 files changed, 36 insertions(+), 23 deletions(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 6dc4449b55f..6d1c3cd6a3b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -21,10 +21,10 @@ public PlanConfigQueryBuilder(Configuration config) { private static final String PLAN_CONFIG_SEARCH_BASE_QUERY = "SELECT id FROM plan_configuration pc "; - private static final String PLAN_CONFIG_QUERY = "SELECT pc.id as plan_configuration_id, pc.tenant_id as plan_configuration_tenant_id, pc.name as plan_configuration_name, pc.execution_plan_id as plan_configuration_execution_plan_id, pc.status as plan_configuration_status, pc.created_by as plan_configuration_created_by, pc.created_time as plan_configuration_created_time, pc.last_modified_by as plan_configuration_last_modified_by, pc.last_modified_time as plan_configuration_last_modified_time, \n" + + private static final String PLAN_CONFIG_QUERY = "SELECT pc.id as plan_configuration_id, pc.tenant_id as plan_configuration_tenant_id, pc.name as plan_configuration_name, pc.campaign_id as plan_configuration_campaign_id, pc.status as plan_configuration_status, pc.created_by as plan_configuration_created_by, pc.created_time as plan_configuration_created_time, pc.last_modified_by as plan_configuration_last_modified_by, pc.last_modified_time as plan_configuration_last_modified_time, \n" + "\t pcf.id as plan_configuration_files_id, pcf.plan_configuration_id as plan_configuration_files_plan_configuration_id, pcf.filestore_id as plan_configuration_files_filestore_id, pcf.input_file_type as plan_configuration_files_input_file_type, pcf.template_identifier as plan_configuration_files_template_identifier, pcf.active as plan_configuration_files_active, pcf.created_by as plan_configuration_files_created_by, pcf.created_time as plan_configuration_files_created_time, pcf.last_modified_by as plan_configuration_files_last_modified_by, pcf.last_modified_time as plan_configuration_files_last_modified_time,\n" + "\t pca.id as plan_configuration_assumptions_id, pca.key as plan_configuration_assumptions_key, pca.value as plan_configuration_assumptions_value, pca.active as plan_configuration_assumptions_active, pca.plan_configuration_id as plan_configuration_assumptions_plan_configuration_id, pca.created_by as plan_configuration_assumptions_created_by, pca.created_time as plan_configuration_assumptions_created_time, pca.last_modified_by as plan_configuration_assumptions_last_modified_by, pca.last_modified_time as plan_configuration_assumptions_last_modified_time,\n" + - "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.active as plan_configuration_operations_active, pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + + "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.active as plan_configuration_operations_active, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + "\t pcm.id as plan_configuration_mapping_id, pcm.filestore_id as plan_configuration_mapping_filestore_id, pcm.mapped_from as plan_configuration_mapping_mapped_from, pcm.mapped_to as plan_configuration_mapping_mapped_to, pcm.active as plan_configuration_mapping_active, pcm.plan_configuration_id as plan_configuration_mapping_plan_configuration_id, pcm.created_by as plan_configuration_mapping_created_by, pcm.created_time as plan_configuration_mapping_created_time, pcm.last_modified_by as plan_configuration_mapping_last_modified_by, pcm.last_modified_time as plan_configuration_mapping_last_modified_time\n" + "\t FROM plan_configuration pc\n" + "\t LEFT JOIN plan_configuration_files pcf ON pc.id = pcf.plan_configuration_id\n" + @@ -97,10 +97,10 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter preparedStmtList.add(criteria.getId()); } - if (criteria.getExecutionPlanId() != null) { + if (criteria.getCampaignId() != null) { addClauseIfRequired(preparedStmtList, builder); - builder.append(" pc.execution_plan_id = ?"); - preparedStmtList.add(criteria.getExecutionPlanId()); + builder.append(" pc.campaign_id = ?"); + preparedStmtList.add(criteria.getCampaignId()); } if (criteria.getName() != null) { diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 1b0adb59213..34b9a1f5981 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -20,7 +20,7 @@ public PlanQueryBuilder(Configuration config) { private static final String PLAN_SEARCH_BASE_QUERY = "SELECT id FROM plan "; - private static final String PLAN_QUERY = "SELECT plan.id as plan_id, plan.tenant_id as plan_tenant_id, plan.locality as plan_locality, plan.execution_plan_id as plan_execution_plan_id, plan.plan_configuration_id as plan_plan_configuration_id, plan.additional_details as plan_additional_details, plan.created_by as plan_created_by, plan.created_time as plan_created_time, plan.last_modified_by as plan_last_modified_by, plan.last_modified_time as plan_last_modified_time,\n" + + private static final String PLAN_QUERY = "SELECT plan.id as plan_id, plan.tenant_id as plan_tenant_id, plan.locality as plan_locality, plan.campaign_id as plan_campaign_id, plan.plan_configuration_id as plan_plan_configuration_id, plan.additional_details as plan_additional_details, plan.created_by as plan_created_by, plan.created_time as plan_created_time, plan.last_modified_by as plan_last_modified_by, plan.last_modified_time as plan_last_modified_time,\n" + "\t plan_activity.id as plan_activity_id, plan_activity.code as plan_activity_code, plan_activity.description as plan_activity_description, plan_activity.planned_start_date as plan_activity_planned_start_date, plan_activity.planned_end_date as plan_activity_planned_end_date, plan_activity.dependencies as plan_activity_dependencies, plan_activity.plan_id as plan_activity_plan_id, plan_activity.created_by as plan_activity_created_by, plan_activity.created_time as plan_activity_created_time, plan_activity.last_modified_by as plan_activity_last_modified_by, plan_activity.last_modified_time as plan_activity_last_modified_time,\n" + "\t plan_activity_condition.id as plan_activity_condition_id, plan_activity_condition.entity as plan_activity_condition_entity, plan_activity_condition.entity_property as plan_activity_condition_entity_property, plan_activity_condition.expression as plan_activity_condition_expression, plan_activity_condition.activity_id as plan_activity_condition_activity_id, plan_activity_condition.is_active as plan_activity_condition_is_active, plan_activity_condition.created_by as plan_activity_condition_created_by, plan_activity_condition.created_time as plan_activity_condition_created_time, plan_activity_condition.last_modified_by as plan_activity_condition_last_modified_by, plan_activity_condition.last_modified_time as plan_activity_condition_last_modified_time,\n" + "\t plan_resource.id as plan_resource_id, plan_resource.resource_type as plan_resource_resource_type, plan_resource.estimated_number as plan_resource_estimated_number, plan_resource.plan_id as plan_resource_plan_id, plan_resource.activity_code as plan_resource_activity_code, plan_resource.created_by as plan_resource_created_by, plan_resource.created_time as plan_resource_created_time, plan_resource.last_modified_by as plan_resource_last_modified_by, plan_resource.last_modified_time as plan_resource_last_modified_time,\n" + @@ -83,10 +83,10 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< preparedStmtList.add(planSearchCriteria.getLocality()); } - if (!ObjectUtils.isEmpty(planSearchCriteria.getExecutionPlanId())) { + if (!ObjectUtils.isEmpty(planSearchCriteria.getCampaignId())) { QueryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" execution_plan_id = ? "); - preparedStmtList.add(planSearchCriteria.getExecutionPlanId()); + builder.append(" campaign_id = ? "); + preparedStmtList.add(planSearchCriteria.getCampaignId()); } if (!ObjectUtils.isEmpty(planSearchCriteria.getPlanConfigurationId())) { diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index f8aebd12a9a..31ce9002c1e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java @@ -45,7 +45,7 @@ public List extractData(ResultSet rs) throws SQLException, Da planConfigEntry.setId(planConfigId); planConfigEntry.setTenantId(rs.getString("plan_configuration_tenant_id")); planConfigEntry.setName(rs.getString("plan_configuration_name")); - planConfigEntry.setExecutionPlanId(rs.getString("plan_configuration_execution_plan_id")); + planConfigEntry.setCampaignId(rs.getString("plan_configuration_campaign_id")); planConfigEntry.setStatus(PlanConfiguration.StatusEnum.valueOf(rs.getString("plan_configuration_status").toUpperCase())); planConfigEntry.setAuditDetails(auditDetails); @@ -147,6 +147,7 @@ private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Map< operation.setAssumptionValue(rs.getString("plan_configuration_operations_assumption_value")); operation.setOutput(rs.getString("plan_configuration_operations_output")); operation.setActive(rs.getBoolean("plan_configuration_operations_active")); + operation.setShowOnEstimationDashboard(rs.getBoolean("plan_configuration_operations_show_on_estimation_dashboard")); if (CollectionUtils.isEmpty(planConfigEntry.getOperations())) { List operationList = new ArrayList<>(); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index a82919fed46..f8ebb0c588c 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java @@ -55,7 +55,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep planEntry.setId(planId); planEntry.setTenantId(rs.getString("plan_tenant_id")); planEntry.setLocality(rs.getString("plan_locality")); - planEntry.setExecutionPlanId(rs.getString("plan_execution_plan_id")); + planEntry.setCampaignId(rs.getString("plan_campaign_id")); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); planEntry.setAdditionalDetails(getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); planEntry.setAuditDetails(auditDetails); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 40958a9e0d3..d9bb36aa2ba 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -137,13 +137,13 @@ private void validateActivities(PlanRequest request) { } // If execution plan id is not provided, providing activities is mandatory - if(ObjectUtils.isEmpty(request.getPlan().getExecutionPlanId()) + if(ObjectUtils.isEmpty(request.getPlan().getCampaignId()) && CollectionUtils.isEmpty(request.getPlan().getActivities())) { throw new CustomException(PLAN_ACTIVITIES_MANDATORY_CODE, PLAN_ACTIVITIES_MANDATORY_MESSAGE); } // If execution plan id is provided, providing activities is not allowed - if(!ObjectUtils.isEmpty(request.getPlan().getExecutionPlanId()) + if(!ObjectUtils.isEmpty(request.getPlan().getCampaignId()) && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { throw new CustomException(PLAN_ACTIVITIES_NOT_ALLOWED_CODE, PLAN_ACTIVITIES_NOT_ALLOWED_MESSAGE); } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 22d316b707e..b656c104615 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -147,7 +147,7 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; + final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptionCategories[*].assumptions[*]"; List assumptionListFromMDMS = null; try { diff --git a/health-services/plan-service/src/main/java/digit/web/models/Operation.java b/health-services/plan-service/src/main/java/digit/web/models/Operation.java index fbc647cfc1d..a515261aec3 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Operation.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Operation.java @@ -48,6 +48,10 @@ public class Operation { @Size(min = 1, max = 64) private String output = null; + @JsonProperty("showOnEstimationDashboard") + @NotNull + private Boolean showOnEstimationDashboard = true; + @JsonProperty("active") @NotNull private Boolean active = true; diff --git a/health-services/plan-service/src/main/java/digit/web/models/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index f1fb59a400e..2db15b594ed 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Plan.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Plan.java @@ -35,9 +35,9 @@ public class Plan { @Size(min = 1, max = 64) private String locality = null; - @JsonProperty("executionPlanId") + @JsonProperty("campaignId") @Size(max = 64) - private String executionPlanId = null; + private String campaignId = null; @JsonProperty("planConfigurationId") @Size(max = 64) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index 9032da0bfed..4ad6bb95eb0 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -41,11 +41,11 @@ public class PlanConfiguration { @Size(min = 3, max = 128) private String name = null; - @JsonProperty("executionPlanId") + @JsonProperty("campaignId") @NotNull @Size(min = 2, max = 64) - @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Execution Plan Id must not contain only special characters") - private String executionPlanId = null; + @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Campaign Id must not contain only special characters") + private String campaignId = null; @JsonProperty("status") @NotNull diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java index ab7c827c49a..7362278ccec 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java @@ -33,8 +33,8 @@ public class PlanConfigurationSearchCriteria { @JsonProperty("name") private String name = null; - @JsonProperty("executionPlanId") - private String executionPlanId = null; + @JsonProperty("campaignId") + private String campaignId = null; @JsonProperty("status") private String status = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java index 6e9cc9449d1..d5ed80467fa 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java @@ -31,8 +31,8 @@ public class PlanSearchCriteria { @JsonProperty("locality") private String locality = null; - @JsonProperty("executionPlanId") - private String executionPlanId = null; + @JsonProperty("campaignId") + private String campaignId = null; @JsonProperty("planConfigurationId") private String planConfigurationId = null; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql new file mode 100644 index 00000000000..de75f95a6ac --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql @@ -0,0 +1,8 @@ +ALTER TABLE plan_configuration +RENAME COLUMN execution_plan_id TO campaign_id; + +ALTER TABLE plan +RENAME COLUMN execution_plan_id TO campaign_id; + +ALTER TABLE plan_configuration_operations ADD show_on_estimation_dashboard boolean; +UPDATE plan_configuration_operations SET show_on_estimation_dashboard = true WHERE active IS NULL; \ No newline at end of file From b6e940f298aa71081aef8db899b2758bde64c4ab Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 12 Sep 2024 17:15:16 +0530 Subject: [PATCH 014/351] HCMPRE-503, HCMPRE-513 renaming executionPlanId to campaignId and adding showOnEstimationDashboard to operations. --- .../V20241109150000__rename_execution_id_campaign_id_ddl.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql index de75f95a6ac..33c6ebccf89 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql @@ -5,4 +5,4 @@ ALTER TABLE plan RENAME COLUMN execution_plan_id TO campaign_id; ALTER TABLE plan_configuration_operations ADD show_on_estimation_dashboard boolean; -UPDATE plan_configuration_operations SET show_on_estimation_dashboard = true WHERE active IS NULL; \ No newline at end of file +UPDATE plan_configuration_operations SET show_on_estimation_dashboard = true WHERE show_on_estimation_dashboard IS NULL; \ No newline at end of file From 3f08690ff8e4e39452cba46ddfa91aea59c42f86 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 13 Sep 2024 13:25:19 +0530 Subject: [PATCH 015/351] added pojos for PlanEmployeeAssignment --- .../web/models/PlanEmployeeAssignment.java | 60 +++++++++++++++++++ .../models/PlanEmployeeAssignmentRequest.java | 30 ++++++++++ .../PlanEmployeeAssignmentResponse.java | 32 ++++++++++ .../PlanEmployeeAssignmentSearchCriteria.java | 43 +++++++++++++ .../PlanEmployeeAssignmentSearchRequest.java | 29 +++++++++ 5 files changed, 194 insertions(+) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchRequest.java diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java new file mode 100644 index 00000000000..568ea1b82b4 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java @@ -0,0 +1,60 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * PlanEmployeeAssignment + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignment { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @NotNull + @Size(min = 2, max = 64) + private String planConfigurationId = null; + + @JsonProperty("employeeId") + @NotNull + @Size(min = 2, max = 64) + private String employeeId = null; + + @JsonProperty("role") + @NotNull + @Size(min = 2, max = 64) + private String role = null; + + @JsonProperty("jurisdiction") + @Valid + private List jurisdiction = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + private Boolean active = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequest.java new file mode 100644 index 00000000000..4361b16dde2 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequest.java @@ -0,0 +1,30 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + + +/** + * PlanEmployeeAssignmentRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanEmployeeAssignment") + @Valid + private PlanEmployeeAssignment planEmployeeAssignment = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java new file mode 100644 index 00000000000..9c2c71dae60 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java @@ -0,0 +1,32 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import jakarta.validation.Valid; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + + +/** + * PlanEmployeeAssignmentResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("PlanEmployeeAssignment") + @Valid + private List planEmployeeAssignment = null; +} + diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java new file mode 100644 index 00000000000..5e3aec1206d --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -0,0 +1,43 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * PlanEmployeeAssignmentSearchCriteria + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentSearchCriteria { + + @JsonProperty("tenantId") + @Size(min = 2, max = 100) + @NotNull + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("role") + @Size(min = 2, max = 64) + private String role = null; + + @JsonProperty("jurisdiction") + @Valid + private List jurisdiction = null; + + @JsonProperty("active") + private Boolean active = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchRequest.java new file mode 100644 index 00000000000..a8b3a40a41f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchRequest.java @@ -0,0 +1,29 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * PlanEmployeeAssignmentSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentSearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanEmployeeAssignmentSearchCriteria") + @Valid + private PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = null; +} From 4397a69b1bc2253d1a7ca3ac4a9fd605fc0a6b54 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 13 Sep 2024 13:32:40 +0530 Subject: [PATCH 016/351] moved "%" to serviceConstants file --- .../src/main/java/digit/config/ServiceConstants.java | 2 ++ .../digit/repository/querybuilder/PlanConfigQueryBuilder.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 2266c82de93..ed278e05a15 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -110,4 +110,6 @@ public class ServiceConstants { public static final String MDMS_SCHEMA_PROPERTIES_IS_REQUIRED = "isRequired"; public static final String BOUNDARY_CODE = "boundaryCode"; + public static final String PERCENTAGE_WILDCARD = "%"; + } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 74deaa36dac..94e799589f9 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -9,6 +9,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import static digit.config.ServiceConstants.*; @Component public class PlanConfigQueryBuilder { @@ -106,7 +107,7 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter if (criteria.getName() != null) { addClauseIfRequired(preparedStmtList, builder); builder.append(" pc.name LIKE ?"); - preparedStmtList.add(criteria.getName() + '%'); + preparedStmtList.add(criteria.getName() + PERCENTAGE_WILDCARD); } if (criteria.getStatus() != null) { From c763ca676fde3c2a659a11eb783053fcd8c16e4c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 13 Sep 2024 14:00:43 +0530 Subject: [PATCH 017/351] resolved review comments --- .../validator/PlanConfigurationValidator.java | 19 +++++++++---------- .../{ServiceUtil.java => CommonUtil.java} | 4 ++-- 2 files changed, 11 insertions(+), 12 deletions(-) rename health-services/plan-service/src/main/java/digit/util/{ServiceUtil.java => CommonUtil.java} (96%) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 13e17188953..af4b74bf93e 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -5,7 +5,7 @@ import digit.repository.PlanConfigurationRepository; import digit.util.MdmsUtil; import digit.util.MdmsV2Util; -import digit.util.ServiceUtil; +import digit.util.CommonUtil; import digit.web.models.*; import java.util.*; @@ -31,15 +31,15 @@ public class PlanConfigurationValidator { private PlanConfigurationRepository planConfigRepository; - private ServiceUtil serviceUtil; + private CommonUtil commonUtil; private MultiStateInstanceUtil centralInstanceUtil; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, ServiceUtil serviceUtil, MultiStateInstanceUtil centralInstanceUtil) { + public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil) { this.mdmsUtil = mdmsUtil; this.mdmsV2Util = mdmsV2Util; this.planConfigRepository = planConfigRepository; - this.serviceUtil = serviceUtil; + this.commonUtil = commonUtil; this.centralInstanceUtil = centralInstanceUtil; } @@ -51,7 +51,7 @@ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); @@ -111,7 +111,7 @@ public void validatePlanConfigName(PlanConfigurationRequest request, Object mdms } String regexPattern = (String) nameValidationListFromMDMS.get(0); - if (!serviceUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) { + if (!commonUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) { throw new CustomException(NAME_VALIDATION_FAILED_CODE, NAME_VALIDATION_FAILED_MESSAGE); } @@ -369,7 +369,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(),rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); // Validate the existence of the plan configuration in the request validatePlanConfigExistence(request); @@ -540,13 +540,12 @@ public void validateUserInfo(PlanConfigurationRequest request) */ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, Object mdmsV2Data) { - List vehicleIds = serviceUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); + List vehicleIdsLinkedWithPlanConfig = commonUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); String jsonPathForVehicleIds = JSON_ROOT_PATH + MDMS_CODE + DOT_SEPARATOR + FILTER_TO_GET_ALL_IDS; List vehicleIdsFromMdms = null; try { - log.info(jsonPathForVehicleIds); vehicleIdsFromMdms = JsonPath.read(mdmsV2Data, jsonPathForVehicleIds); } catch (Exception e) { log.error(e.getMessage()); @@ -555,7 +554,7 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration List finalVehicleIdsFromMdms = vehicleIdsFromMdms; - vehicleIds.stream() + vehicleIdsLinkedWithPlanConfig.stream() .forEach(vehicleId -> { if(!finalVehicleIdsFromMdms.contains(vehicleId)) { diff --git a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java similarity index 96% rename from health-services/plan-service/src/main/java/digit/util/ServiceUtil.java rename to health-services/plan-service/src/main/java/digit/util/CommonUtil.java index a8c85e55252..07d2f01d7cd 100644 --- a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -15,11 +15,11 @@ @Component @Slf4j -public class ServiceUtil { +public class CommonUtil { private ObjectMapper objectMapper; - public ServiceUtil(ObjectMapper objectMapper) + public CommonUtil(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } From 6e46941190069fd0ebd50d3545d0d5408220af85 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 13 Sep 2024 14:34:54 +0530 Subject: [PATCH 018/351] added mdmsV2 response pojo --- .../validator/PlanConfigurationValidator.java | 2 +- .../src/main/java/digit/util/MdmsV2Util.java | 8 +++--- .../models/mdmsV2/MdmsV2CriteriaResponse.java | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index af4b74bf93e..1f2f0a67d23 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -542,7 +542,7 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration { List vehicleIdsLinkedWithPlanConfig = commonUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); - String jsonPathForVehicleIds = JSON_ROOT_PATH + MDMS_CODE + DOT_SEPARATOR + FILTER_TO_GET_ALL_IDS; + String jsonPathForVehicleIds = FILTER_ID; List vehicleIdsFromMdms = null; try { diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index 5c4196f0d24..22c9bb05966 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -35,21 +35,21 @@ public Object fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String s { StringBuilder uri = getMdmsV2Uri(); MdmsV2CriteriaReq mdmsV2CriteriaReq = getMdmsV2Request(requestInfo, tenantId, schemaCode); - Object mdmsResponseMap = new HashMap<>(); + MdmsV2CriteriaResponse mdmsV2CriteriaResponse = null; try{ - mdmsResponseMap = restTemplate.postForObject(uri.toString(), mdmsV2CriteriaReq, Map.class); + mdmsV2CriteriaResponse = restTemplate.postForObject(uri.toString(), mdmsV2CriteriaReq, MdmsV2CriteriaResponse.class); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); } - if(ObjectUtils.isEmpty(mdmsResponseMap)) + if(ObjectUtils.isEmpty(mdmsV2CriteriaResponse.getMdmsV2Data())) { log.error(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE + " - " + tenantId); throw new CustomException(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE, NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE); } - return mdmsResponseMap; + return mdmsV2CriteriaResponse.getMdmsV2Data(); } private StringBuilder getMdmsV2Uri() diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java new file mode 100644 index 00000000000..35ecab66957 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java @@ -0,0 +1,26 @@ +package digit.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.response.ResponseInfo; + +import javax.validation.Valid; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) + +public class MdmsV2CriteriaResponse { + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("mdms") + @Valid + List MdmsV2Data = null; +} \ No newline at end of file From 1095d8f3e48f594d34e0e02335e8db1f5368e842 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 13 Sep 2024 17:14:13 +0530 Subject: [PATCH 019/351] made changes to mdmsV2 util --- .../validator/PlanConfigurationValidator.java | 24 +++----- .../src/main/java/digit/util/MdmsV2Util.java | 6 +- .../java/digit/web/models/mdmsV2/Mdms.java | 56 +++++++++++++++++++ .../models/mdmsV2/MdmsV2CriteriaResponse.java | 2 +- 4 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 1f2f0a67d23..f2a291c53ed 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -11,6 +11,7 @@ import java.util.*; import java.util.stream.Collectors; +import digit.web.models.mdmsV2.Mdms; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.egov.common.utils.MultiStateInstanceUtil; @@ -51,7 +52,7 @@ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); @@ -369,7 +370,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - Object mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); // Validate the existence of the plan configuration in the request validatePlanConfigExistence(request); @@ -538,28 +539,21 @@ public void validateUserInfo(PlanConfigurationRequest request) * @param request plan configuration request * @param mdmsV2Data mdms v2 data object */ - public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, Object mdmsV2Data) + public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, List mdmsV2Data) { List vehicleIdsLinkedWithPlanConfig = commonUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); - String jsonPathForVehicleIds = FILTER_ID; - - List vehicleIdsFromMdms = null; - try { - vehicleIdsFromMdms = JsonPath.read(mdmsV2Data, jsonPathForVehicleIds); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - + List vehicleIdsFromMdms = mdmsV2Data.stream() + .map(Mdms::getId) + .collect(Collectors.toList()); - List finalVehicleIdsFromMdms = vehicleIdsFromMdms; + List finalVehicleIdsFromMdms = vehicleIdsFromMdms; vehicleIdsLinkedWithPlanConfig.stream() .forEach(vehicleId -> { if(!finalVehicleIdsFromMdms.contains(vehicleId)) { log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); - throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForVehicleIds); + throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE); } }); } diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index 22c9bb05966..813b7db8b6b 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -31,7 +31,7 @@ public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configur this.configs = configs; } - public Object fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode) + public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode) { StringBuilder uri = getMdmsV2Uri(); MdmsV2CriteriaReq mdmsV2CriteriaReq = getMdmsV2Request(requestInfo, tenantId, schemaCode); @@ -43,13 +43,13 @@ public Object fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String s log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); } - if(ObjectUtils.isEmpty(mdmsV2CriteriaResponse.getMdmsV2Data())) + if(ObjectUtils.isEmpty(mdmsV2CriteriaResponse.getMdms())) { log.error(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE + " - " + tenantId); throw new CustomException(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE, NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE); } - return mdmsV2CriteriaResponse.getMdmsV2Data(); + return mdmsV2CriteriaResponse.getMdms(); } private StringBuilder getMdmsV2Uri() diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java new file mode 100644 index 00000000000..96ffefc2bf2 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java @@ -0,0 +1,56 @@ +package digit.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * Mdms + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Mdms { + + @JsonProperty("id") + @Size(min = 2, max = 64) + private String id; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 128) + private String tenantId = null; + + @JsonProperty("schemaCode") + @NotNull + @Size(min = 2, max = 128) + private String schemaCode = null; + + @JsonProperty("uniqueIdentifier") + @Size(min = 2, max = 128) + private String uniqueIdentifier = null; + + @JsonProperty("data") + @NotNull + private JsonNode data = null; + + @JsonProperty("isActive") + private Boolean isActive = true; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails = null; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java index 35ecab66957..bc02da63d9d 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java @@ -22,5 +22,5 @@ public class MdmsV2CriteriaResponse { @JsonProperty("mdms") @Valid - List MdmsV2Data = null; + private List mdms = null; } \ No newline at end of file From 100cf6414c5d4027008da8771fa3258747a8dfd1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 13 Sep 2024 17:25:52 +0530 Subject: [PATCH 020/351] made changes to mdmsV2 util --- .../src/main/java/digit/util/MdmsV2Util.java | 18 +++++++++--------- ...CriteriaReq.java => MdmsCriteriaReqV2.java} | 4 ++-- ...MdmsV2Criteria.java => MdmsCriteriaV2.java} | 2 +- ...iteriaResponse.java => MdmsResponseV2.java} | 3 +-- 4 files changed, 13 insertions(+), 14 deletions(-) rename health-services/plan-service/src/main/java/digit/web/models/mdmsV2/{MdmsV2CriteriaReq.java => MdmsCriteriaReqV2.java} (86%) rename health-services/plan-service/src/main/java/digit/web/models/mdmsV2/{MdmsV2Criteria.java => MdmsCriteriaV2.java} (97%) rename health-services/plan-service/src/main/java/digit/web/models/mdmsV2/{MdmsV2CriteriaResponse.java => MdmsResponseV2.java} (85%) diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index 813b7db8b6b..809a072954f 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -34,22 +34,22 @@ public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configur public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode) { StringBuilder uri = getMdmsV2Uri(); - MdmsV2CriteriaReq mdmsV2CriteriaReq = getMdmsV2Request(requestInfo, tenantId, schemaCode); - MdmsV2CriteriaResponse mdmsV2CriteriaResponse = null; + MdmsCriteriaReqV2 mdmsCriteriaReqV2 = getMdmsV2Request(requestInfo, tenantId, schemaCode); + MdmsResponseV2 mdmsResponseV2 = null; try{ - mdmsV2CriteriaResponse = restTemplate.postForObject(uri.toString(), mdmsV2CriteriaReq, MdmsV2CriteriaResponse.class); + mdmsResponseV2 = restTemplate.postForObject(uri.toString(), mdmsCriteriaReqV2, MdmsResponseV2.class); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); } - if(ObjectUtils.isEmpty(mdmsV2CriteriaResponse.getMdms())) + if(ObjectUtils.isEmpty(mdmsResponseV2.getMdms())) { log.error(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE + " - " + tenantId); throw new CustomException(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE, NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE); } - return mdmsV2CriteriaResponse.getMdms(); + return mdmsResponseV2.getMdms(); } private StringBuilder getMdmsV2Uri() @@ -58,17 +58,17 @@ private StringBuilder getMdmsV2Uri() return uri.append(configs.getMdmsHost()).append(configs.getMdmsV2EndPoint()); } - private MdmsV2CriteriaReq getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode) + private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode) { - MdmsV2Criteria mdmsV2Criteria = MdmsV2Criteria.builder() + MdmsCriteriaV2 mdmsCriteriaV2 = MdmsCriteriaV2.builder() .tenantId(tenantId) .schemaCode(schemaCode) .limit(configs.getDefaultLimit()) .offset(configs.getDefaultOffset()).build(); - return MdmsV2CriteriaReq.builder() + return MdmsCriteriaReqV2.builder() .requestInfo(requestInfo) - .mdmsV2Criteria(mdmsV2Criteria).build(); + .mdmsCriteriaV2(mdmsCriteriaV2).build(); } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaReq.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaReqV2.java similarity index 86% rename from health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaReq.java rename to health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaReqV2.java index c0264560928..f6af90e1b82 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaReq.java +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaReqV2.java @@ -12,12 +12,12 @@ @NoArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class MdmsV2CriteriaReq { +public class MdmsCriteriaReqV2 { @JsonProperty("RequestInfo") @Valid private RequestInfo requestInfo; @JsonProperty("MdmsCriteria") @Valid - private MdmsV2Criteria mdmsV2Criteria; + private MdmsCriteriaV2 mdmsCriteriaV2; } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2Criteria.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaV2.java similarity index 97% rename from health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2Criteria.java rename to health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaV2.java index b1ab701ed45..88e8a715810 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2Criteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaV2.java @@ -21,7 +21,7 @@ @NoArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class MdmsV2Criteria { +public class MdmsCriteriaV2 { @JsonProperty("tenantId") @Size(min = 1, max = 100) diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsResponseV2.java similarity index 85% rename from health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java rename to health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsResponseV2.java index bc02da63d9d..090b41f90da 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsV2CriteriaResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsResponseV2.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; -import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.response.ResponseInfo; import javax.validation.Valid; @@ -15,7 +14,7 @@ @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class MdmsV2CriteriaResponse { +public class MdmsResponseV2 { @JsonProperty("ResponseInfo") @Valid private ResponseInfo responseInfo = null; From bb72eeb4293cd498d8f61a01419528ae2d802e70 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 16 Sep 2024 15:20:52 +0530 Subject: [PATCH 021/351] added DB migration script for plan_employee_assignment table --- ...800__plan_employee_assignment_create_ddl.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql new file mode 100644 index 00000000000..c6a0c797eaa --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql @@ -0,0 +1,17 @@ +-- Table: plan_employee_assignment +CREATE TABLE plan_employee_assignment ( + id character varying(64), + tenant_id character varying(64), + plan_configuration_id character varying(64), + employee_id character varying(64), + role character varying(64), + jurisdiction text[] DEFAULT '{}', + additional_details JSONB, + active boolean DEFAULT true, + created_by character varying(64), + created_time bigint, + last_modified_by character varying(64), + last_modified_time bigint, + CONSTRAINT uk_plan_employee_assignment_id PRIMARY KEY (id), + FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id) +); From 427202edae682b763f4a1f8a904e6facdf0aec08 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 18 Sep 2024 14:54:13 +0530 Subject: [PATCH 022/351] HCMPRE-503 updating flyway version in Dockerfile for flyway migration --- health-services/plan-service/src/main/resources/db/Dockerfile | 2 +- .../src/main/resources/db/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/resources/db/Dockerfile b/health-services/plan-service/src/main/resources/db/Dockerfile index 60fc07ce69f..f5241a8f861 100644 --- a/health-services/plan-service/src/main/resources/db/Dockerfile +++ b/health-services/plan-service/src/main/resources/db/Dockerfile @@ -1,4 +1,4 @@ -FROM egovio/flyway:4.1.2 +FROM egovio/flyway:10.7.1 COPY ./migration/main /flyway/sql diff --git a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile b/health-services/resource-estimation-service/src/main/resources/db/Dockerfile index 60fc07ce69f..f5241a8f861 100644 --- a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile +++ b/health-services/resource-estimation-service/src/main/resources/db/Dockerfile @@ -1,4 +1,4 @@ -FROM egovio/flyway:4.1.2 +FROM egovio/flyway:10.7.1 COPY ./migration/main /flyway/sql From 05bc3df79b3490fae594250b97877c652d1ec7cc Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 18 Sep 2024 15:10:32 +0530 Subject: [PATCH 023/351] formatting --- .../plan-service/src/main/java/digit/util/MdmsV2Util.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index 809a072954f..8a3601b9c86 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -36,10 +36,9 @@ public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, Stri StringBuilder uri = getMdmsV2Uri(); MdmsCriteriaReqV2 mdmsCriteriaReqV2 = getMdmsV2Request(requestInfo, tenantId, schemaCode); MdmsResponseV2 mdmsResponseV2 = null; - try{ + try { mdmsResponseV2 = restTemplate.postForObject(uri.toString(), mdmsCriteriaReqV2, MdmsResponseV2.class); - } catch (Exception e) - { + } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); } From 293f1d84c0f6f8bdfee35109cae9114e4aa5164b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 18 Sep 2024 15:58:38 +0530 Subject: [PATCH 024/351] Added controller, service layer, validator and enrichment layer for plan employee assignment --- .../main/java/digit/config/Configuration.java | 12 +++ .../java/digit/config/ServiceConstants.java | 5 + .../PlanEmployeeAssignmentRepository.java | 10 ++ .../impl/PlanEmployeeAssignmentImpl.java | 39 ++++++++ .../digit/service/PlanEmployeeService.java | 86 ++++++++++++++++ .../java/digit/service/PlanValidator.java | 13 ++- .../PlanEmployeeAssignmentEnricher.java | 43 ++++++++ .../src/main/java/digit/util/HrmsUtil.java | 58 +++++++++++ .../src/main/java/digit/util/ServiceUtil.java | 27 +++++ .../controllers/PlanEmployeeController.java | 62 ++++++++++++ .../digit/web/models/RequestInfoWrapper.java | 18 ++++ .../digit/web/models/hrms/Assignment.java | 53 ++++++++++ .../web/models/hrms/DeactivationDetails.java | 46 +++++++++ .../web/models/hrms/DepartmentalTest.java | 44 +++++++++ .../models/hrms/EducationalQualification.java | 49 +++++++++ .../java/digit/web/models/hrms/Employee.java | 99 +++++++++++++++++++ .../web/models/hrms/EmployeeDocument.java | 69 +++++++++++++ .../web/models/hrms/EmployeeRequest.java | 36 +++++++ .../web/models/hrms/EmployeeResponse.java | 32 ++++++ .../digit/web/models/hrms/Jurisdiction.java | 49 +++++++++ .../web/models/hrms/ReactivationDetails.java | 47 +++++++++ .../digit/web/models/hrms/ServiceHistory.java | 46 +++++++++ 22 files changed, 938 insertions(+), 5 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java create mode 100644 health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java create mode 100644 health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java create mode 100644 health-services/plan-service/src/main/java/digit/util/HrmsUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/controllers/PlanEmployeeController.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/RequestInfoWrapper.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 7cf4b3549f7..22bc1f4eb07 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -28,6 +28,12 @@ public class Configuration { @Value("${egov.mdms.search.endpoint}") private String mdmsEndPoint; + //HRMS + @Value("${egov.hrms.host}") + private String hrmsHost; + + @Value("${egov.hrms.search.endpoint}") + private String hrmsEndPoint; //Persister Topic @Value("${plan.configuration.create.topic}") @@ -36,6 +42,12 @@ public class Configuration { @Value("${plan.configuration.update.topic}") private String planConfigUpdateTopic; + @Value("${plan.employee.assignment.create.topic}") + private String planEmployeeAssignmentCreateTopic; + + @Value("${plan.employee.assignment.update.topic}") + private String planEmployeeAssignmentUpdateTopic; + @Value("${plan.create.topic}") private String planCreateTopic; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index ab694a05961..59754cb8048 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -12,6 +12,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; + public static final String ERROR_WHILE_FETCHING_DATA_FROM_HRMS = "Exception occurred while fetching employee from hrms: "; + public static final String RES_MSG_ID = "uief87324"; public static final String SUCCESSFUL = "successful"; public static final String FAILED = "failed"; @@ -55,6 +57,9 @@ public class ServiceConstants { public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE = "NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT"; public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE = "Invalid or incorrect TenantId. No mdms data found for provided Tenant."; + public static final String NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_CODE = "NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID"; + public static final String NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE = "Invalid or incorrect employee id. No hrms data found for provided employee id."; + public static final String SEARCH_CRITERIA_EMPTY_CODE = "SEARCH_CRITERIA_EMPTY"; public static final String SEARCH_CRITERIA_EMPTY_MESSAGE = "Search criteria cannot be empty"; diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java new file mode 100644 index 00000000000..557d010697b --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java @@ -0,0 +1,10 @@ +package digit.repository; + +import digit.web.models.PlanEmployeeAssignmentRequest; + +public interface PlanEmployeeAssignmentRepository { + + public void create(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest); + + public void update(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest); +} diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java new file mode 100644 index 00000000000..a724c239ab8 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -0,0 +1,39 @@ +package digit.repository.impl; + +import digit.config.Configuration; +import digit.kafka.Producer; +import digit.repository.PlanEmployeeAssignmentRepository; +import digit.web.models.PlanEmployeeAssignmentRequest; +import org.springframework.stereotype.Repository; + +@Repository +public class PlanEmployeeAssignmentImpl implements PlanEmployeeAssignmentRepository { + + private Producer producer; + + private Configuration config; + + public PlanEmployeeAssignmentImpl(Producer producer, Configuration config) + { + this.producer = producer; + this.config = config; + } + + /** + * Pushes a new plan employee assignment to persister kafka topic. + * @param planEmployeeAssignmentRequest The request containing the plan employee assignment details. + */ + @Override + public void create(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { + producer.push(config.getPlanEmployeeAssignmentCreateTopic(), planEmployeeAssignmentRequest); + } + + /** + * Pushes an updated existing plan employee assignment to persister kafka topic. + * @param planEmployeeAssignmentRequest The request containing the updated plan employee assignment details. + */ + @Override + public void update(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { + producer.push(config.getPlanEmployeeAssignmentUpdateTopic(), planEmployeeAssignmentRequest); + } +} diff --git a/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java new file mode 100644 index 00000000000..d0fbb68f108 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java @@ -0,0 +1,86 @@ +package digit.service; + +import digit.config.Configuration; +import digit.kafka.Producer; +import digit.repository.PlanEmployeeAssignmentRepository; +import digit.service.enrichment.PlanEmployeeAssignmentEnricher; +import digit.service.validator.PlanEmployeeAssignmentValidator; +import digit.util.ResponseInfoFactory; +import digit.web.models.*; +import org.egov.common.utils.ResponseInfoUtil; +import org.springframework.stereotype.Service; + +import java.util.Collections; + +@Service +public class PlanEmployeeService { + + Producer producer; + + Configuration config; + + ResponseInfoFactory responseInfoFactory; + + PlanEmployeeAssignmentRepository repository; + + PlanEmployeeAssignmentEnricher enricher; + + PlanEmployeeAssignmentValidator validator; + + public PlanEmployeeService(Producer producer, Configuration config, ResponseInfoFactory responseInfoFactory, PlanEmployeeAssignmentRepository repository, PlanEmployeeAssignmentEnricher enricher, PlanEmployeeAssignmentValidator validator) + { + this.producer = producer; + this.config = config; + this.responseInfoFactory = responseInfoFactory; + this.repository = repository; + this.enricher = enricher; + this.validator = validator; + } + + /** + * Creates a new plan employee assignment based on the provided request. + * @param request The request containing the plan employee assignment details. + * @return The response containing the created plan employee assignment. + */ + public PlanEmployeeAssignmentResponse create(PlanEmployeeAssignmentRequest request) { + + validator.validateCreate(request); + enricher.enrichCreate(request); + repository.create(request); + + return PlanEmployeeAssignmentResponse.builder() + .planEmployeeAssignment(Collections.singletonList(request.getPlanEmployeeAssignment())) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) + .build(); + } + + /** + * Searches for plan employee assignment based on the provided search criteria. + * @param request The search request containing the criteria. + * @return A list of plan employee assignments that matches the search criteria. + */ + public PlanEmployeeAssignmentResponse search(PlanEmployeeAssignmentSearchRequest request) { + + return PlanEmployeeAssignmentResponse.builder(). + responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) + .build(); + } + + /** + * Updates an existing plan employee assignment based on the provided request. + * @param request The request containing the updated plan employee assignment details. + * @return The response containing the updated plan employee assignment. + */ + + public PlanEmployeeAssignmentResponse update(PlanEmployeeAssignmentRequest request) { + + validator.validateUpdate(request); + enricher.enrichUpdate(request); + repository.update(request); + + return PlanEmployeeAssignmentResponse.builder() + .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) + .planEmployeeAssignment(Collections.singletonList(request.getPlanEmployeeAssignment())) + .build(); + } +} diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 40958a9e0d3..cca38f58e19 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -4,6 +4,7 @@ import digit.repository.PlanConfigurationRepository; import digit.repository.PlanRepository; import digit.util.MdmsUtil; +import digit.util.ServiceUtil; import digit.web.models.*; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; @@ -27,11 +28,14 @@ public class PlanValidator { private MultiStateInstanceUtil centralInstanceUtil; - public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil) { + private ServiceUtil serviceUtil; + + public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, ServiceUtil serviceUtil) { this.planRepository = planRepository; this.planConfigurationRepository = planConfigurationRepository; this.mdmsUtil = mdmsUtil; this.centralInstanceUtil = centralInstanceUtil; + this.serviceUtil = serviceUtil; } /** @@ -163,10 +167,9 @@ private void validateActivities(PlanRequest request) { */ private void validatePlanConfigurationExistence(PlanRequest request) { // If plan id provided is invalid, throw an exception - if(!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && CollectionUtils.isEmpty(planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() - .id(request.getPlan().getPlanConfigurationId()) - .tenantId(request.getPlan().getTenantId()) - .build()))) { + if(!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && + CollectionUtils.isEmpty(serviceUtil.searchPlanConfigId(request.getPlan().getPlanConfigurationId(), request.getPlan().getTenantId()))) + { throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); } } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java new file mode 100644 index 00000000000..ff716387626 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -0,0 +1,43 @@ +package digit.service.enrichment; + +import digit.web.models.PlanEmployeeAssignment; +import digit.web.models.PlanEmployeeAssignmentRequest; +import org.egov.common.utils.UUIDEnrichmentUtil; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; + +@Component +public class PlanEmployeeAssignmentEnricher { + + /** + * Enriches the PlanEmployeeAssignmentRequest with id and audit details. + * @param request The PlanEmployeeAssignmentRequest body to be enriched + */ + public void enrichCreate(PlanEmployeeAssignmentRequest request) + { + PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); + + // Generate id for Plan employee assignment body + UUIDEnrichmentUtil.enrichRandomUuid(planEmployeeAssignment, "id"); + + // Set Audit Details for Plan employee assignment + planEmployeeAssignment.setAuditDetails(prepareAuditDetails(planEmployeeAssignment.getAuditDetails(), + request.getRequestInfo(), + Boolean.TRUE)); + } + + /** + * Enriches the PlanEmployeeAssignmentRequest for updating an existing plan employee assignment with audit details. + * @param request The PlanEmployeeAssignmentRequest body to be enriched + */ + public void enrichUpdate(PlanEmployeeAssignmentRequest request) + { + PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); + + // Set Audit Details for Plan employee assignment update + planEmployeeAssignment.setAuditDetails(prepareAuditDetails(planEmployeeAssignment.getAuditDetails(), + request.getRequestInfo(), + Boolean.FALSE)); + } +} diff --git a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java new file mode 100644 index 00000000000..fac5852a01c --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java @@ -0,0 +1,58 @@ +package digit.util; + + +import digit.config.Configuration; +import digit.web.models.hrms.*; +import digit.web.models.RequestInfoWrapper; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + + +import java.util.*; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class HrmsUtil { + + private RestTemplate restTemplate; + + private Configuration configs; + + private RequestInfoWrapper requestInfoWrapper; + + public HrmsUtil(RestTemplate restTemplate, Configuration configs, RequestInfoWrapper requestInfoWrapper) + { + this.restTemplate = restTemplate; + this.configs = configs; + this.requestInfoWrapper = requestInfoWrapper; + } + + public List fetchHrmsData(RequestInfo requestInfo, String employeeId, String tenantId) { + + StringBuilder uri = new StringBuilder(); + uri.append(configs.getHrmsHost()).append(configs.getHrmsEndPoint()).append("?limit={limit}&tenantId={tenantId}&offset={offset}&ids={employeeId}"); + + Map uriParameters = new HashMap<>(); + uriParameters.put("limit", configs.getDefaultLimit().toString()); + uriParameters.put("tenantId", tenantId); + uriParameters.put("offset", configs.getDefaultOffset().toString()); + uriParameters.put("employeeId", employeeId); + + RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); + EmployeeResponse employeeResponse = new EmployeeResponse(); + + try { + employeeResponse = restTemplate.postForObject(uri.toString(), requestInfoWrapper, EmployeeResponse.class, uriParameters); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_DATA_FROM_HRMS, e); + } + + return employeeResponse.getEmployees(); + } + + +} diff --git a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java index 51959990534..373127d63aa 100644 --- a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java @@ -1,13 +1,24 @@ package digit.util; +import digit.repository.PlanConfigurationRepository; +import digit.web.models.PlanConfiguration; +import digit.web.models.PlanConfigurationSearchCriteria; import org.springframework.stereotype.Component; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @Component public class ServiceUtil { + private PlanConfigurationRepository planConfigurationRepository; + + public ServiceUtil(PlanConfigurationRepository planConfigurationRepository) + { + this.planConfigurationRepository = planConfigurationRepository; + } + /** * Validates the given input string against the provided regex pattern. * @@ -20,4 +31,20 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri Matcher matcher = pattern.matcher(inputString); return matcher.matches(); } + + /** + * Searches the plan config based on the plan config id provided + * @param planConfigId the plan config id to validate + * @param tenantId the tenant id of the plan config + * @return list of planConfiguration for the provided plan config id + */ + public List searchPlanConfigId(String planConfigId, String tenantId) + { + List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() + .id(planConfigId) + .tenantId(tenantId) + .build()); + + return planConfigurations; + } } diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanEmployeeController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanEmployeeController.java new file mode 100644 index 00000000000..db707f9e872 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanEmployeeController.java @@ -0,0 +1,62 @@ +package digit.web.controllers; + +import digit.service.PlanEmployeeService; +import digit.web.models.*; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +public class PlanEmployeeController { + + PlanEmployeeService planEmployeeService; + + public PlanEmployeeController(PlanEmployeeService planEmployeeService) + { + this.planEmployeeService = planEmployeeService; + } + + /** + * Request handler for serving plan employee assignment create requests + * @param body + * @return + */ + @RequestMapping(value = "/employee/_create", method = RequestMethod.POST) + public ResponseEntity employeeCreatePost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody PlanEmployeeAssignmentRequest body) { + + PlanEmployeeAssignmentResponse response = planEmployeeService.create(body); + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + + } + + /** + * Request handler for serving plan employee assignment search requests + * @param body + * @return + */ + @RequestMapping(value = "/employee/_search", method = RequestMethod.POST) + public ResponseEntity employeeSearchPost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody PlanEmployeeAssignmentSearchRequest body) { + + PlanEmployeeAssignmentResponse response = planEmployeeService.search(body); + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + /** + * Request handler for serving plan employee assignment update requests + * @param body + * @return + */ + @RequestMapping(value = "/employee/_update", method = RequestMethod.POST) + public ResponseEntity employeeUpdatePost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody PlanEmployeeAssignmentRequest body) { + + PlanEmployeeAssignmentResponse response = planEmployeeService.update(body); + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/RequestInfoWrapper.java b/health-services/plan-service/src/main/java/digit/web/models/RequestInfoWrapper.java new file mode 100644 index 00000000000..9613a753b82 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/RequestInfoWrapper.java @@ -0,0 +1,18 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Component +public class RequestInfoWrapper { + + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java new file mode 100644 index 00000000000..b14d6e616f6 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java @@ -0,0 +1,53 @@ +package digit.web.models.hrms; + + +import javax.validation.constraints.NotNull; + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.*; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@AllArgsConstructor +@Builder +@Getter +@NoArgsConstructor +@Setter +@ToString +public class Assignment { + + private String id; + + private Long position; + + @NotNull + private String designation; + + @NotNull + private String department; + + @NotNull + private Long fromDate; + + private Long toDate; + + private String govtOrderNumber; + + private String tenantid; + + private String reportingTo; + + @JsonProperty("isHOD") + private Boolean isHOD; + + @NotNull + @JsonProperty("isCurrentAssignment") + private Boolean isCurrentAssignment; + + private AuditDetails auditDetails; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java new file mode 100644 index 00000000000..73e08c0446d --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java @@ -0,0 +1,46 @@ +package digit.web.models.hrms; + + +import javax.validation.constraints.NotNull; + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class DeactivationDetails { + + private String id; + + @NotNull + private String reasonForDeactivation; + + private String orderNo; + + private String remarks; + + @NotNull + private Long effectiveFrom; + + private String tenantId; + + private AuditDetails auditDetails; + + + + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java new file mode 100644 index 00000000000..982ff7e6aad --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java @@ -0,0 +1,44 @@ +package digit.web.models.hrms; + + +import javax.validation.constraints.NotNull; + + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class DepartmentalTest { + + private String id; + + @NotNull + private String test; + + @NotNull + private Long yearOfPassing; + + private String remarks; + + private String tenantId; + + private AuditDetails auditDetails; + + private Boolean isActive; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java new file mode 100644 index 00000000000..c1c82017647 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java @@ -0,0 +1,49 @@ +package digit.web.models.hrms; + + +import javax.validation.constraints.NotNull; + + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class EducationalQualification { + private String id; + + @NotNull + private String qualification; + + @NotNull + private String stream; + + @NotNull + private Long yearOfPassing; + + private String university; + + private String remarks; + + private String tenantId; + + private AuditDetails auditDetails; + + private Boolean isActive; + + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java new file mode 100644 index 00000000000..a4de5473f27 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java @@ -0,0 +1,99 @@ +package digit.web.models.hrms; + + + +import java.util.ArrayList; +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + + +import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.request.User; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; + +@Validated +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class Employee { + + private Long id; + + private String uuid; + + @Size(min = 1, max = 256) + private String code; + + @NotNull + private String employeeStatus; + + @NotNull + private String employeeType; + + private Long dateOfAppointment; + + @Valid + @NonNull + @Size(min = 1,max = 50) + private List jurisdictions = new ArrayList<>(); + + + @Valid + @NonNull + @Size(min = 1) + private List assignments = new ArrayList<>(); + + @Valid + @Size(max=25) + private List serviceHistory = new ArrayList<>(); + + + private Boolean isActive; + + @Valid + @Size(max=25) + private List education = new ArrayList<>(); + + @Valid + @Size(max=25) + private List tests = new ArrayList<>(); + + @NotNull + @Size(max = 256) + private String tenantId; + + @Valid + @Size(max=50) + private List documents = new ArrayList<>(); + + @Valid + private List deactivationDetails = new ArrayList<>(); + + private List reactivationDetails = new ArrayList<>(); + + private AuditDetails auditDetails; + + private Boolean reActivateEmployee; + + @Valid + @NotNull + private User user; + + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java new file mode 100644 index 00000000000..86a77013762 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java @@ -0,0 +1,69 @@ +package digit.web.models.hrms; + + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = { "auditDetails" }) +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class EmployeeDocument { + + private String id; + + private String documentName; + + private String documentId; + + private EmployeeDocumentReferenceType referenceType; + + private String referenceId; + + private String tenantId; + + private AuditDetails auditDetails; + + public enum EmployeeDocumentReferenceType { + HEADER("HEADER"), ASSIGNMENT("ASSIGNMENT"), JURISDICTION("JURISDICTION"), SERVICE("SERVICE"), + EDUCATION("EDUCATION"), TEST("TEST"), DEACTIVATION("DEACTIVATION"); + + private String value; + + EmployeeDocumentReferenceType(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return name(); + } + + @JsonCreator + public static EmployeeDocumentReferenceType fromValue(String passedValue) { + for (EmployeeDocumentReferenceType obj : EmployeeDocumentReferenceType.values()) { + if (String.valueOf(obj.value).equalsIgnoreCase(passedValue)) { + return obj; + } + } + return null; + } + } + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java new file mode 100644 index 00000000000..00c62c9b846 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java @@ -0,0 +1,36 @@ +package digit.web.models.hrms; + + +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +@Validated +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmployeeRequest { + + @NotNull + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + + @Valid + @NonNull + @JsonProperty("Employees") + private List employees; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java new file mode 100644 index 00000000000..890c19a476f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java @@ -0,0 +1,32 @@ +package digit.web.models.hrms; + + +import java.util.List; + +import org.egov.common.contract.response.ResponseInfo; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +@Builder +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +public class EmployeeResponse { + + @JsonProperty("ResponseInfo") + private ResponseInfo responseInfo; + + @JsonProperty("Employees") + private List employees; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java new file mode 100644 index 00000000000..cc5a3fc62e9 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java @@ -0,0 +1,49 @@ +package digit.web.models.hrms; + + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class Jurisdiction { + + private String id; + + @NotNull + @Size(min=2, max=100) + private String hierarchy; + + @NotNull + @Size(min=2, max=100) + private String boundary; + + @NotNull + @Size(max=256) + private String boundaryType; + + private String tenantId; + + private AuditDetails auditDetails; + + private Boolean isActive; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java new file mode 100644 index 00000000000..b0c95cffdc3 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java @@ -0,0 +1,47 @@ +package digit.web.models.hrms; + +import javax.validation.constraints.NotNull; + + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class ReactivationDetails { + + private String id; + + @NotNull + private String reasonForReactivation; + + private String orderNo; + + private String remarks; + + @NotNull + private Long effectiveFrom; + + private String tenantId; + + private AuditDetails auditDetails; + + + + +} + diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java new file mode 100644 index 00000000000..592aa078479 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java @@ -0,0 +1,46 @@ +package digit.web.models.hrms; + + + +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class ServiceHistory { + + private String id; + + private String serviceStatus; + + private Long serviceFrom; + + private Long serviceTo; + + private String orderNo; + + private String location; + + private String tenantId; + + private Boolean isCurrentPosition; + + private AuditDetails auditDetails; + + + +} From 57a5861664d53902b5fe81268e70707953dd3065 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 19 Sep 2024 10:59:24 +0530 Subject: [PATCH 025/351] HCMPRE-503 updating migrate.sh file for LTS upgrade --- health-services/plan-service/src/main/resources/db/migrate.sh | 2 +- .../src/main/resources/db/migrate.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/resources/db/migrate.sh b/health-services/plan-service/src/main/resources/db/migrate.sh index 43960b25cdb..c58d6f91e3f 100644 --- a/health-services/plan-service/src/main/resources/db/migrate.sh +++ b/health-services/plan-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true -ignoreMissingMigrations=true migrate \ No newline at end of file +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate \ No newline at end of file diff --git a/health-services/resource-estimation-service/src/main/resources/db/migrate.sh b/health-services/resource-estimation-service/src/main/resources/db/migrate.sh index 43960b25cdb..c58d6f91e3f 100644 --- a/health-services/resource-estimation-service/src/main/resources/db/migrate.sh +++ b/health-services/resource-estimation-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true -ignoreMissingMigrations=true migrate \ No newline at end of file +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate \ No newline at end of file From fc6bbbd6bb977a641a2713906914ad3f84a3e28c Mon Sep 17 00:00:00 2001 From: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:34:54 +0530 Subject: [PATCH 026/351] Update Dockerfile --- health-services/plan-service/src/main/resources/db/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/Dockerfile b/health-services/plan-service/src/main/resources/db/Dockerfile index f5241a8f861..f38638a269f 100644 --- a/health-services/plan-service/src/main/resources/db/Dockerfile +++ b/health-services/plan-service/src/main/resources/db/Dockerfile @@ -6,4 +6,4 @@ COPY migrate.sh /usr/bin/migrate.sh RUN chmod +x /usr/bin/migrate.sh -CMD ["/usr/bin/migrate.sh"] \ No newline at end of file +ENTRYPOINT ["/usr/bin/migrate.sh"] From 318872757d595cd1dabdc96267a5e47082d5faff Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 19 Sep 2024 15:41:32 +0530 Subject: [PATCH 027/351] Added pojos for project factory and hrms, and validations --- .../main/java/digit/config/Configuration.java | 7 + .../java/digit/config/ServiceConstants.java | 8 + .../PlanEmployeeAssignmentEnricher.java | 8 +- .../PlanEmployeeAssignmentValidator.java | 179 ++++++++++++++++++ .../main/java/digit/util/CampaignUtil.java | 56 ++++++ .../src/main/java/digit/util/HrmsUtil.java | 18 +- .../web/models/projectFactory/Boundary.java | 32 ++++ .../models/projectFactory/CampaignDetail.java | 87 +++++++++ .../projectFactory/CampaignResponse.java | 29 +++ .../CampaignSearchCriteria.java | 51 +++++ .../projectFactory/CampaignSearchReq.java | 22 +++ .../web/models/projectFactory/Condition.java | 27 +++ .../models/projectFactory/DeliveryRule.java | 43 +++++ .../web/models/projectFactory/Pagination.java | 35 ++++ .../web/models/projectFactory/Product.java | 27 +++ .../web/models/projectFactory/Resource.java | 32 ++++ 16 files changed, 650 insertions(+), 11 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java create mode 100644 health-services/plan-service/src/main/java/digit/util/CampaignUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 22bc1f4eb07..cca4bab1a54 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -35,6 +35,13 @@ public class Configuration { @Value("${egov.hrms.search.endpoint}") private String hrmsEndPoint; + //Project Factory + @Value("${egov.project.factory.host}") + private String projectFactoryHost; + + @Value("${egov.project.factory.search.endpoint}") + private String projectFactorySearchEndPoint; + //Persister Topic @Value("${plan.configuration.create.topic}") private String planConfigCreateTopic; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 59754cb8048..dbebe6f4d4e 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -12,6 +12,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; + public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from project factory: "; + public static final String ERROR_WHILE_FETCHING_DATA_FROM_HRMS = "Exception occurred while fetching employee from hrms: "; public static final String RES_MSG_ID = "uief87324"; @@ -60,6 +62,12 @@ public class ServiceConstants { public static final String NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_CODE = "NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID"; public static final String NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE = "Invalid or incorrect employee id. No hrms data found for provided employee id."; + public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; + public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; + + public static final String INVALID_EMPLOYEE_JURISDICTION_CODE = "INVALID_EMPLOYEE_JURISDICTION"; + public static final String INVALID_EMPLOYEE_JURISDICTION_MESSAGE = "The provided employee's jurisdiction is invalid"; + public static final String SEARCH_CRITERIA_EMPTY_CODE = "SEARCH_CRITERIA_EMPTY"; public static final String SEARCH_CRITERIA_EMPTY_MESSAGE = "Search criteria cannot be empty"; diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java index ff716387626..96121ac318f 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -12,10 +12,10 @@ public class PlanEmployeeAssignmentEnricher { /** * Enriches the PlanEmployeeAssignmentRequest with id and audit details. + * * @param request The PlanEmployeeAssignmentRequest body to be enriched */ - public void enrichCreate(PlanEmployeeAssignmentRequest request) - { + public void enrichCreate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); // Generate id for Plan employee assignment body @@ -29,10 +29,10 @@ public void enrichCreate(PlanEmployeeAssignmentRequest request) /** * Enriches the PlanEmployeeAssignmentRequest for updating an existing plan employee assignment with audit details. + * * @param request The PlanEmployeeAssignmentRequest body to be enriched */ - public void enrichUpdate(PlanEmployeeAssignmentRequest request) - { + public void enrichUpdate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); // Set Audit Details for Plan employee assignment update diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java new file mode 100644 index 00000000000..7eebf25501f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -0,0 +1,179 @@ +package digit.service.validator; + +import digit.util.CampaignUtil; +import digit.util.HrmsUtil; +import digit.util.ServiceUtil; +import digit.web.models.PlanConfiguration; +import digit.web.models.PlanEmployeeAssignment; +import digit.web.models.PlanEmployeeAssignmentRequest; +import digit.web.models.hrms.EmployeeResponse; +import digit.web.models.projectFactory.Boundary; +import digit.web.models.projectFactory.CampaignDetail; +import digit.web.models.projectFactory.CampaignResponse; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.utils.MultiStateInstanceUtil; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class PlanEmployeeAssignmentValidator { + + private MultiStateInstanceUtil centralInstanceUtil; + + private HrmsUtil hrmsUtil; + + private ServiceUtil serviceUtil; + + private CampaignUtil campaignUtil; + + public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, HrmsUtil hrmsUtil, ServiceUtil serviceUtil, CampaignUtil campaignUtil) { + this.centralInstanceUtil = centralInstanceUtil; + this.hrmsUtil = hrmsUtil; + this.serviceUtil = serviceUtil; + this.campaignUtil = campaignUtil; + } + + + /** + * This method validates the create request for plan employee assignment. + * + * @param request The create request for plan employee assignment + */ + public void validateCreate(PlanEmployeeAssignmentRequest request) { + PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); + String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); + List planConfigurations = serviceUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); + + // Validate if plan config id exists + validatePlanConfigId(planConfigurations); + + // Validate if employee exists against hrms + validateEmployeeAgainstHRMS(request); + + // Validate campaign id and employee jurisdiction + validateCampaignDetails(planConfigurations.get(0).getExecutionPlanId(), rootTenantId, request); + } + + + /** + * This method validates campaign id and employee's jurisdiction against project factory + * + * @param campaignId the campaign id corresponding to the plan config id provided in the request + * @param tenantId the tenant id provided in the request + * @param planEmployeeAssignmentRequest the plan employee assignment request provided + */ + private void validateCampaignDetails(String campaignId, String tenantId, PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { + + PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentRequest.getPlanEmployeeAssignment(); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planEmployeeAssignmentRequest.getRequestInfo(), campaignId, tenantId); + + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + + // Validate the provided jurisdiction for employee + validateEmployeeJurisdiction(campaignResponse.getCampaignDetails().get(0), planEmployeeAssignment); + } + + /** + * This method validates if employee's jurisdiction exist in campaign details + * + * @param campaignDetail the campaign details for the corresponding campaign id + * @param planEmployeeAssignment the plan employee assignment provided in request + */ + private void validateEmployeeJurisdiction(CampaignDetail campaignDetail, PlanEmployeeAssignment planEmployeeAssignment) { + + // Collect all boundary code for the campaign + Set boundaryCode = campaignDetail.getBoundaries().stream() + .map(Boundary::getCode) + .collect(Collectors.toSet()); + + planEmployeeAssignment.getJurisdiction().stream() + .forEach(jurisdiction -> { + if (!boundaryCode.contains(jurisdiction)) { + throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); + } + }); + + } + + /** + * This method validates if the campaign id provided in the request exists + * + * @param campaignResponse The campaign details response from project factory + */ + private void validateCampaignId(CampaignResponse campaignResponse) { + + if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { + throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); + } + } + + /** + * This method validates if the employee provided in plan employee assignment request exist in hrms + * + * @param request The request for plan employee assignment + */ + private void validateEmployeeAgainstHRMS(PlanEmployeeAssignmentRequest request) { + + PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); + EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); + + if (CollectionUtils.isEmpty(employeeResponse.getEmployees())) { + log.error(NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE + " - " + planEmployeeAssignment.getEmployeeId()); + throw new CustomException(NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_CODE, NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE); + } + } + + + /** + * This method validates if the plan configuration id provided in the request exists + * + * @param planConfigurations The list of plan configuration for the provided plan config id + */ + private void validatePlanConfigId(List planConfigurations) { + if (CollectionUtils.isEmpty(planConfigurations)) { + throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); + } + } + + + /** + * This method validates the update request for plan employee assignment. + * + * @param request The update request for plan employee assignment. + */ + public void validateUpdate(PlanEmployeeAssignmentRequest request) { + PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); + String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); + List planConfigurations = serviceUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); + + // Validate if Plan employee assignment exists + validatePlanEmployeeAssignment(planEmployeeAssignment); + + // Validate if plan config id exists + validatePlanConfigId(planConfigurations); + + // Validate if employee exists against hrms + validateEmployeeAgainstHRMS(request); + + // Validate campaign id and employee jurisdiction + validateCampaignDetails(planConfigurations.get(0).getExecutionPlanId(), rootTenantId, request); + + } + + /** + * This method validates if the plan employee assignment id provided in the update request exists + * + * @param planEmployeeAssignment The plan employee assignment details from the request + */ + private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeAssignment) { + + } +} diff --git a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java new file mode 100644 index 00000000000..b7044e841a7 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java @@ -0,0 +1,56 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.projectFactory.*; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class CampaignUtil { + + private RestTemplate restTemplate; + + private Configuration configs; + + public CampaignUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campaignId, String tenantId) { + StringBuilder uri = new StringBuilder(); + uri = uri.append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndPoint()); + + CampaignSearchReq campaignSearchReq = getSearchReq(requestInfo, campaignId, tenantId); + CampaignResponse campaignResponse = new CampaignResponse(); + try { + campaignResponse = restTemplate.postForObject(uri.toString(), campaignSearchReq, CampaignResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY, e); + } + + return campaignResponse; + } + + private CampaignSearchReq getSearchReq(RequestInfo requestInfo, String campaignId, String tenantId) { + Pagination pagination = Pagination.builder().limit(configs.getDefaultLimit()).offset(configs.getDefaultOffset()).build(); + CampaignSearchCriteria searchCriteria = CampaignSearchCriteria.builder() + .ids(Collections.singletonList(campaignId)) + .tenantId(tenantId) + .pagination(pagination) + .build(); + + return CampaignSearchReq.builder() + .requestInfo(requestInfo) + .campaignSearchCriteria(searchCriteria) + .build(); + } + +} diff --git a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java index fac5852a01c..252ab35c82c 100644 --- a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java @@ -22,16 +22,20 @@ public class HrmsUtil { private Configuration configs; - private RequestInfoWrapper requestInfoWrapper; - public HrmsUtil(RestTemplate restTemplate, Configuration configs, RequestInfoWrapper requestInfoWrapper) - { + public HrmsUtil(RestTemplate restTemplate, Configuration configs) { this.restTemplate = restTemplate; this.configs = configs; - this.requestInfoWrapper = requestInfoWrapper; } - public List fetchHrmsData(RequestInfo requestInfo, String employeeId, String tenantId) { + /** + * This method fetches data from HRMS service for provided employeeId + * + * @param employeeId employee id provided in the request + * @param requestInfo request info from the request + * @param tenantId tenant id from the request + */ + public EmployeeResponse fetchHrmsData(RequestInfo requestInfo, String employeeId, String tenantId) { StringBuilder uri = new StringBuilder(); uri.append(configs.getHrmsHost()).append(configs.getHrmsEndPoint()).append("?limit={limit}&tenantId={tenantId}&offset={offset}&ids={employeeId}"); @@ -46,12 +50,12 @@ public List fetchHrmsData(RequestInfo requestInfo, String employeeId, EmployeeResponse employeeResponse = new EmployeeResponse(); try { - employeeResponse = restTemplate.postForObject(uri.toString(), requestInfoWrapper, EmployeeResponse.class, uriParameters); + employeeResponse = restTemplate.postForObject(uri.toString(), requestInfoWrapper, EmployeeResponse.class, uriParameters); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_DATA_FROM_HRMS, e); } - return employeeResponse.getEmployees(); + return employeeResponse; } diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java new file mode 100644 index 00000000000..1661f3329d9 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java @@ -0,0 +1,32 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Boundary + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Boundary { + + @JsonProperty("code") + private String code; + + @JsonProperty("type") + private String type; + + @JsonProperty("isRoot") + private Boolean isRoot; + + @JsonProperty("includeAllChildren") + private Boolean includeAllChildren; + + @JsonProperty("parent") + private String parent; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java new file mode 100644 index 00000000000..9b920859072 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java @@ -0,0 +1,87 @@ +package digit.web.models.projectFactory; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; + +import java.util.List; + +/** + * CampaignDetails + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CampaignDetail { + + @JsonProperty("id") + private String id; + + @JsonProperty("tenantId") + @NotNull + private String tenantId; + + @JsonProperty("status") + private String status; + + @JsonProperty("action") + private String action; + + @JsonProperty("campaignNumber") + private String campaignNumber; + + @JsonProperty("isActive") + private Boolean isActive; + + @JsonProperty("parentId") + private String parentId; + + @JsonProperty("campaignName") + private String campaignName; + + @JsonProperty("projectType") + private String projectType; + + @JsonProperty("hierarchyType") + private String hierarchyType; + + @JsonProperty("boundaryCode") + private String boundaryCode; + + @JsonProperty("projectId") + private String projectId; + + @JsonProperty("startDate") + private Long startDate; + + @JsonProperty("endDate") + private Long endDate; + + @JsonProperty("additionalDetails") + @Valid + private Object additionalDetails; + + @JsonProperty("resources") + @Valid + private List resources; + + @JsonProperty("boundaries") + @Valid + private List boundaries; + + @JsonProperty("deliveryRules") + @Valid + private List deliveryRules; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails; +} + + diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java new file mode 100644 index 00000000000..4c2c1108fdf --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java @@ -0,0 +1,29 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.*; +import org.egov.common.contract.response.ResponseInfo; + +import java.util.List; + +/** + * CampaignResponse + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CampaignResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("CampaignDetails") + @Valid + private List campaignDetails = null; + + @JsonProperty("totalCount") + @Valid + private Integer totalCount = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java new file mode 100644 index 00000000000..2638663fa11 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java @@ -0,0 +1,51 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * CampaignSearchCriteria + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Validated +public class CampaignSearchCriteria { + + @JsonProperty("ids") + @Size(min = 1) + private List ids; + + @JsonProperty("tenantId") + @Size(min = 2, max = 256) + private String tenantId; + + @JsonIgnore + private List status; + + @JsonIgnore + private String createdBy; + + @JsonIgnore + private Boolean campaignsIncludeDates; + + @JsonIgnore + private Integer startDate; + + @JsonIgnore + private Integer endDate; + + @JsonProperty("pagination") + @Valid + private Pagination pagination; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java new file mode 100644 index 00000000000..ad83d373652 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java @@ -0,0 +1,22 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.Builder; +import lombok.Data; +import org.egov.common.contract.request.RequestInfo; + +/** + * CampaignSearchReq + */ +@Data +@Builder +public class CampaignSearchReq { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo; + + @JsonProperty("CampaignDetails") + private CampaignSearchCriteria campaignSearchCriteria; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java new file mode 100644 index 00000000000..5ad19e29aef --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java @@ -0,0 +1,27 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Condition + **/ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Condition { + + @JsonProperty("value") + private String value; + + @JsonProperty("operator") + private String operator; + + @JsonProperty("attribute") + private String attribute; +} + diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java new file mode 100644 index 00000000000..7eef58fd8ae --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java @@ -0,0 +1,43 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * DeliveryRule + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DeliveryRule { + + @JsonProperty("endDate") + private Long endDate; + + @JsonProperty("products") + @Valid + private List products; + + @JsonProperty("startDate") + private Long startDate; + + @JsonProperty("conditions") + @Valid + private List conditions; + + @JsonProperty("cycleNumber") + private Integer cycleNumber; + + @JsonProperty("deliveryNumber") + private Integer deliveryNumber; + + @JsonProperty("deliveryRuleNumber") + private Integer deliveryRuleNumber; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java new file mode 100644 index 00000000000..7e8d28c30ce --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java @@ -0,0 +1,35 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Pagination + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Pagination { + + @JsonIgnore + private String sortBy; + + @JsonIgnore + private String sortOrder; + + @JsonProperty("limit") + @Min(1) + @Max(50) + private Integer limit; + + @JsonProperty("offset") + @Min(0) + private Integer offset; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java new file mode 100644 index 00000000000..9508480da05 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java @@ -0,0 +1,27 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Product + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Product { + + @JsonProperty("name") + private String name; + + @JsonProperty("count") + private Integer count; + + @JsonProperty("value") + private String value; +} + diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java new file mode 100644 index 00000000000..3a45c4fa9b8 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java @@ -0,0 +1,32 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Resource + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Resource { + + @JsonProperty("type") + private String type; + + @JsonProperty("filename") + private String filename; + + @JsonProperty("resourceId") + private String resourceId; + + @JsonProperty("filestoreId") + private String filestoreId; + + @JsonProperty("createResourceId") + private String createResourceId; +} From e34fad1421c0e4c9c7db99e54ef337ba86a7524b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 19 Sep 2024 15:58:54 +0530 Subject: [PATCH 028/351] DB migration Script --- .../V20242109141800__plan_employee_assignment_create_ddl.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql index c6a0c797eaa..768d92201de 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql @@ -5,7 +5,7 @@ CREATE TABLE plan_employee_assignment ( plan_configuration_id character varying(64), employee_id character varying(64), role character varying(64), - jurisdiction text[] DEFAULT '{}', + jurisdiction JSONB, additional_details JSONB, active boolean DEFAULT true, created_by character varying(64), From 2f5b713f98cbe192f653f2e9e05be4a42ed95688 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 19 Sep 2024 16:16:35 +0530 Subject: [PATCH 029/351] added hrms and project factory urls --- .../src/main/resources/application.properties | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 03ee3da916d..3789512de58 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -49,10 +49,21 @@ plan.configuration.update.topic=plan-config-update-topic plan.create.topic=save-plan plan.update.topic=update-plan +plan.employee.assignment.create.topic=plan-employee-assignment-create-topic +plan.employee.assignment.update.topic=plan-employee-assignment-update-topic + #mdms urls egov.mdms.host=https://unified-dev.digit.org egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +#hrms urls +egov.hrms.host=https://unified-dev.digit.org +egov.hrms.search.endpoint=/health-hrms/employees/_search + +#project factory urls +egov.project.factory.host=https://unified-dev.digit.org +egov.project.factory.search.endpoint=/project-factory/v1/project-type/search + # Pagination config plan.default.offset=0 plan.default.limit=10 From b7648eb200aadf9c76a6e94fc162bc6f240398bc Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 23 Sep 2024 17:26:56 +0530 Subject: [PATCH 030/351] changed jurisdiction from JSONB to TEXT --- .../V20242109141800__plan_employee_assignment_create_ddl.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql index 768d92201de..002b34d35ff 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql @@ -5,7 +5,7 @@ CREATE TABLE plan_employee_assignment ( plan_configuration_id character varying(64), employee_id character varying(64), role character varying(64), - jurisdiction JSONB, + jurisdiction TEXT, additional_details JSONB, active boolean DEFAULT true, created_by character varying(64), From b6c6846908cd8855af9030b71a83862af494a435 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 23 Sep 2024 17:40:28 +0530 Subject: [PATCH 031/351] QueryBuilder and RowMapper for planEmployeeAssignment search api --- .../PlanEmployeeAssignmentRepository.java | 6 +- .../impl/PlanEmployeeAssignmentImpl.java | 46 ++++++++++- .../PlanEmployeeAssignmentQueryBuilder.java | 75 ++++++++++++++++++ .../PlanEmployeeAssignmentRowMapper.java | 62 +++++++++++++++ .../repository/rowmapper/PlanRowMapper.java | 29 ++----- .../digit/service/PlanEmployeeService.java | 15 ++-- .../PlanEmployeeAssignmentValidator.java | 22 +++++- .../src/main/java/digit/util/QueryUtil.java | 30 ++++++- .../src/main/java/digit/util/ServiceUtil.java | 79 +++++++++++++++++-- .../web/models/PlanEmployeeAssignmentDTO.java | 60 ++++++++++++++ .../PlanEmployeeAssignmentRequestDTO.java | 30 +++++++ 11 files changed, 405 insertions(+), 49 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequestDTO.java diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java index 557d010697b..e900e1b41a2 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java @@ -1,10 +1,14 @@ package digit.repository; -import digit.web.models.PlanEmployeeAssignmentRequest; +import digit.web.models.*; + +import java.util.List; public interface PlanEmployeeAssignmentRepository { public void create(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest); + public List search(PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria); + public void update(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index a724c239ab8..4fd363cd385 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -3,9 +3,19 @@ import digit.config.Configuration; import digit.kafka.Producer; import digit.repository.PlanEmployeeAssignmentRepository; +import digit.repository.querybuilder.PlanEmployeeAssignmentQueryBuilder; +import digit.repository.rowmapper.PlanEmployeeAssignmentRowMapper; +import digit.util.ServiceUtil; +import digit.web.models.PlanEmployeeAssignment; +import digit.web.models.PlanEmployeeAssignmentRequestDTO; import digit.web.models.PlanEmployeeAssignmentRequest; +import digit.web.models.PlanEmployeeAssignmentSearchCriteria; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; +import java.util.ArrayList; +import java.util.List; + @Repository public class PlanEmployeeAssignmentImpl implements PlanEmployeeAssignmentRepository { @@ -13,27 +23,55 @@ public class PlanEmployeeAssignmentImpl implements PlanEmployeeAssignmentReposit private Configuration config; - public PlanEmployeeAssignmentImpl(Producer producer, Configuration config) - { + private PlanEmployeeAssignmentQueryBuilder queryBuilder; + + private JdbcTemplate jdbcTemplate; + + private PlanEmployeeAssignmentRowMapper rowMapper; + + private ServiceUtil serviceUtil; + + public PlanEmployeeAssignmentImpl(Producer producer, Configuration config, PlanEmployeeAssignmentQueryBuilder queryBuilder, JdbcTemplate jdbcTemplate, PlanEmployeeAssignmentRowMapper rowMapper, ServiceUtil serviceUtil) { this.producer = producer; this.config = config; + this.queryBuilder = queryBuilder; + this.jdbcTemplate = jdbcTemplate; + this.rowMapper = rowMapper; + this.serviceUtil = serviceUtil; } /** * Pushes a new plan employee assignment to persister kafka topic. + * * @param planEmployeeAssignmentRequest The request containing the plan employee assignment details. */ @Override public void create(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { - producer.push(config.getPlanEmployeeAssignmentCreateTopic(), planEmployeeAssignmentRequest); + PlanEmployeeAssignmentRequestDTO requestDTO = serviceUtil.convertToReqDTO(planEmployeeAssignmentRequest); + producer.push(config.getPlanEmployeeAssignmentCreateTopic(), requestDTO); + } + + /** + * Searches for Plan employee assignments based on provided search criteria + * + * @param searchCriteria The criteria used for searching plan employee assignments + * @return A list of Plan employee assignments that matches the search criteria + */ + @Override + public List search(PlanEmployeeAssignmentSearchCriteria searchCriteria) { + List preparedStmtList = new ArrayList<>(); + String searchQuery = queryBuilder.getPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); + return jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); } /** * Pushes an updated existing plan employee assignment to persister kafka topic. + * * @param planEmployeeAssignmentRequest The request containing the updated plan employee assignment details. */ @Override public void update(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { - producer.push(config.getPlanEmployeeAssignmentUpdateTopic(), planEmployeeAssignmentRequest); + PlanEmployeeAssignmentRequestDTO requestDTO = serviceUtil.convertToReqDTO(planEmployeeAssignmentRequest); + producer.push(config.getPlanEmployeeAssignmentUpdateTopic(), requestDTO); } } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java new file mode 100644 index 00000000000..fd192d38435 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -0,0 +1,75 @@ +package digit.repository.querybuilder; + +import digit.config.Configuration; +import digit.util.QueryUtil; +import digit.web.models.PlanEmployeeAssignmentSearchCriteria; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class PlanEmployeeAssignmentQueryBuilder { + + private QueryUtil queryUtil; + + public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { + this.queryUtil = queryUtil; + } + + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; + + /** + * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. + * Also adds an ORDER BY clause and handles pagination. + * + * @param searchCriteria The criteria used for filtering PlanEmployeeAssignment objects. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A complete SQL query string for searching PlanEmployeeAssignment objects. + */ + public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { + String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); + query = queryUtil.addOrderByClause(query, PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = queryUtil.getPaginatedQuery(query, preparedStmtList); + return query; + } + + /** + * Constructs query based on the provided search criteria + * + * @param searchCriteria The criteria used for filtering PlanEmployeeAssignment objects. + * @param preparedStmtList A list to store prepared statement parameters. + * @return + */ + private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { + StringBuilder builder = new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); + + if (searchCriteria.getTenantId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" tenant_id = ?"); + preparedStmtList.add(searchCriteria.getTenantId()); + } + + if (searchCriteria.getPlanConfigurationId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" plan_configuration_id = ?"); + preparedStmtList.add(searchCriteria.getPlanConfigurationId()); + } + + if (searchCriteria.getRole() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" role = ?"); + preparedStmtList.add(searchCriteria.getRole()); + } + + if (searchCriteria.getActive() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" active = ?"); + preparedStmtList.add(Boolean.TRUE); + } + + return builder.toString(); + } + +} diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java new file mode 100644 index 00000000000..faf538252a5 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -0,0 +1,62 @@ +package digit.repository.rowmapper; + +import digit.util.ServiceUtil; +import digit.web.models.PlanEmployeeAssignment; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.models.AuditDetails; +import org.postgresql.util.PGobject; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +@Slf4j +@Component +public class PlanEmployeeAssignmentRowMapper implements ResultSetExtractor> { + + private ServiceUtil serviceUtil; + + public PlanEmployeeAssignmentRowMapper(ServiceUtil serviceUtil) { + this.serviceUtil = serviceUtil; + } + + @Override + public List extractData(ResultSet rs) throws SQLException, DataAccessException { + Map planEmployeeAssignmentMap = new LinkedHashMap<>(); + + while (rs.next()) { + String planEmployeeAssignmentId = rs.getString("id"); + + PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentMap.get(planEmployeeAssignmentId); + + if (ObjectUtils.isEmpty(planEmployeeAssignment)) { + planEmployeeAssignment = new PlanEmployeeAssignment(); + + // Prepare audit details + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("created_by")).createdTime(rs.getLong("created_time")).lastModifiedBy(rs.getString("last_modified_by")).lastModifiedTime(rs.getLong("last_modified_time")).build(); + + // Converting jurisdiction from comma separated string to a list of string + String jurisdiction = rs.getString("jurisdiction"); + List jurisdictionList = Arrays.asList(jurisdiction.split(", ")); + + // Prepare PlanEmployeeAssignment object + planEmployeeAssignment.setId(planEmployeeAssignmentId); + planEmployeeAssignment.setTenantId(rs.getString("tenant_id")); + planEmployeeAssignment.setPlanConfigurationId(rs.getString("plan_configuration_id")); + planEmployeeAssignment.setEmployeeId(rs.getString("employee_id")); + planEmployeeAssignment.setRole(rs.getString("role")); + planEmployeeAssignment.setJurisdiction(jurisdictionList); + planEmployeeAssignment.setAdditionalDetails(serviceUtil.getAdditionalDetail((PGobject) rs.getObject("additional_details"))); + planEmployeeAssignment.setAuditDetails(auditDetails); + + planEmployeeAssignmentMap.put(planEmployeeAssignmentId, planEmployeeAssignment); + } + } + + return new ArrayList<>(planEmployeeAssignmentMap.values()); + } +} diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index a82919fed46..91197c133c6 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java @@ -1,10 +1,8 @@ package digit.repository.rowmapper; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import digit.util.ServiceUtil; import digit.web.models.*; import org.egov.common.contract.models.AuditDetails; -import org.egov.tracer.model.CustomException; import org.postgresql.util.PGobject; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ResultSetExtractor; @@ -12,7 +10,6 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -20,10 +17,10 @@ @Component public class PlanRowMapper implements ResultSetExtractor> { - private ObjectMapper objectMapper; + private ServiceUtil serviceUtil; - public PlanRowMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; + public PlanRowMapper(ServiceUtil serviceUtil) { + this.serviceUtil = serviceUtil; } @Override @@ -57,7 +54,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep planEntry.setLocality(rs.getString("plan_locality")); planEntry.setExecutionPlanId(rs.getString("plan_execution_plan_id")); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); - planEntry.setAdditionalDetails(getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); + planEntry.setAdditionalDetails(serviceUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); planEntry.setAuditDetails(auditDetails); } @@ -228,20 +225,4 @@ private void addTargets(ResultSet rs, Plan planEntry, Map target targetMap.put(target.getId(), target); } - - private JsonNode getAdditionalDetail(PGobject pGobject){ - JsonNode additionalDetail = null; - - try { - if(ObjectUtils.isEmpty(pGobject)){ - additionalDetail = objectMapper.readTree(pGobject.getValue()); - } - } - catch (IOException e){ - throw new CustomException("PARSING_ERROR", "Failed to parse additionalDetails object"); - } - - return additionalDetail; - } - } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java index d0fbb68f108..05117fb221e 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java @@ -27,8 +27,7 @@ public class PlanEmployeeService { PlanEmployeeAssignmentValidator validator; - public PlanEmployeeService(Producer producer, Configuration config, ResponseInfoFactory responseInfoFactory, PlanEmployeeAssignmentRepository repository, PlanEmployeeAssignmentEnricher enricher, PlanEmployeeAssignmentValidator validator) - { + public PlanEmployeeService(Producer producer, Configuration config, ResponseInfoFactory responseInfoFactory, PlanEmployeeAssignmentRepository repository, PlanEmployeeAssignmentEnricher enricher, PlanEmployeeAssignmentValidator validator) { this.producer = producer; this.config = config; this.responseInfoFactory = responseInfoFactory; @@ -39,11 +38,11 @@ public PlanEmployeeService(Producer producer, Configuration config, ResponseInfo /** * Creates a new plan employee assignment based on the provided request. + * * @param request The request containing the plan employee assignment details. * @return The response containing the created plan employee assignment. */ public PlanEmployeeAssignmentResponse create(PlanEmployeeAssignmentRequest request) { - validator.validateCreate(request); enricher.enrichCreate(request); repository.create(request); @@ -56,24 +55,26 @@ public PlanEmployeeAssignmentResponse create(PlanEmployeeAssignmentRequest reque /** * Searches for plan employee assignment based on the provided search criteria. + * * @param request The search request containing the criteria. * @return A list of plan employee assignments that matches the search criteria. */ public PlanEmployeeAssignmentResponse search(PlanEmployeeAssignmentSearchRequest request) { + validator.validateSearch(request); - return PlanEmployeeAssignmentResponse.builder(). - responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) + return PlanEmployeeAssignmentResponse.builder() + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) + .planEmployeeAssignment(repository.search(request.getPlanEmployeeAssignmentSearchCriteria())) .build(); } /** * Updates an existing plan employee assignment based on the provided request. + * * @param request The request containing the updated plan employee assignment details. * @return The response containing the updated plan employee assignment. */ - public PlanEmployeeAssignmentResponse update(PlanEmployeeAssignmentRequest request) { - validator.validateUpdate(request); enricher.enrichUpdate(request); repository.update(request); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 7eebf25501f..afe9164c0ff 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -3,14 +3,13 @@ import digit.util.CampaignUtil; import digit.util.HrmsUtil; import digit.util.ServiceUtil; -import digit.web.models.PlanConfiguration; -import digit.web.models.PlanEmployeeAssignment; -import digit.web.models.PlanEmployeeAssignmentRequest; +import digit.web.models.*; import digit.web.models.hrms.EmployeeResponse; import digit.web.models.projectFactory.Boundary; import digit.web.models.projectFactory.CampaignDetail; import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -72,7 +71,7 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { private void validateCampaignDetails(String campaignId, String tenantId, PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentRequest.getPlanEmployeeAssignment(); - CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planEmployeeAssignmentRequest.getRequestInfo(), campaignId, tenantId); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planEmployeeAssignmentRequest.getRequestInfo(), campaignId, tenantId); // Validate if campaign id exists against project factory validateCampaignId(campaignResponse); @@ -143,6 +142,21 @@ private void validatePlanConfigId(List planConfigurations) { } } + /** + * Validates the search request for plan employee assignment + * + * @param request the request to search plan employee assignment + */ + public void validateSearch(PlanEmployeeAssignmentSearchRequest request) { + PlanEmployeeAssignmentSearchCriteria searchCriteria = request.getPlanEmployeeAssignmentSearchCriteria(); + if (Objects.isNull(searchCriteria)) { + throw new CustomException(SEARCH_CRITERIA_EMPTY_CODE, SEARCH_CRITERIA_EMPTY_MESSAGE); + } + + if (StringUtils.isEmpty(searchCriteria.getTenantId())) { + throw new CustomException(TENANT_ID_EMPTY_CODE, TENANT_ID_EMPTY_MESSAGE); + } + } /** * This method validates the update request for plan employee assignment. diff --git a/health-services/plan-service/src/main/java/digit/util/QueryUtil.java b/health-services/plan-service/src/main/java/digit/util/QueryUtil.java index 84817b60870..d2da03ec1b0 100644 --- a/health-services/plan-service/src/main/java/digit/util/QueryUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/QueryUtil.java @@ -1,6 +1,8 @@ package digit.util; import com.google.gson.Gson; +import digit.config.Configuration; +import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; @@ -11,10 +13,14 @@ import static digit.config.ServiceConstants.DOT_REGEX; import static digit.config.ServiceConstants.DOT_SEPARATOR; - +@Component public class QueryUtil { - private QueryUtil(){} + private Configuration config; + + private QueryUtil(Configuration config) { + this.config = config; + } private static final Gson gson = new Gson(); @@ -123,4 +129,24 @@ else if (index == nestedKeyArray.length - 1) { prepareNestedQueryMap(index + 1, nestedKeyArray, (Map) currentQueryMap.get(nestedKeyArray[index]), value); } + /** + * This method adds pagination to the query + * + * @param query + * @param preparedStmtList + * @return + */ + public String getPaginatedQuery(String query, List preparedStmtList) { + StringBuilder paginatedQuery = new StringBuilder(query); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(config.getDefaultOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(config.getDefaultLimit()); + + return paginatedQuery.toString(); + } } diff --git a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java index 373127d63aa..d3352bcc070 100644 --- a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java @@ -1,22 +1,30 @@ package digit.util; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import digit.repository.PlanConfigurationRepository; -import digit.web.models.PlanConfiguration; -import digit.web.models.PlanConfigurationSearchCriteria; +import digit.web.models.*; +import org.egov.tracer.model.CustomException; +import org.postgresql.util.PGobject; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import java.io.IOException; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; @Component public class ServiceUtil { private PlanConfigurationRepository planConfigurationRepository; - public ServiceUtil(PlanConfigurationRepository planConfigurationRepository) - { + private ObjectMapper objectMapper; + + public ServiceUtil(PlanConfigurationRepository planConfigurationRepository, ObjectMapper objectMapper) { this.planConfigurationRepository = planConfigurationRepository; + this.objectMapper = objectMapper; } /** @@ -34,12 +42,12 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri /** * Searches the plan config based on the plan config id provided + * * @param planConfigId the plan config id to validate - * @param tenantId the tenant id of the plan config + * @param tenantId the tenant id of the plan config * @return list of planConfiguration for the provided plan config id */ - public List searchPlanConfigId(String planConfigId, String tenantId) - { + public List searchPlanConfigId(String planConfigId, String tenantId) { List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() .id(planConfigId) .tenantId(tenantId) @@ -47,4 +55,61 @@ public List searchPlanConfigId(String planConfigId, String te return planConfigurations; } + + /** + * Converts the PlanEmployeeAssignmentRequest to a data transfer object (DTO) + * + * @param planEmployeeAssignmentRequest The request to be converted to DTO + * @return a DTO for PlanEmployeeAssignmentRequest + */ + public PlanEmployeeAssignmentRequestDTO convertToReqDTO(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { + PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentRequest.getPlanEmployeeAssignment(); + + // Creating a new data transfer object (DTO) for PlanEmployeeAssignment + PlanEmployeeAssignmentDTO planEmployeeAssignmentDTO = PlanEmployeeAssignmentDTO.builder() + .id(planEmployeeAssignment.getId()) + .tenantId(planEmployeeAssignment.getTenantId()) + .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) + .employeeId(planEmployeeAssignment.getEmployeeId()) + .role(planEmployeeAssignment.getRole()) + .jurisdiction(convertArrayToString(planEmployeeAssignment.getJurisdiction())) + .additionalDetails(planEmployeeAssignment.getAdditionalDetails()) + .active(planEmployeeAssignment.getActive()) + .auditDetails(planEmployeeAssignment.getAuditDetails()) + .build(); + + return PlanEmployeeAssignmentRequestDTO.builder() + .requestInfo(planEmployeeAssignmentRequest.getRequestInfo()) + .planEmployeeAssignmentDTO(planEmployeeAssignmentDTO) + .build(); + } + + /** + * This is a helper function to convert an array of string to comma separated string + * + * @param stringList Array of string to be converted + * @return a string + */ + private String convertArrayToString(List stringList) { + return String.join(", ", stringList); + } + + /** + * This method is used to extract and parse JSON data into a JsonNode object + * + * @param pGobject postgreSQL specific object + * @return returns a JsonNode + */ + public JsonNode getAdditionalDetail(PGobject pGobject) { + JsonNode additionalDetail = null; + + try { + if (!ObjectUtils.isEmpty(pGobject)) { + additionalDetail = objectMapper.readTree(pGobject.getValue()); + } + } catch (IOException e) { + throw new CustomException("PARSING_ERROR", "Failed to parse additionalDetails object"); + } + return additionalDetail; + } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java new file mode 100644 index 00000000000..9c57bbf4554 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java @@ -0,0 +1,60 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * PlanEmployeeAssignmentDTO + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentDTO { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @NotNull + @Size(min = 2, max = 64) + private String planConfigurationId = null; + + @JsonProperty("employeeId") + @NotNull + @Size(min = 2, max = 64) + private String employeeId = null; + + @JsonProperty("role") + @NotNull + @Size(min = 2, max = 64) + private String role = null; + + @JsonProperty("jurisdiction") + @Valid + private String jurisdiction = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + private Boolean active = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequestDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequestDTO.java new file mode 100644 index 00000000000..f21bc83a3e8 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequestDTO.java @@ -0,0 +1,30 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + + +/** + * PlanEmployeeAssignmentRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentRequestDTO { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanEmployeeAssignment") + @Valid + private PlanEmployeeAssignmentDTO planEmployeeAssignmentDTO = null; +} From 5c5a3d21811cbbe644aebb82d8c1f4753cc5817f Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 24 Sep 2024 14:38:37 +0530 Subject: [PATCH 032/351] added function to filter by jurisdiction in search api --- .../impl/PlanEmployeeAssignmentImpl.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index ab3dc15e2e3..2e6619e6ae9 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -12,9 +12,13 @@ import digit.web.models.PlanEmployeeAssignmentSearchCriteria; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; @Repository public class PlanEmployeeAssignmentImpl implements PlanEmployeeAssignmentRepository { @@ -61,7 +65,14 @@ public void create(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) public List search(PlanEmployeeAssignmentSearchCriteria searchCriteria) { List preparedStmtList = new ArrayList<>(); String searchQuery = queryBuilder.getPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); - return jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); + List planEmployeeAssignments = jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); + + // If searchCriteria has jurisdiction, filter the list of planEmployeeAssignments by jurisdiction + if (!CollectionUtils.isEmpty(searchCriteria.getJurisdiction())) { + planEmployeeAssignments = filterByJurisdiction(planEmployeeAssignments, searchCriteria.getJurisdiction()); + } + + return planEmployeeAssignments; } /** @@ -74,4 +85,26 @@ public void update(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) PlanEmployeeAssignmentRequestDTO requestDTO = commonUtil.convertToReqDTO(planEmployeeAssignmentRequest); producer.push(config.getPlanEmployeeAssignmentUpdateTopic(), requestDTO); } + + /** + * This is a helper method to filter out list of PlanEmployeeAssignment by jurisdiction provided + * + * @param planEmployeeAssignments List of planEmployeeAssignment based on search criteria + * @param jurisdictionFromSearchCriteria jurisdiction provided in search criteria + * @return a list of planEmployeeAssignment filtered by jurisdiction + */ + private List filterByJurisdiction(List planEmployeeAssignments, List jurisdictionFromSearchCriteria) { + + // Convert jurisdictionFromSearchCriteria to a Set + Set jurisdictionSet = new HashSet<>(jurisdictionFromSearchCriteria); + + return planEmployeeAssignments.stream().filter(assignment -> { + for (String jurisdiction : assignment.getJurisdiction()) { + if (jurisdictionSet.contains(jurisdiction)) { + return true; + } + } + return false; + }).collect(Collectors.toList()); + } } From de092a7c74fccfdf3983e7467a884b3e11d32501 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 24 Sep 2024 15:28:32 +0530 Subject: [PATCH 033/351] pull from microplanning-dev --- .../src/main/java/digit/config/Configuration.java | 5 ----- .../java/digit/web/controllers/PlanConfigController.java | 1 - .../src/main/java/digit/web/models/PlanConfiguration.java | 3 --- .../digit/web/models/PlanConfigurationSearchCriteria.java | 1 - .../src/main/java/digit/web/models/mdmsV2/Mdms.java | 1 - 5 files changed, 11 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 03ea5c05d16..d0e9ca38962 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -1,16 +1,11 @@ package digit.config; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.*; import org.egov.tracer.config.TracerConfiguration; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Component; -import java.util.TimeZone; @Component @Data diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanConfigController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanConfigController.java index 4729cdd736e..d50610832e9 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanConfigController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanConfigController.java @@ -3,7 +3,6 @@ import digit.service.PlanConfigurationService; import digit.util.ResponseInfoFactory; -import digit.web.models.PlanConfiguration; import digit.web.models.PlanConfigurationRequest; import digit.web.models.PlanConfigurationResponse; import digit.web.models.PlanConfigurationSearchRequest; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index afab6d9b113..970037cf4ec 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -1,9 +1,6 @@ package digit.web.models; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; -import jakarta.validation.constraints.NotEmpty; import java.util.ArrayList; import java.util.List; import jakarta.validation.Valid; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java index 7362278ccec..2f9f3cd7831 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java @@ -1,6 +1,5 @@ package digit.web.models; -import jakarta.validation.Valid; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java index 96ffefc2bf2..be5e324cd5f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; From b781dacbca8e9f722607dcf42f84a3da92936ab5 Mon Sep 17 00:00:00 2001 From: palak-egov Date: Tue, 24 Sep 2024 15:55:35 +0530 Subject: [PATCH 034/351] plan facility search API --- .../repository/PlanFacilityRepository.java | 13 +++ .../impl/PlanFacilityRepositoryImpl.java | 94 +++++++++++++++++++ .../PlanFacilityQueryBuilder.java | 90 ++++++++++++++++++ .../rowmapper/PlanFacilityRowMapper.java | 78 +++++++++++++++ .../digit/service/PlanFacilityService.java | 35 +++++++ .../src/main/java/digit/util/ServiceUtil.java | 23 +++++ .../controllers/PlanFacilityController.java | 28 ++++++ .../java/digit/web/models/PlanFacility.java | 69 ++++++++++++++ .../digit/web/models/PlanFacilityRequest.java | 30 ++++++ .../web/models/PlanFacilityResponse.java | 44 +++++++++ .../models/PlanFacilitySearchCriteria.java | 39 ++++++++ .../web/models/PlanFacilitySearchRequest.java | 30 ++++++ .../src/main/resources/application.properties | 2 +- ...240923113045__plan_facility_create_ddl.sql | 18 ++++ 14 files changed, 592 insertions(+), 1 deletion(-) create mode 100644 health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java create mode 100644 health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java create mode 100644 health-services/plan-service/src/main/java/digit/util/ServiceUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java new file mode 100644 index 00000000000..ec1ec2191cf --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java @@ -0,0 +1,13 @@ +package digit.repository; + +import digit.web.models.*; + +import java.util.List; + +public interface PlanFacilityRepository { + public void create(PlanFacilityRequest planFacilityRequest); + + public List search(PlanFacilitySearchCriteria planSearchCriteria); + + public void update(PlanFacilityRequest planFacilityRequest); +} diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java new file mode 100644 index 00000000000..f47aff0fb9e --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -0,0 +1,94 @@ +package digit.repository.impl; + +import digit.config.Configuration; +import digit.kafka.Producer; +import digit.repository.PlanFacilityRepository; +import digit.repository.querybuilder.PlanFacilityQueryBuilder; +import digit.repository.querybuilder.PlanQueryBuilder; +import digit.repository.rowmapper.PlanFacilityRowMapper; +import digit.repository.rowmapper.PlanRowMapper; +import digit.web.models.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.SingleColumnRowMapper; +import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +@Repository +@Slf4j +public class PlanFacilityRepositoryImpl implements PlanFacilityRepository { + private Producer producer; + private JdbcTemplate jdbcTemplate; + + private PlanFacilityQueryBuilder planFacilityQueryBuilder; + + private PlanFacilityRowMapper planFacilityRowMapper; + private Configuration config; + + public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, PlanFacilityQueryBuilder planFacilityQueryBuilder, PlanFacilityRowMapper planFacilityRowMapper, Configuration config) { + this.producer = producer; + this.jdbcTemplate = jdbcTemplate; + this.planFacilityQueryBuilder = planFacilityQueryBuilder; + this.planFacilityRowMapper = planFacilityRowMapper; + this.config = config; + } + + @Override + public void create(PlanFacilityRequest planFacilityRequest) { + + } + + /** + * This method searches for plans based on the search criteria. + * @param planFacilitySearchCriteria + * @return + */ + @Override + public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria) { + // Fetch plan facility ids from database + List planFacilityIds = queryDatabaseForPlanFacilityIds(planFacilitySearchCriteria); + + // Return empty list back as response if no plan facility ids are found + if(CollectionUtils.isEmpty(planFacilityIds)) { + log.info("No planFacility ids found for provided plan facility search criteria."); + return new ArrayList<>(); + } + + // Fetch plans facilities from database based on the acquired ids + List planFacilities = searchPlanFacilityByIds(planFacilityIds); + + return planFacilities; + } + + @Override + public void update(PlanFacilityRequest planFacilityRequest) { + + } + + /** + * Helper method to query database for plan facility ids based on the provided search criteria. + * @param planFacilitySearchCriteria + * @return + */ + private List queryDatabaseForPlanFacilityIds(PlanFacilitySearchCriteria planFacilitySearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = planFacilityQueryBuilder.getPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); + log.info("Plan search query: " + query); + return jdbcTemplate.query(query, new SingleColumnRowMapper<>(String.class), preparedStmtList.toArray()); + } + + /** + * Helper method to search for plans facility based on the provided plan ids. + * @param planFacilityIds + * @return + */ + private List searchPlanFacilityByIds(List planFacilityIds) { + List preparedStmtList = new ArrayList<>(); + String query = planFacilityQueryBuilder.getPlanFacilityQuery(planFacilityIds, preparedStmtList); + log.info("Plan facility query: " + query); + return jdbcTemplate.query(query, planFacilityRowMapper, preparedStmtList.toArray()); + } +} diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java new file mode 100644 index 00000000000..143a53ad259 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -0,0 +1,90 @@ +package digit.repository.querybuilder; + +import digit.config.Configuration; +import digit.util.QueryUtil; +import digit.web.models.PlanFacilitySearchCriteria; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.LinkedHashSet; +import java.util.List; + +@Component +public class PlanFacilityQueryBuilder { + + private Configuration config; + + public PlanFacilityQueryBuilder(Configuration config) { + this.config = config; + } + + private static final String PLAN_FACILITY_SEARCH_BASE_QUERY = "SELECT id FROM plan_facility_linkage "; + + private static final String PLAN_FACILITY_QUERY = "SELECT plan_facility_linkage.id as plan_facility_id, plan_facility_linkage.tenant_id as plan_facility_tenant_id, plan_facility_linkage.plan_configuration_id as plan_facility_plan_configuration_id, plan_facility_linkage.facility_id as plan_facility_facility_id, plan_facility_linkage.residing_boundary as plan_facility_residing_boundary, plan_facility_linkage.service_boundaries as plan_facility_service_boundaries, plan_facility_linkage.additional_details as plan_facility_additional_details, plan_facility_linkage.created_by as plan_facility_created_by, plan_facility_linkage.created_time as plan_facility_created_time, plan_facility_linkage.last_modified_by as plan_facility_last_modified_by, plan_facility_linkage.last_modified_time as plan_facility_last_modified_time, plan_facility_linkage.active as plan_facility_active FROM plan_facility_linkage"; + + private static final String PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE = " order by plan_facility_linkage.last_modified_time desc "; + + public String getPlanFacilityQuery(List ids, List preparedStmtList) { + return buildPlanFacilityQuery(ids, preparedStmtList); + } + + private String buildPlanFacilityQuery(List ids, List preparedStmtList) { + StringBuilder builder = new StringBuilder(PLAN_FACILITY_QUERY); + + if (!CollectionUtils.isEmpty(ids)) { + QueryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" plan_facility_linkage.id IN ( ").append(QueryUtil.createQuery(ids.size())).append(" )"); + QueryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); + } + + return builder.toString(); + } + public String getPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { + String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); + query = QueryUtil.addOrderByClause(query, PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = getPaginatedQuery(query, planFacilitySearchCriteria, preparedStmtList); + return query; + } + + private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { + StringBuilder builder = new StringBuilder(PLAN_FACILITY_SEARCH_BASE_QUERY); + + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getTenantId())) { + QueryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" tenant_id = ? "); + preparedStmtList.add(planFacilitySearchCriteria.getTenantId()); + } + + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getPlanConfigurationId())) { + QueryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" plan_configuration_id = ? "); + preparedStmtList.add(planFacilitySearchCriteria.getPlanConfigurationId()); + } + + if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getResidingBoundaries())){ + List residingBoundaries = planFacilitySearchCriteria.getResidingBoundaries(); + QueryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" residing_boundary IN ( ").append(QueryUtil.createQuery(residingBoundaries.size())).append(" )"); + QueryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(residingBoundaries)); + } + + return builder.toString(); + } + + private String getPaginatedQuery(String query, PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { + StringBuilder paginatedQuery = new StringBuilder(query); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(ObjectUtils.isEmpty(planFacilitySearchCriteria.getOffset()) ? config.getDefaultOffset() : planFacilitySearchCriteria.getOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(ObjectUtils.isEmpty(planFacilitySearchCriteria.getLimit()) ? config.getDefaultLimit() : planFacilitySearchCriteria.getLimit()); + + return paginatedQuery.toString(); + } + + +} diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java new file mode 100644 index 00000000000..7cc75ca63c1 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java @@ -0,0 +1,78 @@ +package digit.repository.rowmapper; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.web.models.PlanFacility; +import org.egov.common.contract.models.AuditDetails; +import org.egov.tracer.model.CustomException; +import org.postgresql.util.PGobject; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.io.IOException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +@Component +public class PlanFacilityRowMapper implements ResultSetExtractor> { + + private ObjectMapper objectMapper; + + public PlanFacilityRowMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public List extractData(ResultSet rs) throws SQLException, DataAccessException { + Map planFacilityMap = new LinkedHashMap<>(); + while(rs.next()){ + String planFacilityId = rs.getString("plan_facility_id"); + + PlanFacility planFacilityEntry = planFacilityMap.get(planFacilityId); + if(ObjectUtils.isEmpty(planFacilityEntry)){ + planFacilityEntry = new PlanFacility(); + + // Prepare audit details + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(rs.getString("plan_facility_created_by")) + .createdTime(rs.getLong("plan_facility_created_time")) + .lastModifiedBy(rs.getString("plan_facility_last_modified_by")) + .lastModifiedTime(rs.getLong("plan_facility_last_modified_time")) + .build(); + + // Prepare plan facility object + planFacilityEntry.setId(planFacilityId); + planFacilityEntry.setTenantId(rs.getString("plan_facility_tenant_id")); + planFacilityEntry.setPlanConfigurationId(rs.getString("plan_facility_plan_configuration_id")); + planFacilityEntry.setFacilityId(rs.getString("plan_facility_facility_id")); + planFacilityEntry.setResidingBoundary(rs.getString("plan_facility_residing_boundary")); + String serviceBoundaries = rs.getString("plan_facility_service_boundaries"); + planFacilityEntry.setServiceBoundaries(ObjectUtils.isEmpty(serviceBoundaries) ? new ArrayList<>() : Arrays.asList(rs.getString("plan_facility_service_boundaries").split(","))); + planFacilityEntry.setAdditionalDetails(getAdditionalDetail((PGobject) rs.getObject("plan_facility_additional_details"))); + planFacilityEntry.setAuditDetails(auditDetails); + planFacilityEntry.setActive(rs.getBoolean("plan_facility_active")); + } + + planFacilityMap.put(planFacilityId, planFacilityEntry); + } + return new ArrayList<>(planFacilityMap.values()); + } + + private JsonNode getAdditionalDetail(PGobject pGobject){ + JsonNode additionalDetail = null; + + try { + if(!ObjectUtils.isEmpty(pGobject)){ + additionalDetail = objectMapper.readTree(pGobject.getValue()); + } + } + catch (IOException e){ + throw new CustomException("PARSING_ERROR", "Failed to parse additionalDetails object"); + } + + return additionalDetail; + } +} diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java new file mode 100644 index 00000000000..e525fde7746 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -0,0 +1,35 @@ +package digit.service; + +import digit.repository.PlanFacilityRepository; +import digit.repository.PlanRepository; +import digit.web.models.*; +import org.egov.common.utils.ResponseInfoUtil; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class PlanFacilityService { + + private PlanFacilityRepository planFacilityRepository; + + public PlanFacilityService(PlanFacilityRepository planFacilityRepository) { + this.planFacilityRepository = planFacilityRepository; + } + + /** + * This method processes the requests that come for searching plans. + * @param body + * @return + */ + public PlanFacilityResponse searchPlanFacility(PlanFacilitySearchRequest body) { + // Delegate search request to repository + List planFacilityList = planFacilityRepository.search(body.getPlanFacilitySearchCriteria()); + + // Build and return response back to controller + return PlanFacilityResponse.builder() + .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(body.getRequestInfo(), Boolean.TRUE)) + .planFacility(planFacilityList) + .build(); + } +} diff --git a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java new file mode 100644 index 00000000000..51959990534 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java @@ -0,0 +1,23 @@ +package digit.util; + +import org.springframework.stereotype.Component; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Component +public class ServiceUtil { + + /** + * Validates the given input string against the provided regex pattern. + * + * @param patternString the regex pattern to validate against + * @param inputString the input string to be validated + * @return true if the input string matches the regex pattern, false otherwise + */ + public Boolean validateStringAgainstRegex(String patternString, String inputString) { + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(inputString); + return matcher.matches(); + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java new file mode 100644 index 00000000000..b6f285d61ef --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -0,0 +1,28 @@ +package digit.web.controllers; + + +import digit.service.PlanFacilityService; +import digit.web.models.PlanFacilityResponse; +import digit.web.models.PlanFacilitySearchRequest; +import digit.web.models.PlanResponse; +import digit.web.models.PlanSearchRequest; +import jakarta.validation.Valid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +@RequestMapping("plan") +public class PlanFacilityController { + @Autowired + private PlanFacilityService planFacilityService; + @RequestMapping(value = "/facility/_search", method = RequestMethod.POST) + public ResponseEntity searchPost(@Valid @RequestBody PlanFacilitySearchRequest body) { + PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(body); + return ResponseEntity.status(HttpStatus.OK).body(planFacilityResponse); + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java new file mode 100644 index 00000000000..9cbdd5537ed --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -0,0 +1,69 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import java.util.ArrayList; +import java.util.List; + +/** + * Plan Facility + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacility { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("facilityId") + @Size(max = 64) + private String facilityId = null; + + @JsonProperty("residingBoundary") + @Size(min = 1, max = 64) + private String residingBoundary = null; + + @JsonProperty("serviceBoundaries") + @Valid + private List serviceBoundaries = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + private Boolean active = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; + + + public PlanFacility addServiceBoundariesItem(String serviceBoundariesItem) { + if (this.serviceBoundaries == null) { + this.serviceBoundaries = new ArrayList<>(); + } + this.serviceBoundaries.add(serviceBoundariesItem); + return this; + } + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java new file mode 100644 index 00000000000..3406f2614ce --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java @@ -0,0 +1,30 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanFacilityRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityRequest { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanFacility") + @Valid + private PlanFacility planFacility = null; + + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java new file mode 100644 index 00000000000..d43710facbc --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java @@ -0,0 +1,44 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import java.util.ArrayList; +import java.util.List; + +/** + * PlanFacilityResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityResponse { + + @JsonProperty("ResponseInfo") + private ResponseInfo responseInfo = null; + + @JsonProperty("PlanFacility") + @Valid + private List planFacility = null; + + public PlanFacilityResponse responseInfo(ResponseInfo responseInfo) { + this.responseInfo = responseInfo; + return this; + } + + public PlanFacilityResponse addPlanFacilityItem(PlanFacility planFacilityItem) { + if (this.planFacility == null) { + this.planFacility = new ArrayList<>(); + } + this.planFacility.add(planFacilityItem); + return this; + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java new file mode 100644 index 00000000000..3a60edec530 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java @@ -0,0 +1,39 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; +import java.util.Set; + +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilitySearchCriteria { + + @JsonProperty("ids") + private Set ids = null; + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("planConfigurationId") + private String planConfigurationId = null; + + @JsonProperty("residingBoundaries") + private List residingBoundaries = null; + + @JsonProperty("offset") + private Integer offset = null; + + @JsonProperty("limit") + private Integer limit = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java new file mode 100644 index 00000000000..fd64c3da77f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java @@ -0,0 +1,30 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilitySearchRequest { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanFacilitySearchCriteria") + @Valid + private PlanFacilitySearchCriteria planFacilitySearchCriteria = null; + + +} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 25456401843..77c0cfde74a 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -9,7 +9,7 @@ app.timezone=UTC spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5432/plandb spring.datasource.username=postgres -spring.datasource.password=postgres +spring.datasource.password=123 #FLYWAY CONFIGURATION spring.flyway.url=jdbc:postgresql://localhost:5432/plandb diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql new file mode 100644 index 00000000000..f7c4e69cad3 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql @@ -0,0 +1,18 @@ +-- Table: plan_facility +CREATE TABLE plan_facility_linkage ( + id varchar(64), + tenant_id varchar(64), + plan_configuration_id varchar(64), + facility_id varchar(64), + residing_boundary varchar(64), + service_boundaries varchar(2048), + additional_details JSONB, + active boolean, + created_by varchar(64), + created_time bigint, + last_modified_by varchar(64), + last_modified_time bigint, + CONSTRAINT uk_plan_facility_linkage_id PRIMARY KEY (id), + FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id), + FOREIGN KEY (facility_id) REFERENCES facility(id) +); \ No newline at end of file From 00feaee29f349270647fc9442d544a16d21ebf0f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 24 Sep 2024 15:57:41 +0530 Subject: [PATCH 035/351] HCMPRE-470 adding changes for validating assumptions on the basis of campaign details --- .../java/digit/config/ServiceConstants.java | 20 ++++++- .../validator/PlanConfigurationValidator.java | 14 +++-- .../src/main/java/digit/util/CommonUtil.java | 57 ++++++++++++++++--- 3 files changed, 76 insertions(+), 15 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 1528951de9c..742b16c909c 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -174,10 +174,26 @@ public class ServiceConstants { public static final String BOUNDARY_CODE = "boundaryCode"; - public static final String FILTER_ALL_ASSUMPTIONS = "[*].assumptionCategories[*].assumptions[*]"; + public static final String FILTER_ALL_ASSUMPTIONS = ".assumptionCategories[*].assumptions[*]"; public static final String NAME_VALIDATION_DATA = "Data"; - public static final String VEHICLE_ID_FIELD = "vehicleIds"; + + // Constants for operators and JSON fields + public static final String AND = " && "; + public static final String EQUALS = " == "; + public static final String SINGLE_QUOTE = "'"; + public static final String CAMPAIGN_TYPE = "campaignType"; + public static final String DISTRIBUTION_PROCESS = "DistributionProcess"; + public static final String REGISTRATION_PROCESS = "RegistrationProcess"; + public static final String RESOURCE_DISTRIBUTION_STRATEGY_CODE = "resourceDistributionStrategyCode"; + public static final String IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "isRegistrationAndDistributionHappeningTogetherOrSeparately"; + + public static final String JSON_FIELD_CAMPAIGN_TYPE = "@.campaignType"; + public static final String JSON_FIELD_DISTRIBUTION_PROCESS = "@.DistributionProcess"; + public static final String JSON_FIELD_REGISTRATION_PROCESS = "@.RegistrationProcess"; + public static final String JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE = "@.resourceDistributionStrategyCode"; + public static final String JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "@.isRegistrationAndDistributionHappeningTogetherOrSeparately"; + public static final String JSON_FIELD_VEHICLE_ID = "vehicleIds"; } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index f2a291c53ed..005b9789a1b 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -151,8 +151,13 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + FILTER_ALL_ASSUMPTIONS; + Object additionalDetails = request.getPlanConfiguration().getAdditionalDetails(); + String jsonPathForAssumption = commonUtil.createJsonPathForAssumption((String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,CAMPAIGN_TYPE), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,DISTRIBUTION_PROCESS), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,REGISTRATION_PROCESS), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,RESOURCE_DISTRIBUTION_STRATEGY_CODE), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); List assumptionListFromMDMS = null; try { log.info(jsonPathForAssumption); @@ -541,16 +546,15 @@ public void validateUserInfo(PlanConfigurationRequest request) */ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, List mdmsV2Data) { - List vehicleIdsLinkedWithPlanConfig = commonUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); + List vehicleIdsLinkedWithPlanConfig = (List) commonUtil.extractFieldsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails(), JSON_FIELD_VEHICLE_ID); List vehicleIdsFromMdms = mdmsV2Data.stream() .map(Mdms::getId) - .collect(Collectors.toList()); + .toList(); - List finalVehicleIdsFromMdms = vehicleIdsFromMdms; vehicleIdsLinkedWithPlanConfig.stream() .forEach(vehicleId -> { - if(!finalVehicleIdsFromMdms.contains(vehicleId)) + if(!vehicleIdsFromMdms.contains(vehicleId)) { log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE); diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 07d2f01d7cd..20dbe458a11 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -44,23 +44,64 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri * @param additionalDetails the additionalDetails object from PlanConfigurationRequest * @return a list of vehicle Ids from additional details */ - public List extractVehicleIdsFromAdditionalDetails(Object additionalDetails) { + public Object extractFieldsFromAdditionalDetails(Object additionalDetails, String fieldToExtract) { try { String jsonString = objectMapper.writeValueAsString(additionalDetails); JsonNode rootNode = objectMapper.readTree(jsonString); - List vehicleIds = new ArrayList<>(); - JsonNode vehicleIdsNode = rootNode.get(VEHICLE_ID_FIELD); - if (vehicleIdsNode != null && vehicleIdsNode.isArray()) { - for (JsonNode idNode : vehicleIdsNode) { - vehicleIds.add(idNode.asText()); + List listFromAdditionalDetails = new ArrayList<>(); + JsonNode node = rootNode.get(fieldToExtract); + if (node != null && node.isArray()) { + for (JsonNode idNode : node) { + listFromAdditionalDetails.add(idNode.asText()); + } + return listFromAdditionalDetails; + } else if (node != null) { + // Return the value in its original type based on its type + if (node.isInt()) { + return node.asInt(); + } else if (node.isBoolean()) { + return node.asBoolean(); + } else if (node.isTextual()) { + return node.asText(); } } - - return vehicleIds; + // In case the node is of some other type (like object or binary), handle accordingly + return node; } catch (Exception e) { log.error(e.getMessage()); throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } } + + /** + * Constructs a JSONPath expression used to filter assumptions based on the given parameters - + * campaign type, distribution process, registration process, resource distribution strategy, + * and whether registration and distribution are together match the provided values. + * + * @param campaignType The type of campaign to filter by (e.g., "Health", "Education"). + * @param distributionProcess The process of distribution to filter by (e.g., "Central", "Decentralized"). + * @param registrationProcess The registration process to filter by (e.g., "Online", "In-Person"). + * @param resourceDistributionStrategyCode The strategy code for resource distribution to filter by (e.g., "Strategy1"). + * @param isRegistrationAndDistributionTogether Whether registration and distribution are combined, to filter by ("true"/"false"). + * @return A JSONPath expression string that filters assumptions based on the given criteria. + */ + public String createJsonPathForAssumption( + String campaignType, + String distributionProcess, + String registrationProcess, + String resourceDistributionStrategyCode, + String isRegistrationAndDistributionTogether + ) { + + StringBuilder jsonPathFilters = new StringBuilder("[?("); + jsonPathFilters.append(JSON_FIELD_CAMPAIGN_TYPE).append(EQUALS).append(SINGLE_QUOTE).append(campaignType).append(SINGLE_QUOTE) + .append(AND).append(JSON_FIELD_DISTRIBUTION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(distributionProcess).append(SINGLE_QUOTE) + .append(AND).append(JSON_FIELD_REGISTRATION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(registrationProcess).append(SINGLE_QUOTE) + .append(AND).append(JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE).append(EQUALS).append(SINGLE_QUOTE).append(resourceDistributionStrategyCode).append(SINGLE_QUOTE) + .append(AND).append(JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER).append(EQUALS).append(SINGLE_QUOTE).append(isRegistrationAndDistributionTogether).append(SINGLE_QUOTE) + .append(")]"); + + return JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + jsonPathFilters + FILTER_ALL_ASSUMPTIONS; + } } From 25c57d14d7ccfbf0fa4769f1b45b42a7c7fd801f Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Tue, 24 Sep 2024 22:29:27 +0530 Subject: [PATCH 036/351] Added pojos for PlanFacility --- .../java/digit/web/models/PlanFacility.java | 69 +++++++++++++++++++ .../digit/web/models/PlanFacilityRequest.java | 30 ++++++++ .../web/models/PlanFacilityResponse.java | 44 ++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java new file mode 100644 index 00000000000..9cbdd5537ed --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -0,0 +1,69 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import java.util.ArrayList; +import java.util.List; + +/** + * Plan Facility + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacility { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("facilityId") + @Size(max = 64) + private String facilityId = null; + + @JsonProperty("residingBoundary") + @Size(min = 1, max = 64) + private String residingBoundary = null; + + @JsonProperty("serviceBoundaries") + @Valid + private List serviceBoundaries = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + private Boolean active = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; + + + public PlanFacility addServiceBoundariesItem(String serviceBoundariesItem) { + if (this.serviceBoundaries == null) { + this.serviceBoundaries = new ArrayList<>(); + } + this.serviceBoundaries.add(serviceBoundariesItem); + return this; + } + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java new file mode 100644 index 00000000000..3406f2614ce --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java @@ -0,0 +1,30 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanFacilityRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityRequest { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanFacility") + @Valid + private PlanFacility planFacility = null; + + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java new file mode 100644 index 00000000000..d43710facbc --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java @@ -0,0 +1,44 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import java.util.ArrayList; +import java.util.List; + +/** + * PlanFacilityResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityResponse { + + @JsonProperty("ResponseInfo") + private ResponseInfo responseInfo = null; + + @JsonProperty("PlanFacility") + @Valid + private List planFacility = null; + + public PlanFacilityResponse responseInfo(ResponseInfo responseInfo) { + this.responseInfo = responseInfo; + return this; + } + + public PlanFacilityResponse addPlanFacilityItem(PlanFacility planFacilityItem) { + if (this.planFacility == null) { + this.planFacility = new ArrayList<>(); + } + this.planFacility.add(planFacilityItem); + return this; + } +} From 62ce120b970c409dbae080761542ff2ad4847bb2 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Tue, 24 Sep 2024 22:32:57 +0530 Subject: [PATCH 037/351] Plan facility - DB migration script --- ...20240923113045__plan_facility_create_ddl.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql new file mode 100644 index 00000000000..f0d64025b62 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql @@ -0,0 +1,17 @@ +-- Table: plan_facility_linkage +CREATE TABLE plan_facility_linkage ( + id varchar(64), + tenant_id varchar(64), + plan_configuration_id varchar(64), + facility_id varchar(64), + residing_boundary varchar(64), + service_boundaries varchar(2048), + additional_details JSONB, + active boolean, + created_by varchar(64), + created_time bigint, + last_modified_by varchar(64), + last_modified_time bigint, + CONSTRAINT uk_plan_facility_linkage_id PRIMARY KEY (id), + FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id) +); \ No newline at end of file From 1048d459122e39bbe10d473fabd54a65f9080942 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 25 Sep 2024 10:46:11 +0530 Subject: [PATCH 038/351] HCMPRE-470 adding migration file from HCMPRE-499 for testing --- ...800__plan_employee_assignment_create_ddl.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql new file mode 100644 index 00000000000..002b34d35ff --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql @@ -0,0 +1,17 @@ +-- Table: plan_employee_assignment +CREATE TABLE plan_employee_assignment ( + id character varying(64), + tenant_id character varying(64), + plan_configuration_id character varying(64), + employee_id character varying(64), + role character varying(64), + jurisdiction TEXT, + additional_details JSONB, + active boolean DEFAULT true, + created_by character varying(64), + created_time bigint, + last_modified_by character varying(64), + last_modified_time bigint, + CONSTRAINT uk_plan_employee_assignment_id PRIMARY KEY (id), + FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id) +); From 9e4643c59f36b243568913f7ce60a9a3c1cdfc48 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Wed, 25 Sep 2024 10:56:41 +0530 Subject: [PATCH 039/351] HCMPRE-585 - Plan facility - Create API - Controller,Service,Repository,Encrihment , PlanConfigurationId Validator --- .../main/java/digit/config/Configuration.java | 3 ++ .../repository/PlanFacilityRepository.java | 8 +++ .../impl/PlanFacilityRepositoryImpl.java | 36 +++++++++++++ .../digit/service/PlanFacilityService.java | 51 ++++++++++++++++++ .../PlanFacilityEnrichementService.java | 35 +++++++++++++ .../validator/PlanFacilityValidator.java | 52 +++++++++++++++++++ .../controllers/PlanFacilityController.java | 37 +++++++++++++ .../src/main/resources/application.properties | 1 + 8 files changed, 223 insertions(+) create mode 100644 health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java create mode 100644 health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java create mode 100644 health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java create mode 100644 health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 03ea5c05d16..235a2d8783d 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -44,6 +44,9 @@ public class Configuration { @Value("${plan.update.topic}") private String planUpdateTopic; + @Value("${plan.facility.create.topic}") + private String planFacilityCreateTopic; + @Value("${plan.default.offset}") private Integer defaultOffset; diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java new file mode 100644 index 00000000000..4d464bf03ee --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java @@ -0,0 +1,8 @@ +package digit.repository; + +import digit.web.models.PlanFacilityRequest; + + +public interface PlanFacilityRepository { + public void create(PlanFacilityRequest planFacilityRequest); +} diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java new file mode 100644 index 00000000000..0ff20da5d04 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -0,0 +1,36 @@ +package digit.repository.impl; + +import digit.config.Configuration; +import digit.kafka.Producer; +import digit.repository.PlanFacilityRepository; +import digit.web.models.PlanFacilityRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +@Repository +@Slf4j +public class PlanFacilityRepositoryImpl implements PlanFacilityRepository { + + private Producer producer; + private Configuration config; + + public PlanFacilityRepositoryImpl(Producer producer, Configuration config) { + this.producer = producer; + this.config = config; + } + + /** + * This method emits an event to the persister for it to save the plan facility linkage in the database. + * @param planFacilityRequest + */ + @Override + public void create(PlanFacilityRequest planFacilityRequest) { + try { + producer.push(config.getPlanFacilityCreateTopic(), planFacilityRequest); + } catch (Exception e) { + log.info("Pushing message to topic " + config.getPlanFacilityCreateTopic() + " failed.", e); + } + } + + +} diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java new file mode 100644 index 00000000000..1629b7c4f84 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -0,0 +1,51 @@ +package digit.service; + +import digit.repository.PlanFacilityRepository; +import digit.service.enrichment.PlanFacilityEnrichementService; +import digit.service.validator.PlanFacilityValidator; +import digit.util.ResponseInfoFactory; +import digit.web.models.PlanFacilityRequest; +import digit.web.models.PlanFacilityResponse; +import org.springframework.stereotype.Service; + +import java.util.Collections; + +@Service +public class PlanFacilityService { + + private PlanFacilityValidator planFacilityValidator; + private ResponseInfoFactory responseInfoFactory; + private PlanFacilityEnrichementService planFacilityEnricher; + private PlanFacilityRepository planFacilityRepository; + + public PlanFacilityService(PlanFacilityValidator planFacilityValidator, ResponseInfoFactory responseInfoFactory, PlanFacilityEnrichementService planFacilityEnricher, PlanFacilityRepository planFacilityRepository) { + this.planFacilityValidator = planFacilityValidator; + this.responseInfoFactory = responseInfoFactory; + this.planFacilityEnricher = planFacilityEnricher; + this.planFacilityRepository = planFacilityRepository; + } + + /** + * This method processes the requests that come for creating plans. + * @param planFacilityRequest + * @return + */ + public PlanFacilityResponse createPlanFacility(PlanFacilityRequest planFacilityRequest) { + // Validate plan facility create request + planFacilityValidator.validatePlanFacilityCreate(planFacilityRequest); + + // Enrich plan facility create request + planFacilityEnricher.enrichPlanFacilityCreate(planFacilityRequest); + + // Delegate creation request to repository + planFacilityRepository.create(planFacilityRequest); + + // Build and return response back to controller + PlanFacilityResponse response = PlanFacilityResponse.builder() + .planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())) + .responseInfo(responseInfoFactory + .createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), true)) + .build(); + return response; + } +} diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java new file mode 100644 index 00000000000..72e13c6e40b --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java @@ -0,0 +1,35 @@ +package digit.service.enrichment; + +import digit.web.models.PlanFacilityRequest; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.utils.AuditDetailsEnrichmentUtil; +import org.egov.common.utils.UUIDEnrichmentUtil; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class PlanFacilityEnrichementService { + + /** + * Enriches the plan facility create request + * + * @param planFacilityRequest + */ + public void enrichPlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { + if (planFacilityRequest.getPlanFacility() == null) { + throw new IllegalArgumentException("Plan Facility details are missing in the request."); + } + + // Generate id for plan facility + UUIDEnrichmentUtil.enrichRandomUuid(planFacilityRequest.getPlanFacility(), "id"); + + // Enrich audit details + planFacilityRequest.getPlanFacility().setAuditDetails(AuditDetailsEnrichmentUtil + .prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.TRUE)); + + //Set Active + planFacilityRequest.getPlanFacility().setActive(true); + + } +} diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java new file mode 100644 index 00000000000..2ee86c308d3 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -0,0 +1,52 @@ +package digit.service.validator; + +import digit.repository.PlanConfigurationRepository; +import digit.util.MdmsUtil; +import digit.web.models.PlanConfigurationSearchCriteria; +import digit.web.models.PlanFacilityRequest; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.utils.MultiStateInstanceUtil; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_CODE; +import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_MESSAGE; + +@Component +@Slf4j +public class PlanFacilityValidator { + + private MdmsUtil mdmsUtil; + + private MultiStateInstanceUtil centralInstanceUtil; + + private PlanConfigurationRepository planConfigurationRepository; + + public PlanFacilityValidator(MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, PlanConfigurationRepository planConfigurationRepository) { + this.mdmsUtil = mdmsUtil; + this.centralInstanceUtil = centralInstanceUtil; + this.planConfigurationRepository = planConfigurationRepository; + } + + public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { + String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); + + // Validate plan configuration existence + validatePlanConfigurationExistence(planFacilityRequest); + + } + + private void validatePlanConfigurationExistence(PlanFacilityRequest request) { + // If plan configuration id provided is invalid, throw an exception + if(!ObjectUtils.isEmpty(request.getPlanFacility().getPlanConfigurationId()) && CollectionUtils.isEmpty( + planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() + .id(request.getPlanFacility().getPlanConfigurationId()) + .tenantId(request.getPlanFacility().getTenantId()) + .build()))) { + throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); + } + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java new file mode 100644 index 00000000000..ffb358bb1eb --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -0,0 +1,37 @@ +package digit.web.controllers; + +import digit.service.PlanFacilityService; +import digit.web.models.PlanFacilityRequest; +import digit.web.models.PlanFacilityResponse; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Validated +@Controller +@RequestMapping("/plan/facility") +public class PlanFacilityController { + + private PlanFacilityService planFacilityService; + + public PlanFacilityController(PlanFacilityService planFacilityService) { + this.planFacilityService = planFacilityService; + } + + /** + * Request handler for serving plan facility create requests + * + * @param planFacilityRequest + * @return + */ + @RequestMapping(value = "/_create", method = RequestMethod.POST) + public ResponseEntity planFacilityCreatePost(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { + PlanFacilityResponse planFacilityResponse = planFacilityService.createPlanFacility(planFacilityRequest); + return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse); + } +} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 25456401843..716f65f2105 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -48,6 +48,7 @@ plan.configuration.update.topic=plan-config-update-topic plan.create.topic=save-plan plan.update.topic=update-plan +plan.facility.create.topic=save-plan-facility #mdms urls egov.mdms.host=https://unified-dev.digit.org From 3732db81f01e46f4b77798b9bea417822029ed6f Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 25 Sep 2024 11:08:34 +0530 Subject: [PATCH 040/351] search with id --- .../main/java/digit/config/ServiceConstants.java | 3 +++ .../PlanEmployeeAssignmentQueryBuilder.java | 6 ++++++ .../validator/PlanEmployeeAssignmentValidator.java | 14 +++++++++++++- .../PlanEmployeeAssignmentSearchCriteria.java | 3 +++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 3e6b7a1efa9..5519fb7f2ff 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -77,6 +77,9 @@ public class ServiceConstants { public static final String INVALID_PLAN_CONFIG_ID_CODE = "INVALID_PLAN_CONFIG_ID"; public static final String INVALID_PLAN_CONFIG_ID_MESSAGE = "Plan config id provided is invalid"; + public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE = "INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID"; + public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE = "Plan employee assignment id provided is invalid"; + public static final String METRIC_NOT_FOUND_IN_MDMS_CODE = "METRIC_NOT_FOUND_IN_MDMS"; public static final String METRIC_NOT_FOUND_IN_MDMS_MESSAGE = "Metric key not found in MDMS"; diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index fd192d38435..463711aa5d2 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -45,6 +45,12 @@ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteri private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { StringBuilder builder = new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); + if (searchCriteria.getId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" id = ?"); + preparedStmtList.add(searchCriteria.getId()); + } + if (searchCriteria.getTenantId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" tenant_id = ?"); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index ed3fdf63842..8aaa7ca8caf 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -1,5 +1,6 @@ package digit.service.validator; +import digit.repository.PlanEmployeeAssignmentRepository; import digit.util.CampaignUtil; import digit.util.CommonUtil; import digit.util.HrmsUtil; @@ -32,11 +33,14 @@ public class PlanEmployeeAssignmentValidator { private CampaignUtil campaignUtil; - public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, HrmsUtil hrmsUtil, CommonUtil commonUtil, CampaignUtil campaignUtil) { + private PlanEmployeeAssignmentRepository repository; + + public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, HrmsUtil hrmsUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeAssignmentRepository repository) { this.centralInstanceUtil = centralInstanceUtil; this.hrmsUtil = hrmsUtil; this.commonUtil = commonUtil; this.campaignUtil = campaignUtil; + this.repository = repository; } @@ -189,5 +193,13 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { */ private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeAssignment) { + // Validates the existence of plan employee assignment + List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + .id(planEmployeeAssignment.getId()) + .build()); + + if(CollectionUtils.isEmpty(planEmployeeAssignments)) { + throw new CustomException(INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE, INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE); + } } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 5e3aec1206d..b3449f50ec1 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -21,6 +21,9 @@ @Builder public class PlanEmployeeAssignmentSearchCriteria { + @JsonProperty("id") + private String id = null; + @JsonProperty("tenantId") @Size(min = 2, max = 100) @NotNull From 2df6920d198cdb5ef103ccf9cede104fb9ea330a Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Wed, 25 Sep 2024 11:38:24 +0530 Subject: [PATCH 041/351] Added FacilityId validation from Facility Service --- .../main/java/digit/config/Configuration.java | 7 ++ .../java/digit/config/ServiceConstants.java | 2 + .../validator/PlanFacilityValidator.java | 23 +++++- .../main/java/digit/util/FacilityUtil.java | 76 +++++++++++++++++++ .../java/digit/web/models/Pagination.java | 35 +++++++++ .../digit/web/models/facility/Facility.java | 62 +++++++++++++++ .../web/models/facility/FacilityDetail.java | 19 +++++ .../web/models/facility/FacilityResponse.java | 22 ++++++ .../facility/FacilitySearchCriteria.java | 30 ++++++++ .../facility/FacilitySearchRequest.java | 20 +++++ .../src/main/resources/application.properties | 8 +- 11 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/util/FacilityUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/Pagination.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilityDetail.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 235a2d8783d..1360d333824 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -53,4 +53,11 @@ public class Configuration { @Value("${plan.default.limit}") private Integer defaultLimit; + //Facility + @Value("${egov.facility.host}") + private String facilityHost; + + @Value("${egov.facility.search.endpoint}") + private String facilityEndPoint; + } diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 1528951de9c..cac4ce0fc47 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -180,4 +180,6 @@ public class ServiceConstants { public static final String VEHICLE_ID_FIELD = "vehicleIds"; + public static final String ERROR_WHILE_FETCHING_FROM_FACILITY = "Exception occurred while fetching facility details from facility: "; + } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 2ee86c308d3..b2c7f654372 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -1,11 +1,14 @@ package digit.service.validator; import digit.repository.PlanConfigurationRepository; +import digit.util.FacilityUtil; import digit.util.MdmsUtil; import digit.web.models.PlanConfigurationSearchCriteria; import digit.web.models.PlanFacilityRequest; +import digit.web.models.facility.FacilityResponse; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -25,9 +28,12 @@ public class PlanFacilityValidator { private PlanConfigurationRepository planConfigurationRepository; - public PlanFacilityValidator(MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, PlanConfigurationRepository planConfigurationRepository) { + private FacilityUtil facilityUtil; + + public PlanFacilityValidator(MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, FacilityUtil facilityUtil, PlanConfigurationRepository planConfigurationRepository) { this.mdmsUtil = mdmsUtil; this.centralInstanceUtil = centralInstanceUtil; + this.facilityUtil = facilityUtil; this.planConfigurationRepository = planConfigurationRepository; } @@ -37,6 +43,21 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe // Validate plan configuration existence validatePlanConfigurationExistence(planFacilityRequest); + // Validate facility existence + validateFacilityExistence(planFacilityRequest.getPlanFacility().getFacilityId(), + planFacilityRequest.getPlanFacility().getTenantId(), + planFacilityRequest.getRequestInfo()); + + + } + + private void validateFacilityExistence(String facilityId, String tenantId, RequestInfo requestInfo) { + FacilityResponse facilityResponse = facilityUtil.fetchFacilityData(requestInfo, facilityId, tenantId); + + // Check if the facility response is null or if the facilities list is null or empty + if (facilityResponse == null || facilityResponse.getFacilities() == null || facilityResponse.getFacilities().isEmpty()) { + throw new CustomException("FACILITY_NOT_FOUND", "Facility with ID " + facilityId + " not found in the system."); + } } private void validatePlanConfigurationExistence(PlanFacilityRequest request) { diff --git a/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java b/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java new file mode 100644 index 00000000000..5721e3b4a74 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java @@ -0,0 +1,76 @@ +package digit.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.config.Configuration; +import digit.web.models.facility.FacilityResponse; +import digit.web.models.facility.FacilitySearchCriteria; +import digit.web.models.facility.FacilitySearchRequest; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_FROM_FACILITY; + +@Slf4j +@Component +public class FacilityUtil { + + private RestTemplate restTemplate; + private Configuration configs; + @Autowired + private ObjectMapper mapper; + + public FacilityUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + public FacilityResponse fetchFacilityData(RequestInfo requestInfo, String facilityId, String tenantId) { + String baseUri = configs.getFacilityHost()+ configs.getFacilityEndPoint(); + + // Retrieve the limit and offset from the configuration + int limit = configs.getDefaultLimit(); + int offset = configs.getDefaultOffset(); + + // Use UriComponentsBuilder to construct the URI with query parameters + String uri = UriComponentsBuilder.fromHttpUrl(baseUri) + .queryParam("tenantId", tenantId) + .queryParam("limit", limit) + .queryParam("offset", offset) + .toUriString(); + + FacilitySearchRequest facilitySearchRequest = getSearchReq(requestInfo, facilityId); + FacilityResponse facilityResponse = new FacilityResponse(); + Object response = new HashMap<>(); + try { + // Use postForObject to send the request with the URI containing query params + response = restTemplate.postForObject(uri, facilitySearchRequest, Map.class); + facilityResponse = mapper.convertValue(response , FacilityResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_FACILITY, e); + } + log.info(facilityResponse.toString()); + return facilityResponse; + } + + private FacilitySearchRequest getSearchReq(RequestInfo requestInfo, String facilityId) { + FacilitySearchCriteria searchCriteria = FacilitySearchCriteria.builder() + .id(Collections.singletonList(facilityId)) + .build(); + + return FacilitySearchRequest.builder() + .requestInfo(requestInfo) + .facilitySearchCriteria(searchCriteria) + .build(); + } + + + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/Pagination.java b/health-services/plan-service/src/main/java/digit/web/models/Pagination.java new file mode 100644 index 00000000000..6d3fd64df77 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/Pagination.java @@ -0,0 +1,35 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Pagination + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Pagination { + + @JsonIgnore + private String sortBy; + + @JsonIgnore + private String sortOrder; + + @JsonProperty("limit") + @Min(1) + @Max(50) + private Integer limit; + + @JsonProperty("offset") + @Min(0) + private Integer offset; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java b/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java new file mode 100644 index 00000000000..66794a24940 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java @@ -0,0 +1,62 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Facility { + @JsonProperty("id") + private String id; + + @JsonProperty("tenantId") + private String tenantId; + + @JsonProperty("source") + private String source; + + @JsonProperty("rowVersion") + private Integer rowVersion; + + @JsonProperty("applicationId") + private String applicationId; + + @JsonProperty("hasErrors") + private boolean hasErrors; + + @JsonProperty("additionalFields") + private String additionalFields; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails; + + @JsonProperty("clientReferenceId") + private String clientReferenceId; + + @JsonProperty("clientAuditDetails") + private String clientAuditDetails; + + @JsonProperty("isPermanent") + private boolean isPermanent; + + @JsonProperty("name") + private String name; + + @JsonProperty("usage") + private String usage; + + @JsonProperty("storageCapacity") + private Integer storageCapacity; + + @JsonProperty("address") + private String address; + + @JsonProperty("isDeleted") + private boolean isDeleted; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/FacilityDetail.java b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilityDetail.java new file mode 100644 index 00000000000..9f09df28102 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilityDetail.java @@ -0,0 +1,19 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FacilityDetail { + @JsonProperty("facility") + private Facility facility; + + @JsonProperty("additionalInfo") + private String additionalInfo; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java new file mode 100644 index 00000000000..46e98759e48 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java @@ -0,0 +1,22 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FacilityResponse { + @JsonProperty("ResponseInfo") + private ResponseInfo responseInfo; + + @JsonProperty("Facilities") + private List facilities; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java new file mode 100644 index 00000000000..ae76b88fa4a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java @@ -0,0 +1,30 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import digit.web.models.Pagination; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FacilitySearchCriteria { + @JsonProperty("tenantId") + private String tenantId; + + @JsonProperty("id") + private List id; + + @JsonProperty("name") + private String name; + + @JsonProperty("isDeleted") + private Boolean isDeleted; + + @JsonProperty("pagination") + private Pagination pagination; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java new file mode 100644 index 00000000000..c7d39e4053e --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java @@ -0,0 +1,20 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FacilitySearchRequest { + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + + @JsonProperty("Facility") + private FacilitySearchCriteria facilitySearchCriteria; +} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 716f65f2105..9f086434360 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -7,12 +7,12 @@ app.timezone=UTC #DATABASE CONFIGURATION spring.datasource.driver-class-name=org.postgresql.Driver -spring.datasource.url=jdbc:postgresql://localhost:5432/plandb +spring.datasource.url=jdbc:postgresql://localhost:5432/plandbupdate spring.datasource.username=postgres spring.datasource.password=postgres #FLYWAY CONFIGURATION -spring.flyway.url=jdbc:postgresql://localhost:5432/plandb +spring.flyway.url=jdbc:postgresql://localhost:5432/plandbupdate spring.flyway.user=postgres spring.flyway.password=postgres spring.flyway.table=public @@ -55,6 +55,10 @@ egov.mdms.host=https://unified-dev.digit.org egov.mdms.search.endpoint=/egov-mdms-service/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search +#facility urls +egov.facility.host=http://localhost:8092 +egov.facility.search.endpoint=/facility/v1/_search + # Pagination config plan.default.offset=0 plan.default.limit=10 From 985fd63c505bd645969092fe79c9257f07b0c48f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 25 Sep 2024 11:50:05 +0530 Subject: [PATCH 042/351] HCMPRE-470 removing migration file from HCMPRE-499 after testing --- ...800__plan_employee_assignment_create_ddl.sql | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql deleted file mode 100644 index 002b34d35ff..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql +++ /dev/null @@ -1,17 +0,0 @@ --- Table: plan_employee_assignment -CREATE TABLE plan_employee_assignment ( - id character varying(64), - tenant_id character varying(64), - plan_configuration_id character varying(64), - employee_id character varying(64), - role character varying(64), - jurisdiction TEXT, - additional_details JSONB, - active boolean DEFAULT true, - created_by character varying(64), - created_time bigint, - last_modified_by character varying(64), - last_modified_time bigint, - CONSTRAINT uk_plan_employee_assignment_id PRIMARY KEY (id), - FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id) -); From b965b6c3ad2e2cd0761ff8605814a0fdd3743795 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 25 Sep 2024 12:12:07 +0530 Subject: [PATCH 043/351] vehicle id validation --- .../validator/PlanConfigurationValidator.java | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 0736cc5a150..6427534f32d 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -581,18 +581,21 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration request, List mdmsV2Data) { List vehicleIdsLinkedWithPlanConfig = commonUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); - List vehicleIdsFromMdms = mdmsV2Data.stream() - .map(Mdms::getId) - .collect(Collectors.toList()); - - List finalVehicleIdsFromMdms = vehicleIdsFromMdms; - vehicleIdsLinkedWithPlanConfig.stream() - .forEach(vehicleId -> { - if (!finalVehicleIdsFromMdms.contains(vehicleId)) { - log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); - throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE); - } - }); + if (!CollectionUtils.isEmpty(vehicleIdsLinkedWithPlanConfig)) { + List vehicleIdsFromMdms = mdmsV2Data.stream() + .map(Mdms::getId) + .collect(Collectors.toList()); + + List finalVehicleIdsFromMdms = vehicleIdsFromMdms; + vehicleIdsLinkedWithPlanConfig.stream() + .forEach(vehicleId -> { + if (!finalVehicleIdsFromMdms.contains(vehicleId)) { + log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); + throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE); + } + }); + } + } From fe149cd039fe1818e29d49a7c0c3cb5261365376 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Wed, 25 Sep 2024 14:24:03 +0530 Subject: [PATCH 044/351] Added validation for serviceBoundaries --- .../main/java/digit/config/Configuration.java | 7 ++ .../java/digit/config/ServiceConstants.java | 7 ++ .../validator/PlanFacilityValidator.java | 79 ++++++++++++++++- .../main/java/digit/util/CampaignUtil.java | 62 +++++++++++++ .../web/models/projectFactory/Boundary.java | 32 +++++++ .../models/projectFactory/CampaignDetail.java | 87 +++++++++++++++++++ .../projectFactory/CampaignResponse.java | 31 +++++++ .../CampaignSearchCriteria.java | 52 +++++++++++ .../projectFactory/CampaignSearchReq.java | 22 +++++ .../web/models/projectFactory/Condition.java | 27 ++++++ .../models/projectFactory/DeliveryRule.java | 43 +++++++++ .../web/models/projectFactory/Product.java | 27 ++++++ .../web/models/projectFactory/Resource.java | 32 +++++++ .../src/main/resources/application.properties | 10 ++- 14 files changed, 511 insertions(+), 7 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/util/CampaignUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 1360d333824..0ced7b61978 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -60,4 +60,11 @@ public class Configuration { @Value("${egov.facility.search.endpoint}") private String facilityEndPoint; + //Project Factory + @Value("${egov.project.factory.host}") + private String projectFactoryHost; + + @Value("${egov.project.factory.search.endpoint}") + private String projectFactorySearchEndPoint; + } diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index cac4ce0fc47..083751cf5d9 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -181,5 +181,12 @@ public class ServiceConstants { public static final String VEHICLE_ID_FIELD = "vehicleIds"; public static final String ERROR_WHILE_FETCHING_FROM_FACILITY = "Exception occurred while fetching facility details from facility: "; + public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from project factory: "; + + public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; + public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; + + public static final String INVALID_SERVICE_BOUNDARY_CODE = "INVALID_SERVICE_BOUNDARY"; + public static final String INVALID_SERVICE_BOUNDARY_MESSAGE = "The provided service boundary is invalid"; } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index b2c7f654372..ec0dd6b7523 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -1,12 +1,20 @@ package digit.service.validator; import digit.repository.PlanConfigurationRepository; +import digit.util.CampaignUtil; +import digit.util.CommonUtil; import digit.util.FacilityUtil; import digit.util.MdmsUtil; +import digit.web.models.PlanConfiguration; import digit.web.models.PlanConfigurationSearchCriteria; +import digit.web.models.PlanFacility; import digit.web.models.PlanFacilityRequest; import digit.web.models.facility.FacilityResponse; +import digit.web.models.projectFactory.Boundary; +import digit.web.models.projectFactory.CampaignDetail; +import digit.web.models.projectFactory.CampaignResponse; import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.egov.common.utils.MultiStateInstanceUtil; @@ -15,8 +23,11 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_CODE; -import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_MESSAGE; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; @Component @Slf4j @@ -30,16 +41,28 @@ public class PlanFacilityValidator { private FacilityUtil facilityUtil; - public PlanFacilityValidator(MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, FacilityUtil facilityUtil, PlanConfigurationRepository planConfigurationRepository) { + private CommonUtil commonUtil; + + private CampaignUtil campaignUtil; + + public PlanFacilityValidator(MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, PlanConfigurationRepository planConfigurationRepository, FacilityUtil facilityUtil, CommonUtil commonUtil, CampaignUtil campaignUtil) { this.mdmsUtil = mdmsUtil; this.centralInstanceUtil = centralInstanceUtil; - this.facilityUtil = facilityUtil; this.planConfigurationRepository = planConfigurationRepository; + this.facilityUtil = facilityUtil; + this.commonUtil = commonUtil; + this.campaignUtil = campaignUtil; } public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); + List planConfigurations = searchPlanConfigId(planFacilityRequest.getPlanFacility().getPlanConfigurationId(),rootTenantId); + if(planConfigurations.isEmpty()) + { + throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE,INVALID_PLAN_CONFIG_ID_MESSAGE); + } + // Validate plan configuration existence validatePlanConfigurationExistence(planFacilityRequest); @@ -48,9 +71,57 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe planFacilityRequest.getPlanFacility().getTenantId(), planFacilityRequest.getRequestInfo()); + //validate service boundaries and residing boundaries with campaign id + validateCampaignDetails(planConfigurations.get(0).getCampaignId(),rootTenantId,planFacilityRequest); + } + + + + private void validateCampaignDetails(String campaignId,String rootTenantId, PlanFacilityRequest body) + { + PlanFacility planFacility=body.getPlanFacility(); + CampaignResponse campaignResponse=campaignUtil.fetchCampaignData(body.getRequestInfo(),campaignId,rootTenantId); + // Validate if campaign id exists + validateCampaignId(campaignResponse); + + //validate service boundaries + validateServiceBoundaries(campaignResponse.getCampaignDetails().get(0),planFacility); } + private void validateCampaignId(CampaignResponse campaignResponse) { + + if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { + throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); + } + } + + private void validateServiceBoundaries(CampaignDetail campaignDetail, PlanFacility planFacility) + { + // Collect all boundary code for the campaign + Set boundaryCode = campaignDetail.getBoundaries().stream() + .map(Boundary::getCode) + .collect(Collectors.toSet()); + + planFacility.getServiceBoundaries().stream() + .forEach(service -> { + if (!boundaryCode.contains(service)) { + throw new CustomException(INVALID_SERVICE_BOUNDARY_CODE, INVALID_SERVICE_BOUNDARY_MESSAGE); + } + }); + } + + public List searchPlanConfigId(String planConfigurationId, String tenantId) { + List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() + .id(planConfigurationId) + .tenantId(tenantId) + .build()); + + return planConfigurations; + } + + + private void validateFacilityExistence(String facilityId, String tenantId, RequestInfo requestInfo) { FacilityResponse facilityResponse = facilityUtil.fetchFacilityData(requestInfo, facilityId, tenantId); diff --git a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java new file mode 100644 index 00000000000..a3855e4208f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java @@ -0,0 +1,62 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.Pagination; +import digit.web.models.projectFactory.*; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import static digit.config.ServiceConstants.*; + +import java.util.Collections; + +@Slf4j +@Component +public class CampaignUtil { + + private RestTemplate restTemplate; + + private Configuration configs; + + public CampaignUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + /** + * This method calls external service to validate campaign id and service boundaries against project factory + * + * @param requestInfo + * @param campaignId + * @param tenantId + */ + public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campaignId, String tenantId) { + StringBuilder uri = new StringBuilder(); + uri = uri.append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndPoint()); + + CampaignSearchReq campaignSearchReq = getSearchReq(requestInfo, campaignId, tenantId); + CampaignResponse campaignResponse = new CampaignResponse(); + try { + campaignResponse = restTemplate.postForObject(uri.toString(), campaignSearchReq, CampaignResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY, e); + } + return campaignResponse; + } + + private CampaignSearchReq getSearchReq(RequestInfo requestInfo, String campaignId, String tenantId) { + Pagination pagination = Pagination.builder().limit(configs.getDefaultLimit()).offset(configs.getDefaultOffset()).build(); + CampaignSearchCriteria searchCriteria = CampaignSearchCriteria.builder() + .ids(Collections.singletonList(campaignId)) + .tenantId(tenantId) + .pagination(pagination) + .build(); + + return CampaignSearchReq.builder() + .requestInfo(requestInfo) + .campaignSearchCriteria(searchCriteria) + .build(); + } +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java new file mode 100644 index 00000000000..1661f3329d9 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java @@ -0,0 +1,32 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Boundary + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Boundary { + + @JsonProperty("code") + private String code; + + @JsonProperty("type") + private String type; + + @JsonProperty("isRoot") + private Boolean isRoot; + + @JsonProperty("includeAllChildren") + private Boolean includeAllChildren; + + @JsonProperty("parent") + private String parent; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java new file mode 100644 index 00000000000..631ce8d765a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java @@ -0,0 +1,87 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; + +import java.util.List; + +/** + * CampaignDetails + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CampaignDetail { + + @JsonProperty("id") + private String id; + + @JsonProperty("tenantId") + @NotNull + private String tenantId; + + @JsonProperty("status") + private String status; + + @JsonProperty("action") + private String action; + + @JsonProperty("campaignNumber") + private String campaignNumber; + + @JsonProperty("isActive") + private Boolean isActive; + + @JsonProperty("parentId") + private String parentId; + + @JsonProperty("campaignName") + private String campaignName; + + @JsonProperty("projectType") + private String projectType; + + @JsonProperty("hierarchyType") + private String hierarchyType; + + @JsonProperty("boundaryCode") + private String boundaryCode; + + @JsonProperty("projectId") + private String projectId; + + @JsonProperty("startDate") + private Long startDate; + + @JsonProperty("endDate") + private Long endDate; + + @JsonProperty("additionalDetails") + @Valid + private Object additionalDetails; + + @JsonProperty("resources") + @Valid + private List resources; + + @JsonProperty("boundaries") + @Valid + private List boundaries; + + @JsonProperty("deliveryRules") + @Valid + private List deliveryRules; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails; +} + + diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java new file mode 100644 index 00000000000..dc0852665fa --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java @@ -0,0 +1,31 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; + +import java.util.List; + +/** + * CampaignResponse + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CampaignResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("CampaignDetails") + @Valid + private List campaignDetails = null; + + @JsonProperty("totalCount") + @Valid + private Integer totalCount = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java new file mode 100644 index 00000000000..360bf65ce06 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java @@ -0,0 +1,52 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import digit.web.models.Pagination; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * CampaignSearchCriteria + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Validated +public class CampaignSearchCriteria { + + @JsonProperty("ids") + @Size(min = 1) + private List ids; + + @JsonProperty("tenantId") + @Size(min = 2, max = 256) + private String tenantId; + + @JsonIgnore + private List status; + + @JsonIgnore + private String createdBy; + + @JsonIgnore + private Boolean campaignsIncludeDates; + + @JsonIgnore + private Integer startDate; + + @JsonIgnore + private Integer endDate; + + @JsonProperty("pagination") + @Valid + private Pagination pagination; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java new file mode 100644 index 00000000000..ad83d373652 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java @@ -0,0 +1,22 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.Builder; +import lombok.Data; +import org.egov.common.contract.request.RequestInfo; + +/** + * CampaignSearchReq + */ +@Data +@Builder +public class CampaignSearchReq { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo; + + @JsonProperty("CampaignDetails") + private CampaignSearchCriteria campaignSearchCriteria; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java new file mode 100644 index 00000000000..5ad19e29aef --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java @@ -0,0 +1,27 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Condition + **/ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Condition { + + @JsonProperty("value") + private String value; + + @JsonProperty("operator") + private String operator; + + @JsonProperty("attribute") + private String attribute; +} + diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java new file mode 100644 index 00000000000..7eef58fd8ae --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java @@ -0,0 +1,43 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * DeliveryRule + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DeliveryRule { + + @JsonProperty("endDate") + private Long endDate; + + @JsonProperty("products") + @Valid + private List products; + + @JsonProperty("startDate") + private Long startDate; + + @JsonProperty("conditions") + @Valid + private List conditions; + + @JsonProperty("cycleNumber") + private Integer cycleNumber; + + @JsonProperty("deliveryNumber") + private Integer deliveryNumber; + + @JsonProperty("deliveryRuleNumber") + private Integer deliveryRuleNumber; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java new file mode 100644 index 00000000000..9508480da05 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java @@ -0,0 +1,27 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Product + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Product { + + @JsonProperty("name") + private String name; + + @JsonProperty("count") + private Integer count; + + @JsonProperty("value") + private String value; +} + diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java new file mode 100644 index 00000000000..3a45c4fa9b8 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java @@ -0,0 +1,32 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Resource + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Resource { + + @JsonProperty("type") + private String type; + + @JsonProperty("filename") + private String filename; + + @JsonProperty("resourceId") + private String resourceId; + + @JsonProperty("filestoreId") + private String filestoreId; + + @JsonProperty("createResourceId") + private String createResourceId; +} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 9f086434360..65f70628fbb 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -7,12 +7,12 @@ app.timezone=UTC #DATABASE CONFIGURATION spring.datasource.driver-class-name=org.postgresql.Driver -spring.datasource.url=jdbc:postgresql://localhost:5432/plandbupdate +spring.datasource.url=jdbc:postgresql://localhost:5432/plandb spring.datasource.username=postgres spring.datasource.password=postgres #FLYWAY CONFIGURATION -spring.flyway.url=jdbc:postgresql://localhost:5432/plandbupdate +spring.flyway.url=jdbc:postgresql://localhost:5432/plandb spring.flyway.user=postgres spring.flyway.password=postgres spring.flyway.table=public @@ -56,9 +56,13 @@ egov.mdms.search.endpoint=/egov-mdms-service/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search #facility urls -egov.facility.host=http://localhost:8092 +egov.facility.host=https://unified-dev.digit.org egov.facility.search.endpoint=/facility/v1/_search +#project factory urls +egov.project.factory.host=https://unified-dev.digit.org +egov.project.factory.search.endpoint=/project-factory/v1/project-type/search + # Pagination config plan.default.offset=0 plan.default.limit=10 From beefe66d5e61ba77074bbcaa3c54bef78192af33 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 25 Sep 2024 14:43:48 +0530 Subject: [PATCH 045/351] added active in row mapper --- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 2 +- .../repository/rowmapper/PlanEmployeeAssignmentRowMapper.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 463711aa5d2..2705d307ff4 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -72,7 +72,7 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit if (searchCriteria.getActive() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" active = ?"); - preparedStmtList.add(Boolean.TRUE); + preparedStmtList.add(searchCriteria.getActive()); } return builder.toString(); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java index b5ea527b896..3001239a485 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -50,6 +50,7 @@ public List extractData(ResultSet rs) throws SQLExceptio planEmployeeAssignment.setEmployeeId(rs.getString("employee_id")); planEmployeeAssignment.setRole(rs.getString("role")); planEmployeeAssignment.setJurisdiction(jurisdictionList); + planEmployeeAssignment.setActive(rs.getBoolean("active")); planEmployeeAssignment.setAdditionalDetails(commonUtil.getAdditionalDetail((PGobject) rs.getObject("additional_details"))); planEmployeeAssignment.setAuditDetails(auditDetails); From 0b3c2bd1aa0c86a240095a125ed42e5dbfc58f01 Mon Sep 17 00:00:00 2001 From: tanishi-egov Date: Wed, 25 Sep 2024 14:49:49 +0530 Subject: [PATCH 046/351] Update application.properties --- .../project/src/main/resources/application.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index 93f601466a9..71af8eab0d3 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -180,4 +180,7 @@ project.location.capture.kafka.create.topic=save-location-capture-project-topic project.location.capture.consumer.bulk.create.topic=save-location-capture-project-bulk-topic #---------No resource statuses ------------# -project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED \ No newline at end of file +project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED + +#---------Attendance Feature ------------# +project.attendance.feature.enabled=true From 772fcac5b28a74327073ca006044f003e8438e4f Mon Sep 17 00:00:00 2001 From: tanishi-egov Date: Wed, 25 Sep 2024 14:50:45 +0530 Subject: [PATCH 047/351] Update ProjectValidator.java --- .../org/egov/project/validator/project/ProjectValidator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java index 266f664312d..e1e3f709a5c 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java @@ -75,7 +75,7 @@ public void validateCreateProjectRequest(ProjectRequest request) { //Verify MDMS Data // TODO: Uncomment and fix as per HCM once we get clarity // validateRequestMDMSData(request, tenantId, errorMap); - validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); + if(config.getIsAttendanceFeatureEnabled()) validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); //Get boundaries in list from all Projects in request body for validation Map> boundariesForValidation = getBoundaryForValidation(request.getProjects()); @@ -649,4 +649,4 @@ public void validateParentAgainstDB(List projects, List parent } log.info("Parent projects validated against DB"); } -} \ No newline at end of file +} From 249927f799bc6e780285e8107cd950e0e41de075 Mon Sep 17 00:00:00 2001 From: tanishi-egov Date: Wed, 25 Sep 2024 14:51:26 +0530 Subject: [PATCH 048/351] Update ProjectValidator.java --- .../org/egov/project/validator/project/ProjectValidator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java index e1e3f709a5c..ca471f25d48 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java @@ -650,3 +650,4 @@ public void validateParentAgainstDB(List projects, List parent log.info("Parent projects validated against DB"); } } + From afa409c41c92d43f95b13161cf4d3703727bc192 Mon Sep 17 00:00:00 2001 From: tanishi-egov Date: Wed, 25 Sep 2024 14:53:12 +0530 Subject: [PATCH 049/351] Update ProjectValidator.java --- .../org/egov/project/validator/project/ProjectValidator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java index ca471f25d48..e1e3f709a5c 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java @@ -650,4 +650,3 @@ public void validateParentAgainstDB(List projects, List parent log.info("Parent projects validated against DB"); } } - From 3fca3502b763a901ec5ef1ec499adb928fccbb65 Mon Sep 17 00:00:00 2001 From: tanishi-egov Date: Wed, 25 Sep 2024 14:54:56 +0530 Subject: [PATCH 050/351] Update ProjectConfiguration.java --- .../java/org/egov/project/config/ProjectConfiguration.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java index 26759e381e2..67ee5a87af6 100644 --- a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java +++ b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java @@ -222,4 +222,7 @@ public class ProjectConfiguration { @Value("${project.task.no.resource.validation.status}") private List noResourceStatuses; + + @Value("${project.attendance.feature.enabled:true}") + private Boolean isAttendanceFeatureEnabled; } From 91082ef2e999a13ca129593d845360f328c4e2b1 Mon Sep 17 00:00:00 2001 From: tanishi-egov Date: Wed, 25 Sep 2024 14:57:12 +0530 Subject: [PATCH 051/351] Update ProjectValidator.java From 6ebb12282f629da2cc157e1c491f4e05d5e3f87f Mon Sep 17 00:00:00 2001 From: Palak Garg <86659286+palak-egov@users.noreply.github.com> Date: Wed, 25 Sep 2024 15:18:22 +0530 Subject: [PATCH 052/351] migrate to repair --- health-services/plan-service/src/main/resources/db/migrate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migrate.sh b/health-services/plan-service/src/main/resources/db/migrate.sh index c58d6f91e3f..0f00dd9153a 100644 --- a/health-services/plan-service/src/main/resources/db/migrate.sh +++ b/health-services/plan-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate \ No newline at end of file +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true repair From 4a90d7ae20a9e2e53dffc4c33135ee88cdfcf9a3 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 25 Sep 2024 15:51:59 +0530 Subject: [PATCH 053/351] HCMPRE-470 code review comments --- health-services/plan-service/pom.xml | 5 +++ .../java/digit/config/ServiceConstants.java | 31 +++++++++++-------- .../validator/PlanConfigurationValidator.java | 23 ++++++++------ .../src/main/java/digit/util/CommonUtil.java | 17 +++++----- 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/health-services/plan-service/pom.xml b/health-services/plan-service/pom.xml index 148766ff97d..6cb9a4ac3ae 100644 --- a/health-services/plan-service/pom.xml +++ b/health-services/plan-service/pom.xml @@ -95,6 +95,11 @@ 2.9.0-SNAPSHOT compile + + org.apache.commons + commons-text + 1.10.0 + diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 742b16c909c..6273b423347 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -31,6 +31,9 @@ public class ServiceConstants { public static final String VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE = "VEHICLE_ID_NOT_FOUND_IN_MDMS"; public static final String VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE = "Vehicle Id is not present in MDMS"; + public static final String VEHICLE_IDS_INVALID_DATA_TYPE_CODE = "VEHICLE_IDS_INVALID_DATA_TYPE"; + public static final String VEHICLE_IDS_INVALID_DATA_TYPE_MESSAGE = "Vehicle IDs should be a list of strings."; + public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_CODE = "TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS"; public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE = "Template Identifier is not present in MDMS "; @@ -178,22 +181,24 @@ public class ServiceConstants { public static final String NAME_VALIDATION_DATA = "Data"; - - // Constants for operators and JSON fields + // Constants for constructing logical expressions or queries public static final String AND = " && "; public static final String EQUALS = " == "; public static final String SINGLE_QUOTE = "'"; - public static final String CAMPAIGN_TYPE = "campaignType"; - public static final String DISTRIBUTION_PROCESS = "DistributionProcess"; - public static final String REGISTRATION_PROCESS = "RegistrationProcess"; - public static final String RESOURCE_DISTRIBUTION_STRATEGY_CODE = "resourceDistributionStrategyCode"; - public static final String IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "isRegistrationAndDistributionHappeningTogetherOrSeparately"; - - public static final String JSON_FIELD_CAMPAIGN_TYPE = "@.campaignType"; - public static final String JSON_FIELD_DISTRIBUTION_PROCESS = "@.DistributionProcess"; - public static final String JSON_FIELD_REGISTRATION_PROCESS = "@.RegistrationProcess"; - public static final String JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE = "@.resourceDistributionStrategyCode"; - public static final String JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "@.isRegistrationAndDistributionHappeningTogetherOrSeparately"; + + // JSON field constants for campaign details + public static final String JSON_FIELD_CAMPAIGN_TYPE = "campaignType"; + public static final String JSON_FIELD_DISTRIBUTION_PROCESS = "DistributionProcess"; + public static final String JSON_FIELD_REGISTRATION_PROCESS = "RegistrationProcess"; + public static final String JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE = "resourceDistributionStrategyCode"; + public static final String JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "isRegistrationAndDistributionHappeningTogetherOrSeparately"; public static final String JSON_FIELD_VEHICLE_ID = "vehicleIds"; + // JSON path constants for campaign details + public static final String JSON_PATH_FILTER_CAMPAIGN_TYPE = "@.campaignType"; + public static final String JSON_PATH_FILTER_DISTRIBUTION_PROCESS = "@.DistributionProcess"; + public static final String JSON_PATH_FILTER_REGISTRATION_PROCESS = "@.RegistrationProcess"; + public static final String JSON_PATH_FILTER_RESOURCE_DISTRIBUTION_STRATEGY_CODE = "@.resourceDistributionStrategyCode"; + public static final String JSON_PATH_FILTER_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "@.isRegistrationAndDistributionHappeningTogetherOrSeparately"; + } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 005b9789a1b..a4c2d85e4d1 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -153,11 +153,11 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O PlanConfiguration planConfiguration = request.getPlanConfiguration(); Object additionalDetails = request.getPlanConfiguration().getAdditionalDetails(); - String jsonPathForAssumption = commonUtil.createJsonPathForAssumption((String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,CAMPAIGN_TYPE), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,DISTRIBUTION_PROCESS), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,REGISTRATION_PROCESS), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,RESOURCE_DISTRIBUTION_STRATEGY_CODE), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails,IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); + String jsonPathForAssumption = commonUtil.createJsonPathForAssumption((String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE), + (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); List assumptionListFromMDMS = null; try { log.info(jsonPathForAssumption); @@ -544,9 +544,13 @@ public void validateUserInfo(PlanConfigurationRequest request) * @param request plan configuration request * @param mdmsV2Data mdms v2 data object */ - public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, List mdmsV2Data) - { - List vehicleIdsLinkedWithPlanConfig = (List) commonUtil.extractFieldsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails(), JSON_FIELD_VEHICLE_ID); + public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, List mdmsV2Data) { + List vehicleIdsLinkedWithPlanConfig; + try { + vehicleIdsLinkedWithPlanConfig = (List) commonUtil.extractFieldsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails(), JSON_FIELD_VEHICLE_ID); + } catch (ClassCastException e) { + throw new CustomException(VEHICLE_IDS_INVALID_DATA_TYPE_CODE, VEHICLE_IDS_INVALID_DATA_TYPE_MESSAGE); + } List vehicleIdsFromMdms = mdmsV2Data.stream() .map(Mdms::getId) @@ -554,8 +558,7 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration vehicleIdsLinkedWithPlanConfig.stream() .forEach(vehicleId -> { - if(!vehicleIdsFromMdms.contains(vehicleId)) - { + if (!vehicleIdsFromMdms.contains(vehicleId)) { log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE); } diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 20dbe458a11..1a55af33841 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.text.StringEscapeUtils; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -39,10 +40,10 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri /** - * Extracts the list of vehicle Ids provided in additional details object + * Extracts provided field from the additional details object * * @param additionalDetails the additionalDetails object from PlanConfigurationRequest - * @return a list of vehicle Ids from additional details + * @return a field to extract from additional details */ public Object extractFieldsFromAdditionalDetails(Object additionalDetails, String fieldToExtract) { try { @@ -66,7 +67,7 @@ public Object extractFieldsFromAdditionalDetails(Object additionalDetails, Strin return node.asText(); } } - // In case the node is of some other type (like object or binary), handle accordingly + // In case the node is of other type like object, handle accordingly return node; } catch (Exception e) { log.error(e.getMessage()); @@ -95,11 +96,11 @@ public String createJsonPathForAssumption( ) { StringBuilder jsonPathFilters = new StringBuilder("[?("); - jsonPathFilters.append(JSON_FIELD_CAMPAIGN_TYPE).append(EQUALS).append(SINGLE_QUOTE).append(campaignType).append(SINGLE_QUOTE) - .append(AND).append(JSON_FIELD_DISTRIBUTION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(distributionProcess).append(SINGLE_QUOTE) - .append(AND).append(JSON_FIELD_REGISTRATION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(registrationProcess).append(SINGLE_QUOTE) - .append(AND).append(JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE).append(EQUALS).append(SINGLE_QUOTE).append(resourceDistributionStrategyCode).append(SINGLE_QUOTE) - .append(AND).append(JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER).append(EQUALS).append(SINGLE_QUOTE).append(isRegistrationAndDistributionTogether).append(SINGLE_QUOTE) + jsonPathFilters.append(JSON_PATH_FILTER_CAMPAIGN_TYPE).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(campaignType)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_DISTRIBUTION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(distributionProcess)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_REGISTRATION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(registrationProcess)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_RESOURCE_DISTRIBUTION_STRATEGY_CODE).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(resourceDistributionStrategyCode)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(isRegistrationAndDistributionTogether)).append(SINGLE_QUOTE) .append(")]"); return JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + jsonPathFilters + FILTER_ALL_ASSUMPTIONS; From 8d56f1e60ac64347ce7499eb1757a4c9a243bb9f Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Thu, 26 Sep 2024 11:51:37 +0530 Subject: [PATCH 054/351] Provided validation for Service Boundaries and Residing Boundary --- .../java/digit/config/ServiceConstants.java | 7 + .../validator/PlanFacilityValidator.java | 121 +++++++++++++++--- 2 files changed, 112 insertions(+), 16 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 083751cf5d9..b8fcf404838 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -130,6 +130,9 @@ public class ServiceConstants { public static final String DUPLICATE_ACTIVITY_UUIDS_CODE = "DUPLICATE_ACTIVITY_UUIDS"; public static final String DUPLICATE_ACTIVITY_UUIDS_MESSAGE = "Activity UUIDs should be unique"; + public static final String INVALID_RESIDING_BOUNDARY_CODE = "INVALID_RESIDING_BOUNDARY"; + public static final String INVALID_RESIDING_BOUNDARY_MESSAGE = "Residing Boundary is Invalid"; + //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; @@ -141,6 +144,10 @@ public class ServiceConstants { public static final String MDMS_MASTER_UOM = "Uom"; public static final String MDMS_CODE = "mdms"; public static final String MDMS_MASTER_NAME_VALIDATION= "MicroplanNamingRegex"; + public static final String MDMS_HCM_ADMIN_CONSOLE = "HCM-ADMIN-CONSOLE"; + public static final String MDMS_MASTER_HIERARCHY_CONFIG= "hierarchyConfig"; + public static final String HIERARCHY_NOT_FOUND_IN_MDMS_CODE="HIERARCHY_NOT_FOUND_IN_MDMS"; + public static final String HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE="Hierarchy Not Found"; public static final String JSON_ROOT_PATH = "$."; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index ec0dd6b7523..cea65bc85ca 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -1,15 +1,14 @@ package digit.service.validator; +import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; -import digit.util.CampaignUtil; -import digit.util.CommonUtil; -import digit.util.FacilityUtil; -import digit.util.MdmsUtil; +import digit.util.*; import digit.web.models.PlanConfiguration; import digit.web.models.PlanConfigurationSearchCriteria; import digit.web.models.PlanFacility; import digit.web.models.PlanFacilityRequest; import digit.web.models.facility.FacilityResponse; +import digit.web.models.mdmsV2.Mdms; import digit.web.models.projectFactory.Boundary; import digit.web.models.projectFactory.CampaignDetail; import digit.web.models.projectFactory.CampaignResponse; @@ -24,6 +23,7 @@ import org.springframework.util.ObjectUtils; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -54,6 +54,13 @@ public PlanFacilityValidator(MdmsUtil mdmsUtil, MultiStateInstanceUtil centralIn this.campaignUtil = campaignUtil; } + /** + * This method validates the Plan Facility Create request. + * It performs multiple validations such as plan configuration, facility existence, + * and campaign-related validations. + * + * @param planFacilityRequest + */ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); @@ -75,20 +82,85 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe validateCampaignDetails(planConfigurations.get(0).getCampaignId(),rootTenantId,planFacilityRequest); } - - + /** + * Validates campaign details, including hierarchy type and boundaries, + * ensuring the plan facility complies with campaign rules. + * + * @param campaignId The ID of the campaign. + * @param rootTenantId The root tenant ID. + * @param body The request body containing plan facility data. + */ private void validateCampaignDetails(String campaignId,String rootTenantId, PlanFacilityRequest body) { PlanFacility planFacility=body.getPlanFacility(); + Object mdmsData = mdmsUtil.fetchMdmsData(body.getRequestInfo(), rootTenantId); CampaignResponse campaignResponse=campaignUtil.fetchCampaignData(body.getRequestInfo(),campaignId,rootTenantId); // Validate if campaign id exists validateCampaignId(campaignResponse); + // validate hierarchy type for campaign + String lowestHierarchy = validateHierarchyType(campaignResponse, mdmsData); + + // Collect all boundary code for the campaign + CampaignDetail campaignDetail = campaignResponse.getCampaignDetails().get(0); + Set boundaryCode = campaignDetail.getBoundaries().stream() + .filter(boundary -> lowestHierarchy.equals(boundary.getType())) + .map(Boundary::getCode) + .collect(Collectors.toSet()); + //validate service boundaries - validateServiceBoundaries(campaignResponse.getCampaignDetails().get(0),planFacility); + validateServiceBoundaries(boundaryCode, planFacility); + + //validate residing boundaries + validateResidingBoundaries(boundaryCode, planFacility); + } + + /** + * This method validates if residing boundaries exist in campaign details + * + * @param boundaryCode + * @param planFacility + */ + private void validateResidingBoundaries(Set boundaryCode, PlanFacility planFacility) { + String residingBoundary = planFacility.getResidingBoundary(); + if (residingBoundary != null && !boundaryCode.contains(residingBoundary)) { + throw new CustomException(INVALID_RESIDING_BOUNDARY_CODE, INVALID_RESIDING_BOUNDARY_MESSAGE); + } } + /** + * This method validates if the hierarchy type provided in the request exists + * + * @param campaignResponse + * @param mdmsData + */ + private String validateHierarchyType(CampaignResponse campaignResponse, Object mdmsData) { + String hierarchyType = campaignResponse.getCampaignDetails().get(0).getHierarchyType(); + final String jsonPathForHierarchy = "$.HCM-ADMIN-CONSOLE.hierarchyConfig[*]"; + + List> hierarchyConfigList = null; + System.out.println("Jsonpath for hierarchy config -> " + jsonPathForHierarchy); + try { + hierarchyConfigList = JsonPath.read(mdmsData, jsonPathForHierarchy); + } catch (Exception e) { + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + for (Map hierarchyConfig : hierarchyConfigList) { + if (hierarchyType.equals(hierarchyConfig.get("hierarchy"))) { + return (String) hierarchyConfig.get("lowestHierarchy"); + } + } + // Throw exception if no matching hierarchy is found + throw new CustomException(HIERARCHY_NOT_FOUND_IN_MDMS_CODE, HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE); + } + + /** + * This method validates if the campaign response contains campaign details. + * + * @param campaignResponse + */ private void validateCampaignId(CampaignResponse campaignResponse) { if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { @@ -96,13 +168,13 @@ private void validateCampaignId(CampaignResponse campaignResponse) { } } - private void validateServiceBoundaries(CampaignDetail campaignDetail, PlanFacility planFacility) - { - // Collect all boundary code for the campaign - Set boundaryCode = campaignDetail.getBoundaries().stream() - .map(Boundary::getCode) - .collect(Collectors.toSet()); - + /** + * This method validates if service boundaries exist in campaign details + * + * @param boundaryCode + * @param planFacility + */ + private void validateServiceBoundaries(Set boundaryCode, PlanFacility planFacility) { planFacility.getServiceBoundaries().stream() .forEach(service -> { if (!boundaryCode.contains(service)) { @@ -111,6 +183,13 @@ private void validateServiceBoundaries(CampaignDetail campaignDetail, PlanFacili }); } + /** + * Searches for a PlanConfiguration by ID and tenant ID. + * + * @param planConfigurationId The plan configuration ID. + * @param tenantId The tenant ID. + * @return The list of plan configurations matching the search criteria. + */ public List searchPlanConfigId(String planConfigurationId, String tenantId) { List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() .id(planConfigurationId) @@ -120,8 +199,13 @@ public List searchPlanConfigId(String planConfigurationId, St return planConfigurations; } - - + /** + * Validates if the facility with the provided ID exists in the system. + * + * @param facilityId The facility ID to validate. + * @param tenantId The tenant ID. + * @param requestInfo The request information for the API call. + */ private void validateFacilityExistence(String facilityId, String tenantId, RequestInfo requestInfo) { FacilityResponse facilityResponse = facilityUtil.fetchFacilityData(requestInfo, facilityId, tenantId); @@ -131,6 +215,11 @@ private void validateFacilityExistence(String facilityId, String tenantId, Reque } } + /** + * Validates if the plan configuration ID provided in the request exists. + * + * @param request The request object containing the plan configuration ID. + */ private void validatePlanConfigurationExistence(PlanFacilityRequest request) { // If plan configuration id provided is invalid, throw an exception if(!ObjectUtils.isEmpty(request.getPlanFacility().getPlanConfigurationId()) && CollectionUtils.isEmpty( From 8c3856be1138c56edfa4ecfe08746b0a3a8d0cdc Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 27 Sep 2024 10:30:31 +0530 Subject: [PATCH 055/351] made planConfig id mandatory for search api --- .../src/main/java/digit/config/ServiceConstants.java | 3 +++ .../service/validator/PlanEmployeeAssignmentValidator.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 5519fb7f2ff..edd7f058f10 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -59,6 +59,9 @@ public class ServiceConstants { public static final String TENANT_ID_EMPTY_CODE = "TENANT_ID_EMPTY"; public static final String TENANT_ID_EMPTY_MESSAGE = "Tenant Id cannot be empty, TenantId should be present"; + public static final String PLAN_CONFIG_ID_EMPTY_CODE = "PLAN_CONFIG_ID_EMPTY"; + public static final String PLAN_CONFIG_ID_EMPTY_MESSAGE = "Plan config Id cannot be empty, PlanConfigID should be present"; + public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE = "NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT"; public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE = "Invalid or incorrect TenantId. No mdms data found for provided Tenant."; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 8aaa7ca8caf..449671ccc16 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -160,6 +160,10 @@ public void validateSearch(PlanEmployeeAssignmentSearchRequest request) { if (StringUtils.isEmpty(searchCriteria.getTenantId())) { throw new CustomException(TENANT_ID_EMPTY_CODE, TENANT_ID_EMPTY_MESSAGE); } + + if (StringUtils.isEmpty(searchCriteria.getPlanConfigurationId())) { + throw new CustomException(PLAN_CONFIG_ID_EMPTY_CODE, PLAN_CONFIG_ID_EMPTY_MESSAGE); + } } /** From 9069c7dcae3015a8fb94eb644a355665f95cfe24 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 27 Sep 2024 11:18:48 +0530 Subject: [PATCH 056/351] formatting --- .../service/enrichment/EnrichmentService.java | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index 0717999c708..3be90d8bda2 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java @@ -11,11 +11,14 @@ import org.springframework.stereotype.Component; import java.util.List; + import static digit.config.ServiceConstants.USERINFO_MISSING_CODE; import static digit.config.ServiceConstants.USERINFO_MISSING_MESSAGE; import org.springframework.util.CollectionUtils; + import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; + import org.springframework.util.ObjectUtils; @Component @@ -31,6 +34,7 @@ public EnrichmentService(Configuration config) { * Enriches the PlanConfigurationRequest for creating a new plan configuration. * Enriches the given plan configuration with generated IDs for plan, files, assumptions, operations, and resource mappings, * validates user information, and enriches audit details for create operation. + * * @param request The PlanConfigurationRequest to be enriched. * @throws CustomException if user information is missing in the request. */ @@ -42,8 +46,7 @@ public void enrichCreate(PlanConfigurationRequest request) { UUIDEnrichmentUtil.enrichRandomUuid(planConfiguration, "id"); // Generate id for files - if(!CollectionUtils.isEmpty(planConfiguration.getFiles())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getFiles())) { planConfiguration.getFiles().forEach(file -> { UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); enrichActiveForResourceMapping(file, planConfiguration.getResourceMapping()); @@ -51,21 +54,18 @@ public void enrichCreate(PlanConfigurationRequest request) { } // Generate id for assumptions - if(!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { planConfiguration.getAssumptions().forEach(assumption -> UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id")); } // Generate id for operations - if(!CollectionUtils.isEmpty(planConfiguration.getOperations())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getOperations())) { planConfiguration.getOperations().forEach(operation -> UUIDEnrichmentUtil.enrichRandomUuid(operation, "id")); } // Generate id for resource mappings - if(!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { planConfiguration.getResourceMapping().forEach(resourceMapping -> UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id")); } @@ -75,6 +75,7 @@ public void enrichCreate(PlanConfigurationRequest request) { /** * Enriches the PlanConfigurationRequest for updating an existing plan configuration. * This method enriches the plan configuration for update, validates user information, and enriches audit details for update operation. + * * @param request The PlanConfigurationRequest to be enriched. * @throws CustomException if user information is missing in the request. */ @@ -82,8 +83,7 @@ public void enrichUpdate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); // Generate id for Files - if(!CollectionUtils.isEmpty(planConfiguration.getFiles())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getFiles())) { planConfiguration.getFiles().forEach(file -> { if (ObjectUtils.isEmpty(file.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); @@ -93,8 +93,7 @@ public void enrichUpdate(PlanConfigurationRequest request) { } // Generate id for Assumptions - if(!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { planConfiguration.getAssumptions().forEach(assumption -> { if (ObjectUtils.isEmpty(assumption.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id"); @@ -103,8 +102,7 @@ public void enrichUpdate(PlanConfigurationRequest request) { } // Generate id for Operations - if(!CollectionUtils.isEmpty(planConfiguration.getOperations())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getOperations())) { planConfiguration.getOperations().forEach(operation -> { if (ObjectUtils.isEmpty(operation.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(operation, "id"); @@ -113,8 +111,7 @@ public void enrichUpdate(PlanConfigurationRequest request) { } // Generate id for ResourceMappings - if(!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { planConfiguration.getResourceMapping().forEach(resourceMapping -> { if (ObjectUtils.isEmpty(resourceMapping.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); @@ -128,7 +125,7 @@ public void enrichUpdate(PlanConfigurationRequest request) { /** * Sets all corresponding resource mappings to inactive if the given file is inactive. * - * @param file the file object which may be inactive + * @param file the file object which may be inactive * @param resourceMappings the list of resource mappings to update */ public void enrichActiveForResourceMapping(File file, List resourceMappings) { @@ -147,13 +144,11 @@ public void enrichActiveForResourceMapping(File file, List reso * * @param request the plan configuration request containing the plan configuration to be enriched */ - public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest request) - { + public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); // For Files, Operations, Assumptions and Resource Mappings override active to be True - if(!CollectionUtils.isEmpty(planConfiguration.getFiles())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getFiles())) { planConfiguration.getFiles().forEach(file -> { if (ObjectUtils.isEmpty(file.getId())) { file.setActive(Boolean.TRUE); @@ -161,8 +156,7 @@ public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest req }); } - if(!CollectionUtils.isEmpty(planConfiguration.getOperations())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getOperations())) { planConfiguration.getOperations().forEach(operation -> { if (ObjectUtils.isEmpty(operation.getId())) { operation.setActive(Boolean.TRUE); @@ -170,8 +164,7 @@ public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest req }); } - if(!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { planConfiguration.getAssumptions().forEach(assumption -> { if (ObjectUtils.isEmpty(assumption.getId())) { assumption.setActive(Boolean.TRUE); @@ -179,8 +172,7 @@ public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest req }); } - if(!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) - { + if (!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { planConfiguration.getResourceMapping().forEach(resourceMapping -> { if (ObjectUtils.isEmpty(resourceMapping.getId())) { resourceMapping.setActive(Boolean.TRUE); From 9a745be49a58827b0b137190453443d424b4ce9b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 27 Sep 2024 14:44:51 +0530 Subject: [PATCH 057/351] moved a function to queryUtil --- .../querybuilder/PlanConfigQueryBuilder.java | 20 ++++--- .../querybuilder/PlanQueryBuilder.java | 29 ++++++---- .../PlanEmployeeAssignmentRowMapper.java | 10 ++-- .../repository/rowmapper/PlanRowMapper.java | 26 ++++----- .../src/main/java/digit/util/CommonUtil.java | 18 ------ .../src/main/java/digit/util/QueryUtil.java | 58 +++++++++++++++---- 6 files changed, 93 insertions(+), 68 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 6d1c3cd6a3b..cedb3b01be9 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -4,8 +4,10 @@ import digit.util.QueryUtil; import digit.web.models.PlanConfigurationSearchCriteria; + import java.util.LinkedHashSet; import java.util.List; + import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -15,8 +17,11 @@ public class PlanConfigQueryBuilder { private Configuration config; - public PlanConfigQueryBuilder(Configuration config) { + private QueryUtil queryUtil; + + public PlanConfigQueryBuilder(Configuration config, QueryUtil queryUtil) { this.config = config; + this.queryUtil = queryUtil; } private static final String PLAN_CONFIG_SEARCH_BASE_QUERY = "SELECT id FROM plan_configuration pc "; @@ -44,14 +49,14 @@ private String buildPlanConfigQuery(List ids, List preparedStmtL StringBuilder builder = new StringBuilder(PLAN_CONFIG_QUERY); if (!CollectionUtils.isEmpty(ids)) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pc.id IN ( ").append(QueryUtil.createQuery(ids.size())).append(" )"); - QueryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pc.id IN ( ").append(queryUtil.createQuery(ids.size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); } addActiveWhereClause(builder, preparedStmtList); - return QueryUtil.addOrderByClause(builder.toString(), PLAN_CONFIG_SEARCH_QUERY_ORDER_BY_CLAUSE); + return queryUtil.addOrderByClause(builder.toString(), PLAN_CONFIG_SEARCH_QUERY_ORDER_BY_CLAUSE); } /** @@ -64,7 +69,7 @@ private String buildPlanConfigQuery(List ids, List preparedStmtL */ public String getPlanConfigSearchQuery(PlanConfigurationSearchCriteria criteria, List preparedStmtList) { String query = buildPlanConfigSearchQuery(criteria, preparedStmtList, Boolean.FALSE); - query = QueryUtil.addOrderByClause(query, PLAN_CONFIG_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = queryUtil.addOrderByClause(query, PLAN_CONFIG_SEARCH_QUERY_ORDER_BY_CLAUSE); query = getPaginatedQuery(query, criteria, preparedStmtList); return query; @@ -162,8 +167,7 @@ private String getPaginatedQuery(String query, PlanConfigurationSearchCriteria p return paginatedQuery.toString(); } - public void addActiveWhereClause(StringBuilder builder, List preparedStmtList) - { + public void addActiveWhereClause(StringBuilder builder, List preparedStmtList) { addClauseIfRequired(preparedStmtList, builder); builder.append(" pcf.active = ?"); preparedStmtList.add(Boolean.TRUE); diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 34b9a1f5981..8dc0ec74384 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; + import java.util.LinkedHashSet; import java.util.List; @@ -14,8 +15,11 @@ public class PlanQueryBuilder { private Configuration config; - public PlanQueryBuilder(Configuration config) { + private QueryUtil queryUtil; + + public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { this.config = config; + this.queryUtil = queryUtil; } private static final String PLAN_SEARCH_BASE_QUERY = "SELECT id FROM plan "; @@ -41,9 +45,9 @@ private String buildPlanQuery(List ids, List preparedStmtList) { StringBuilder builder = new StringBuilder(PLAN_QUERY); if (!CollectionUtils.isEmpty(ids)) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan.id IN ( ").append(QueryUtil.createQuery(ids.size())).append(" )"); - QueryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" plan.id IN ( ").append(queryUtil.createQuery(ids.size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); } return builder.toString(); @@ -51,13 +55,14 @@ private String buildPlanQuery(List ids, List preparedStmtList) { public String getPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList) { String query = buildPlanSearchQuery(planSearchCriteria, preparedStmtList); - query = QueryUtil.addOrderByClause(query, PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = queryUtil.addOrderByClause(query, PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE); query = getPaginatedQuery(query, planSearchCriteria, preparedStmtList); return query; } /** * Method to build query dynamically based on the criteria passed to the method + * * @param planSearchCriteria * @param preparedStmtList * @return @@ -66,31 +71,31 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< StringBuilder builder = new StringBuilder(PLAN_SEARCH_BASE_QUERY); if (!ObjectUtils.isEmpty(planSearchCriteria.getTenantId())) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); + queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" tenant_id = ? "); preparedStmtList.add(planSearchCriteria.getTenantId()); } if (!CollectionUtils.isEmpty(planSearchCriteria.getIds())) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" id IN ( ").append(QueryUtil.createQuery(planSearchCriteria.getIds().size())).append(" )"); - QueryUtil.addToPreparedStatement(preparedStmtList, planSearchCriteria.getIds()); + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" id IN ( ").append(queryUtil.createQuery(planSearchCriteria.getIds().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, planSearchCriteria.getIds()); } if (!ObjectUtils.isEmpty(planSearchCriteria.getLocality())) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); + queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" locality = ? "); preparedStmtList.add(planSearchCriteria.getLocality()); } if (!ObjectUtils.isEmpty(planSearchCriteria.getCampaignId())) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); + queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" campaign_id = ? "); preparedStmtList.add(planSearchCriteria.getCampaignId()); } if (!ObjectUtils.isEmpty(planSearchCriteria.getPlanConfigurationId())) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); + queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" plan_configuration_id = ? "); preparedStmtList.add(planSearchCriteria.getPlanConfigurationId()); } diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java index 3001239a485..284d7df19ff 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -1,6 +1,6 @@ package digit.repository.rowmapper; -import digit.util.CommonUtil; +import digit.util.QueryUtil; import digit.web.models.PlanEmployeeAssignment; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.AuditDetails; @@ -18,10 +18,10 @@ @Component public class PlanEmployeeAssignmentRowMapper implements ResultSetExtractor> { - private CommonUtil commonUtil; + private QueryUtil queryUtil; - public PlanEmployeeAssignmentRowMapper(CommonUtil commonUtil) { - this.commonUtil = commonUtil; + public PlanEmployeeAssignmentRowMapper(QueryUtil queryUtil) { + this.queryUtil = queryUtil; } @Override @@ -51,7 +51,7 @@ public List extractData(ResultSet rs) throws SQLExceptio planEmployeeAssignment.setRole(rs.getString("role")); planEmployeeAssignment.setJurisdiction(jurisdictionList); planEmployeeAssignment.setActive(rs.getBoolean("active")); - planEmployeeAssignment.setAdditionalDetails(commonUtil.getAdditionalDetail((PGobject) rs.getObject("additional_details"))); + planEmployeeAssignment.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("additional_details"))); planEmployeeAssignment.setAuditDetails(auditDetails); planEmployeeAssignmentMap.put(planEmployeeAssignmentId, planEmployeeAssignment); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index ca3f70489b7..c56375d7f96 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java @@ -1,6 +1,7 @@ package digit.repository.rowmapper; import digit.util.CommonUtil; +import digit.util.QueryUtil; import digit.web.models.*; import org.egov.common.contract.models.AuditDetails; import org.postgresql.util.PGobject; @@ -17,10 +18,10 @@ @Component public class PlanRowMapper implements ResultSetExtractor> { - private CommonUtil commonUtil; + private QueryUtil queryUtil; - public PlanRowMapper(CommonUtil commonUtil) { - this.commonUtil = commonUtil; + public PlanRowMapper(QueryUtil queryUtil) { + this.queryUtil = queryUtil; } @Override @@ -32,12 +33,12 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep Map targetMap = new LinkedHashMap<>(); // Traverse through result set and create plan objects - while(rs.next()) { + while (rs.next()) { String planId = rs.getString("plan_id"); Plan planEntry = planMap.get(planId); - if(ObjectUtils.isEmpty(planEntry)) { + if (ObjectUtils.isEmpty(planEntry)) { planEntry = new Plan(); // Prepare audit details @@ -54,7 +55,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep planEntry.setLocality(rs.getString("plan_locality")); planEntry.setCampaignId(rs.getString("plan_campaign_id")); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); - planEntry.setAdditionalDetails(commonUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); + planEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); planEntry.setAuditDetails(auditDetails); } @@ -73,11 +74,10 @@ private void addActivities(ResultSet rs, Plan plan, String activityId = rs.getString("plan_activity_id"); - if(!ObjectUtils.isEmpty(activityId) && activityMap.containsKey(activityId)) { + if (!ObjectUtils.isEmpty(activityId) && activityMap.containsKey(activityId)) { addActivityConditions(rs, activityMap.get(activityId), conditionMap); return; - } - else if (ObjectUtils.isEmpty(activityId)) { + } else if (ObjectUtils.isEmpty(activityId)) { // Set activities list to empty if no activity found plan.setActivities(new ArrayList<>()); return; @@ -117,7 +117,7 @@ else if (ObjectUtils.isEmpty(activityId)) { private void addActivityConditions(ResultSet rs, Activity activity, Map conditionMap) throws SQLException, DataAccessException { String conditionId = rs.getString("plan_activity_condition_id"); - if(ObjectUtils.isEmpty(conditionId) || conditionMap.containsKey(conditionId)) { + if (ObjectUtils.isEmpty(conditionId) || conditionMap.containsKey(conditionId)) { List conditionList = new ArrayList<>(); activity.setConditions(conditionList); return; @@ -137,7 +137,7 @@ private void addActivityConditions(ResultSet rs, Activity activity, Map conditionList = new ArrayList<>(); conditionList.add(condition); activity.setConditions(conditionList); @@ -153,7 +153,7 @@ private void addResources(ResultSet rs, Plan planEntry, Map re String resourceId = rs.getString("plan_resource_id"); - if(ObjectUtils.isEmpty(resourceId) || resourceMap.containsKey(resourceId)) { + if (ObjectUtils.isEmpty(resourceId) || resourceMap.containsKey(resourceId)) { List resourceList = new ArrayList<>(); planEntry.setResources(resourceList); return; @@ -188,7 +188,7 @@ private void addResources(ResultSet rs, Plan planEntry, Map re private void addTargets(ResultSet rs, Plan planEntry, Map targetMap) throws SQLException, DataAccessException { String targetId = rs.getString("plan_target_id"); - if(ObjectUtils.isEmpty(targetId) || targetMap.containsKey(targetId)) { + if (ObjectUtils.isEmpty(targetId) || targetMap.containsKey(targetId)) { List targetList = new ArrayList<>(); planEntry.setTargets(targetList); return; diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 20b00295cc4..3c49209d861 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -125,22 +125,4 @@ private String convertArrayToString(List stringList) { return String.join(", ", stringList); } - /** - * This method is used to extract and parse JSON data into a JsonNode object - * - * @param pGobject postgreSQL specific object - * @return returns a JsonNode - */ - public JsonNode getAdditionalDetail(PGobject pGobject) { - JsonNode additionalDetail = null; - - try { - if (!ObjectUtils.isEmpty(pGobject)) { - additionalDetail = objectMapper.readTree(pGobject.getValue()); - } - } catch (IOException e) { - throw new CustomException("PARSING_ERROR", "Failed to parse additionalDetails object"); - } - return additionalDetail; - } } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/util/QueryUtil.java b/health-services/plan-service/src/main/java/digit/util/QueryUtil.java index d2da03ec1b0..2bb3156c2f5 100644 --- a/health-services/plan-service/src/main/java/digit/util/QueryUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/QueryUtil.java @@ -1,9 +1,15 @@ package digit.util; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import digit.config.Configuration; +import org.egov.tracer.model.CustomException; +import org.postgresql.util.PGobject; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -18,8 +24,11 @@ public class QueryUtil { private Configuration config; - private QueryUtil(Configuration config) { + private ObjectMapper objectMapper; + + private QueryUtil(Configuration config, ObjectMapper objectMapper) { this.config = config; + this.objectMapper = objectMapper; } private static final Gson gson = new Gson(); @@ -28,13 +37,14 @@ private QueryUtil(Configuration config) { * This method aids in adding "WHERE" clause and "AND" condition depending on preparedStatementList i.e., * if preparedStatementList is empty, it will understand that it is the first clause being added so it * will add "WHERE" to the query and otherwise it will + * * @param query * @param preparedStmtList */ - public static void addClauseIfRequired(StringBuilder query, List preparedStmtList){ - if(preparedStmtList.isEmpty()){ + public void addClauseIfRequired(StringBuilder query, List preparedStmtList) { + if (preparedStmtList.isEmpty()) { query.append(" WHERE "); - }else{ + } else { query.append(" AND "); } } @@ -42,10 +52,11 @@ public static void addClauseIfRequired(StringBuilder query, List prepare /** * This method returns a string with placeholders equal to the number of values that need to be put inside * "IN" clause + * * @param size * @return */ - public static String createQuery(Integer size) { + public String createQuery(Integer size) { StringBuilder builder = new StringBuilder(); IntStream.range(0, size).forEach(i -> { @@ -59,10 +70,11 @@ public static String createQuery(Integer size) { /** * This method adds a set of String values into preparedStatementList + * * @param preparedStmtList * @param ids */ - public static void addToPreparedStatement(List preparedStmtList, Set ids) { + public void addToPreparedStatement(List preparedStmtList, Set ids) { ids.forEach(id -> { preparedStmtList.add(id); }); @@ -70,29 +82,31 @@ public static void addToPreparedStatement(List preparedStmtList, Set filterMap) { + public String preparePartialJsonStringFromFilterMap(Map filterMap) { Map queryMap = new HashMap<>(); filterMap.keySet().forEach(key -> { - if(key.contains(DOT_SEPARATOR)){ + if (key.contains(DOT_SEPARATOR)) { String[] keyArray = key.split(DOT_REGEX); Map nestedQueryMap = new HashMap<>(); prepareNestedQueryMap(0, keyArray, nestedQueryMap, filterMap.get(key)); queryMap.put(keyArray[0], nestedQueryMap.get(keyArray[0])); - } else{ + } else { queryMap.put(key, filterMap.get(key)); } }); @@ -106,14 +120,15 @@ public static String preparePartialJsonStringFromFilterMap(Map f * Tail recursive method to prepare n-level nested partial json for queries on nested data in * master data. For e.g. , if the key is in the format a.b.c, it will construct a nested json * object of the form - {"a":{"b":{"c": "value"}}} + * * @param index * @param nestedKeyArray * @param currentQueryMap * @param value */ - private static void prepareNestedQueryMap(int index, String[] nestedKeyArray, Map currentQueryMap, String value) { + private void prepareNestedQueryMap(int index, String[] nestedKeyArray, Map currentQueryMap, String value) { // Return when all levels have been reached. - if(index == nestedKeyArray.length) + if (index == nestedKeyArray.length) return; // For the final level simply put the value in the map. @@ -149,4 +164,23 @@ public String getPaginatedQuery(String query, List preparedStmtList) { return paginatedQuery.toString(); } + + /** + * This method is used to extract and parse JSON data into a JsonNode object + * + * @param pGobject postgreSQL specific object + * @return returns a JsonNode + */ + public JsonNode getAdditionalDetail(PGobject pGobject) { + JsonNode additionalDetail = null; + + try { + if (!ObjectUtils.isEmpty(pGobject)) { + additionalDetail = objectMapper.readTree(pGobject.getValue()); + } + } catch (IOException e) { + throw new CustomException("PARSING_ERROR", "Failed to parse additionalDetails object"); + } + return additionalDetail; + } } From 54538bc931884534757cc35c9b9f5b68a5b08992 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 27 Sep 2024 14:52:00 +0530 Subject: [PATCH 058/351] HCMPRE-470 code review comments --- health-services/plan-service/pom.xml | 2 +- .../java/digit/config/ServiceConstants.java | 7 +++++ .../validator/PlanConfigurationValidator.java | 21 ++++++++----- .../src/main/java/digit/util/CommonUtil.java | 31 ++++++------------- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/health-services/plan-service/pom.xml b/health-services/plan-service/pom.xml index 6cb9a4ac3ae..c41f44a9f05 100644 --- a/health-services/plan-service/pom.xml +++ b/health-services/plan-service/pom.xml @@ -98,7 +98,7 @@ org.apache.commons commons-text - 1.10.0 + 1.10.0 diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 6273b423347..59212f0836e 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -133,6 +133,11 @@ public class ServiceConstants { public static final String DUPLICATE_ACTIVITY_UUIDS_CODE = "DUPLICATE_ACTIVITY_UUIDS"; public static final String DUPLICATE_ACTIVITY_UUIDS_MESSAGE = "Activity UUIDs should be unique"; + public static final String ADDITIONAL_DETAILS_MISSING_CODE = "ADDITIONAL_DETAILS_MISSING"; + public static final String ADDITIONAL_DETAILS_MISSING_MESSAGE = "Additional details are missing in the plan configuration request."; + + 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 - "; //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; @@ -195,6 +200,8 @@ public class ServiceConstants { public static final String JSON_FIELD_VEHICLE_ID = "vehicleIds"; // JSON path constants for campaign details + public static final String JSONPATH_FILTER_PREFIX = "[?("; + public static final String JSONPATH_FILTER_SUFFIX = ")]"; public static final String JSON_PATH_FILTER_CAMPAIGN_TYPE = "@.campaignType"; public static final String JSON_PATH_FILTER_DISTRIBUTION_PROCESS = "@.DistributionProcess"; public static final String JSON_PATH_FILTER_REGISTRATION_PROCESS = "@.RegistrationProcess"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index a4c2d85e4d1..d807e7c8740 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -152,12 +152,15 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); Object additionalDetails = request.getPlanConfiguration().getAdditionalDetails(); + if (additionalDetails == null) { + throw new CustomException(ADDITIONAL_DETAILS_MISSING_CODE, ADDITIONAL_DETAILS_MISSING_MESSAGE); + } - String jsonPathForAssumption = commonUtil.createJsonPathForAssumption((String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE), - (String) commonUtil.extractFieldsFromAdditionalDetails(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); + String jsonPathForAssumption = commonUtil.createJsonPathForAssumption(commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE, String.class), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS, String.class), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS, String.class), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE, String.class), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER, String.class)); List assumptionListFromMDMS = null; try { log.info(jsonPathForAssumption); @@ -545,9 +548,13 @@ public void validateUserInfo(PlanConfigurationRequest request) * @param mdmsV2Data mdms v2 data object */ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, List mdmsV2Data) { - List vehicleIdsLinkedWithPlanConfig; + Object vehicleIdsfromAdditionalDetails; + List vehicleIdsLinkedWithPlanConfig = new ArrayList<>(); try { - vehicleIdsLinkedWithPlanConfig = (List) commonUtil.extractFieldsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails(), JSON_FIELD_VEHICLE_ID); + vehicleIdsfromAdditionalDetails = commonUtil.extractFieldsFromJsonObject(request.getPlanConfiguration().getAdditionalDetails(), JSON_FIELD_VEHICLE_ID, String.class); + if (vehicleIdsfromAdditionalDetails instanceof List vehicleIdsList) { + vehicleIdsList.stream().allMatch(String.class::isInstance); + } } catch (ClassCastException e) { throw new CustomException(VEHICLE_IDS_INVALID_DATA_TYPE_CODE, VEHICLE_IDS_INVALID_DATA_TYPE_MESSAGE); } diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 1a55af33841..4d422457984 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -5,13 +5,13 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; import org.egov.tracer.model.CustomException; +import org.postgresql.util.PGobject; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; -import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; - import static digit.config.ServiceConstants.*; @Component @@ -45,33 +45,22 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri * @param additionalDetails the additionalDetails object from PlanConfigurationRequest * @return a field to extract from additional details */ - public Object extractFieldsFromAdditionalDetails(Object additionalDetails, String fieldToExtract) { + public T extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract, Class valueType) { try { String jsonString = objectMapper.writeValueAsString(additionalDetails); JsonNode rootNode = objectMapper.readTree(jsonString); - List listFromAdditionalDetails = new ArrayList<>(); JsonNode node = rootNode.get(fieldToExtract); if (node != null && node.isArray()) { - for (JsonNode idNode : node) { - listFromAdditionalDetails.add(idNode.asText()); - } - return listFromAdditionalDetails; + return objectMapper.convertValue(node, objectMapper.getTypeFactory().constructCollectionType(List.class, valueType)); } else if (node != null) { - // Return the value in its original type based on its type - if (node.isInt()) { - return node.asInt(); - } else if (node.isBoolean()) { - return node.asBoolean(); - } else if (node.isTextual()) { - return node.asText(); - } + return objectMapper.convertValue(node, valueType); } // In case the node is of other type like object, handle accordingly - return node; + return (T) node; } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + 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); } } @@ -95,13 +84,13 @@ public String createJsonPathForAssumption( String isRegistrationAndDistributionTogether ) { - StringBuilder jsonPathFilters = new StringBuilder("[?("); + StringBuilder jsonPathFilters = new StringBuilder(JSONPATH_FILTER_PREFIX); jsonPathFilters.append(JSON_PATH_FILTER_CAMPAIGN_TYPE).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(campaignType)).append(SINGLE_QUOTE) .append(AND).append(JSON_PATH_FILTER_DISTRIBUTION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(distributionProcess)).append(SINGLE_QUOTE) .append(AND).append(JSON_PATH_FILTER_REGISTRATION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(registrationProcess)).append(SINGLE_QUOTE) .append(AND).append(JSON_PATH_FILTER_RESOURCE_DISTRIBUTION_STRATEGY_CODE).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(resourceDistributionStrategyCode)).append(SINGLE_QUOTE) .append(AND).append(JSON_PATH_FILTER_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(isRegistrationAndDistributionTogether)).append(SINGLE_QUOTE) - .append(")]"); + .append(JSONPATH_FILTER_SUFFIX); return JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + jsonPathFilters + FILTER_ALL_ASSUMPTIONS; } From f6ff12a0e38320ca95c88ef42e936c3374401165 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 27 Sep 2024 14:54:57 +0530 Subject: [PATCH 059/351] added additional_details in planConfigRowMapper --- .../repository/querybuilder/PlanConfigQueryBuilder.java | 2 +- .../digit/repository/rowmapper/PlanConfigRowMapper.java | 9 +++++++++ .../egov/project/validator/project/ProjectValidator.java | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index cedb3b01be9..bf8d2c94d52 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -26,7 +26,7 @@ public PlanConfigQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_CONFIG_SEARCH_BASE_QUERY = "SELECT id FROM plan_configuration pc "; - private static final String PLAN_CONFIG_QUERY = "SELECT pc.id as plan_configuration_id, pc.tenant_id as plan_configuration_tenant_id, pc.name as plan_configuration_name, pc.campaign_id as plan_configuration_campaign_id, pc.status as plan_configuration_status, pc.created_by as plan_configuration_created_by, pc.created_time as plan_configuration_created_time, pc.last_modified_by as plan_configuration_last_modified_by, pc.last_modified_time as plan_configuration_last_modified_time, \n" + + private static final String PLAN_CONFIG_QUERY = "SELECT pc.id as plan_configuration_id, pc.tenant_id as plan_configuration_tenant_id, pc.name as plan_configuration_name, pc.campaign_id as plan_configuration_campaign_id, pc.status as plan_configuration_status, pc.additional_details as plan_configuration_additional_details, pc.created_by as plan_configuration_created_by, pc.created_time as plan_configuration_created_time, pc.last_modified_by as plan_configuration_last_modified_by, pc.last_modified_time as plan_configuration_last_modified_time, \n" + "\t pcf.id as plan_configuration_files_id, pcf.plan_configuration_id as plan_configuration_files_plan_configuration_id, pcf.filestore_id as plan_configuration_files_filestore_id, pcf.input_file_type as plan_configuration_files_input_file_type, pcf.template_identifier as plan_configuration_files_template_identifier, pcf.active as plan_configuration_files_active, pcf.created_by as plan_configuration_files_created_by, pcf.created_time as plan_configuration_files_created_time, pcf.last_modified_by as plan_configuration_files_last_modified_by, pcf.last_modified_time as plan_configuration_files_last_modified_time,\n" + "\t pca.id as plan_configuration_assumptions_id, pca.key as plan_configuration_assumptions_key, pca.value as plan_configuration_assumptions_value, pca.active as plan_configuration_assumptions_active, pca.plan_configuration_id as plan_configuration_assumptions_plan_configuration_id, pca.created_by as plan_configuration_assumptions_created_by, pca.created_time as plan_configuration_assumptions_created_time, pca.last_modified_by as plan_configuration_assumptions_last_modified_by, pca.last_modified_time as plan_configuration_assumptions_last_modified_time,\n" + "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.active as plan_configuration_operations_active, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index 31ce9002c1e..34ff1083ec6 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java @@ -1,5 +1,6 @@ package digit.repository.rowmapper; +import digit.util.QueryUtil; import digit.web.models.Assumption; import digit.web.models.File; import digit.web.models.Operation; @@ -12,6 +13,7 @@ import java.util.List; import java.util.Map; import org.egov.common.contract.models.AuditDetails; +import org.postgresql.util.PGobject; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.stereotype.Component; @@ -21,6 +23,12 @@ @Component public class PlanConfigRowMapper implements ResultSetExtractor> { + private QueryUtil queryUtil; + + public PlanConfigRowMapper(QueryUtil queryUtil) { + this.queryUtil = queryUtil; + } + @Override public List extractData(ResultSet rs) throws SQLException, DataAccessException { Map planConfigurationMap = new LinkedHashMap<>(); @@ -47,6 +55,7 @@ public List extractData(ResultSet rs) throws SQLException, Da planConfigEntry.setName(rs.getString("plan_configuration_name")); planConfigEntry.setCampaignId(rs.getString("plan_configuration_campaign_id")); planConfigEntry.setStatus(PlanConfiguration.StatusEnum.valueOf(rs.getString("plan_configuration_status").toUpperCase())); + planConfigEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_configuration_additional_details"))); planConfigEntry.setAuditDetails(auditDetails); } diff --git a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java index e1e3f709a5c..9aaba88a427 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java @@ -649,4 +649,4 @@ public void validateParentAgainstDB(List projects, List parent } log.info("Parent projects validated against DB"); } -} +} \ No newline at end of file From 9fc5f1e47211d9efce47e1b7b2215cd4d7819e9e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 27 Sep 2024 14:56:08 +0530 Subject: [PATCH 060/351] HCMPRE-470 code review comments --- .../plan-service/src/main/java/digit/util/CommonUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 4d422457984..f0876ca28c9 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -56,7 +56,7 @@ public T extractFieldsFromJsonObject(Object additionalDetails, String fieldT } else if (node != null) { return objectMapper.convertValue(node, valueType); } - // In case the node is of other type like object, handle accordingly + // In case the node is of other type like object return (T) node; } catch (Exception e) { log.error(e.getMessage() + fieldToExtract); From 9168a04d5521da01a728269bd1154ddc7a3d296c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 27 Sep 2024 15:01:19 +0530 Subject: [PATCH 061/351] formatting --- .../java/digit/service/enrichment/EnrichmentService.java | 4 +--- .../java/org/egov/project/config/ProjectConfiguration.java | 3 +++ .../org/egov/project/validator/project/ProjectValidator.java | 2 +- .../project/src/main/resources/application.properties | 5 ++++- .../src/main/resources/db/Dockerfile | 2 +- .../src/main/resources/db/migrate.sh | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index 3be90d8bda2..77d186bc88c 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java @@ -12,11 +12,9 @@ import java.util.List; -import static digit.config.ServiceConstants.USERINFO_MISSING_CODE; -import static digit.config.ServiceConstants.USERINFO_MISSING_MESSAGE; - import org.springframework.util.CollectionUtils; +import static digit.config.ServiceConstants.*; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; import org.springframework.util.ObjectUtils; diff --git a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java index 26759e381e2..67ee5a87af6 100644 --- a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java +++ b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java @@ -222,4 +222,7 @@ public class ProjectConfiguration { @Value("${project.task.no.resource.validation.status}") private List noResourceStatuses; + + @Value("${project.attendance.feature.enabled:true}") + private Boolean isAttendanceFeatureEnabled; } diff --git a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java index 266f664312d..9aaba88a427 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java @@ -75,7 +75,7 @@ public void validateCreateProjectRequest(ProjectRequest request) { //Verify MDMS Data // TODO: Uncomment and fix as per HCM once we get clarity // validateRequestMDMSData(request, tenantId, errorMap); - validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); + if(config.getIsAttendanceFeatureEnabled()) validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); //Get boundaries in list from all Projects in request body for validation Map> boundariesForValidation = getBoundaryForValidation(request.getProjects()); diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index 93f601466a9..71af8eab0d3 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -180,4 +180,7 @@ project.location.capture.kafka.create.topic=save-location-capture-project-topic project.location.capture.consumer.bulk.create.topic=save-location-capture-project-bulk-topic #---------No resource statuses ------------# -project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED \ No newline at end of file +project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED + +#---------Attendance Feature ------------# +project.attendance.feature.enabled=true diff --git a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile b/health-services/resource-estimation-service/src/main/resources/db/Dockerfile index 60fc07ce69f..f5241a8f861 100644 --- a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile +++ b/health-services/resource-estimation-service/src/main/resources/db/Dockerfile @@ -1,4 +1,4 @@ -FROM egovio/flyway:4.1.2 +FROM egovio/flyway:10.7.1 COPY ./migration/main /flyway/sql diff --git a/health-services/resource-estimation-service/src/main/resources/db/migrate.sh b/health-services/resource-estimation-service/src/main/resources/db/migrate.sh index 43960b25cdb..c58d6f91e3f 100644 --- a/health-services/resource-estimation-service/src/main/resources/db/migrate.sh +++ b/health-services/resource-estimation-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true -ignoreMissingMigrations=true migrate \ No newline at end of file +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate \ No newline at end of file From d6bb7d34c8b4263bf265440bf23412c88d95dd72 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 27 Sep 2024 15:01:53 +0530 Subject: [PATCH 062/351] HCMPRE-470 enhancing method comment --- .../plan-service/src/main/java/digit/util/CommonUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index f0876ca28c9..174aa7ab784 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -43,7 +43,11 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri * Extracts provided field from the additional details object * * @param additionalDetails the additionalDetails object from PlanConfigurationRequest - * @return a field to extract from additional details + * @param fieldToExtract the name of the field to be extracted from the additional details + * @param valueType the class type to which the extracted field should be converted + * @return the value of the specified field, converted to the specified type + * @throws CustomException if the field does not exist or cannot be converted to the specified type + */ public T extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract, Class valueType) { try { From 48d7d9930732c6ac3932481f26a0dab915185f90 Mon Sep 17 00:00:00 2001 From: palak-egov Date: Fri, 27 Sep 2024 15:05:12 +0530 Subject: [PATCH 063/351] review code changes --- .../repository/PlanFacilityRepository.java | 6 +- .../impl/PlanFacilityRepositoryImpl.java | 52 ++++++----------- .../PlanFacilityQueryBuilder.java | 56 ++++++++++--------- .../rowmapper/PlanFacilityRowMapper.java | 16 +++--- .../digit/service/PlanFacilityService.java | 29 +++++++--- .../src/main/java/digit/util/ServiceUtil.java | 13 +---- .../controllers/PlanFacilityController.java | 7 ++- .../java/digit/web/models/PlanFacility.java | 3 +- .../digit/web/models/PlanFacilityRequest.java | 6 +- .../web/models/PlanFacilityResponse.java | 15 ----- .../models/PlanFacilitySearchCriteria.java | 2 + .../web/models/PlanFacilitySearchRequest.java | 4 +- .../src/main/resources/db/migrate.sh | 2 +- 13 files changed, 91 insertions(+), 120 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java index ec1ec2191cf..673496a3f23 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java @@ -5,9 +5,9 @@ import java.util.List; public interface PlanFacilityRepository { - public void create(PlanFacilityRequest planFacilityRequest); + public void create(PlanFacilitySearchCriteria planFacilitySearchCriteria); - public List search(PlanFacilitySearchCriteria planSearchCriteria); + public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria); - public void update(PlanFacilityRequest planFacilityRequest); + public void update(PlanFacilitySearchCriteria planFacilitySearchCriteria); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index f47aff0fb9e..d6a58b2ffd1 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -4,28 +4,26 @@ import digit.kafka.Producer; import digit.repository.PlanFacilityRepository; import digit.repository.querybuilder.PlanFacilityQueryBuilder; -import digit.repository.querybuilder.PlanQueryBuilder; import digit.repository.rowmapper.PlanFacilityRowMapper; -import digit.repository.rowmapper.PlanRowMapper; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.stereotype.Repository; -import org.springframework.util.CollectionUtils; - import java.util.ArrayList; import java.util.List; @Repository @Slf4j public class PlanFacilityRepositoryImpl implements PlanFacilityRepository { + private Producer producer; + private JdbcTemplate jdbcTemplate; private PlanFacilityQueryBuilder planFacilityQueryBuilder; private PlanFacilityRowMapper planFacilityRowMapper; + private Configuration config; public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, PlanFacilityQueryBuilder planFacilityQueryBuilder, PlanFacilityRowMapper planFacilityRowMapper, Configuration config) { @@ -37,58 +35,40 @@ public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, } @Override - public void create(PlanFacilityRequest planFacilityRequest) { + public void create(PlanFacilitySearchCriteria planFacilitySearchCriteria) { } /** * This method searches for plans based on the search criteria. + * * @param planFacilitySearchCriteria - * @return + * @return List */ @Override public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria) { - // Fetch plan facility ids from database - List planFacilityIds = queryDatabaseForPlanFacilityIds(planFacilitySearchCriteria); - - // Return empty list back as response if no plan facility ids are found - if(CollectionUtils.isEmpty(planFacilityIds)) { - log.info("No planFacility ids found for provided plan facility search criteria."); - return new ArrayList<>(); - } - - // Fetch plans facilities from database based on the acquired ids - List planFacilities = searchPlanFacilityByIds(planFacilityIds); - + // Fetch plan facility from database + List planFacilities = queryDatabaseForPlanFacilities(planFacilitySearchCriteria); return planFacilities; } @Override - public void update(PlanFacilityRequest planFacilityRequest) { + public void update(PlanFacilitySearchCriteria planFacilitySearchCriteria) { } /** - * Helper method to query database for plan facility ids based on the provided search criteria. + * Helper method to query database for plan facilities based on the provided search criteria. + * * @param planFacilitySearchCriteria - * @return + * @return List */ - private List queryDatabaseForPlanFacilityIds(PlanFacilitySearchCriteria planFacilitySearchCriteria) { + private List queryDatabaseForPlanFacilities(PlanFacilitySearchCriteria planFacilitySearchCriteria) { List preparedStmtList = new ArrayList<>(); String query = planFacilityQueryBuilder.getPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); - log.info("Plan search query: " + query); - return jdbcTemplate.query(query, new SingleColumnRowMapper<>(String.class), preparedStmtList.toArray()); - } - - /** - * Helper method to search for plans facility based on the provided plan ids. - * @param planFacilityIds - * @return - */ - private List searchPlanFacilityByIds(List planFacilityIds) { - List preparedStmtList = new ArrayList<>(); - String query = planFacilityQueryBuilder.getPlanFacilityQuery(planFacilityIds, preparedStmtList); - log.info("Plan facility query: " + query); + log.debug("Plan facility search {}", query); + log.debug(preparedStmtList.toString()); return jdbcTemplate.query(query, planFacilityRowMapper, preparedStmtList.toArray()); } + } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index 143a53ad259..20f7496b74a 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -6,40 +6,36 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; - import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; @Component public class PlanFacilityQueryBuilder { - private Configuration config; + private Configuration configuration; - public PlanFacilityQueryBuilder(Configuration config) { - this.config = config; + public PlanFacilityQueryBuilder(Configuration configuration) { + this.configuration = configuration; } - private static final String PLAN_FACILITY_SEARCH_BASE_QUERY = "SELECT id FROM plan_facility_linkage "; - - private static final String PLAN_FACILITY_QUERY = "SELECT plan_facility_linkage.id as plan_facility_id, plan_facility_linkage.tenant_id as plan_facility_tenant_id, plan_facility_linkage.plan_configuration_id as plan_facility_plan_configuration_id, plan_facility_linkage.facility_id as plan_facility_facility_id, plan_facility_linkage.residing_boundary as plan_facility_residing_boundary, plan_facility_linkage.service_boundaries as plan_facility_service_boundaries, plan_facility_linkage.additional_details as plan_facility_additional_details, plan_facility_linkage.created_by as plan_facility_created_by, plan_facility_linkage.created_time as plan_facility_created_time, plan_facility_linkage.last_modified_by as plan_facility_last_modified_by, plan_facility_linkage.last_modified_time as plan_facility_last_modified_time, plan_facility_linkage.active as plan_facility_active FROM plan_facility_linkage"; + private static final String PLAN_FACILITY_QUERY = + "SELECT plan_facility_linkage.id as plan_facility_id, " + + "plan_facility_linkage.tenant_id as plan_facility_tenant_id, " + + "plan_facility_linkage.plan_configuration_id as plan_facility_plan_configuration_id, " + + "plan_facility_linkage.facility_id as plan_facility_facility_id, " + + "plan_facility_linkage.residing_boundary as plan_facility_residing_boundary, " + + "plan_facility_linkage.service_boundaries as plan_facility_service_boundaries, " + + "plan_facility_linkage.additional_details as plan_facility_additional_details, " + + "plan_facility_linkage.created_by as plan_facility_created_by, " + + "plan_facility_linkage.created_time as plan_facility_created_time, " + + "plan_facility_linkage.last_modified_by as plan_facility_last_modified_by, " + + "plan_facility_linkage.last_modified_time as plan_facility_last_modified_time, " + + "plan_facility_linkage.active as plan_facility_active " + + "FROM plan_facility_linkage"; private static final String PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE = " order by plan_facility_linkage.last_modified_time desc "; - public String getPlanFacilityQuery(List ids, List preparedStmtList) { - return buildPlanFacilityQuery(ids, preparedStmtList); - } - - private String buildPlanFacilityQuery(List ids, List preparedStmtList) { - StringBuilder builder = new StringBuilder(PLAN_FACILITY_QUERY); - - if (!CollectionUtils.isEmpty(ids)) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_facility_linkage.id IN ( ").append(QueryUtil.createQuery(ids.size())).append(" )"); - QueryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); - } - - return builder.toString(); - } public String getPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); query = QueryUtil.addOrderByClause(query, PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE); @@ -48,7 +44,14 @@ public String getPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacility } private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { - StringBuilder builder = new StringBuilder(PLAN_FACILITY_SEARCH_BASE_QUERY); + StringBuilder builder = new StringBuilder(PLAN_FACILITY_QUERY); + + if (!CollectionUtils.isEmpty(planFacilitySearchCriteria.getIds())) { + Set ids = planFacilitySearchCriteria.getIds(); + QueryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" id IN ( ").append(QueryUtil.createQuery(ids.size())).append(" )"); + QueryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); + } if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getTenantId())) { QueryUtil.addClauseIfRequired(builder, preparedStmtList); @@ -62,7 +65,7 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil preparedStmtList.add(planFacilitySearchCriteria.getPlanConfigurationId()); } - if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getResidingBoundaries())){ + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getResidingBoundaries())) { List residingBoundaries = planFacilitySearchCriteria.getResidingBoundaries(); QueryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" residing_boundary IN ( ").append(QueryUtil.createQuery(residingBoundaries.size())).append(" )"); @@ -77,14 +80,13 @@ private String getPaginatedQuery(String query, PlanFacilitySearchCriteria planFa // Append offset paginatedQuery.append(" OFFSET ? "); - preparedStmtList.add(ObjectUtils.isEmpty(planFacilitySearchCriteria.getOffset()) ? config.getDefaultOffset() : planFacilitySearchCriteria.getOffset()); + preparedStmtList.add(ObjectUtils.isEmpty(planFacilitySearchCriteria.getOffset()) ? configuration.getDefaultOffset() : planFacilitySearchCriteria.getOffset()); // Append limit paginatedQuery.append(" LIMIT ? "); - preparedStmtList.add(ObjectUtils.isEmpty(planFacilitySearchCriteria.getLimit()) ? config.getDefaultLimit() : planFacilitySearchCriteria.getLimit()); + preparedStmtList.add(ObjectUtils.isEmpty(planFacilitySearchCriteria.getLimit()) ? configuration.getDefaultLimit() : planFacilitySearchCriteria.getLimit()); return paginatedQuery.toString(); } - } diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java index 7cc75ca63c1..48331c86b75 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java @@ -10,7 +10,6 @@ import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; - import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; @@ -19,7 +18,7 @@ @Component public class PlanFacilityRowMapper implements ResultSetExtractor> { - private ObjectMapper objectMapper; + private final ObjectMapper objectMapper; public PlanFacilityRowMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; @@ -28,11 +27,11 @@ public PlanFacilityRowMapper(ObjectMapper objectMapper) { @Override public List extractData(ResultSet rs) throws SQLException, DataAccessException { Map planFacilityMap = new LinkedHashMap<>(); - while(rs.next()){ + while (rs.next()) { String planFacilityId = rs.getString("plan_facility_id"); PlanFacility planFacilityEntry = planFacilityMap.get(planFacilityId); - if(ObjectUtils.isEmpty(planFacilityEntry)){ + if (planFacilityEntry == null || ObjectUtils.isEmpty(planFacilityEntry)) { planFacilityEntry = new PlanFacility(); // Prepare audit details @@ -50,7 +49,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAcc planFacilityEntry.setFacilityId(rs.getString("plan_facility_facility_id")); planFacilityEntry.setResidingBoundary(rs.getString("plan_facility_residing_boundary")); String serviceBoundaries = rs.getString("plan_facility_service_boundaries"); - planFacilityEntry.setServiceBoundaries(ObjectUtils.isEmpty(serviceBoundaries) ? new ArrayList<>() : Arrays.asList(rs.getString("plan_facility_service_boundaries").split(","))); + planFacilityEntry.setServiceBoundaries(ObjectUtils.isEmpty(serviceBoundaries) ? new ArrayList<>() : Arrays.asList(serviceBoundaries.split(","))); planFacilityEntry.setAdditionalDetails(getAdditionalDetail((PGobject) rs.getObject("plan_facility_additional_details"))); planFacilityEntry.setAuditDetails(auditDetails); planFacilityEntry.setActive(rs.getBoolean("plan_facility_active")); @@ -61,15 +60,14 @@ public List extractData(ResultSet rs) throws SQLException, DataAcc return new ArrayList<>(planFacilityMap.values()); } - private JsonNode getAdditionalDetail(PGobject pGobject){ + private JsonNode getAdditionalDetail(PGobject pGobject) { JsonNode additionalDetail = null; try { - if(!ObjectUtils.isEmpty(pGobject)){ + if (!ObjectUtils.isEmpty(pGobject)) { additionalDetail = objectMapper.readTree(pGobject.getValue()); } - } - catch (IOException e){ + } catch (IOException e) { throw new CustomException("PARSING_ERROR", "Failed to parse additionalDetails object"); } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index e525fde7746..4f74002fb12 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -1,11 +1,9 @@ package digit.service; import digit.repository.PlanFacilityRepository; -import digit.repository.PlanRepository; import digit.web.models.*; import org.egov.common.utils.ResponseInfoUtil; import org.springframework.stereotype.Service; - import java.util.List; @Service @@ -18,18 +16,31 @@ public PlanFacilityService(PlanFacilityRepository planFacilityRepository) { } /** - * This method processes the requests that come for searching plans. - * @param body - * @return + * This method processes the requests that come for searching plan facilities. + * + * @param planFacilitySearchRequest containing the search criteria and request information. + * @return PlanFacilityResponse object containing the search results and response information. */ - public PlanFacilityResponse searchPlanFacility(PlanFacilitySearchRequest body) { - // Delegate search request to repository - List planFacilityList = planFacilityRepository.search(body.getPlanFacilitySearchCriteria()); + public PlanFacilityResponse searchPlanFacility(PlanFacilitySearchRequest planFacilitySearchRequest) { + + // search validations + if (planFacilitySearchRequest == null || planFacilitySearchRequest.getPlanFacilitySearchCriteria() == null) { + throw new IllegalArgumentException("Search request or criteria cannot be null"); + } + else if (planFacilitySearchRequest.getPlanFacilitySearchCriteria().getTenantId().isEmpty()) { + throw new IllegalArgumentException("Tenant Id cannot be null"); + } + else if (planFacilitySearchRequest.getPlanFacilitySearchCriteria().getPlanConfigurationId().isEmpty()) { + throw new IllegalArgumentException("Plan Configuration ID cannot be null"); + } + + List planFacilityList = planFacilityRepository.search(planFacilitySearchRequest.getPlanFacilitySearchCriteria()); // Build and return response back to controller return PlanFacilityResponse.builder() - .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(body.getRequestInfo(), Boolean.TRUE)) + .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(planFacilitySearchRequest.getRequestInfo(), Boolean.TRUE)) .planFacility(planFacilityList) .build(); } + } diff --git a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java index 51959990534..19c7bebeea7 100644 --- a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java @@ -8,16 +8,5 @@ @Component public class ServiceUtil { - /** - * Validates the given input string against the provided regex pattern. - * - * @param patternString the regex pattern to validate against - * @param inputString the input string to be validated - * @return true if the input string matches the regex pattern, false otherwise - */ - public Boolean validateStringAgainstRegex(String patternString, String inputString) { - Pattern pattern = Pattern.compile(patternString); - Matcher matcher = pattern.matcher(inputString); - return matcher.matches(); - } + } diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java index b6f285d61ef..fe7e4c04b37 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -18,8 +18,13 @@ @Controller @RequestMapping("plan") public class PlanFacilityController { - @Autowired + private PlanFacilityService planFacilityService; + + public PlanFacilityController(PlanFacilityService planFacilityService) { + this.planFacilityService = planFacilityService; + } + @RequestMapping(value = "/facility/_search", method = RequestMethod.POST) public ResponseEntity searchPost(@Valid @RequestBody PlanFacilitySearchRequest body) { PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(body); diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 9cbdd5537ed..c3503041b3b 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -52,12 +52,11 @@ public class PlanFacility { private Object additionalDetails = null; @JsonProperty("active") - private Boolean active = null; + private Boolean active = true; @JsonProperty("auditDetails") private AuditDetails auditDetails = null; - public PlanFacility addServiceBoundariesItem(String serviceBoundariesItem) { if (this.serviceBoundaries == null) { this.serviceBoundaries = new ArrayList<>(); diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java index 3406f2614ce..061acb30ceb 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java @@ -18,13 +18,13 @@ @NoArgsConstructor @Builder public class PlanFacilityRequest { + @JsonProperty("RequestInfo") @Valid - private RequestInfo requestInfo = null; + private RequestInfo requestInfo; @JsonProperty("PlanFacility") @Valid - private PlanFacility planFacility = null; - + private PlanFacility planFacility; } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java index d43710facbc..e2ca983a8a8 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java @@ -8,8 +8,6 @@ import lombok.NoArgsConstructor; import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; - -import java.util.ArrayList; import java.util.List; /** @@ -28,17 +26,4 @@ public class PlanFacilityResponse { @JsonProperty("PlanFacility") @Valid private List planFacility = null; - - public PlanFacilityResponse responseInfo(ResponseInfo responseInfo) { - this.responseInfo = responseInfo; - return this; - } - - public PlanFacilityResponse addPlanFacilityItem(PlanFacility planFacilityItem) { - if (this.planFacility == null) { - this.planFacility = new ArrayList<>(); - } - this.planFacility.add(planFacilityItem); - return this; - } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java index 3a60edec530..464a8bdf19f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java @@ -26,6 +26,7 @@ public class PlanFacilitySearchCriteria { private String tenantId = null; @JsonProperty("planConfigurationId") + @NotNull private String planConfigurationId = null; @JsonProperty("residingBoundaries") @@ -36,4 +37,5 @@ public class PlanFacilitySearchCriteria { @JsonProperty("limit") private Integer limit = null; + } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java index fd64c3da77f..85f3a26ba0b 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java @@ -10,7 +10,7 @@ import org.springframework.validation.annotation.Validated; /** - * PlanSearchRequest + * PlanFacilitySearchRequest */ @Validated @Data @@ -18,6 +18,7 @@ @NoArgsConstructor @Builder public class PlanFacilitySearchRequest { + @JsonProperty("RequestInfo") @Valid private RequestInfo requestInfo = null; @@ -26,5 +27,4 @@ public class PlanFacilitySearchRequest { @Valid private PlanFacilitySearchCriteria planFacilitySearchCriteria = null; - } diff --git a/health-services/plan-service/src/main/resources/db/migrate.sh b/health-services/plan-service/src/main/resources/db/migrate.sh index 0f00dd9153a..f9d6617822c 100644 --- a/health-services/plan-service/src/main/resources/db/migrate.sh +++ b/health-services/plan-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true repair +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate From cb72ae2343bf090ab57b593b281f239808637e03 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 27 Sep 2024 15:30:19 +0530 Subject: [PATCH 064/351] added census service --- health-services/census-service/README.md | 18 ++ health-services/census-service/pom.xml | 135 ++++++++++++++ .../src/main/java/digit/Main.java | 20 ++ .../main/java/digit/config/Configuration.java | 93 ++++++++++ .../java/digit/config/MainConfiguration.java | 41 +++++ .../java/digit/config/ServiceConstants.java | 50 +++++ .../src/main/java/digit/kafka/Consumer.java | 21 +++ .../src/main/java/digit/kafka/Producer.java | 20 ++ .../repository/ServiceRequestRepository.java | 47 +++++ .../java/digit/service/CensusService.java | 57 ++++++ .../src/main/java/digit/util/IdgenUtil.java | 51 ++++++ .../src/main/java/digit/util/MdmsUtil.java | 81 +++++++++ .../java/digit/util/ResponseInfoFactory.java | 27 +++ .../java/digit/util/UrlShortenerUtil.java | 39 ++++ .../src/main/java/digit/util/UserUtil.java | 136 ++++++++++++++ .../main/java/digit/util/WorkflowUtil.java | 172 ++++++++++++++++++ .../web/controllers/CensusController.java | 70 +++++++ .../main/java/digit/web/models/Census.java | 118 ++++++++++++ .../java/digit/web/models/CensusRequest.java | 31 ++++ .../java/digit/web/models/CensusResponse.java | 43 +++++ .../web/models/CensusSearchCriteria.java | 49 +++++ .../digit/web/models/CensusSearchRequest.java | 31 ++++ .../src/main/java/digit/web/models/Error.java | 54 ++++++ .../main/java/digit/web/models/ErrorRes.java | 47 +++++ .../web/models/PopulationByDemographic.java | 71 ++++++++ .../digit/web/models/RequestInfoWrapper.java | 18 ++ .../src/main/java/digit/web/models/Role1.java | 36 ++++ .../java/digit/web/models/TenantRole.java | 46 +++++ .../src/main/java/digit/web/models/User.java | 170 +++++++++++++++++ .../main/java/digit/web/models/UserInfo.java | 72 ++++++++ .../src/main/resources/Dockerfile | 20 ++ .../src/main/resources/application.properties | 85 +++++++++ .../V20240925155908__census_create_ddl.sql | 32 ++++ .../src/main/resources/start.sh | 11 ++ .../test/java/digit/TestConfiguration.java | 16 ++ .../controllers/CreateApiControllerTest.java | 53 ++++++ .../controllers/SearchApiControllerTest.java | 53 ++++++ .../controllers/UpdateApiControllerTest.java | 53 ++++++ 38 files changed, 2187 insertions(+) create mode 100644 health-services/census-service/README.md create mode 100644 health-services/census-service/pom.xml create mode 100644 health-services/census-service/src/main/java/digit/Main.java create mode 100644 health-services/census-service/src/main/java/digit/config/Configuration.java create mode 100644 health-services/census-service/src/main/java/digit/config/MainConfiguration.java create mode 100644 health-services/census-service/src/main/java/digit/config/ServiceConstants.java create mode 100644 health-services/census-service/src/main/java/digit/kafka/Consumer.java create mode 100644 health-services/census-service/src/main/java/digit/kafka/Producer.java create mode 100644 health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java create mode 100644 health-services/census-service/src/main/java/digit/service/CensusService.java create mode 100644 health-services/census-service/src/main/java/digit/util/IdgenUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/MdmsUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/ResponseInfoFactory.java create mode 100644 health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/UserUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/WorkflowUtil.java create mode 100644 health-services/census-service/src/main/java/digit/web/controllers/CensusController.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/Census.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusRequest.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/Error.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/ErrorRes.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/RequestInfoWrapper.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/Role1.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/TenantRole.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/User.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/UserInfo.java create mode 100644 health-services/census-service/src/main/resources/Dockerfile create mode 100644 health-services/census-service/src/main/resources/application.properties create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql create mode 100644 health-services/census-service/src/main/resources/start.sh create mode 100644 health-services/census-service/src/test/java/digit/TestConfiguration.java create mode 100644 health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java create mode 100644 health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java create mode 100644 health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java diff --git a/health-services/census-service/README.md b/health-services/census-service/README.md new file mode 100644 index 00000000000..a2e8a9f7b84 --- /dev/null +++ b/health-services/census-service/README.md @@ -0,0 +1,18 @@ +# Swagger generated server + +Spring Boot Server + + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. +By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core), you can easily generate a server stub. +This is an example of building a swagger-enabled server in Java using the SpringBoot framework. + +The underlying library integrating swagger to SpringBoot is [springfox](https://github.com/springfox/springfox) + +Start your server as an simple java application + +You can view the api documentation in swagger-ui by pointing to +http://localhost:8080/ + +Change default port value in application.properties \ No newline at end of file diff --git a/health-services/census-service/pom.xml b/health-services/census-service/pom.xml new file mode 100644 index 00000000000..e4342a7b1b1 --- /dev/null +++ b/health-services/census-service/pom.xml @@ -0,0 +1,135 @@ + + 4.0.0 + org.egov + census-serivce + jar + census-serivce + 1.0.0 + + 17 + ${java.version} + ${java.version} + + + org.springframework.boot + spring-boot-starter-parent + 3.2.2 + + + src/main/java + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + junit + junit + 4.13.2 + test + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.flywaydb + flyway-core + 9.22.3 + + + org.postgresql + postgresql + 42.7.1 + + + org.springframework.boot + spring-boot-starter-test + test + + + + io.swagger + swagger-core + 1.5.18 + + + io.swagger.core.v3 + swagger-annotations + 2.2.8 + + + net.minidev + json-smart + 2.5.0 + + + + org.egov.services + tracer + 2.9.0-SNAPSHOT + + + + + + + + org.egov + mdms-client + 2.9.0-SNAPSHOT + compile + + + org.projectlombok + lombok + true + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + org.springframework.boot + spring-boot-starter-validation + + + + + repo.egovernments.org + eGov ERP Releases Repository + https://nexus-repo.egovernments.org/nexus/content/repositories/releases/ + + + repo.egovernments.org.snapshots + eGov ERP Releases Repository + https://nexus-repo.egovernments.org/nexus/content/repositories/snapshots/ + + + repo.egovernments.org.public + eGov Public Repository Group + https://nexus-repo.egovernments.org/nexus/content/groups/public/ + + + repo.digit.org + eGov DIGIT Releases Repository + https://nexus-repo.digit.org/nexus/content/repositories/snapshots/ + + + diff --git a/health-services/census-service/src/main/java/digit/Main.java b/health-services/census-service/src/main/java/digit/Main.java new file mode 100644 index 00000000000..6e3d79db11c --- /dev/null +++ b/health-services/census-service/src/main/java/digit/Main.java @@ -0,0 +1,20 @@ +package digit; + + +import org.egov.tracer.config.TracerConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Import; + +@Import({ TracerConfiguration.class }) +@SpringBootApplication +@ComponentScan(basePackages = { "digit", "digit.web.controllers" , "digit.config"}) +public class Main { + + + public static void main(String[] args) throws Exception { + SpringApplication.run(Main.class, args); + } + +} diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java new file mode 100644 index 00000000000..6a9c1d422b0 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -0,0 +1,93 @@ +package digit.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.*; +import org.egov.tracer.config.TracerConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.stereotype.Component; + +import jakarta.annotation.PostConstruct; + +import java.util.TimeZone; + +@Component +@Data +@Import({TracerConfiguration.class}) +@NoArgsConstructor +@AllArgsConstructor +@Setter +@Getter +public class Configuration { + + + // User Config + @Value("${egov.user.host}") + private String userHost; + + @Value("${egov.user.context.path}") + private String userContextPath; + + @Value("${egov.user.create.path}") + private String userCreateEndpoint; + + @Value("${egov.user.search.path}") + private String userSearchEndpoint; + + @Value("${egov.user.update.path}") + private String userUpdateEndpoint; + + + //Idgen Config + @Value("${egov.idgen.host}") + private String idGenHost; + + @Value("${egov.idgen.path}") + private String idGenPath; + + + //Workflow Config + @Value("${egov.workflow.host}") + private String wfHost; + + @Value("${egov.workflow.transition.path}") + private String wfTransitionPath; + + @Value("${egov.workflow.businessservice.search.path}") + private String wfBusinessServiceSearchPath; + + @Value("${egov.workflow.processinstance.search.path}") + private String wfProcessInstanceSearchPath; + + + //MDMS + @Value("${egov.mdms.host}") + private String mdmsHost; + + @Value("${egov.mdms.search.endpoint}") + private String mdmsEndPoint; + + + //HRMS + @Value("${egov.hrms.host}") + private String hrmsHost; + + @Value("${egov.hrms.search.endpoint}") + private String hrmsEndPoint; + + + //URLShortening + @Value("${egov.url.shortner.host}") + private String urlShortnerHost; + + @Value("${egov.url.shortner.endpoint}") + private String urlShortnerEndpoint; + + + //SMSNotification + @Value("${egov.sms.notification.topic}") + private String smsNotificationTopic; +} diff --git a/health-services/census-service/src/main/java/digit/config/MainConfiguration.java b/health-services/census-service/src/main/java/digit/config/MainConfiguration.java new file mode 100644 index 00000000000..239331c9cd8 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/config/MainConfiguration.java @@ -0,0 +1,41 @@ +package digit.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +import java.util.TimeZone; + +import jakarta.annotation.PostConstruct; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.egov.tracer.config.TracerConfiguration; + + +@Import({TracerConfiguration.class}) +public class MainConfiguration { + + @Value("${app.timezone}") + private String timeZone; + + @PostConstruct + public void initialize() { + TimeZone.setDefault(TimeZone.getTimeZone(timeZone)); + } + + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).setTimeZone(TimeZone.getTimeZone(timeZone)); + } + + @Bean + @Autowired + public MappingJackson2HttpMessageConverter jacksonConverter(ObjectMapper objectMapper) { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setObjectMapper(objectMapper); + return converter; + } +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java new file mode 100644 index 00000000000..6b0c4a6f9ab --- /dev/null +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -0,0 +1,50 @@ +package digit.config; + + +import org.springframework.stereotype.Component; + + +@Component +public class ServiceConstants { + + public static final String EXTERNAL_SERVICE_EXCEPTION = "External Service threw an Exception: "; + public static final String SEARCHER_SERVICE_EXCEPTION = "Exception while fetching from searcher: "; + + public static final String IDGEN_ERROR = "IDGEN ERROR"; + public static final String NO_IDS_FOUND_ERROR = "No ids returned from idgen Service"; + + public static final String ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; + + public static final String RES_MSG_ID = "uief87324"; + public static final String SUCCESSFUL = "successful"; + public static final String FAILED = "failed"; + + public static final String URL = "url"; + public static final String URL_SHORTENING_ERROR_CODE = "URL_SHORTENING_ERROR"; + public static final String URL_SHORTENING_ERROR_MESSAGE = "Unable to shorten url: "; + + public static final String DOB_FORMAT_Y_M_D = "yyyy-MM-dd"; + public static final String DOB_FORMAT_D_M_Y = "dd/MM/yyyy"; + public static final String ILLEGAL_ARGUMENT_EXCEPTION_CODE = "IllegalArgumentException"; + public static final String OBJECTMAPPER_UNABLE_TO_CONVERT = "ObjectMapper not able to convertValue in userCall"; + public static final String DOB_FORMAT_D_M_Y_H_M_S = "dd-MM-yyyy HH:mm:ss"; + public static final String CREATED_DATE = "createdDate"; + public static final String LAST_MODIFIED_DATE = "lastModifiedDate"; + public static final String DOB = "dob"; + public static final String PWD_EXPIRY_DATE = "pwdExpiryDate"; + public static final String INVALID_DATE_FORMAT_CODE = "INVALID_DATE_FORMAT"; + public static final String INVALID_DATE_FORMAT_MESSAGE = "Failed to parse date format in user"; + public static final String CITIZEN_UPPER = "CITIZEN"; + public static final String CITIZEN_LOWER = "Citizen"; + public static final String USER = "user"; + + public static final String PARSING_ERROR = "PARSING ERROR"; + public static final String FAILED_TO_PARSE_BUSINESS_SERVICE_SEARCH = "Failed to parse response of workflow business service search"; + public static final String BUSINESS_SERVICE_NOT_FOUND = "BUSINESSSERVICE_NOT_FOUND"; + public static final String THE_BUSINESS_SERVICE = "The businessService "; + public static final String NOT_FOUND = " is not found"; + public static final String TENANTID = "?tenantId="; + public static final String BUSINESS_SERVICES = "&businessServices="; + + +} diff --git a/health-services/census-service/src/main/java/digit/kafka/Consumer.java b/health-services/census-service/src/main/java/digit/kafka/Consumer.java new file mode 100644 index 00000000000..557ffe5d7bb --- /dev/null +++ b/health-services/census-service/src/main/java/digit/kafka/Consumer.java @@ -0,0 +1,21 @@ +package digit.kafka; + +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +import java.util.HashMap; + +@Component +public class Consumer { + + /* + * Uncomment the below line to start consuming record from kafka.topics.consumer + * Value of the variable kafka.topics.consumer should be overwritten in application.properties + */ + //@KafkaListener(topics = {"kafka.topics.consumer"}) + public void listen(final HashMap record) { + + //TODO + + } +} diff --git a/health-services/census-service/src/main/java/digit/kafka/Producer.java b/health-services/census-service/src/main/java/digit/kafka/Producer.java new file mode 100644 index 00000000000..542f4f686c0 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/kafka/Producer.java @@ -0,0 +1,20 @@ +package digit.kafka; + +import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.kafka.CustomKafkaTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +// NOTE: If tracer is disabled change CustomKafkaTemplate to KafkaTemplate in autowiring + +@Service +@Slf4j +public class Producer { + + @Autowired + private CustomKafkaTemplate kafkaTemplate; + + public void push(String topic, Object value) { + kafkaTemplate.send(topic, value); + } +} diff --git a/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java b/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java new file mode 100644 index 00000000000..7a2ebeeca71 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java @@ -0,0 +1,47 @@ +package digit.repository; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.ServiceCallException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +import static digit.config.ServiceConstants.*; + +@Repository +@Slf4j +public class ServiceRequestRepository { + + private ObjectMapper mapper; + + private RestTemplate restTemplate; + + + @Autowired + public ServiceRequestRepository(ObjectMapper mapper, RestTemplate restTemplate) { + this.mapper = mapper; + this.restTemplate = restTemplate; + } + + + public Object fetchResult(StringBuilder uri, Object request) { + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + Object response = null; + try { + response = restTemplate.postForObject(uri.toString(), request, Map.class); + } catch (HttpClientErrorException e) { + log.error(EXTERNAL_SERVICE_EXCEPTION, e); + throw new ServiceCallException(e.getResponseBodyAsString()); + } catch (Exception e) { + log.error(SEARCHER_SERVICE_EXCEPTION, e); + } + + return response; + } +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java new file mode 100644 index 00000000000..1043246e644 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -0,0 +1,57 @@ +package digit.service; + +import digit.util.ResponseInfoFactory; +import digit.web.models.CensusRequest; +import digit.web.models.CensusResponse; +import digit.web.models.CensusSearchRequest; +import org.springframework.stereotype.Service; + +import java.util.Collections; + +@Service +public class CensusService { + + private ResponseInfoFactory responseInfoFactory; + + /** + * Creates a new census record based on the provided request. + * + * @param request The request containing the census data. + * @return The created census reponse. + */ + public CensusResponse create(CensusRequest request) { + CensusResponse response = CensusResponse.builder() + .census(Collections.singletonList(request.getCensus())) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .build(); + return response; + } + + /** + * Searches for census record based on the provided search criteria. + * + * @param request The search request containing the criteria. + * @return A list of census record that matches the search criteria. + */ + public CensusResponse search(CensusSearchRequest request) { + CensusResponse response = CensusResponse.builder() + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .build(); + + return response; + } + + /** + * Updates an existing census record based on the provided request. + * + * @param request The request containing the updated census data. + * @return The updated census response. + */ + public CensusResponse update(CensusRequest request) { + CensusResponse response = CensusResponse.builder() + .census(Collections.singletonList(request.getCensus())) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .build(); + return response; + } +} diff --git a/health-services/census-service/src/main/java/digit/util/IdgenUtil.java b/health-services/census-service/src/main/java/digit/util/IdgenUtil.java new file mode 100644 index 00000000000..650af00bde8 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/IdgenUtil.java @@ -0,0 +1,51 @@ +package digit.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.repository.ServiceRequestRepository; +import digit.config.Configuration; +import org.egov.common.contract.idgen.IdGenerationRequest; +import org.egov.common.contract.idgen.IdGenerationResponse; +import org.egov.common.contract.idgen.IdRequest; +import org.egov.common.contract.idgen.IdResponse; +import org.egov.common.contract.request.RequestInfo; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; + +@Component +public class IdgenUtil { + + @Autowired + private ObjectMapper mapper; + + @Autowired + private ServiceRequestRepository restRepo; + + @Autowired + private Configuration configs; + + public List getIdList(RequestInfo requestInfo, String tenantId, String idName, String idformat, Integer count) { + List reqList = new ArrayList<>(); + for (int i = 0; i < count; i++) { + reqList.add(IdRequest.builder().idName(idName).format(idformat).tenantId(tenantId).build()); + } + + IdGenerationRequest request = IdGenerationRequest.builder().idRequests(reqList).requestInfo(requestInfo).build(); + StringBuilder uri = new StringBuilder(configs.getIdGenHost()).append(configs.getIdGenPath()); + IdGenerationResponse response = mapper.convertValue(restRepo.fetchResult(uri, request), IdGenerationResponse.class); + + List idResponses = response.getIdResponses(); + + if (CollectionUtils.isEmpty(idResponses)) + throw new CustomException(IDGEN_ERROR, NO_IDS_FOUND_ERROR); + + return idResponses.stream().map(IdResponse::getId).collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/MdmsUtil.java b/health-services/census-service/src/main/java/digit/util/MdmsUtil.java new file mode 100644 index 00000000000..5db8d2c4f1d --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/MdmsUtil.java @@ -0,0 +1,81 @@ +package digit.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.config.Configuration; +import lombok.extern.slf4j.Slf4j; +import net.minidev.json.JSONArray; +import org.egov.common.contract.request.RequestInfo; +import org.egov.mdms.model.*; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class MdmsUtil { + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private ObjectMapper mapper; + + @Autowired + private Configuration configs; + + + + + public Map> fetchMdmsData(RequestInfo requestInfo, String tenantId, String moduleName, + List masterNameList) { + StringBuilder uri = new StringBuilder(); + uri.append(configs.getMdmsHost()).append(configs.getMdmsEndPoint()); + MdmsCriteriaReq mdmsCriteriaReq = getMdmsRequest(requestInfo, tenantId, moduleName, masterNameList); + Object response = new HashMap<>(); + Integer rate = 0; + MdmsResponse mdmsResponse = new MdmsResponse(); + try { + response = restTemplate.postForObject(uri.toString(), mdmsCriteriaReq, Map.class); + mdmsResponse = mapper.convertValue(response, MdmsResponse.class); + }catch(Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_MDMS,e); + } + + return mdmsResponse.getMdmsRes(); + //log.info(ulbToCategoryListMap.toString()); + } + + private MdmsCriteriaReq getMdmsRequest(RequestInfo requestInfo, String tenantId, + String moduleName, List masterNameList) { + List masterDetailList = new ArrayList<>(); + for(String masterName: masterNameList) { + MasterDetail masterDetail = new MasterDetail(); + masterDetail.setName(masterName); + masterDetailList.add(masterDetail); + } + + ModuleDetail moduleDetail = new ModuleDetail(); + moduleDetail.setMasterDetails(masterDetailList); + moduleDetail.setModuleName(moduleName); + List moduleDetailList = new ArrayList<>(); + moduleDetailList.add(moduleDetail); + + MdmsCriteria mdmsCriteria = new MdmsCriteria(); + mdmsCriteria.setTenantId(tenantId.split("\\.")[0]); + mdmsCriteria.setModuleDetails(moduleDetailList); + + MdmsCriteriaReq mdmsCriteriaReq = new MdmsCriteriaReq(); + mdmsCriteriaReq.setMdmsCriteria(mdmsCriteria); + mdmsCriteriaReq.setRequestInfo(requestInfo); + + return mdmsCriteriaReq; + } +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/ResponseInfoFactory.java b/health-services/census-service/src/main/java/digit/util/ResponseInfoFactory.java new file mode 100644 index 00000000000..a10e7f50841 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/ResponseInfoFactory.java @@ -0,0 +1,27 @@ +package digit.util; + +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.stereotype.Component; + +import static digit.config.ServiceConstants.*; + +@Component +public class ResponseInfoFactory { + + public ResponseInfo createResponseInfoFromRequestInfo(final RequestInfo requestInfo, final Boolean success) { + + final String apiId = requestInfo != null ? requestInfo.getApiId() : ""; + final String ver = requestInfo != null ? requestInfo.getVer() : ""; + Long ts = null; + if (requestInfo != null) + ts = requestInfo.getTs(); + + final String msgId = requestInfo != null ? requestInfo.getMsgId() : ""; + final String responseStatus = success ? SUCCESSFUL : FAILED; + + return ResponseInfo.builder().apiId(apiId).ver(ver).ts(ts).resMsgId(RES_MSG_ID).msgId(msgId).resMsgId(RES_MSG_ID) + .status(responseStatus).build(); + } + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java b/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java new file mode 100644 index 00000000000..efb4d3d3fa3 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java @@ -0,0 +1,39 @@ +package digit.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import java.util.HashMap; +import digit.config.Configuration; +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class UrlShortenerUtil { + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private Configuration configs; + + + public String getShortenedUrl(String url){ + + HashMap body = new HashMap<>(); + body.put(URL,url); + StringBuilder builder = new StringBuilder(configs.getUrlShortnerHost()); + builder.append(configs.getUrlShortnerEndpoint()); + String res = restTemplate.postForObject(builder.toString(), body, String.class); + + if(StringUtils.isEmpty(res)){ + log.error(URL_SHORTENING_ERROR_CODE, URL_SHORTENING_ERROR_MESSAGE + url); ; + return url; + } + else return res; + } + + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/UserUtil.java b/health-services/census-service/src/main/java/digit/util/UserUtil.java new file mode 100644 index 00000000000..09b8adca5c1 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/UserUtil.java @@ -0,0 +1,136 @@ +package digit.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.config.Configuration; +import static digit.config.ServiceConstants.*; +import org.egov.common.contract.request.Role; +import org.egov.common.contract.request.User; +import org.egov.common.contract.user.UserDetailResponse; +import org.egov.common.contract.user.enums.UserType; +import digit.repository.ServiceRequestRepository; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +@Component +public class UserUtil { + + @Autowired + private ObjectMapper mapper; + + @Autowired + private ServiceRequestRepository serviceRequestRepository; + + @Autowired + private Configuration configs; + + + @Autowired + public UserUtil(ObjectMapper mapper, ServiceRequestRepository serviceRequestRepository) { + this.mapper = mapper; + this.serviceRequestRepository = serviceRequestRepository; + } + + /** + * Returns UserDetailResponse by calling user service with given uri and object + * @param userRequest Request object for user service + * @param uri The address of the endpoint + * @return Response from user service as parsed as userDetailResponse + */ + + public UserDetailResponse userCall(Object userRequest, StringBuilder uri) { + String dobFormat = null; + if(uri.toString().contains(configs.getUserSearchEndpoint()) || uri.toString().contains(configs.getUserUpdateEndpoint())) + dobFormat=DOB_FORMAT_Y_M_D; + else if(uri.toString().contains(configs.getUserCreateEndpoint())) + dobFormat = DOB_FORMAT_D_M_Y; + try{ + LinkedHashMap responseMap = (LinkedHashMap)serviceRequestRepository.fetchResult(uri, userRequest); + parseResponse(responseMap,dobFormat); + UserDetailResponse userDetailResponse = mapper.convertValue(responseMap,UserDetailResponse.class); + return userDetailResponse; + } + catch(IllegalArgumentException e) + { + throw new CustomException(ILLEGAL_ARGUMENT_EXCEPTION_CODE,OBJECTMAPPER_UNABLE_TO_CONVERT); + } + } + + + /** + * Parses date formats to long for all users in responseMap + * @param responseMap LinkedHashMap got from user api response + */ + + public void parseResponse(LinkedHashMap responseMap, String dobFormat){ + List users = (List)responseMap.get(USER); + String format1 = DOB_FORMAT_D_M_Y_H_M_S; + if(users!=null){ + users.forEach( map -> { + map.put(CREATED_DATE,dateTolong((String)map.get(CREATED_DATE),format1)); + if((String)map.get(LAST_MODIFIED_DATE)!=null) + map.put(LAST_MODIFIED_DATE,dateTolong((String)map.get(LAST_MODIFIED_DATE),format1)); + if((String)map.get(DOB)!=null) + map.put(DOB,dateTolong((String)map.get(DOB),dobFormat)); + if((String)map.get(PWD_EXPIRY_DATE)!=null) + map.put(PWD_EXPIRY_DATE,dateTolong((String)map.get(PWD_EXPIRY_DATE),format1)); + } + ); + } + } + + /** + * Converts date to long + * @param date date to be parsed + * @param format Format of the date + * @return Long value of date + */ + private Long dateTolong(String date,String format){ + SimpleDateFormat f = new SimpleDateFormat(format); + Date d = null; + try { + d = f.parse(date); + } catch (ParseException e) { + throw new CustomException(INVALID_DATE_FORMAT_CODE,INVALID_DATE_FORMAT_MESSAGE); + } + return d.getTime(); + } + + /** + * enriches the userInfo with statelevel tenantId and other fields + * The function creates user with username as mobile number. + * @param mobileNumber + * @param tenantId + * @param userInfo + */ + public void addUserDefaultFields(String mobileNumber,String tenantId, User userInfo, UserType userType){ + Role role = getCitizenRole(tenantId); + userInfo.setRoles((List) Collections.singleton(role)); + userInfo.setType(String.valueOf(userType)); +// userInfo.setUsername(mobileNumber); + userInfo.setTenantId(getStateLevelTenant(tenantId)); +// userInfo.setActive(true); + } + + /** + * Returns role object for citizen + * @param tenantId + * @return + */ + private Role getCitizenRole(String tenantId){ + Role role = Role.builder().build(); + role.setCode(CITIZEN_UPPER); + role.setName(CITIZEN_LOWER); + role.setTenantId(getStateLevelTenant(tenantId)); + return role; + } + + public String getStateLevelTenant(String tenantId){ + return tenantId.split("\\.")[0]; + } + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java b/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java new file mode 100644 index 00000000000..ed996e01813 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java @@ -0,0 +1,172 @@ +package digit.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.config.Configuration; +import static digit.config.ServiceConstants.*; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.request.User; +import org.egov.common.contract.workflow.*; +import org.egov.common.contract.models.*; +import digit.repository.ServiceRequestRepository; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class WorkflowUtil { + + @Autowired + private ServiceRequestRepository repository; + + @Autowired + private ObjectMapper mapper; + + @Autowired + private Configuration configs; + + + + /** + * Searches the BussinessService corresponding to the businessServiceCode + * Returns applicable BussinessService for the given parameters + * @param requestInfo + * @param tenantId + * @param businessServiceCode + * @return + */ + public BusinessService getBusinessService(RequestInfo requestInfo, String tenantId, String businessServiceCode) { + + StringBuilder url = getSearchURLWithParams(tenantId, businessServiceCode); + RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); + Object result = repository.fetchResult(url, requestInfoWrapper); + BusinessServiceResponse response = null; + try { + response = mapper.convertValue(result, BusinessServiceResponse.class); + } catch (IllegalArgumentException e) { + throw new CustomException(PARSING_ERROR, FAILED_TO_PARSE_BUSINESS_SERVICE_SEARCH); + } + + if (CollectionUtils.isEmpty(response.getBusinessServices())) + throw new CustomException(BUSINESS_SERVICE_NOT_FOUND, THE_BUSINESS_SERVICE + businessServiceCode + NOT_FOUND); + + return response.getBusinessServices().get(0); + } + + /** + * Calls the workflow service with the given action and updates the status + * Returns the updated status of the application + * @param requestInfo + * @param tenantId + * @param businessId + * @param businessServiceCode + * @param workflow + * @param wfModuleName + * @return + */ + public String updateWorkflowStatus(RequestInfo requestInfo, String tenantId, + String businessId, String businessServiceCode, Workflow workflow, String wfModuleName) { + ProcessInstance processInstance = getProcessInstanceForWorkflow(requestInfo, tenantId, businessId, + businessServiceCode, workflow, wfModuleName); + ProcessInstanceRequest workflowRequest = new ProcessInstanceRequest(requestInfo, Collections.singletonList(processInstance)); + State state = callWorkFlow(workflowRequest); + + return state.getApplicationStatus(); + } + + /** + * Creates url for search based on given tenantId and businessServices + * @param tenantId + * @param businessService + * @return + */ + private StringBuilder getSearchURLWithParams(String tenantId, String businessService) { + StringBuilder url = new StringBuilder(configs.getWfHost()); + url.append(configs.getWfBusinessServiceSearchPath()); + url.append(TENANTID); + url.append(tenantId); + url.append(BUSINESS_SERVICES); + url.append(businessService); + return url; + } + + /** + * Enriches ProcessInstance Object for Workflow + * @param requestInfo + * @param tenantId + * @param businessId + * @param businessServiceCode + * @param workflow + * @param wfModuleName + * @return + */ + private ProcessInstance getProcessInstanceForWorkflow(RequestInfo requestInfo, String tenantId, + String businessId, String businessServiceCode, Workflow workflow, String wfModuleName) { + + ProcessInstance processInstance = new ProcessInstance(); + processInstance.setBusinessId(businessId); + processInstance.setAction(workflow.getAction()); + processInstance.setModuleName(wfModuleName); + processInstance.setTenantId(tenantId); + processInstance.setBusinessService(getBusinessService(requestInfo, tenantId, businessServiceCode).getBusinessService()); + processInstance.setComment(workflow.getComments()); + + if(!CollectionUtils.isEmpty(workflow.getAssignes())) { + List users = new ArrayList<>(); + + workflow.getAssignes().forEach(uuid -> { + User user = new User(); + user.setUuid(uuid); + users.add(user); + }); + + processInstance.setAssignes(users); + } + + return processInstance; + } + + /** + * Gets the workflow corresponding to the processInstance + * @param processInstances + * @return + */ + public Map getWorkflow(List processInstances) { + + Map businessIdToWorkflow = new HashMap<>(); + + processInstances.forEach(processInstance -> { + List userIds = null; + + if(!CollectionUtils.isEmpty(processInstance.getAssignes())){ + userIds = processInstance.getAssignes().stream().map(User::getUuid).collect(Collectors.toList()); + } + + Workflow workflow = Workflow.builder() + .action(processInstance.getAction()) + .assignes(userIds) + .comments(processInstance.getComment()) + .build(); + + businessIdToWorkflow.put(processInstance.getBusinessId(), workflow); + }); + + return businessIdToWorkflow; + } + + /** + * Method to take the ProcessInstanceRequest as parameter and set resultant status + * @param workflowReq + * @return + */ + private State callWorkFlow(ProcessInstanceRequest workflowReq) { + ProcessInstanceResponse response = null; + StringBuilder url = new StringBuilder(configs.getWfHost().concat(configs.getWfTransitionPath())); + Object optional = repository.fetchResult(url, workflowReq); + response = mapper.convertValue(optional, ProcessInstanceResponse.class); + return response.getProcessInstances().get(0).getState(); + } +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java new file mode 100644 index 00000000000..4e1a668a1fb --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java @@ -0,0 +1,70 @@ +package digit.web.controllers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.service.CensusService; +import digit.util.ResponseInfoFactory; +import digit.web.models.CensusRequest; +import digit.web.models.CensusResponse; +import digit.web.models.CensusSearchRequest; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.io.IOException; + +@Controller +public class CensusController { + + private CensusService censusService; + + public CensusController(CensusService censusService) { + this.censusService = censusService; + } + + /** + * Request handler for serving census create requests + * + * @param body + * @return + */ + @RequestMapping(value = "/_create", method = RequestMethod.POST) + public ResponseEntity censusCreatePost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusRequest body) { + + CensusResponse response = censusService.create(body); + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } + + /** + * Request handler for serving census search requests + * + * @param body + * @return + */ + @RequestMapping(value = "/_search", method = RequestMethod.POST) + public ResponseEntity censusSearchPost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusSearchRequest body) { + + CensusResponse response = censusService.search(body); + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + /** + * Request handler for serving census update requests + * + * @param body + * @return + */ + @RequestMapping(value = "/_update", method = RequestMethod.POST) + public ResponseEntity censusUpdatePost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusRequest body) { + + CensusResponse response = censusService.update(body); + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } +} diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java new file mode 100644 index 00000000000..88b8a594ba0 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -0,0 +1,118 @@ +package digit.web.models; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import digit.web.models.PopulationByDemographic; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * Census + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Census { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("hierarchyType") + @NotNull + private String hierarchyType = null; + + @JsonProperty("boundaryCode") + @NotNull + private String boundaryCode = null; + + /** + * Gets or Sets type + */ + public enum TypeEnum { + PEOPLE("people"), + + ANIMALS("animals"), + + PLANTS("plants"), + + OTHER("other"); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String text) { + for (TypeEnum b : TypeEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("effectiveFrom") + private Long effectiveFrom = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("source") + @NotNull + private String source = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + + public Census addPopulationByDemographicsItem(PopulationByDemographic populationByDemographicsItem) { + if (this.populationByDemographics == null) { + this.populationByDemographics = new ArrayList<>(); + } + this.populationByDemographics.add(populationByDemographicsItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusRequest.java b/health-services/census-service/src/main/java/digit/web/models/CensusRequest.java new file mode 100644 index 00000000000..d8755bbbda9 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusRequest.java @@ -0,0 +1,31 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Census") + @Valid + private Census census = null; + + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusResponse.java b/health-services/census-service/src/main/java/digit/web/models/CensusResponse.java new file mode 100644 index 00000000000..7c7815ce4a1 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusResponse.java @@ -0,0 +1,43 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Census") + @Valid + private List census = null; + + + public CensusResponse addCensusItem(Census censusItem) { + if (this.census == null) { + this.census = new ArrayList<>(); + } + this.census.add(censusItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java new file mode 100644 index 00000000000..c51a8eb8356 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -0,0 +1,49 @@ +package digit.web.models; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchCriteria + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchCriteria { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + private String tenantId = null; + + @JsonProperty("areaCodes") + private List areaCodes = null; + + + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { + if (this.areaCodes == null) { + this.areaCodes = new ArrayList<>(); + } + this.areaCodes.add(areaCodesItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java new file mode 100644 index 00000000000..222e8989858 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java @@ -0,0 +1,31 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("CensusSearchCriteria") + @Valid + private CensusSearchCriteria censusSearchCriteria = null; + + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/Error.java b/health-services/census-service/src/main/java/digit/web/models/Error.java new file mode 100644 index 00000000000..5d82d49a046 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/Error.java @@ -0,0 +1,54 @@ +package digit.web.models; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * Error object will be returned as a part of reponse body in conjunction with ResponseInfo as part of ErrorResponse whenever the request processing status in the ResponseInfo is FAILED. HTTP return in this scenario will usually be HTTP 400. + */ +@Schema(description = "Error object will be returned as a part of reponse body in conjunction with ResponseInfo as part of ErrorResponse whenever the request processing status in the ResponseInfo is FAILED. HTTP return in this scenario will usually be HTTP 400.") +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2024-09-25T15:46:57.876914059+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Error { + @JsonProperty("code") + @NotNull + private String code = null; + + @JsonProperty("message") + @NotNull + private String message = null; + + @JsonProperty("description") + private String description = null; + + @JsonProperty("params") + private List params = null; + + + public Error addParamsItem(String paramsItem) { + if (this.params == null) { + this.params = new ArrayList<>(); + } + this.params.add(paramsItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/ErrorRes.java b/health-services/census-service/src/main/java/digit/web/models/ErrorRes.java new file mode 100644 index 00000000000..e864a188e9a --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/ErrorRes.java @@ -0,0 +1,47 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.ArrayList; +import java.util.List; + +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * All APIs will return ErrorRes in case of failure which will carry ResponseInfo as metadata and Error object as actual representation of error. In case of bulk apis, some apis may chose to return the array of Error objects to indicate individual failure. + */ +@Schema(description = "All APIs will return ErrorRes in case of failure which will carry ResponseInfo as metadata and Error object as actual representation of error. In case of bulk apis, some apis may chose to return the array of Error objects to indicate individual failure.") +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2024-09-25T15:46:57.876914059+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ErrorRes { + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Errors") + @Valid + private List errors = null; + + + public ErrorRes addErrorsItem(Error errorsItem) { + if (this.errors == null) { + this.errors = new ArrayList<>(); + } + this.errors.add(errorsItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java b/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java new file mode 100644 index 00000000000..6b5a1da5a03 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java @@ -0,0 +1,71 @@ +package digit.web.models; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * PopulationByDemographic + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PopulationByDemographic { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + /** + * Gets or Sets demographicVariable + */ + public enum DemographicVariableEnum { + AGE("age"), + + GENDER("gender"), + + ETHNICITY("ethnicity"); + + private String value; + + DemographicVariableEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static DemographicVariableEnum fromValue(String text) { + for (DemographicVariableEnum b : DemographicVariableEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + + @JsonProperty("demographicVariable") + private DemographicVariableEnum demographicVariable = null; + + @JsonProperty("populationDistribution") + private Object populationDistribution = null; + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/RequestInfoWrapper.java b/health-services/census-service/src/main/java/digit/web/models/RequestInfoWrapper.java new file mode 100644 index 00000000000..b36665e3e25 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/RequestInfoWrapper.java @@ -0,0 +1,18 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import org.egov.common.contract.request.RequestInfo; + + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class RequestInfoWrapper { + + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/web/models/Role1.java b/health-services/census-service/src/main/java/digit/web/models/Role1.java new file mode 100644 index 00000000000..cea8fb9ce17 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/Role1.java @@ -0,0 +1,36 @@ +package digit.web.models; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * minimal representation of the Roles in the system to be carried along in UserInfo with RequestInfo meta data. Actual authorization service to extend this to have more role related attributes + */ +@Schema(description = "minimal representation of the Roles in the system to be carried along in UserInfo with RequestInfo meta data. Actual authorization service to extend this to have more role related attributes ") +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Role1 { + + @JsonProperty("name") + @NotNull + @Size(max = 64) + private String name = null; + + @JsonProperty("description") + private String description = null; + + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/TenantRole.java b/health-services/census-service/src/main/java/digit/web/models/TenantRole.java new file mode 100644 index 00000000000..c7e04032adf --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/TenantRole.java @@ -0,0 +1,46 @@ +package digit.web.models; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import digit.web.models.Role1; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * User role carries the tenant related role information for the user. A user can have multiple roles per tenant based on the need of the tenant. A user may also have multiple roles for multiple tenants. + */ +@Schema(description = "User role carries the tenant related role information for the user. A user can have multiple roles per tenant based on the need of the tenant. A user may also have multiple roles for multiple tenants.") +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class TenantRole { + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("roles") + @NotNull + @Valid + private List roles = new ArrayList<>(); + + + public TenantRole addRolesItem(Role1 rolesItem) { + this.roles.add(rolesItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/User.java b/health-services/census-service/src/main/java/digit/web/models/User.java new file mode 100644 index 00000000000..3d82a69903e --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/User.java @@ -0,0 +1,170 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import org.egov.common.contract.request.Role; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server. + */ +@Schema(description = "This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server.") +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class User { + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("id") + private Integer id = null; + + @JsonProperty("uuid") + private String uuid = null; + + @JsonProperty("userName") + @NotNull + private String userName = null; + + @JsonProperty("mobileNumber") + private String mobileNumber = null; + + @JsonProperty("emailId") + private String emailId = null; + + @JsonProperty("roles") + @NotNull + @Valid + private List roles = new ArrayList<>(); + + @JsonProperty("salutation") + private String salutation = null; + + @JsonProperty("name") + private String name = null; + + @JsonProperty("gender") + private String gender = null; + + @JsonProperty("alternateMobileNumber") + private String alternateMobileNumber = null; + + @JsonProperty("altContactNumber") + private String altContactNumber = null; + + @JsonProperty("pan") + private String pan = null; + + @JsonProperty("aadhaarNumber") + private String aadhaarNumber = null; + + @JsonProperty("permanentAddress") + @Size(max = 300) + private String permanentAddress = null; + + @JsonProperty("permanentCity") + @Size(max = 300) + private String permanentCity = null; + + @JsonProperty("permanentPincode") + @Size(max = 6) + private String permanentPincode = null; + + @JsonProperty("correspondenceCity") + @Size(max = 50) + private String correspondenceCity = null; + + @JsonProperty("correspondencePincode") + @Size(max = 6) + private String correspondencePincode = null; + + @JsonProperty("correspondenceAddress") + @Size(max = 300) + private String correspondenceAddress = null; + + @JsonProperty("active") + private Boolean active = null; + + @JsonProperty("locale") + @Size(max = 10) + private String locale = null; + + @JsonProperty("type") + @Size(max = 20) + private String type = null; + + @JsonProperty("accountLocked") + private Boolean accountLocked = null; + + @JsonProperty("accountLockedDate") + private Long accountLockedDate = null; + + @JsonProperty("fatherOrHusbandName") + @Size(max = 100) + private String fatherOrHusbandName = null; + + @JsonProperty("relationship") + @Size(max = 20) + private String relationship = null; + + @JsonProperty("signature") + private String signature = null; + + @JsonProperty("bloodGroup") + @Size(max = 3) + private String bloodGroup = null; + + @JsonProperty("photo") + private String photo = null; + + @JsonProperty("identificationMark") + private String identificationMark = null; + + @JsonProperty("createdBy") + private Long createdBy = null; + + @JsonProperty("password") + private String password = null; + + @JsonProperty("otpReference") + private String otpReference = null; + + @JsonProperty("lastModifiedBy") + private Long lastModifiedBy = null; + + @JsonProperty("createdDate") + @Valid + private LocalDate createdDate = null; + + @JsonProperty("lastModifiedDate") + @Valid + private LocalDate lastModifiedDate = null; + + @JsonProperty("dob") + private Long dob = null; + + @JsonProperty("pwdExpiryDate") + private Long pwdExpiryDate = null; + + + public User addRolesItem(Role rolesItem) { + this.roles.add(rolesItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/UserInfo.java b/health-services/census-service/src/main/java/digit/web/models/UserInfo.java new file mode 100644 index 00000000000..057d0750b6b --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/UserInfo.java @@ -0,0 +1,72 @@ +package digit.web.models; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import digit.web.models.Role1; +import digit.web.models.TenantRole; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server. + */ +@Schema(description = "This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server.") +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UserInfo { + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("id") + private Integer id = null; + + @JsonProperty("userName") + @NotNull + private String userName = null; + + @JsonProperty("mobile") + private String mobile = null; + + @JsonProperty("email") + private String email = null; + + @JsonProperty("primaryrole") + @NotNull + @Valid + private List primaryrole = new ArrayList<>(); + + @JsonProperty("additionalroles") + @Valid + private List additionalroles = null; + + + public UserInfo addPrimaryroleItem(Role1 primaryroleItem) { + this.primaryrole.add(primaryroleItem); + return this; + } + + public UserInfo addAdditionalrolesItem(TenantRole additionalrolesItem) { + if (this.additionalroles == null) { + this.additionalroles = new ArrayList<>(); + } + this.additionalroles.add(additionalrolesItem); + return this; + } + +} diff --git a/health-services/census-service/src/main/resources/Dockerfile b/health-services/census-service/src/main/resources/Dockerfile new file mode 100644 index 00000000000..910b6c12e4a --- /dev/null +++ b/health-services/census-service/src/main/resources/Dockerfile @@ -0,0 +1,20 @@ +#FROM egovio/alpine-maven-builder-jdk-8:1-master-NA-6036091e AS build +FROM egovio/amazoncorretto:17-alpine3.19 AS build +ARG WORK_DIR +WORKDIR /app +# Install Maven +RUN apk add --no-cache maven +# copy the project files +COPY ${WORK_DIR}/pom.xml ./pom.xml +COPY build/maven/start.sh ./start.sh +# not useful for stateless builds +# RUN mvn -B dependency:go-offline +COPY ${WORK_DIR}/src ./src +RUN mvn -B -f /app/pom.xml package +# Create runtime image +#FROM egovio/8-openjdk-alpine +FROM egovio/amazoncorretto:17-alpine3.19 +WORKDIR /opt/egov +COPY --from=build /app/target/*.jar /app/start.sh /opt/egov/ +RUN chmod +x /opt/egov/start.sh +CMD ["/opt/egov/start.sh"] \ No newline at end of file diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties new file mode 100644 index 00000000000..d3332f5b476 --- /dev/null +++ b/health-services/census-service/src/main/resources/application.properties @@ -0,0 +1,85 @@ +server.contextPath=/census-serivce +server.servlet.context-path=/census-serivce +management.endpoints.web.base-path=/ +server.port=8080 +app.timezone=UTC + +#DATABASE CONFIGURATION +spring.datasource.driver-class-name=org.postgresql.Driver +spring.datasource.url=jdbc:postgresql://localhost:5432/censusDB +spring.datasource.username=postgres +spring.datasource.password=postgres + +#FLYWAY CONFIGURATION +spring.flyway.url=jdbc:postgresql://localhost:5432/censusDB +spring.flyway.user=postgres +spring.flyway.password=postgres +spring.flyway.table=public +spring.flyway.baseline-on-migrate=true +spring.flyway.outOfOrder=true +spring.flyway.locations=classpath:/db/migration/main +spring.flyway.enabled=true + +# KAFKA SERVER CONFIGURATIONS +kafka.config.bootstrap_server_config=localhost:9092 +spring.kafka.consumer.value-deserializer=org.egov.tracer.kafka.deserializer.HashMapDeserializer +spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer +spring.kafka.consumer.group-id=census-serivce +spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer +spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer +spring.kafka.listener.missing-topics-fatal=false +spring.kafka.consumer.properties.spring.json.use.type.headers=false + +# KAFKA CONSUMER CONFIGURATIONS +kafka.consumer.config.auto_commit=true +kafka.consumer.config.auto_commit_interval=100 +kafka.consumer.config.session_timeout=15000 +kafka.consumer.config.auto_offset_reset=earliest +# KAFKA PRODUCER CONFIGURATIONS +kafka.producer.config.retries_config=0 +kafka.producer.config.batch_size_config=16384 +kafka.producer.config.linger_ms_config=1 +kafka.producer.config.buffer_memory_config=33554432 + +#Localization config +egov.localization.host=https://dev.digit.org +egov.localization.workDir.path=/localization/messages/v1 +egov.localization.context.path=/localization/messages/v1 +egov.localization.search.endpoint=/_search +egov.localization.statelevel=true + +#mdms urls +egov.mdms.host=https://dev.digit.org +egov.mdms.search.endpoint=/egov-mdms-service/v1/_search + +#hrms urls +egov.hrms.host=https://dev.digit.org +egov.hrms.search.endpoint=/egov-hrms/employees/_search + +#User config +egov.user.host=https://dev.digit.org +egov.user.context.path=/user/users +egov.user.create.path=/_createnovalidate +egov.user.search.path=/user/_search +egov.user.update.path=/_updatenovalidate + +#Idgen Config +egov.idgen.host=https://dev.digit.org/ +egov.idgen.path=egov-idgen/id/_generate + +#Workflow config +is.workflow.enabled=true +egov.workflow.host=https://dev.digit.org +egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition +egov.workflow.businessservice.search.path=/egov-workflow-v2/egov-wf/businessservice/_search +egov.workflow.processinstance.search.path=/egov-workflow-v2/egov-wf/process/_search + +#url shortner +egov.url.shortner.host=https://dev.digit.org +egov.url.shortner.endpoint=/egov-url-shortening/shortener + +egov.sms.notification.topic=egov.core.notification.sms +kafka.topics.receipt.create=dss-collection + +# The value of the following field should be changed to service specific name +kafka.topics.consumer=service-consumer-topic \ No newline at end of file diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql new file mode 100644 index 00000000000..14900e23d5a --- /dev/null +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -0,0 +1,32 @@ +-- Table: census +CREATE TABLE census ( + id character varying(64), + tenant_id character varying(64), + hierarchy_type character varying(64), + boundary_code character varying(64), + type character varying(64), + total_population bigint, + effective_from bigint, + effective_to bigint, + source character varying(255), + additional_details JSONB, + created_by character varying(64), + created_time bigint, + last_modified_by character varying(64), + last_modified_time bigint, + CONSTRAINT uk_census_id PRIMARY KEY (id) +); + +-- Table: population_by_demographics +CREATE TABLE population_by_demographics ( + id character varying(64), + census_id character varying(64), + demographic_variable character varying(64), + population_distribution JSONB, + created_by character varying(64), + created_time bigint, + last_modified_by character varying(64), + last_modified_time bigint, + CONSTRAINT uk_population_by_demographics_id PRIMARY KEY (id), + FOREIGN KEY (census_id) REFERENCES census(id) +); diff --git a/health-services/census-service/src/main/resources/start.sh b/health-services/census-service/src/main/resources/start.sh new file mode 100644 index 00000000000..36eccc0ae97 --- /dev/null +++ b/health-services/census-service/src/main/resources/start.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +if [[ -z "${JAVA_OPTS}" ]];then +export JAVA_OPTS="-Xmx64m -Xms64m" +fi + +if [ x"${JAVA_ENABLE_DEBUG}" != x ] && [ "${JAVA_ENABLE_DEBUG}" != "false" ]; then +java_debug_args="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${JAVA_DEBUG_PORT:-5005}" +fi + +exec java ${java_debug_args} ${JAVA_OPTS} ${JAVA_ARGS} -jar /opt/egov/*.jar \ No newline at end of file diff --git a/health-services/census-service/src/test/java/digit/TestConfiguration.java b/health-services/census-service/src/test/java/digit/TestConfiguration.java new file mode 100644 index 00000000000..570236cfc94 --- /dev/null +++ b/health-services/census-service/src/test/java/digit/TestConfiguration.java @@ -0,0 +1,16 @@ +package digit; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.KafkaTemplate; + +import static org.mockito.Mockito.mock; + +@Configuration +public class TestConfiguration { + @Bean + @SuppressWarnings("unchecked") + public KafkaTemplate kafkaTemplate() { + return mock(KafkaTemplate.class); + } +} \ No newline at end of file diff --git a/health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java b/health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java new file mode 100644 index 00000000000..d65b8f5d44e --- /dev/null +++ b/health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java @@ -0,0 +1,53 @@ +package digit.web.controllers; + +import digit.web.models.CensusRequest; +import digit.web.models.CensusResponse; +import digit.web.models.ErrorRes; +import org.junit.Test; +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.context.annotation.Import; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import digit.TestConfiguration; + + import java.util.ArrayList; + import java.util.HashMap; + import java.util.List; + import java.util.Map; + +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** +* API tests for CreateApiController +*/ +@Ignore +@RunWith(SpringRunner.class) +@WebMvcTest(CreateApiController.class) +@Import(TestConfiguration.class) +public class CreateApiControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void createPostSuccess() throws Exception { + mockMvc.perform(post("/_create").contentType(MediaType + .APPLICATION_JSON_UTF8)) + .andExpect(status().isOk()); + } + + @Test + public void createPostFailure() throws Exception { + mockMvc.perform(post("/_create").contentType(MediaType + .APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()); + } + +} diff --git a/health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java b/health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java new file mode 100644 index 00000000000..87ec62ea284 --- /dev/null +++ b/health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java @@ -0,0 +1,53 @@ +package digit.web.controllers; + +import digit.web.models.CensusResponse; +import digit.web.models.CensusSearchRequest; +import digit.web.models.ErrorRes; +import org.junit.Test; +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.context.annotation.Import; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import digit.TestConfiguration; + + import java.util.ArrayList; + import java.util.HashMap; + import java.util.List; + import java.util.Map; + +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** +* API tests for SearchApiController +*/ +@Ignore +@RunWith(SpringRunner.class) +@WebMvcTest(SearchApiController.class) +@Import(TestConfiguration.class) +public class SearchApiControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void searchPostSuccess() throws Exception { + mockMvc.perform(post("/_search").contentType(MediaType + .APPLICATION_JSON_UTF8)) + .andExpect(status().isOk()); + } + + @Test + public void searchPostFailure() throws Exception { + mockMvc.perform(post("/_search").contentType(MediaType + .APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()); + } + +} diff --git a/health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java b/health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java new file mode 100644 index 00000000000..811169a1837 --- /dev/null +++ b/health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java @@ -0,0 +1,53 @@ +package digit.web.controllers; + +import digit.web.models.CensusRequest; +import digit.web.models.CensusResponse; +import digit.web.models.ErrorRes; +import org.junit.Test; +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.context.annotation.Import; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import digit.TestConfiguration; + + import java.util.ArrayList; + import java.util.HashMap; + import java.util.List; + import java.util.Map; + +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** +* API tests for UpdateApiController +*/ +@Ignore +@RunWith(SpringRunner.class) +@WebMvcTest(UpdateApiController.class) +@Import(TestConfiguration.class) +public class UpdateApiControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void updatePostSuccess() throws Exception { + mockMvc.perform(post("/_update").contentType(MediaType + .APPLICATION_JSON_UTF8)) + .andExpect(status().isOk()); + } + + @Test + public void updatePostFailure() throws Exception { + mockMvc.perform(post("/_update").contentType(MediaType + .APPLICATION_JSON_UTF8)) + .andExpect(status().isBadRequest()); + } + +} From 404fe86f1451b0ffe1d3652b051d98c49ebcd08f Mon Sep 17 00:00:00 2001 From: Saloni-eGov Date: Fri, 27 Sep 2024 20:23:29 +0530 Subject: [PATCH 065/351] update api for plan facility --- .../main/java/digit/config/Configuration.java | 10 + .../java/digit/config/ServiceConstants.java | 20 ++ .../repository/PlanFacilityRepository.java | 2 +- .../impl/PlanFacilityRepositoryImpl.java | 14 +- .../digit/service/PlanFacilityService.java | 29 ++- .../enrichment/PlanFacilityEnricher.java | 25 +++ .../validator/PlanFacilityValidator.java | 183 ++++++++++++++++++ .../main/java/digit/util/CampaignUtil.java | 59 ++++++ .../src/main/java/digit/util/MdmsUtil.java | 13 ++ .../controllers/PlanFacilityController.java | 17 +- .../web/models/projectFactory/Boundary.java | 32 +++ .../models/projectFactory/CampaignDetail.java | 85 ++++++++ .../projectFactory/CampaignResponse.java | 29 +++ .../CampaignSearchCriteria.java | 51 +++++ .../projectFactory/CampaignSearchReq.java | 22 +++ .../web/models/projectFactory/Condition.java | 26 +++ .../models/projectFactory/DeliveryRule.java | 43 ++++ .../web/models/projectFactory/Pagination.java | 34 ++++ .../web/models/projectFactory/Product.java | 26 +++ .../web/models/projectFactory/Resource.java | 32 +++ .../src/main/resources/application.properties | 7 +- 21 files changed, 750 insertions(+), 9 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java create mode 100644 health-services/plan-service/src/main/java/digit/util/CampaignUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 03ea5c05d16..d44ea23409b 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -44,10 +44,20 @@ public class Configuration { @Value("${plan.update.topic}") private String planUpdateTopic; + @Value("${plan.facility.update.topic}") + private String planFacilityUpdateTopic; + @Value("${plan.default.offset}") private Integer defaultOffset; @Value("${plan.default.limit}") private Integer defaultLimit; + //Project Factory + @Value("${egov.project.factory.host}") + private String projectFactoryHost; + + @Value("${egov.project.factory.search.endpoint}") + private String projectFactorySearchEndpoint; + } diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 1528951de9c..0dca72c3ae0 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -180,4 +180,24 @@ public class ServiceConstants { public static final String VEHICLE_ID_FIELD = "vehicleIds"; + public static final String MDMS_HCM_ADMIN_CONSOLE = "HCM-ADMIN-CONSOLE"; + public static final String MDMS_MASTER_HIERARCHY_CONFIG = "hierarchyConfig"; + + public static final String INVALID_PLAN_FACILITY_ID_CODE = "INVALID_PLAN_FACILITY_ID"; + public static final String INVALID_PLAN_FACILITY_ID_MESSAGE = "Plan facility id provided is invalid"; + + public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from ProjectFactory service "; + + public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; + public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; + + public static final String INVALID_SERVICE_BOUNDARY_CODE = "INVALID_SERVICE_BOUNDARY"; + public static final String INVALID_SERVICE_BOUNDARY_MESSAGE = "The provided service boundary is invalid"; + + public static final String INVALID_RESIDING_BOUNDARY_CODE = "INVALID_RESIDING_BOUNDARY"; + public static final String INVALID_RESIDING_BOUNDARY_MESSAGE = "The provided residing boundary is invalid"; + + public static final String HIERARCHY_NOT_FOUND_IN_MDMS_CODE = "HIERARCHY_NOT_FOUND_IN_MDMS"; + public static final String HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE = "Hierarchy key not found in mdms"; + } diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java index 673496a3f23..23988e9775d 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java @@ -9,5 +9,5 @@ public interface PlanFacilityRepository { public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria); - public void update(PlanFacilitySearchCriteria planFacilitySearchCriteria); + void update(PlanFacilityRequest planFacilityRequest); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index d6a58b2ffd1..40edc26d05e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -52,9 +52,19 @@ public List search(PlanFacilitySearchCriteria planFacilitySearchCr return planFacilities; } + /** + * This method emits an event to the persister for it to update the plan facility in the database. + * + * @param planFacilityRequest + */ @Override - public void update(PlanFacilitySearchCriteria planFacilitySearchCriteria) { - + public void update(PlanFacilityRequest planFacilityRequest) { + try { + producer.push(config.getPlanFacilityUpdateTopic(), planFacilityRequest); + log.info("Successfully pushed update for plan facility: {}", planFacilityRequest.getPlanFacility().getId()); + } catch (Exception e) { + log.info("Failed to push message to topic {}. Error: {}", config.getPlanFacilityUpdateTopic(), e.getMessage(), e); + } } /** diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index 4f74002fb12..bf5b7d58bd9 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -1,18 +1,25 @@ package digit.service; import digit.repository.PlanFacilityRepository; +import digit.service.enrichment.PlanFacilityEnricher; +import digit.service.validator.PlanFacilityValidator; import digit.web.models.*; import org.egov.common.utils.ResponseInfoUtil; import org.springframework.stereotype.Service; +import java.util.Collections; import java.util.List; @Service public class PlanFacilityService { private PlanFacilityRepository planFacilityRepository; + private PlanFacilityValidator planFacilityValidator; + private PlanFacilityEnricher planFacilityEnricher; - public PlanFacilityService(PlanFacilityRepository planFacilityRepository) { + public PlanFacilityService(PlanFacilityRepository planFacilityRepository, PlanFacilityValidator planFacilityValidator, PlanFacilityEnricher planFacilityEnricher) { this.planFacilityRepository = planFacilityRepository; + this.planFacilityValidator = planFacilityValidator; + this.planFacilityEnricher = planFacilityEnricher; } /** @@ -43,4 +50,24 @@ else if (planFacilitySearchRequest.getPlanFacilitySearchCriteria().getPlanConfig .build(); } + /** + * Processes requests for updating plan facilities. + * + * @param planFacilityRequest The PlanFacilityRequest containing the update information. + * @return PlanFacilityResponse containing the updated plan facility and response information. + */ + public PlanFacilityResponse updatePlanFacility(PlanFacilityRequest planFacilityRequest) { + //validate plan facility request + planFacilityValidator.validatePlanFacilityUpdate(planFacilityRequest); + //enrich plan facilty request + planFacilityEnricher.enrichPlanFacilityUpdate(planFacilityRequest); + //delegate update request to repository + planFacilityRepository.update(planFacilityRequest); + //Build and return response back to controller + return PlanFacilityResponse.builder() + .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), Boolean.TRUE)). + planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())) + .build(); + } + } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java new file mode 100644 index 00000000000..88026df3fbe --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -0,0 +1,25 @@ +package digit.service.enrichment; + +import digit.web.models.PlanFacility; +import digit.web.models.PlanFacilityRequest; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; + +@Component +public class PlanFacilityEnricher { + + /** + * Enriches the plan facility update request + * + * @param planFacilityRequest The PlanFacilityRequest object contains the plan facility to be enriched. + */ + public void enrichPlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { + if (planFacilityRequest == null || planFacilityRequest.getPlanFacility() == null) { + throw new IllegalArgumentException("PlanFacilityRequest or PlanFacility cannot be null"); + } + PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + //enrich audit details + planFacility.setAuditDetails(prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.FALSE)); + } +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java new file mode 100644 index 00000000000..996506fbd5a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -0,0 +1,183 @@ +package digit.service.validator; + +import com.jayway.jsonpath.JsonPath; +import digit.repository.PlanConfigurationRepository; +import digit.repository.PlanFacilityRepository; +import digit.util.CampaignUtil; +import digit.util.MdmsUtil; +import digit.web.models.*; +import digit.web.models.projectFactory.CampaignDetail; +import digit.web.models.projectFactory.CampaignResponse; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.utils.MultiStateInstanceUtil; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import digit.web.models.projectFactory.Boundary; + +import static digit.config.ServiceConstants.*; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class PlanFacilityValidator { + private PlanFacilityRepository planFacilityRepository; + private PlanConfigurationRepository planConfigurationRepository; + private CampaignUtil campaignUtil; + private MultiStateInstanceUtil centralInstanceUtil; + private MdmsUtil mdmsUtil; + + public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil) { + this.planFacilityRepository = planFacilityRepository; + this.planConfigurationRepository = planConfigurationRepository; + this.campaignUtil = campaignUtil; + this.centralInstanceUtil = centralInstanceUtil; + this.mdmsUtil = mdmsUtil; + } + + public void validatePlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { + //validate plan facility existence + validatePlanFacilityExistence(planFacilityRequest); + + String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); + List planConfigurations = searchPlanConfigId(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); + if (planConfigurations == null || planConfigurations.isEmpty()) { + throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); + } + //validate service boundaries and residing boundaries with campaign id + validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, planFacilityRequest); + } + + /** + * This method validates campaign id and service boundaries against project factory + * + * @param campaignId the campaign id corresponding to the plan config id provided in the request + * @param rootTenantId the tenant id provided in the request + * @param planFacilityRequest the plan facility request provided + */ + private void validateCampaignDetails(String campaignId, String rootTenantId, PlanFacilityRequest planFacilityRequest) { + PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + Object mdmsData = mdmsUtil.fetchMdmsData(planFacilityRequest.getRequestInfo(), rootTenantId); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planFacilityRequest.getRequestInfo(), campaignId, rootTenantId); + + // Validate if campaign id exists + validateCampaignId(campaignResponse); + + // validate hierarchy type for campaign + String lowestHierarchy = validateHierarchyType(campaignResponse, mdmsData); + + // Collect all boundary code for the campaign + CampaignDetail campaignDetail = campaignResponse.getCampaignDetails().get(0); + Set boundaryCodes = campaignDetail.getBoundaries().stream() + .filter(boundary -> lowestHierarchy.equals(boundary.getType())) + .map(Boundary::getCode) + .collect(Collectors.toSet()); + + //validate service boundaries + validateServiceBoundaries(boundaryCodes, planFacility); + + //validate residing boundaries + validateResidingBoundaries(boundaryCodes, planFacility); + + } + + /** + * This method validates if residing boundaries exist in campaign details + * + * @param boundaryCodes + * @param planFacility + */ + private void validateResidingBoundaries(Set boundaryCodes, PlanFacility planFacility) { + String residingBoundary = planFacility.getResidingBoundary(); + if (residingBoundary != null && !boundaryCodes.contains(residingBoundary)) { + throw new CustomException(INVALID_RESIDING_BOUNDARY_CODE, INVALID_RESIDING_BOUNDARY_MESSAGE); + } + } + + /** + * This method validates if service boundaries exist in campaign details + * + * @param boundaryCodes + * @param planFacility + */ + private void validateServiceBoundaries(Set boundaryCodes, PlanFacility planFacility) { + planFacility.getServiceBoundaries().stream() + .forEach(service -> { + if (!boundaryCodes.contains(service)) { + throw new CustomException(INVALID_SERVICE_BOUNDARY_CODE, INVALID_SERVICE_BOUNDARY_MESSAGE); + } + }); + } + + /** + * This method validates if the hierarchy type provided in the request exists + * + * @param campaignResponse + * @param mdmsData + */ + private String validateHierarchyType(CampaignResponse campaignResponse, Object mdmsData) { + String hierarchyType = campaignResponse.getCampaignDetails().get(0).getHierarchyType(); + final String jsonPathForHierarchy = "$.HCM-ADMIN-CONSOLE.hierarchyConfig[*]"; + + List> hierarchyConfigList = null; + System.out.println("Jsonpath for hierarchy config -> " + jsonPathForHierarchy); + try { + hierarchyConfigList = JsonPath.read(mdmsData, jsonPathForHierarchy); + } catch (Exception e) { + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + for (Map hierarchyConfig : hierarchyConfigList) { + if (hierarchyType.equals(hierarchyConfig.get("hierarchy"))) { + return (String) hierarchyConfig.get("lowestHierarchy"); + } + } + // Throw exception if no matching hierarchy is found + throw new CustomException(HIERARCHY_NOT_FOUND_IN_MDMS_CODE, HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE); + } + + /** + * This method validates if the campaign id provided in the request exists + * + * @param campaignResponse The campaign details response from project factory + */ + private void validateCampaignId(CampaignResponse campaignResponse) { + + if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { + throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); + } + } + + /** + * This method validates if the plan facility id provided in the update request exists + * + * @param planFacilityRequest + */ + private void validatePlanFacilityExistence(PlanFacilityRequest planFacilityRequest) { + // If plan facility id provided is invalid, throw an exception + if (CollectionUtils.isEmpty(planFacilityRepository.search(PlanFacilitySearchCriteria.builder() + .ids(Collections.singleton(planFacilityRequest.getPlanFacility().getId())) + .build()))) { + throw new CustomException(INVALID_PLAN_FACILITY_ID_CODE, INVALID_PLAN_FACILITY_ID_MESSAGE); + } + } + + /** + * Searches the plan config based on the plan config id provided + * + * @param planConfigurationId + * @param tenantId + * @return + */ + public List searchPlanConfigId(String planConfigurationId, String tenantId) { + List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() + .id(planConfigurationId) + .tenantId(tenantId) + .build()); + + return planConfigurations; + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java new file mode 100644 index 00000000000..3062368e233 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java @@ -0,0 +1,59 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.projectFactory.*; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import static digit.config.ServiceConstants.*; +import java.util.Collections; + +@Slf4j +@Component +public class CampaignUtil { + + private RestTemplate restTemplate; + + private Configuration configs; + + public CampaignUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + /** + * This method calls external service to validate campaign id and service boundaries against project factory + * + * @param requestInfo + * @param campaignId + * @param tenantId + */ + public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campaignId, String tenantId) { + StringBuilder uri = new StringBuilder(); + uri = uri.append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndpoint()); + + CampaignSearchReq campaignSearchReq = getSearchReq(requestInfo, campaignId, tenantId); + CampaignResponse campaignResponse = new CampaignResponse(); + try { + campaignResponse = restTemplate.postForObject(uri.toString(), campaignSearchReq, CampaignResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY, e); + } + return campaignResponse; + } + + private CampaignSearchReq getSearchReq(RequestInfo requestInfo, String campaignId, String tenantId) { + Pagination pagination = Pagination.builder().limit(configs.getDefaultLimit()).offset(configs.getDefaultOffset()).build(); + CampaignSearchCriteria searchCriteria = CampaignSearchCriteria.builder() + .ids(Collections.singletonList(campaignId)) + .tenantId(tenantId) + .pagination(pagination) + .build(); + + return CampaignSearchReq.builder() + .requestInfo(requestInfo) + .campaignSearchCriteria(searchCriteria) + .build(); + } +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java index fb0f6560908..54999dddcb7 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java @@ -61,6 +61,7 @@ public MdmsCriteriaReq getMdmsRequest(RequestInfo requestInfo, String tenantId) List moduleDetails = new LinkedList<>(); moduleDetails.add(assumptionModuleDetail); + moduleDetails.add(getHCMAdminConsoleModuleDetail()); MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId).build(); @@ -89,4 +90,16 @@ private ModuleDetail getPlanModuleDetail() { return ModuleDetail.builder().masterDetails(assumptionMasterDetails).moduleName(MDMS_PLAN_MODULE_NAME).build(); } + /** + * This method get HCM-Admin-Console module details + */ + private ModuleDetail getHCMAdminConsoleModuleDetail() { + List hcmAdminConsoleMasterDetails = new ArrayList<>(); + + MasterDetail hierarchyConfigMasterDetail = MasterDetail.builder().name(MDMS_MASTER_HIERARCHY_CONFIG).build(); + hcmAdminConsoleMasterDetails.add(hierarchyConfigMasterDetail); + + return ModuleDetail.builder().masterDetails(hcmAdminConsoleMasterDetails).moduleName(MDMS_HCM_ADMIN_CONSOLE).build(); + } + } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java index fe7e4c04b37..e9ab71e1ae8 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -2,10 +2,7 @@ import digit.service.PlanFacilityService; -import digit.web.models.PlanFacilityResponse; -import digit.web.models.PlanFacilitySearchRequest; -import digit.web.models.PlanResponse; -import digit.web.models.PlanSearchRequest; +import digit.web.models.*; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -30,4 +27,16 @@ public ResponseEntity searchPost(@Valid @RequestBody PlanF PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(body); return ResponseEntity.status(HttpStatus.OK).body(planFacilityResponse); } + + /** + * Request handler for serving plan facility update requests + * + * @param planFacilityRequest + * @return + */ + @RequestMapping(value = "/facility/update", method = RequestMethod.POST) + public ResponseEntity planFacilityUpdatePost(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { + PlanFacilityResponse planFacilityResponse = planFacilityService.updatePlanFacility(planFacilityRequest); + return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse); + } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java new file mode 100644 index 00000000000..a1b725cbd6f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java @@ -0,0 +1,32 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Boundary + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Boundary { + + @JsonProperty("code") + private String code; + + @JsonProperty("type") + private String type; + + @JsonProperty("isRoot") + private Boolean isRoot; + + @JsonProperty("includeAllChildren") + private Boolean includeAllChildren; + + @JsonProperty("parent") + private String parent; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java new file mode 100644 index 00000000000..ee9d064547a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java @@ -0,0 +1,85 @@ +package digit.web.models.projectFactory; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; + +import java.util.List; + +/** + * CampaignDetails + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CampaignDetail { + + @JsonProperty("id") + private String id; + + @JsonProperty("tenantId") + @NotNull + private String tenantId; + + @JsonProperty("status") + private String status; + + @JsonProperty("action") + private String action; + + @JsonProperty("campaignNumber") + private String campaignNumber; + + @JsonProperty("isActive") + private Boolean isActive; + + @JsonProperty("parentId") + private String parentId; + + @JsonProperty("campaignName") + private String campaignName; + + @JsonProperty("projectType") + private String projectType; + + @JsonProperty("hierarchyType") + private String hierarchyType; + + @JsonProperty("boundaryCode") + private String boundaryCode; + + @JsonProperty("projectId") + private String projectId; + + @JsonProperty("startDate") + private Long startDate; + + @JsonProperty("endDate") + private Long endDate; + + @JsonProperty("additionalDetails") + @Valid + private Object additionalDetails; + + @JsonProperty("resources") + @Valid + private List resources; + + @JsonProperty("boundaries") + @Valid + private List boundaries; + + @JsonProperty("deliveryRules") + @Valid + private List deliveryRules; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java new file mode 100644 index 00000000000..e03e4bb01c7 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java @@ -0,0 +1,29 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.*; +import org.egov.common.contract.response.ResponseInfo; + +import java.util.List; + +/** + * CampaignResponse + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CampaignResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("CampaignDetails") + @Valid + private List campaignDetails = null; + + @JsonProperty("totalCount") + @Valid + private Integer totalCount = null; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java new file mode 100644 index 00000000000..36ef6675594 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java @@ -0,0 +1,51 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * CampaignSearchCriteria + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Validated +public class CampaignSearchCriteria { + + @JsonProperty("ids") + @Size(min = 1) + private List ids; + + @JsonProperty("tenantId") + @Size(min = 2, max = 256) + private String tenantId; + + @JsonIgnore + private List status; + + @JsonIgnore + private String createdBy; + + @JsonIgnore + private Boolean campaignsIncludeDates; + + @JsonIgnore + private Integer startDate; + + @JsonIgnore + private Integer endDate; + + @JsonProperty("pagination") + @Valid + private Pagination pagination; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java new file mode 100644 index 00000000000..391420396ed --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java @@ -0,0 +1,22 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.Builder; +import lombok.Data; +import org.egov.common.contract.request.RequestInfo; + +/** + * CampaignSearchReq + */ +@Data +@Builder +public class CampaignSearchReq { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo; + + @JsonProperty("CampaignDetails") + private CampaignSearchCriteria campaignSearchCriteria; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java new file mode 100644 index 00000000000..7b271c9006a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java @@ -0,0 +1,26 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Condition + **/ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Condition { + + @JsonProperty("value") + private String value; + + @JsonProperty("operator") + private String operator; + + @JsonProperty("attribute") + private String attribute; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java new file mode 100644 index 00000000000..4ad241db9e3 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java @@ -0,0 +1,43 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +/** + * DeliveryRule + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class DeliveryRule { + @JsonProperty("endDate") + private Long endDate; + + @JsonProperty("products") + @Valid + private List products; + + @JsonProperty("startDate") + private Long startDate; + + @JsonProperty("conditions") + @Valid + private List conditions; + + @JsonProperty("cycleNumber") + private Integer cycleNumber; + + @JsonProperty("deliveryNumber") + private Integer deliveryNumber; + + @JsonProperty("deliveryRuleNumber") + private Integer deliveryRuleNumber; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java new file mode 100644 index 00000000000..82f3b54418b --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java @@ -0,0 +1,34 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Pagination + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Pagination { + @JsonIgnore + private String sortBy; + + @JsonIgnore + private String sortOrder; + + @JsonProperty("limit") + @Min(1) + @Max(50) + private Integer limit; + + @JsonProperty("offset") + @Min(0) + private Integer offset; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java new file mode 100644 index 00000000000..9c4e560cc7f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java @@ -0,0 +1,26 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Product + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Product { + + @JsonProperty("name") + private String name; + + @JsonProperty("count") + private Integer count; + + @JsonProperty("value") + private String value; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java new file mode 100644 index 00000000000..07f04a281bb --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java @@ -0,0 +1,32 @@ +package digit.web.models.projectFactory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Resource + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Resource { + + @JsonProperty("type") + private String type; + + @JsonProperty("filename") + private String filename; + + @JsonProperty("resourceId") + private String resourceId; + + @JsonProperty("filestoreId") + private String filestoreId; + + @JsonProperty("createResourceId") + private String createResourceId; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 77c0cfde74a..3f965d5498b 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -48,6 +48,7 @@ plan.configuration.update.topic=plan-config-update-topic plan.create.topic=save-plan plan.update.topic=update-plan +plan.facility.update.topic=update-plan-facility #mdms urls egov.mdms.host=https://unified-dev.digit.org @@ -59,4 +60,8 @@ plan.default.offset=0 plan.default.limit=10 resource.config.consumer.plan.create.topic=resource-microplan-create-topic -resource.update.plan.config.consumer.topic=resource-plan-config-update-topic \ No newline at end of file +resource.update.plan.config.consumer.topic=resource-plan-config-update-topic + +#project factory urls +egov.project.factory.host=http://localhost:8009 +egov.project.factory.search.endpoint=/project-factory/v1/project-type/search \ No newline at end of file From 94953af7dbd26b8550ac6b75e09fc8d1e4d46c83 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Sat, 28 Sep 2024 19:36:33 +0530 Subject: [PATCH 066/351] added mdms call to HCM-Admin-Console --- .../src/main/java/digit/util/MdmsUtil.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java index fb0f6560908..1ffd1677dc7 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java @@ -61,6 +61,7 @@ public MdmsCriteriaReq getMdmsRequest(RequestInfo requestInfo, String tenantId) List moduleDetails = new LinkedList<>(); moduleDetails.add(assumptionModuleDetail); + moduleDetails.add(getHCMAdminConsoleModuleDetail()); MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId).build(); @@ -89,4 +90,15 @@ private ModuleDetail getPlanModuleDetail() { return ModuleDetail.builder().masterDetails(assumptionMasterDetails).moduleName(MDMS_PLAN_MODULE_NAME).build(); } + /** + * This method get HCM-Admin-Console module details + */ + private ModuleDetail getHCMAdminConsoleModuleDetail() { + List hcmAdminConsoleMasterDetails = new ArrayList<>(); + + MasterDetail hierarchyConfigMasterDetail = MasterDetail.builder().name(MDMS_MASTER_HIERARCHY_CONFIG).build(); + hcmAdminConsoleMasterDetails.add(hierarchyConfigMasterDetail); + + return ModuleDetail.builder().masterDetails(hcmAdminConsoleMasterDetails).moduleName(MDMS_HCM_ADMIN_CONSOLE).build(); + } } \ No newline at end of file From 2ece230b51c0e0b92e8ecb231960820db5194fbb Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Sat, 28 Sep 2024 19:39:16 +0530 Subject: [PATCH 067/351] review changes --- .../java/digit/config/ServiceConstants.java | 2 ++ .../impl/PlanFacilityRepositoryImpl.java | 2 ++ .../digit/service/PlanFacilityService.java | 15 ++++------ .../validator/PlanFacilityValidator.java | 29 +++++++++---------- .../controllers/PlanFacilityController.java | 4 +-- 5 files changed, 25 insertions(+), 27 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index b8fcf404838..5e310b6b657 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -146,6 +146,8 @@ public class ServiceConstants { public static final String MDMS_MASTER_NAME_VALIDATION= "MicroplanNamingRegex"; public static final String MDMS_HCM_ADMIN_CONSOLE = "HCM-ADMIN-CONSOLE"; public static final String MDMS_MASTER_HIERARCHY_CONFIG= "hierarchyConfig"; + public static final String MDMS_MASTER_HIERARCHY= "hierarchy"; + public static final String MDMS_MASTER_LOWEST_HIERARCHY= "lowestHierarchy"; public static final String HIERARCHY_NOT_FOUND_IN_MDMS_CODE="HIERARCHY_NOT_FOUND_IN_MDMS"; public static final String HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE="Hierarchy Not Found"; diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 0ff20da5d04..1a20a56f7c4 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -5,6 +5,7 @@ import digit.repository.PlanFacilityRepository; import digit.web.models.PlanFacilityRequest; import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Repository; @Repository @@ -29,6 +30,7 @@ public void create(PlanFacilityRequest planFacilityRequest) { producer.push(config.getPlanFacilityCreateTopic(), planFacilityRequest); } catch (Exception e) { log.info("Pushing message to topic " + config.getPlanFacilityCreateTopic() + " failed.", e); + throw new CustomException("KAFKA_PUSH_FAILED", "Failed to push event to Kafka, operation could not be completed."); } } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index 1629b7c4f84..1206ea3df95 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -13,10 +13,10 @@ @Service public class PlanFacilityService { - private PlanFacilityValidator planFacilityValidator; - private ResponseInfoFactory responseInfoFactory; - private PlanFacilityEnrichementService planFacilityEnricher; - private PlanFacilityRepository planFacilityRepository; + private final PlanFacilityValidator planFacilityValidator; + private final ResponseInfoFactory responseInfoFactory; + private final PlanFacilityEnrichementService planFacilityEnricher; + private final PlanFacilityRepository planFacilityRepository; public PlanFacilityService(PlanFacilityValidator planFacilityValidator, ResponseInfoFactory responseInfoFactory, PlanFacilityEnrichementService planFacilityEnricher, PlanFacilityRepository planFacilityRepository) { this.planFacilityValidator = planFacilityValidator; @@ -27,6 +27,7 @@ public PlanFacilityService(PlanFacilityValidator planFacilityValidator, Response /** * This method processes the requests that come for creating plans. + * * @param planFacilityRequest * @return */ @@ -41,11 +42,7 @@ public PlanFacilityResponse createPlanFacility(PlanFacilityRequest planFacilityR planFacilityRepository.create(planFacilityRequest); // Build and return response back to controller - PlanFacilityResponse response = PlanFacilityResponse.builder() - .planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())) - .responseInfo(responseInfoFactory - .createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), true)) - .build(); + PlanFacilityResponse response = PlanFacilityResponse.builder().planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())).responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), true)).build(); return response; } } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index cea65bc85ca..28302643daf 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -65,18 +65,12 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); List planConfigurations = searchPlanConfigId(planFacilityRequest.getPlanFacility().getPlanConfigurationId(),rootTenantId); - if(planConfigurations.isEmpty()) - { - throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE,INVALID_PLAN_CONFIG_ID_MESSAGE); - } // Validate plan configuration existence validatePlanConfigurationExistence(planFacilityRequest); // Validate facility existence - validateFacilityExistence(planFacilityRequest.getPlanFacility().getFacilityId(), - planFacilityRequest.getPlanFacility().getTenantId(), - planFacilityRequest.getRequestInfo()); + validateFacilityExistence(planFacilityRequest); //validate service boundaries and residing boundaries with campaign id validateCampaignDetails(planConfigurations.get(0).getCampaignId(),rootTenantId,planFacilityRequest); @@ -137,7 +131,7 @@ private void validateResidingBoundaries(Set boundaryCode, PlanFacility p */ private String validateHierarchyType(CampaignResponse campaignResponse, Object mdmsData) { String hierarchyType = campaignResponse.getCampaignDetails().get(0).getHierarchyType(); - final String jsonPathForHierarchy = "$.HCM-ADMIN-CONSOLE.hierarchyConfig[*]"; + final String jsonPathForHierarchy = JSON_ROOT_PATH + MDMS_HCM_ADMIN_CONSOLE + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + "[*]";; List> hierarchyConfigList = null; System.out.println("Jsonpath for hierarchy config -> " + jsonPathForHierarchy); @@ -148,8 +142,8 @@ private String validateHierarchyType(CampaignResponse campaignResponse, Object m } for (Map hierarchyConfig : hierarchyConfigList) { - if (hierarchyType.equals(hierarchyConfig.get("hierarchy"))) { - return (String) hierarchyConfig.get("lowestHierarchy"); + if (hierarchyType.equals(hierarchyConfig.get(MDMS_MASTER_HIERARCHY))) { + return (String) hierarchyConfig.get(MDMS_MASTER_LOWEST_HIERARCHY); } } // Throw exception if no matching hierarchy is found @@ -202,19 +196,22 @@ public List searchPlanConfigId(String planConfigurationId, St /** * Validates if the facility with the provided ID exists in the system. * - * @param facilityId The facility ID to validate. - * @param tenantId The tenant ID. - * @param requestInfo The request information for the API call. + * @param planFacilityRequest */ - private void validateFacilityExistence(String facilityId, String tenantId, RequestInfo requestInfo) { + private void validateFacilityExistence(PlanFacilityRequest planFacilityRequest) { + String facilityId = planFacilityRequest.getPlanFacility().getFacilityId(); + String tenantId = planFacilityRequest.getPlanFacility().getTenantId(); + RequestInfo requestInfo = planFacilityRequest.getRequestInfo(); + FacilityResponse facilityResponse = facilityUtil.fetchFacilityData(requestInfo, facilityId, tenantId); - // Check if the facility response is null or if the facilities list is null or empty - if (facilityResponse == null || facilityResponse.getFacilities() == null || facilityResponse.getFacilities().isEmpty()) { + // Use ObjectUtils and CollectionUtils to handle null or empty checks + if (ObjectUtils.isEmpty(facilityResponse) || CollectionUtils.isEmpty(facilityResponse.getFacilities())) { throw new CustomException("FACILITY_NOT_FOUND", "Facility with ID " + facilityId + " not found in the system."); } } + /** * Validates if the plan configuration ID provided in the request exists. * diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java index ffb358bb1eb..a25f0117f1a 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -17,7 +17,7 @@ @RequestMapping("/plan/facility") public class PlanFacilityController { - private PlanFacilityService planFacilityService; + private final PlanFacilityService planFacilityService; public PlanFacilityController(PlanFacilityService planFacilityService) { this.planFacilityService = planFacilityService; @@ -30,7 +30,7 @@ public PlanFacilityController(PlanFacilityService planFacilityService) { * @return */ @RequestMapping(value = "/_create", method = RequestMethod.POST) - public ResponseEntity planFacilityCreatePost(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { + public ResponseEntity createPlanFacility(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { PlanFacilityResponse planFacilityResponse = planFacilityService.createPlanFacility(planFacilityRequest); return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse); } From 80e9654562f943617a96a1f8d6df900a2aeb4297 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Sun, 29 Sep 2024 12:23:03 +0530 Subject: [PATCH 068/351] modified files --- .../src/main/java/digit/config/Configuration.java | 2 +- .../src/main/java/digit/config/ServiceConstants.java | 4 ++-- .../src/main/java/digit/service/PlanFacilityService.java | 6 +++--- ...ityEnrichementService.java => PlanFacilityEnricher.java} | 2 +- .../plan-service/src/main/java/digit/util/FacilityUtil.java | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename health-services/plan-service/src/main/java/digit/service/enrichment/{PlanFacilityEnrichementService.java => PlanFacilityEnricher.java} (96%) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 0ced7b61978..106bbe7c54d 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -58,7 +58,7 @@ public class Configuration { private String facilityHost; @Value("${egov.facility.search.endpoint}") - private String facilityEndPoint; + private String facilitySearchEndPoint; //Project Factory @Value("${egov.project.factory.host}") diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 5e310b6b657..043211c2bed 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -189,8 +189,8 @@ public class ServiceConstants { public static final String VEHICLE_ID_FIELD = "vehicleIds"; - public static final String ERROR_WHILE_FETCHING_FROM_FACILITY = "Exception occurred while fetching facility details from facility: "; - public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from project factory: "; + public static final String ERROR_WHILE_FETCHING_FROM_FACILITY = "Exception occurred while fetching facility details from facility service "; + public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from ProjectFactory service "; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index 1206ea3df95..574a80a02ed 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -1,7 +1,7 @@ package digit.service; import digit.repository.PlanFacilityRepository; -import digit.service.enrichment.PlanFacilityEnrichementService; +import digit.service.enrichment.PlanFacilityEnricher; import digit.service.validator.PlanFacilityValidator; import digit.util.ResponseInfoFactory; import digit.web.models.PlanFacilityRequest; @@ -15,10 +15,10 @@ public class PlanFacilityService { private final PlanFacilityValidator planFacilityValidator; private final ResponseInfoFactory responseInfoFactory; - private final PlanFacilityEnrichementService planFacilityEnricher; + private final PlanFacilityEnricher planFacilityEnricher; private final PlanFacilityRepository planFacilityRepository; - public PlanFacilityService(PlanFacilityValidator planFacilityValidator, ResponseInfoFactory responseInfoFactory, PlanFacilityEnrichementService planFacilityEnricher, PlanFacilityRepository planFacilityRepository) { + public PlanFacilityService(PlanFacilityValidator planFacilityValidator, ResponseInfoFactory responseInfoFactory, PlanFacilityEnricher planFacilityEnricher, PlanFacilityRepository planFacilityRepository) { this.planFacilityValidator = planFacilityValidator; this.responseInfoFactory = responseInfoFactory; this.planFacilityEnricher = planFacilityEnricher; diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java similarity index 96% rename from health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java rename to health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 72e13c6e40b..21292376dc3 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnrichementService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -9,7 +9,7 @@ @Component @Slf4j -public class PlanFacilityEnrichementService { +public class PlanFacilityEnricher { /** * Enriches the plan facility create request diff --git a/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java b/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java index 5721e3b4a74..d864f98bad5 100644 --- a/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java @@ -33,7 +33,7 @@ public FacilityUtil(RestTemplate restTemplate, Configuration configs) { } public FacilityResponse fetchFacilityData(RequestInfo requestInfo, String facilityId, String tenantId) { - String baseUri = configs.getFacilityHost()+ configs.getFacilityEndPoint(); + String baseUri = configs.getFacilityHost()+ configs.getFacilitySearchEndPoint(); // Retrieve the limit and offset from the configuration int limit = configs.getDefaultLimit(); From 9fd4f26f6a09fb7352430d3a9ba229800cd053c1 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Sun, 29 Sep 2024 19:54:04 +0530 Subject: [PATCH 069/351] updated conflict changes --- .../digit/service/PlanFacilityService.java | 6 ++-- .../validator/PlanFacilityValidator.java | 18 ++++++++++ .../controllers/PlanFacilityController.java | 12 +++++-- .../web/models/projectFactory/Pagination.java | 34 ------------------- 4 files changed, 30 insertions(+), 40 deletions(-) delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index dc8f22f334c..72421d3a829 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -30,10 +30,10 @@ public PlanFacilityService(PlanFacilityValidator planFacilityValidator, Response } /** - * This method processes the requests that come for creating plans. + * This method processes the requests that come for creating plan facilities. * - * @param planFacilityRequest - * @return + * @param planFacilityRequest The PlanFacilityRequest containing the plan facility details for creation. + * @return PlanFacilityResponse containing the created plan facility and response information. */ public PlanFacilityResponse createPlanFacility(PlanFacilityRequest planFacilityRequest) { // Validate plan facility create request diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index c10aad3be74..793ccc0a6e2 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -5,6 +5,7 @@ import digit.repository.PlanFacilityRepository; import digit.util.*; import digit.web.models.*; +import digit.web.models.facility.FacilityResponse; import digit.web.models.projectFactory.CampaignDetail; import digit.web.models.projectFactory.CampaignResponse; import jakarta.validation.Valid; @@ -32,6 +33,16 @@ public class PlanFacilityValidator { private FacilityUtil facilityUtil; private CommonUtil commonUtil; + public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil, CommonUtil commonUtil) { + this.planFacilityRepository = planFacilityRepository; + this.planConfigurationRepository = planConfigurationRepository; + this.campaignUtil = campaignUtil; + this.centralInstanceUtil = centralInstanceUtil; + this.mdmsUtil = mdmsUtil; + this.facilityUtil = facilityUtil; + this.commonUtil = commonUtil; + } + /** * This method validates the Plan Facility Create request. * It performs multiple validations such as plan configuration, facility existence, @@ -54,6 +65,13 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe validateCampaignDetails(planConfigurations.get(0).getCampaignId(),rootTenantId,planFacilityRequest); } + /** + * This method validates the Plan Facility Update request. + * It performs multiple validations such as plan facility existence + * and campaign-related validations. + * + * @param planFacilityRequest + */ public void validatePlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { //validate plan facility existence validatePlanFacilityExistence(planFacilityRequest); diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java index 89ca56d590a..67dd1bc3109 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -42,14 +42,20 @@ public ResponseEntity createPlanFacility(@Valid @RequestBo * @return */ @RequestMapping(value = "/facility/update", method = RequestMethod.POST) - public ResponseEntity planFacilityUpdatePost(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { + public ResponseEntity updatePlanFacility(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { PlanFacilityResponse planFacilityResponse = planFacilityService.updatePlanFacility(planFacilityRequest); return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse); } + /** + * Request handler for serving plan facility search requests + * + * @param planFacilityRequest + * @return + */ @RequestMapping(value = "/facility/_search", method = RequestMethod.POST) - public ResponseEntity searchPost(@Valid @RequestBody PlanFacilitySearchRequest body) { - PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(body); + public ResponseEntity searchPlanFacility(@Valid @RequestBody PlanFacilitySearchRequest planFacilityRequest) { + PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(planFacilityRequest); return ResponseEntity.status(HttpStatus.OK).body(planFacilityResponse); } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java b/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java deleted file mode 100644 index 82f3b54418b..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java +++ /dev/null @@ -1,34 +0,0 @@ -package digit.web.models.projectFactory; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.Max; -import jakarta.validation.constraints.Min; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Pagination - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class Pagination { - @JsonIgnore - private String sortBy; - - @JsonIgnore - private String sortOrder; - - @JsonProperty("limit") - @Min(1) - @Max(50) - private Integer limit; - - @JsonProperty("offset") - @Min(0) - private Integer offset; -} \ No newline at end of file From 3bb0fb112a2456d4d10a6cfe248b2c0453bbbd1b Mon Sep 17 00:00:00 2001 From: Saloni-eGov Date: Mon, 30 Sep 2024 10:25:23 +0530 Subject: [PATCH 070/351] corrected endpoint --- .../main/java/digit/web/controllers/PlanFacilityController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java index 67dd1bc3109..fc543ced50d 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -41,7 +41,7 @@ public ResponseEntity createPlanFacility(@Valid @RequestBo * @param planFacilityRequest * @return */ - @RequestMapping(value = "/facility/update", method = RequestMethod.POST) + @RequestMapping(value = "/facility/_update", method = RequestMethod.POST) public ResponseEntity updatePlanFacility(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { PlanFacilityResponse planFacilityResponse = planFacilityService.updatePlanFacility(planFacilityRequest); return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse); From c6b8a9df3208c881d930f2b2ea8a6092aad3b941 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 12:49:49 +0530 Subject: [PATCH 071/351] added validation for role conflict --- .../main/java/digit/config/Configuration.java | 7 ++ .../java/digit/config/ServiceConstants.java | 5 +- .../PlanEmployeeAssignmentQueryBuilder.java | 6 ++ .../PlanEmployeeAssignmentValidator.java | 83 +++++++++++++++---- .../PlanEmployeeAssignmentSearchCriteria.java | 3 + 5 files changed, 86 insertions(+), 18 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 7db9eca01f3..0e9218b5f3d 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -5,11 +5,14 @@ import org.egov.tracer.config.TracerConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Component; +import java.util.HashMap; +import java.util.Map; import java.util.TimeZone; @Component @@ -21,6 +24,10 @@ @Getter public class Configuration { + //Role Map + @Value("#{${role.map}}") + public Map roleMap; + //MDMS @Value("${egov.mdms.host}") private String mdmsHost; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index edd7f058f10..fd56e1ab0f8 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -72,7 +72,10 @@ public class ServiceConstants { public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; public static final String INVALID_EMPLOYEE_JURISDICTION_CODE = "INVALID_EMPLOYEE_JURISDICTION"; - public static final String INVALID_EMPLOYEE_JURISDICTION_MESSAGE = "The provided employee's jurisdiction is invalid"; + public static final String INVALID_EMPLOYEE_JURISDICTION_MESSAGE = "The employee's jurisdiction provided is invalid"; + + public static final String INVALID_EMPLOYEE_ROLE_CODE = "INVALID_EMPLOYEE_ROLE"; + public static final String INVALID_EMPLOYEE_ROLE_MESSAGE = "The employee's role provided is invalid"; public static final String SEARCH_CRITERIA_EMPTY_CODE = "SEARCH_CRITERIA_EMPTY"; public static final String SEARCH_CRITERIA_EMPTY_MESSAGE = "Search criteria cannot be empty"; diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 2705d307ff4..5f9c49982f6 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -63,6 +63,12 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit preparedStmtList.add(searchCriteria.getPlanConfigurationId()); } + if (searchCriteria.getEmployeeId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" employee_id = ?"); + preparedStmtList.add(searchCriteria.getEmployeeId()); + } + if (searchCriteria.getRole() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" role = ?"); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 449671ccc16..07f78d98cd5 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -1,5 +1,6 @@ package digit.service.validator; +import digit.config.Configuration; import digit.repository.PlanEmployeeAssignmentRepository; import digit.util.CampaignUtil; import digit.util.CommonUtil; @@ -11,6 +12,7 @@ import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.request.Role; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -35,15 +37,17 @@ public class PlanEmployeeAssignmentValidator { private PlanEmployeeAssignmentRepository repository; - public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, HrmsUtil hrmsUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeAssignmentRepository repository) { + private Configuration config; + + public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, HrmsUtil hrmsUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeAssignmentRepository repository, Configuration config) { this.centralInstanceUtil = centralInstanceUtil; this.hrmsUtil = hrmsUtil; this.commonUtil = commonUtil; this.campaignUtil = campaignUtil; this.repository = repository; + this.config = config; } - /** * This method validates the create request for plan employee assignment. * @@ -53,17 +57,68 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); + EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); // Validate if plan config id exists validatePlanConfigId(planConfigurations); - // Validate if employee exists against hrms - validateEmployeeAgainstHRMS(request); + // Validate if employee exists against HRMS + validateEmployeeAgainstHRMS(employeeResponse); + + // Validate role of employee against HRMS + validateRoleAgainstHRMS(planEmployeeAssignment, employeeResponse); + + // Validate + validateRoleConflict(planEmployeeAssignment); // Validate campaign id and employee jurisdiction validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); } + /** + * This method checks if the employee's role provided is a conflicting role against the role map. + * + * @param planEmployeeAssignment The plan employee assignment provided in request + */ + private void validateRoleConflict(PlanEmployeeAssignment planEmployeeAssignment) { + + // Fetch the role mappings from the configuration + Map roleMap = config.getRoleMap(); + + // Check if the role of the employee exists in the role map + if (roleMap.containsKey(planEmployeeAssignment.getRole())) { + + // Fetch existing role assignments for the employee based on their tenant, planConfig Id, and employee ID + // The search is conducted using the conflicting role + List response = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(planEmployeeAssignment.getTenantId()) + .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) + .employeeId(planEmployeeAssignment.getEmployeeId()) + .role(roleMap.get(planEmployeeAssignment.getRole())).build()); + + // If there are any conflicting assignments found, throw a custom exception + if (!CollectionUtils.isEmpty(response)) { + throw new CustomException(INVALID_EMPLOYEE_ROLE_CODE, INVALID_EMPLOYEE_ROLE_MESSAGE); + } + } + } + + /** + * This method validates the provided roles of the employee against HRMS + * + * @param planEmployeeAssignment The plan employee assignment provided in request + * @param employeeResponse The employee response from HRMS for the provided employeeId + */ + private void validateRoleAgainstHRMS(PlanEmployeeAssignment planEmployeeAssignment, EmployeeResponse employeeResponse) { + Set rolesFromHRMS = employeeResponse.getEmployees().get(0).getUser().getRoles().stream() + .map(Role::getCode) + .collect(Collectors.toSet()); + + if (!rolesFromHRMS.contains(planEmployeeAssignment.getRole())) { + throw new CustomException(INVALID_EMPLOYEE_ROLE_CODE, INVALID_EMPLOYEE_ROLE_MESSAGE); + } + } + /** * This method validates campaign id and employee's jurisdiction against project factory @@ -73,7 +128,6 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { * @param planEmployeeAssignmentRequest the plan employee assignment request provided */ private void validateCampaignDetails(String campaignId, String tenantId, PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { - PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentRequest.getPlanEmployeeAssignment(); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planEmployeeAssignmentRequest.getRequestInfo(), campaignId, tenantId); @@ -112,24 +166,18 @@ private void validateEmployeeJurisdiction(CampaignDetail campaignDetail, PlanEmp * @param campaignResponse The campaign details response from project factory */ private void validateCampaignId(CampaignResponse campaignResponse) { - if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); } } /** - * This method validates if the employee provided in plan employee assignment request exist in hrms + * This method validates if the employee provided in plan employee assignment request exist in HRMS * - * @param request The request for plan employee assignment + * @param employeeResponse The employee response from HRMS for provided employeeId */ - private void validateEmployeeAgainstHRMS(PlanEmployeeAssignmentRequest request) { - - PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); - EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); - + private void validateEmployeeAgainstHRMS(EmployeeResponse employeeResponse) { if (CollectionUtils.isEmpty(employeeResponse.getEmployees())) { - log.error(NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE + " - " + planEmployeeAssignment.getEmployeeId()); throw new CustomException(NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_CODE, NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE); } } @@ -175,6 +223,7 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); + EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); // Validate if Plan employee assignment exists validatePlanEmployeeAssignment(planEmployeeAssignment); @@ -182,8 +231,8 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { // Validate if plan config id exists validatePlanConfigId(planConfigurations); - // Validate if employee exists against hrms - validateEmployeeAgainstHRMS(request); + // Validate if employee exists against HRMS + validateEmployeeAgainstHRMS(employeeResponse); // Validate campaign id and employee jurisdiction validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); @@ -202,7 +251,7 @@ private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeA .id(planEmployeeAssignment.getId()) .build()); - if(CollectionUtils.isEmpty(planEmployeeAssignments)) { + if (CollectionUtils.isEmpty(planEmployeeAssignments)) { throw new CustomException(INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE, INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE); } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index b3449f50ec1..77aee5eac24 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -29,6 +29,9 @@ public class PlanEmployeeAssignmentSearchCriteria { @NotNull private String tenantId = null; + @JsonProperty("employeeId") + private String employeeId = null; + @JsonProperty("planConfigurationId") @Size(max = 64) private String planConfigurationId = null; From 170c585df521b0eaa31a365216474ab83f94d7a0 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 12:50:59 +0530 Subject: [PATCH 072/351] added validation for role conflict --- .../plan-service/src/main/resources/application.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 1dba821b50a..9900545324a 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -70,4 +70,7 @@ plan.default.offset=0 plan.default.limit=10 resource.config.consumer.plan.create.topic=resource-microplan-create-topic -resource.update.plan.config.consumer.topic=resource-plan-config-update-topic \ No newline at end of file +resource.update.plan.config.consumer.topic=resource-plan-config-update-topic + +# Role Map +role.map = {NATIONAL_FACILITY_CATCHMENT_ASSIGNER:'FACILITY_CATCHMENT_ASSIGNER', FACILITY_CATCHMENT_ASSIGNER:'NATIONAL_FACILITY_CATCHMENT_ASSIGNER', NATIONAL_POPULATION_DATA_APPROVER:'POPULATION_DATA_APPROVER', POPULATION_DATA_APPROVER:'NATIONAL_POPULATION_DATA_APPROVER', NATIONAL_MICROPLAN_APPROVER:'MICROPLAN_APPROVER', MICROPLAN_APPROVER:'NATIONAL_MICROPLAN_APPROVER'} \ No newline at end of file From 0c93c1b9e71399ccdc6b93a62e818d2ce9a67ef1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 14:00:49 +0530 Subject: [PATCH 073/351] added plan employee migration script --- ...800__plan_employee_assignment_create_ddl.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql new file mode 100644 index 00000000000..a0d03c51dc4 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql @@ -0,0 +1,17 @@ +-- Table: plan_employee_assignment +CREATE TABLE plan_employee_assignment ( + id character varying(64), + tenant_id character varying(64), + plan_configuration_id character varying(64), + employee_id character varying(64), + role character varying(64), + jurisdiction TEXT, + additional_details JSONB, + active boolean DEFAULT true, + created_by character varying(64), + created_time bigint, + last_modified_by character varying(64), + last_modified_time bigint, + CONSTRAINT uk_plan_employee_assignment_id PRIMARY KEY (id), + FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id) +); \ No newline at end of file From 4559cc0758ff9b69dc6c4c02bf091c4de3cb9a64 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 14:14:11 +0530 Subject: [PATCH 074/351] added campaignId validation for plan config and plan --- .../java/digit/service/PlanValidator.java | 25 ++++++++++++++++++- .../validator/PlanConfigurationValidator.java | 25 ++++++++++++++++++- .../PlanEmployeeAssignmentValidator.java | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 391e812005f..859c2917121 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -3,9 +3,11 @@ import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; import digit.repository.PlanRepository; +import digit.util.CampaignUtil; import digit.util.CommonUtil; import digit.util.MdmsUtil; import digit.web.models.*; +import digit.web.models.projectFactory.CampaignResponse; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -30,12 +32,15 @@ public class PlanValidator { private CommonUtil commonUtil; - public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, CommonUtil commonUtil) { + private CampaignUtil campaignUtil; + + public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, CommonUtil commonUtil, CampaignUtil campaignUtil) { this.planRepository = planRepository; this.planConfigurationRepository = planConfigurationRepository; this.mdmsUtil = mdmsUtil; this.centralInstanceUtil = centralInstanceUtil; this.commonUtil = commonUtil; + this.campaignUtil = campaignUtil; } /** @@ -45,6 +50,7 @@ public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository public void validatePlanCreate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); // Validate activities validateActivities(request); @@ -69,6 +75,20 @@ public void validatePlanCreate(PlanRequest request) { // Validate Metric Detail's Unit against MDMS validateMetricDetailUnit(request, mdmsData); + + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + } + + /** + * This method validates if the campaign id provided in the request exists + * + * @param campaignResponse The campaign details response from project factory + */ + private void validateCampaignId(CampaignResponse campaignResponse) { + if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { + throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); + } } /** @@ -248,6 +268,7 @@ public void validatePlanUpdate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); // Validate activities validateActivities(request); @@ -282,6 +303,8 @@ public void validatePlanUpdate(PlanRequest request) { // Validate Metric Detail's Unit against MDMS validateMetricDetailUnit(request, mdmsData); + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); } /** diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index f2a291c53ed..5dd5815bdb7 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -3,6 +3,7 @@ import com.jayway.jsonpath.JsonPath; import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; +import digit.util.CampaignUtil; import digit.util.MdmsUtil; import digit.util.MdmsV2Util; import digit.util.CommonUtil; @@ -12,6 +13,7 @@ import java.util.stream.Collectors; import digit.web.models.mdmsV2.Mdms; +import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.egov.common.utils.MultiStateInstanceUtil; @@ -36,12 +38,15 @@ public class PlanConfigurationValidator { private MultiStateInstanceUtil centralInstanceUtil; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil) { + private CampaignUtil campaignUtil; + + public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil) { this.mdmsUtil = mdmsUtil; this.mdmsV2Util = mdmsV2Util; this.planConfigRepository = planConfigRepository; this.commonUtil = commonUtil; this.centralInstanceUtil = centralInstanceUtil; + this.campaignUtil = campaignUtil; } /** @@ -53,6 +58,7 @@ public void validateCreate(PlanConfigurationRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); @@ -84,6 +90,19 @@ public void validateCreate(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + } + + /** + * This method validates if the campaign id provided in the request exists + * + * @param campaignResponse The campaign details response from project factory + */ + private void validateCampaignId(CampaignResponse campaignResponse) { + if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { + throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); + } } /** @@ -371,6 +390,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); // Validate the existence of the plan configuration in the request validatePlanConfigExistence(request); @@ -407,6 +427,9 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); + + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); } /** diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 07f78d98cd5..6081a6eb864 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -68,7 +68,7 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { // Validate role of employee against HRMS validateRoleAgainstHRMS(planEmployeeAssignment, employeeResponse); - // Validate + // Validate if role of employee is a conflicting role validateRoleConflict(planEmployeeAssignment); // Validate campaign id and employee jurisdiction From 3bbeaaa4fdd8ef1b2b40d950f443e8a8c9745c9b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 14:17:37 +0530 Subject: [PATCH 075/351] added plan facility migration script --- ...0240923113045__plan_facility_create_ddl.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql new file mode 100644 index 00000000000..f0d64025b62 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql @@ -0,0 +1,17 @@ +-- Table: plan_facility_linkage +CREATE TABLE plan_facility_linkage ( + id varchar(64), + tenant_id varchar(64), + plan_configuration_id varchar(64), + facility_id varchar(64), + residing_boundary varchar(64), + service_boundaries varchar(2048), + additional_details JSONB, + active boolean, + created_by varchar(64), + created_time bigint, + last_modified_by varchar(64), + last_modified_time bigint, + CONSTRAINT uk_plan_facility_linkage_id PRIMARY KEY (id), + FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id) +); \ No newline at end of file From d3a80c7a0bde6cb91c249720d3e91788e14fd8d6 Mon Sep 17 00:00:00 2001 From: Saloni-eGov Date: Mon, 30 Sep 2024 14:40:06 +0530 Subject: [PATCH 076/351] Added update API related changes --- .../repository/impl/PlanFacilityRepositoryImpl.java | 4 +++- .../java/digit/service/PlanFacilityService.java | 13 ++++++++----- .../src/main/java/digit/util/CampaignUtil.java | 11 +++++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 1192f8a504c..4edccdec199 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -7,11 +7,13 @@ import digit.repository.rowmapper.PlanFacilityRowMapper; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.CustomException; import org.springframework.jdbc.core.JdbcTemplate; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.List; +import static digit.config.ServiceConstants.*; @Repository @Slf4j @@ -73,7 +75,7 @@ public void update(PlanFacilityRequest planFacilityRequest) { producer.push(config.getPlanFacilityUpdateTopic(), planFacilityRequest); log.info("Successfully pushed update for plan facility: {}", planFacilityRequest.getPlanFacility().getId()); } catch (Exception e) { - log.info("Failed to push message to topic {}. Error: {}", config.getPlanFacilityUpdateTopic(), e.getMessage(), e); + throw new CustomException(FAILED_MESSAGE,config.getPlanFacilityUpdateTopic()); } } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index 72421d3a829..0d4e71a91e3 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -87,15 +87,18 @@ else if (planFacilitySearchRequest.getPlanFacilitySearchCriteria().getPlanConfig public PlanFacilityResponse updatePlanFacility(PlanFacilityRequest planFacilityRequest) { //validate plan facility request planFacilityValidator.validatePlanFacilityUpdate(planFacilityRequest); - //enrich plan facilty request + + //enrich plan facility request planFacilityEnricher.enrichPlanFacilityUpdate(planFacilityRequest); + //delegate update request to repository planFacilityRepository.update(planFacilityRequest); + //Build and return response back to controller - return PlanFacilityResponse.builder() - .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), Boolean.TRUE)). - planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())) - .build(); + return PlanFacilityResponse.builder(). + responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), Boolean.TRUE)). + planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())). + build(); } } diff --git a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java index 84e643257c7..d8879ad1113 100644 --- a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java @@ -5,7 +5,9 @@ import digit.web.models.projectFactory.*; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import static digit.config.ServiceConstants.*; import java.util.Collections; @@ -35,12 +37,17 @@ public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campai uri = uri.append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndPoint()); CampaignSearchReq campaignSearchReq = getSearchReq(requestInfo, campaignId, tenantId); - CampaignResponse campaignResponse = new CampaignResponse(); + CampaignResponse campaignResponse = null; try { campaignResponse = restTemplate.postForObject(uri.toString(), campaignSearchReq, CampaignResponse.class); } catch (Exception e) { - log.error(ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY, e); + throw new CustomException(NO_CAMPAIGN_RESPONSE_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE,NO_CAMPAIGN_RESPONSE_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); } + + if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { + throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); + } + return campaignResponse; } From 6478db1e6b0b7c7a35388081ae89618dce68b0fc Mon Sep 17 00:00:00 2001 From: Saloni-eGov Date: Mon, 30 Sep 2024 14:43:19 +0530 Subject: [PATCH 077/351] Added update API related changes --- .../validator/PlanFacilityValidator.java | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 793ccc0a6e2..d6373d9d0bf 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -53,7 +53,7 @@ public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, Plan public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); - List planConfigurations = searchPlanConfigId(planFacilityRequest.getPlanFacility().getPlanConfigurationId(),rootTenantId); + List planConfigurations = getPlanConfigurationData(planFacilityRequest.getPlanFacility().getPlanConfigurationId(),rootTenantId); // Validate plan configuration existence validatePlanConfigurationExistence(planFacilityRequest); @@ -73,14 +73,13 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe * @param planFacilityRequest */ public void validatePlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { + String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); + //validate plan facility existence validatePlanFacilityExistence(planFacilityRequest); - String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); - List planConfigurations = searchPlanConfigId(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); - if (planConfigurations == null || planConfigurations.isEmpty()) { - throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); - } + List planConfigurations = getPlanConfigurationData(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); + //validate service boundaries and residing boundaries with campaign id validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, planFacilityRequest); } @@ -97,18 +96,11 @@ private void validateCampaignDetails(String campaignId, String rootTenantId, Pla Object mdmsData = mdmsUtil.fetchMdmsData(planFacilityRequest.getRequestInfo(), rootTenantId); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planFacilityRequest.getRequestInfo(), campaignId, rootTenantId); - // Validate if campaign id exists - validateCampaignId(campaignResponse); - // validate hierarchy type for campaign String lowestHierarchy = validateHierarchyType(campaignResponse, mdmsData); // Collect all boundary code for the campaign - CampaignDetail campaignDetail = campaignResponse.getCampaignDetails().get(0); - Set boundaryCodes = campaignDetail.getBoundaries().stream() - .filter(boundary -> lowestHierarchy.equals(boundary.getType())) - .map(Boundary::getCode) - .collect(Collectors.toSet()); + Set boundaryCodes = fetchBoundaryCodes(campaignResponse.getCampaignDetails().get(0), lowestHierarchy); //validate service boundaries validateServiceBoundaries(boundaryCodes, planFacility); @@ -118,6 +110,21 @@ private void validateCampaignDetails(String campaignId, String rootTenantId, Pla } + /** + * This method returns boundary code for the campaign + * + * @param campaignDetail + * @param lowestHierarchy + */ + private Set fetchBoundaryCodes(CampaignDetail campaignDetail, String lowestHierarchy) { + Set boundaryCodes = campaignDetail.getBoundaries().stream() + .filter(boundary -> lowestHierarchy.equals(boundary.getType())) + .map(Boundary::getCode) + .collect(Collectors.toSet()); + + return boundaryCodes; + } + /** * This method validates if residing boundaries exist in campaign details * @@ -138,12 +145,11 @@ private void validateResidingBoundaries(Set boundaryCodes, PlanFacility * @param planFacility */ private void validateServiceBoundaries(Set boundaryCodes, PlanFacility planFacility) { - planFacility.getServiceBoundaries().stream() - .forEach(service -> { - if (!boundaryCodes.contains(service)) { - throw new CustomException(INVALID_SERVICE_BOUNDARY_CODE, INVALID_SERVICE_BOUNDARY_MESSAGE); - } - }); + planFacility.getServiceBoundaries().forEach(serviceBoundary -> { + if (!boundaryCodes.contains(serviceBoundary)) { + throw new CustomException(INVALID_SERVICE_BOUNDARY_CODE, INVALID_SERVICE_BOUNDARY_MESSAGE); + } + }); } /** @@ -173,18 +179,6 @@ private String validateHierarchyType(CampaignResponse campaignResponse, Object m throw new CustomException(HIERARCHY_NOT_FOUND_IN_MDMS_CODE, HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE); } - /** - * This method validates if the campaign id provided in the request exists - * - * @param campaignResponse The campaign details response from project factory - */ - private void validateCampaignId(CampaignResponse campaignResponse) { - - if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { - throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); - } - } - /** * This method validates if the plan facility id provided in the update request exists * @@ -206,12 +200,16 @@ private void validatePlanFacilityExistence(PlanFacilityRequest planFacilityReque * @param tenantId * @return */ - public List searchPlanConfigId(String planConfigurationId, String tenantId) { + public List getPlanConfigurationData(String planConfigurationId, String tenantId) { List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() .id(planConfigurationId) .tenantId(tenantId) .build()); + if (CollectionUtils.isEmpty(planConfigurations)) { + throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); + } + return planConfigurations; } From 979e4a9eafbb6c684d69165ddcdee12ddf91f436 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 15:02:27 +0530 Subject: [PATCH 078/351] removed plan facility migration script --- ...0240923113045__plan_facility_create_ddl.sql | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql deleted file mode 100644 index f0d64025b62..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql +++ /dev/null @@ -1,17 +0,0 @@ --- Table: plan_facility_linkage -CREATE TABLE plan_facility_linkage ( - id varchar(64), - tenant_id varchar(64), - plan_configuration_id varchar(64), - facility_id varchar(64), - residing_boundary varchar(64), - service_boundaries varchar(2048), - additional_details JSONB, - active boolean, - created_by varchar(64), - created_time bigint, - last_modified_by varchar(64), - last_modified_time bigint, - CONSTRAINT uk_plan_facility_linkage_id PRIMARY KEY (id), - FOREIGN KEY (plan_configuration_id) REFERENCES plan_configuration(id) -); \ No newline at end of file From 1af50fd80dc05a233a36b023763beb74b512accb Mon Sep 17 00:00:00 2001 From: Saloni-eGov Date: Mon, 30 Sep 2024 15:09:41 +0530 Subject: [PATCH 079/351] Added update API related changes --- .../src/main/java/digit/config/ServiceConstants.java | 7 ++++++- .../digit/service/enrichment/PlanFacilityEnricher.java | 6 ++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 4113007b417..5cbcfa9e5f6 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -190,11 +190,14 @@ public class ServiceConstants { public static final String INVALID_PLAN_FACILITY_ID_CODE = "INVALID_PLAN_FACILITY_ID"; public static final String INVALID_PLAN_FACILITY_ID_MESSAGE = "Plan facility id provided is invalid"; - public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from ProjectFactory service "; + public static final String PLAN_FACILITY_MESSAGE = "PlanFacilityRequest or PlanFacility cannot be null"; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; + public static final String NO_CAMPAIGN_RESPONSE_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_RESPONSE_FOUND_FOR_GIVEN_CAMPAIGN_ID"; + public static final String NO_CAMPAIGN_RESPONSE_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign response found for provided campaign id."; + public static final String INVALID_SERVICE_BOUNDARY_CODE = "INVALID_SERVICE_BOUNDARY"; public static final String INVALID_SERVICE_BOUNDARY_MESSAGE = "The provided service boundary is invalid"; @@ -204,4 +207,6 @@ public class ServiceConstants { public static final String HIERARCHY_NOT_FOUND_IN_MDMS_CODE = "HIERARCHY_NOT_FOUND_IN_MDMS"; public static final String HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE = "Hierarchy key not found in mdms"; + public static final String FAILED_MESSAGE = "Failed to push message to topic"; + } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 771859d0a6c..c11839b3eea 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -7,7 +7,7 @@ import org.egov.common.utils.AuditDetailsEnrichmentUtil; import org.egov.common.utils.UUIDEnrichmentUtil; import org.springframework.stereotype.Component; - +import static digit.config.ServiceConstants.*; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @Component @@ -42,10 +42,8 @@ public void enrichPlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequ * @param planFacilityRequest The PlanFacilityRequest object contains the plan facility to be enriched. */ public void enrichPlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { - if (planFacilityRequest == null || planFacilityRequest.getPlanFacility() == null) { - throw new IllegalArgumentException("PlanFacilityRequest or PlanFacility cannot be null"); - } PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + //enrich audit details planFacility.setAuditDetails(prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.FALSE)); } From c331e7f6fb83355ccb166a0f75424253df21898c Mon Sep 17 00:00:00 2001 From: Saloni-eGov Date: Mon, 30 Sep 2024 15:11:02 +0530 Subject: [PATCH 080/351] Added update API related changes --- .../main/java/digit/service/enrichment/PlanFacilityEnricher.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index c11839b3eea..57bce010fa1 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -7,7 +7,6 @@ import org.egov.common.utils.AuditDetailsEnrichmentUtil; import org.egov.common.utils.UUIDEnrichmentUtil; import org.springframework.stereotype.Component; -import static digit.config.ServiceConstants.*; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @Component From 4faa770c8778da102d06495453b0c2875ae2d4d1 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Mon, 30 Sep 2024 15:55:52 +0530 Subject: [PATCH 081/351] provided not null condition to PlanFacility --- .../src/main/java/digit/web/models/PlanFacility.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 175aafa2dea..15312d4f104 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -33,18 +33,22 @@ public class PlanFacility { private String tenantId = null; @JsonProperty("planConfigurationId") + @NotNull @Size(max = 64) private String planConfigurationId = null; @JsonProperty("facilityId") + @NotNull @Size(max = 64) private String facilityId = null; @JsonProperty("residingBoundary") + @NotNull @Size(min = 1, max = 64) private String residingBoundary = null; @JsonProperty("serviceBoundaries") + @NotNull @Valid private List serviceBoundaries = null; From b97474cac58a5c6d3bf179ba12cb141324fa3e00 Mon Sep 17 00:00:00 2001 From: Palak Garg <86659286+palak-egov@users.noreply.github.com> Date: Mon, 30 Sep 2024 17:29:56 +0530 Subject: [PATCH 082/351] Update migrate.sh --- health-services/plan-service/src/main/resources/db/migrate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migrate.sh b/health-services/plan-service/src/main/resources/db/migrate.sh index f9d6617822c..0f00dd9153a 100644 --- a/health-services/plan-service/src/main/resources/db/migrate.sh +++ b/health-services/plan-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true repair From 335ca4636a4dfeec5b463bc7baf245113721ef12 Mon Sep 17 00:00:00 2001 From: Palak Garg <86659286+palak-egov@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:02:20 +0530 Subject: [PATCH 083/351] Update application.properties --- .../plan-service/src/main/resources/application.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 6bd89c4b0ef..72e1d638d0f 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -57,11 +57,11 @@ egov.mdms.search.endpoint=/egov-mdms-service/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search #facility urls -egov.facility.host=https://unified-dev.digit.org +egov.facility.host=http://facility.health:8080 egov.facility.search.endpoint=/facility/v1/_search #project factory urls -egov.project.factory.host=https://unified-dev.digit.org +egov.project.factory.host=http://project-factory.health:8080 egov.project.factory.search.endpoint=/project-factory/v1/project-type/search # Pagination config @@ -69,4 +69,4 @@ plan.default.offset=0 plan.default.limit=10 resource.config.consumer.plan.create.topic=resource-microplan-create-topic -resource.update.plan.config.consumer.topic=resource-plan-config-update-topic \ No newline at end of file +resource.update.plan.config.consumer.topic=resource-plan-config-update-topic From b7103a14003c3fd4adb13f67a70e3a43bae7e01a Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 19:43:36 +0530 Subject: [PATCH 084/351] modified search query --- .../querybuilder/PlanConfigQueryBuilder.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 6d1c3cd6a3b..73d6c3c3d0d 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -162,22 +162,21 @@ private String getPaginatedQuery(String query, PlanConfigurationSearchCriteria p return paginatedQuery.toString(); } - public void addActiveWhereClause(StringBuilder builder, List preparedStmtList) - { + public void addActiveWhereClause(StringBuilder builder, List preparedStmtList) { addClauseIfRequired(preparedStmtList, builder); - builder.append(" pcf.active = ?"); + builder.append(" ( pcf.active = ? OR pcf.active IS NULL )"); preparedStmtList.add(Boolean.TRUE); addClauseIfRequired(preparedStmtList, builder); - builder.append(" pca.active = ?"); + builder.append(" ( pca.active = ? OR pca.active IS NULL )"); preparedStmtList.add(Boolean.TRUE); addClauseIfRequired(preparedStmtList, builder); - builder.append(" pco.active = ?"); + builder.append(" ( pco.active = ? OR pco.active IS NULL )"); preparedStmtList.add(Boolean.TRUE); addClauseIfRequired(preparedStmtList, builder); - builder.append(" pcm.active = ?"); + builder.append(" ( pcm.active = ? OR pcm.active IS NULL )"); preparedStmtList.add(Boolean.TRUE); } From f7efed54084d2122acda4a775522aad171830844 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 19:51:56 +0530 Subject: [PATCH 085/351] modified search query --- .../digit/service/validator/PlanConfigurationValidator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 6427534f32d..65f45534032 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -577,8 +577,7 @@ public void validateUserInfo(PlanConfigurationRequest request) { * @param request plan configuration request * @param mdmsV2Data mdms v2 data object */ - public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest - request, List mdmsV2Data) { + public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, List mdmsV2Data) { List vehicleIdsLinkedWithPlanConfig = commonUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); if (!CollectionUtils.isEmpty(vehicleIdsLinkedWithPlanConfig)) { From f02236df185191a2efb79fa5772be1d6d3d742b5 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 20:03:50 +0530 Subject: [PATCH 086/351] validation --- .../service/validator/PlanEmployeeAssignmentValidator.java | 1 + .../src/main/java/digit/web/models/PlanEmployeeAssignment.java | 2 ++ .../main/java/digit/web/models/PlanEmployeeAssignmentDTO.java | 2 ++ 3 files changed, 5 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 6081a6eb864..561c1650275 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -248,6 +248,7 @@ private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeA // Validates the existence of plan employee assignment List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(planEmployeeAssignment.getTenantId()) .id(planEmployeeAssignment.getId()) .build()); diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java index 568ea1b82b4..5388ee36648 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import org.egov.common.contract.models.AuditDetails; @@ -47,6 +48,7 @@ public class PlanEmployeeAssignment { @JsonProperty("jurisdiction") @Valid + @NotEmpty private List jurisdiction = null; @JsonProperty("additionalDetails") diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java index 9c57bbf4554..346ee066663 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import org.egov.common.contract.models.AuditDetails; @@ -47,6 +48,7 @@ public class PlanEmployeeAssignmentDTO { @JsonProperty("jurisdiction") @Valid + @NotEmpty private String jurisdiction = null; @JsonProperty("additionalDetails") From d6efce2df68172998f5e055a4a23ca5d148e08a8 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 30 Sep 2024 20:42:38 +0530 Subject: [PATCH 087/351] validation --- .../java/digit/config/ServiceConstants.java | 8 ++-- .../PlanEmployeeAssignmentValidator.java | 42 +++++++++++++++---- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index fd56e1ab0f8..f7522d91ca8 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -65,9 +65,8 @@ public class ServiceConstants { public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE = "NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT"; public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE = "Invalid or incorrect TenantId. No mdms data found for provided Tenant."; - public static final String NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_CODE = "NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID"; - public static final String NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE = "Invalid or incorrect employee id. No hrms data found for provided employee id."; - + public static final String INVALID_EMPLOYEE_ID_CODE = "INVALID_EMPLOYEE_ID"; + public static final String INVALID_EMPLOYEE_ID_MESSAGE = "Invalid or incorrect employee id."; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; @@ -86,6 +85,9 @@ public class ServiceConstants { public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE = "INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID"; public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE = "Plan employee assignment id provided is invalid"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE = "Plan employee assignment id cannot be empty"; + public static final String METRIC_NOT_FOUND_IN_MDMS_CODE = "METRIC_NOT_FOUND_IN_MDMS"; public static final String METRIC_NOT_FOUND_IN_MDMS_MESSAGE = "Metric key not found in MDMS"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 561c1650275..6c01b28ba49 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -16,7 +16,7 @@ import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; +import org.springframework.util.*; import java.util.*; import java.util.stream.Collectors; @@ -178,7 +178,7 @@ private void validateCampaignId(CampaignResponse campaignResponse) { */ private void validateEmployeeAgainstHRMS(EmployeeResponse employeeResponse) { if (CollectionUtils.isEmpty(employeeResponse.getEmployees())) { - throw new CustomException(NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_CODE, NO_HRMS_DATA_FOUND_FOR_GIVEN_EMPLOYEE_ID_MESSAGE); + throw new CustomException(INVALID_EMPLOYEE_ID_CODE, INVALID_EMPLOYEE_ID_MESSAGE); } } @@ -226,25 +226,47 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); // Validate if Plan employee assignment exists - validatePlanEmployeeAssignment(planEmployeeAssignment); + PlanEmployeeAssignment existingPlanEmployeeAssignment = validatePlanEmployeeAssignment(planEmployeeAssignment); - // Validate if plan config id exists - validatePlanConfigId(planConfigurations); - - // Validate if employee exists against HRMS - validateEmployeeAgainstHRMS(employeeResponse); + // Validates if planConfig id and employee id provided in request is same in the existing record + validateRequestAgainstExistingRecord(planEmployeeAssignment, existingPlanEmployeeAssignment); // Validate campaign id and employee jurisdiction validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); + // Validate role of employee against HRMS + validateRoleAgainstHRMS(planEmployeeAssignment, employeeResponse); + } + + /** + * This method validates plan config id and employee id provided in the update request is same as in the existing record + * + * @param planEmployeeAssignment the plan employee assignment from the update request + * @param existingPlanEmployeeAssignment the plan employee assignment existing in the db + */ + private void validateRequestAgainstExistingRecord(PlanEmployeeAssignment planEmployeeAssignment, PlanEmployeeAssignment existingPlanEmployeeAssignment) { + + // Validates plan config id against existing record + if (!Objects.equals(planEmployeeAssignment.getPlanConfigurationId(), existingPlanEmployeeAssignment.getPlanConfigurationId())) { + throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); + } + + // Validates employee id against existing record + if (!Objects.equals(planEmployeeAssignment.getEmployeeId(), existingPlanEmployeeAssignment.getEmployeeId())) { + throw new CustomException(INVALID_EMPLOYEE_ID_CODE, INVALID_EMPLOYEE_ID_MESSAGE); + } } /** * This method validates if the plan employee assignment id provided in the update request exists * * @param planEmployeeAssignment The plan employee assignment details from the request + * @return the plan employee assignment from db which is to be updated */ - private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeAssignment) { + private PlanEmployeeAssignment validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeAssignment) { + if (ObjectUtils.isEmpty(planEmployeeAssignment.getId())) { + throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE); + } // Validates the existence of plan employee assignment List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() @@ -255,5 +277,7 @@ private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeA if (CollectionUtils.isEmpty(planEmployeeAssignments)) { throw new CustomException(INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE, INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE); } + + return planEmployeeAssignments.get(0); } } From 0c5454bf7fbdd30ef69243cb1a40afa967d2c500 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 1 Oct 2024 11:50:21 +0530 Subject: [PATCH 088/351] added comments --- .../java/digit/config/ServiceConstants.java | 2 +- .../PlanEmployeeAssignmentQueryBuilder.java | 2 +- .../java/digit/service/PlanValidator.java | 56 +++++++++++-------- .../validator/PlanConfigurationValidator.java | 2 +- .../main/java/digit/util/CampaignUtil.java | 28 +++++++++- .../src/main/java/digit/util/HrmsUtil.java | 30 +++++++--- 6 files changed, 85 insertions(+), 35 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index f7522d91ca8..21c3e7090f3 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -60,7 +60,7 @@ public class ServiceConstants { public static final String TENANT_ID_EMPTY_MESSAGE = "Tenant Id cannot be empty, TenantId should be present"; public static final String PLAN_CONFIG_ID_EMPTY_CODE = "PLAN_CONFIG_ID_EMPTY"; - public static final String PLAN_CONFIG_ID_EMPTY_MESSAGE = "Plan config Id cannot be empty, PlanConfigID should be present"; + public static final String PLAN_CONFIG_ID_EMPTY_MESSAGE = "Plan config Id cannot be empty."; public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE = "NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT"; public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE = "Invalid or incorrect TenantId. No mdms data found for provided Tenant."; diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 5f9c49982f6..dab17739c42 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -40,7 +40,7 @@ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteri * * @param searchCriteria The criteria used for filtering PlanEmployeeAssignment objects. * @param preparedStmtList A list to store prepared statement parameters. - * @return + * @return A SQL query string for searching planEmployeeAssignment */ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { StringBuilder builder = new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 859c2917121..dc976fcecec 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -45,6 +45,7 @@ public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository /** * This method performs business validations on plan create requests + * * @param request */ public void validatePlanCreate(PlanRequest request) { @@ -81,7 +82,7 @@ public void validatePlanCreate(PlanRequest request) { } /** - * This method validates if the campaign id provided in the request exists + * Validates campaign ID from request against project factory * * @param campaignResponse The campaign details response from project factory */ @@ -93,6 +94,7 @@ private void validateCampaignId(CampaignResponse campaignResponse) { /** * This validation method validates if the dependent activities are valid and if they form a cycle + * * @param request */ private void validateActivityDependencies(PlanRequest request) { @@ -105,6 +107,7 @@ private void validateActivityDependencies(PlanRequest request) { /** * This method checks if the activity dependencies form a cycle + * * @param request */ private void checkForCycleInActivityDependencies(PlanRequest request) { @@ -114,7 +117,7 @@ private void checkForCycleInActivityDependencies(PlanRequest request) { activityCodeVsDependenciesMap.keySet().forEach(activityCode -> { activityCodeVsDependenciesMap.get(activityCode).forEach(dependency -> { - if(activityCodeVsDependenciesMap.get(dependency).contains(activityCode)) + if (activityCodeVsDependenciesMap.get(dependency).contains(activityCode)) throw new CustomException(CYCLIC_ACTIVITY_DEPENDENCY_CODE, CYCLIC_ACTIVITY_DEPENDENCY_MESSAGE); }); }); @@ -122,6 +125,7 @@ private void checkForCycleInActivityDependencies(PlanRequest request) { /** * This method validates if the dependent activity codes are valid + * * @param request */ private void validateDependentActivityCodes(PlanRequest request) { @@ -132,9 +136,9 @@ private void validateDependentActivityCodes(PlanRequest request) { // Check if the dependent activity codes are valid request.getPlan().getActivities().forEach(activity -> { - if(!CollectionUtils.isEmpty(activity.getDependencies())) { + if (!CollectionUtils.isEmpty(activity.getDependencies())) { activity.getDependencies().forEach(dependency -> { - if(!activityCodes.contains(dependency)) + if (!activityCodes.contains(dependency)) throw new CustomException(INVALID_ACTIVITY_DEPENDENCY_CODE, INVALID_ACTIVITY_DEPENDENCY_MESSAGE); }); } @@ -144,11 +148,12 @@ private void validateDependentActivityCodes(PlanRequest request) { /** * This method validates the activities provided in the request + * * @param request */ private void validateActivities(PlanRequest request) { // Collect all activity codes - if(request.getPlan().getActivities() == null) + if (request.getPlan().getActivities() == null) throw new CustomException(ACTIVITIES_CANNOT_BE_NULL_CODE, ACTIVITIES_CANNOT_BE_NULL_MESSAGE); Set activityCodes = request.getPlan().getActivities().stream() @@ -156,26 +161,26 @@ private void validateActivities(PlanRequest request) { .collect(Collectors.toSet()); // If activity codes are not unique, throw an exception - if(activityCodes.size() != request.getPlan().getActivities().size()) { + if (activityCodes.size() != request.getPlan().getActivities().size()) { throw new CustomException(DUPLICATE_ACTIVITY_CODES, DUPLICATE_ACTIVITY_CODES_MESSAGE); } // If execution plan id is not provided, providing activities is mandatory - if(ObjectUtils.isEmpty(request.getPlan().getCampaignId()) + if (ObjectUtils.isEmpty(request.getPlan().getCampaignId()) && CollectionUtils.isEmpty(request.getPlan().getActivities())) { throw new CustomException(PLAN_ACTIVITIES_MANDATORY_CODE, PLAN_ACTIVITIES_MANDATORY_MESSAGE); } // If execution plan id is provided, providing activities is not allowed - if(!ObjectUtils.isEmpty(request.getPlan().getCampaignId()) + if (!ObjectUtils.isEmpty(request.getPlan().getCampaignId()) && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { throw new CustomException(PLAN_ACTIVITIES_NOT_ALLOWED_CODE, PLAN_ACTIVITIES_NOT_ALLOWED_MESSAGE); } // Validate activity dates - if(!CollectionUtils.isEmpty(request.getPlan().getActivities())) { + if (!CollectionUtils.isEmpty(request.getPlan().getActivities())) { request.getPlan().getActivities().forEach(activity -> { - if(activity.getPlannedEndDate() < activity.getPlannedStartDate()) + if (activity.getPlannedEndDate() < activity.getPlannedStartDate()) throw new CustomException(INVALID_ACTIVITY_DATES_CODE, INVALID_ACTIVITY_DATES_MESSAGE); }); } @@ -183,36 +188,37 @@ private void validateActivities(PlanRequest request) { /** * This method validates if the plan configuration id provided in the request exists + * * @param request */ private void validatePlanConfigurationExistence(PlanRequest request) { // If plan id provided is invalid, throw an exception - if(!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && - CollectionUtils.isEmpty(commonUtil.searchPlanConfigId(request.getPlan().getPlanConfigurationId(), request.getPlan().getTenantId()))) - { + if (!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && + CollectionUtils.isEmpty(commonUtil.searchPlanConfigId(request.getPlan().getPlanConfigurationId(), request.getPlan().getTenantId()))) { throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); } } /** * This method validates the resources provided in the request + * * @param request */ private void validateResources(PlanRequest request) { // If plan configuration id is not provided, providing resources is mandatory - if(ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) + if (ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && CollectionUtils.isEmpty(request.getPlan().getResources())) { throw new CustomException(PLAN_RESOURCES_MANDATORY_CODE, PLAN_RESOURCES_MANDATORY_MESSAGE); } // If plan configuration id is provided, providing resources is not allowed - if(!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) + if (!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && !CollectionUtils.isEmpty(request.getPlan().getResources())) { throw new CustomException(PLAN_RESOURCES_NOT_ALLOWED_CODE, PLAN_RESOURCES_NOT_ALLOWED_MESSAGE); } // Validate resource type existence - if(!CollectionUtils.isEmpty(request.getPlan().getResources())) { + if (!CollectionUtils.isEmpty(request.getPlan().getResources())) { request.getPlan().getResources().forEach(resource -> { // Validate resource type existence }); @@ -221,10 +227,11 @@ private void validateResources(PlanRequest request) { /** * This method validates the linkage between resources and activities + * * @param request */ private void validateResourceActivityLinkage(PlanRequest request) { - if(ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) + if (ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { // Collect all activity codes Set activityCodes = request.getPlan().getActivities().stream() @@ -233,7 +240,7 @@ private void validateResourceActivityLinkage(PlanRequest request) { // Validate resource-activity linkage request.getPlan().getResources().forEach(resource -> { - if(!activityCodes.contains(resource.getActivityCode())) + if (!activityCodes.contains(resource.getActivityCode())) throw new CustomException(INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE, INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE); }); } @@ -241,10 +248,11 @@ private void validateResourceActivityLinkage(PlanRequest request) { /** * This method validates the linkage between targets and activities + * * @param request */ private void validateTargetActivityLinkage(PlanRequest request) { - if(!CollectionUtils.isEmpty(request.getPlan().getActivities())) { + if (!CollectionUtils.isEmpty(request.getPlan().getActivities())) { // Collect all activity codes Set activityCodes = request.getPlan().getActivities().stream() .map(Activity::getCode) @@ -252,7 +260,7 @@ private void validateTargetActivityLinkage(PlanRequest request) { // Validate target-activity linkage request.getPlan().getTargets().forEach(target -> { - if(!activityCodes.contains(target.getActivityCode())) + if (!activityCodes.contains(target.getActivityCode())) throw new CustomException(INVALID_TARGET_ACTIVITY_LINKAGE_CODE, INVALID_TARGET_ACTIVITY_LINKAGE_MESSAGE); }); } @@ -260,6 +268,7 @@ private void validateTargetActivityLinkage(PlanRequest request) { /** * This method performs business validations on plan update requests + * * @param request */ public void validatePlanUpdate(PlanRequest request) { @@ -364,11 +373,12 @@ private void validateActivitiesUuidUniqueness(PlanRequest request) { /** * This method validates if the plan id provided in the update request exists + * * @param request */ private void validatePlanExistence(PlanRequest request) { // If plan id provided is invalid, throw an exception - if(CollectionUtils.isEmpty(planRepository.search(PlanSearchCriteria.builder() + if (CollectionUtils.isEmpty(planRepository.search(PlanSearchCriteria.builder() .ids(Collections.singleton(request.getPlan().getId())) .build()))) { throw new CustomException(INVALID_PLAN_ID_CODE, INVALID_PLAN_ID_MESSAGE); @@ -381,7 +391,7 @@ private void validatePlanExistence(PlanRequest request) { * This method checks each target metric in the plan to ensure it exists in the MDMS data. * If a metric is not found, it throws a CustomException. * - * @param request the PlanRequest containing the plan and target metrics to be validated + * @param request the PlanRequest containing the plan and target metrics to be validated * @param mdmsData the MDMS data against which the target metrics are validated * @throws CustomException if there is an error reading the MDMS data using JsonPath * or if any target metric is not found in the MDMS data @@ -412,7 +422,7 @@ public void validateTargetMetrics(PlanRequest request, Object mdmsData) { * This method extracts metric details from the plan and checks if each metric unit * is present in the MDMS data. If a metric unit is not found, it throws a CustomException. * - * @param request the PlanRequest containing the plan and metric details to be validated + * @param request the PlanRequest containing the plan and metric details to be validated * @param mdmsData the MDMS data against which the metric units are validated * @throws CustomException if there is an error reading the MDMS data using JsonPath * or if any metric unit is not found in the MDMS data diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 5dd5815bdb7..c49517e11b1 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -95,7 +95,7 @@ public void validateCreate(PlanConfigurationRequest request) { } /** - * This method validates if the campaign id provided in the request exists + * Validates campaign ID from request against project factory * * @param campaignResponse The campaign details response from project factory */ diff --git a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java index b7044e841a7..25e4ca401d9 100644 --- a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java @@ -24,9 +24,15 @@ public CampaignUtil(RestTemplate restTemplate, Configuration configs) { this.configs = configs; } + /** + * This method fetches data from project factory for provided campaignId + * + * @param requestInfo request info from the request + * @param campaignId campaign id provided in the request + * @param tenantId tenant id from the request + */ public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campaignId, String tenantId) { - StringBuilder uri = new StringBuilder(); - uri = uri.append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndPoint()); + StringBuilder uri = getProjectFactoryUri(); CampaignSearchReq campaignSearchReq = getSearchReq(requestInfo, campaignId, tenantId); CampaignResponse campaignResponse = new CampaignResponse(); @@ -39,6 +45,24 @@ public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campai return campaignResponse; } + /** + * This method create the uri for project factory + * + * @return uri for project factory search + */ + private StringBuilder getProjectFactoryUri() { + StringBuilder uri = new StringBuilder(); + return uri.append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndPoint()); + } + + /** + * This method creates the search request body for project factory search + * + * @param requestInfo Request Info from the request body + * @param campaignId Campaign id for the provided plan employee assignment request + * @param tenantId Tenant id from the plan employee assignment request + * @return Search request body for project factory search + */ private CampaignSearchReq getSearchReq(RequestInfo requestInfo, String campaignId, String tenantId) { Pagination pagination = Pagination.builder().limit(configs.getDefaultLimit()).offset(configs.getDefaultOffset()).build(); CampaignSearchCriteria searchCriteria = CampaignSearchCriteria.builder() diff --git a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java index 252ab35c82c..efe12295630 100644 --- a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java @@ -37,15 +37,11 @@ public HrmsUtil(RestTemplate restTemplate, Configuration configs) { */ public EmployeeResponse fetchHrmsData(RequestInfo requestInfo, String employeeId, String tenantId) { - StringBuilder uri = new StringBuilder(); - uri.append(configs.getHrmsHost()).append(configs.getHrmsEndPoint()).append("?limit={limit}&tenantId={tenantId}&offset={offset}&ids={employeeId}"); - + // Create HRMS uri Map uriParameters = new HashMap<>(); - uriParameters.put("limit", configs.getDefaultLimit().toString()); - uriParameters.put("tenantId", tenantId); - uriParameters.put("offset", configs.getDefaultOffset().toString()); - uriParameters.put("employeeId", employeeId); + StringBuilder uri = getHrmsUri(uriParameters, tenantId, employeeId); + // Create request body RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); EmployeeResponse employeeResponse = new EmployeeResponse(); @@ -58,5 +54,25 @@ public EmployeeResponse fetchHrmsData(RequestInfo requestInfo, String employeeId return employeeResponse; } + /** + * This method creates HRMS uri with query parameters + * + * @param uriParameters map that stores values corresponding to the placeholder in uri + * @param tenantId the tenant id from plan employee assignment request + * @param employeeId the employee id from plan employee assignment request + * @return a complete HRMS uri + */ + private StringBuilder getHrmsUri(Map uriParameters, String tenantId, String employeeId) { + StringBuilder uri = new StringBuilder(); + uri.append(configs.getHrmsHost()).append(configs.getHrmsEndPoint()).append("?limit={limit}&tenantId={tenantId}&offset={offset}&ids={employeeId}"); + + uriParameters.put("limit", configs.getDefaultLimit().toString()); + uriParameters.put("tenantId", tenantId); + uriParameters.put("offset", configs.getDefaultOffset().toString()); + uriParameters.put("employeeId", employeeId); + + return uri; + } + } From fad64358ab1c4823e7d8558c3c823c72541b5255 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 1 Oct 2024 15:11:17 +0530 Subject: [PATCH 089/351] added status --- .../src/main/java/digit/web/models/PlanConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index 135f4991a88..44191134a95 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -87,7 +87,8 @@ public class PlanConfiguration { public enum StatusEnum { DRAFT , GENERATED, - INVALID_DATA + INVALID_DATA, + SETUP_COMPLETED } } From 7f4db75c3084a5e9842b146e01969b4b7e33ef9b Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Tue, 1 Oct 2024 16:23:22 +0530 Subject: [PATCH 090/351] review changes and converting serviceBoundary configuration --- .../impl/PlanFacilityRepositoryImpl.java | 53 ++++++++++++--- .../digit/service/PlanFacilityService.java | 15 +++-- .../enrichment/PlanFacilityEnricher.java | 9 +-- .../validator/PlanFacilityValidator.java | 63 +++++++----------- .../main/java/digit/util/CampaignUtil.java | 30 +++++++-- .../main/java/digit/util/FacilityUtil.java | 18 ++++-- .../controllers/PlanFacilityController.java | 3 +- .../java/digit/web/models/PlanFacility.java | 4 +- .../digit/web/models/PlanFacilityDTO.java | 64 +++++++++++++++++++ .../digit/web/models/PlanFacilityRequest.java | 5 +- .../web/models/PlanFacilityRequestDTO.java | 33 ++++++++++ .../web/models/facility/AdditionalFields.java | 25 ++++++++ .../digit/web/models/facility/Address.java | 62 ++++++++++++++++++ .../digit/web/models/facility/Facility.java | 6 +- .../java/digit/web/models/facility/Field.java | 20 ++++++ .../digit/web/models/facility/Locality.java | 33 ++++++++++ .../src/main/resources/application.properties | 12 ++-- ...0241001113045__plan_facility_alter_ddl.sql | 2 + 18 files changed, 374 insertions(+), 83 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequestDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/AdditionalFields.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Address.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Field.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Locality.java create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 4edccdec199..f999a943462 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -1,5 +1,6 @@ package digit.repository.impl; +import com.fasterxml.jackson.databind.ObjectMapper; import digit.config.Configuration; import digit.kafka.Producer; import digit.repository.PlanFacilityRepository; @@ -9,7 +10,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.tracer.model.CustomException; import org.springframework.jdbc.core.JdbcTemplate; -import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.List; @@ -29,12 +29,15 @@ public class PlanFacilityRepositoryImpl implements PlanFacilityRepository { private Configuration config; - public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, PlanFacilityQueryBuilder planFacilityQueryBuilder, PlanFacilityRowMapper planFacilityRowMapper, Configuration config) { + private ObjectMapper mapper; + + public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, PlanFacilityQueryBuilder planFacilityQueryBuilder, PlanFacilityRowMapper planFacilityRowMapper, Configuration config, ObjectMapper mapper) { this.producer = producer; this.jdbcTemplate = jdbcTemplate; this.planFacilityQueryBuilder = planFacilityQueryBuilder; this.planFacilityRowMapper = planFacilityRowMapper; this.config = config; + this.mapper = mapper; } /** @@ -43,14 +46,48 @@ public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, */ @Override public void create(PlanFacilityRequest planFacilityRequest) { - try { - producer.push(config.getPlanFacilityCreateTopic(), planFacilityRequest); - } catch (Exception e) { - log.info("Pushing message to topic " + config.getPlanFacilityCreateTopic() + " failed.", e); - throw new CustomException("KAFKA_PUSH_FAILED", "Failed to push event to Kafka, operation could not be completed."); - } + // Convert the incoming PlanFacilityRequest to PlanFacilityRequestDTO + PlanFacilityRequestDTO requestDTO = convertToDTO(planFacilityRequest); + + // Push the requestDTO to the producer for processing + producer.push(config.getPlanFacilityCreateTopic(), requestDTO); } + public PlanFacilityRequestDTO convertToDTO(PlanFacilityRequest planFacilityRequest) { + PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + + // Create a new PlanFacilityDTO + PlanFacilityDTO planFacilityDTO = PlanFacilityDTO.builder() + .id(planFacility.getId()) + .tenantId(planFacility.getTenantId()) + .planConfigurationId(planFacility.getPlanConfigurationId()) + .facilityId(planFacility.getFacilityId()) + .residingBoundary(planFacility.getResidingBoundary()) + .serviceBoundaries(convertArrayToString(planFacility.getServiceBoundaries())) + .additionalDetails(planFacility.getAdditionalDetails()) + .active(planFacility.getActive()) + .auditDetails(planFacility.getAuditDetails()) + .build(); + + // Return the complete PlanFacilityRequestDTO + return PlanFacilityRequestDTO.builder() + .requestInfo(planFacilityRequest.getRequestInfo()) + .planFacilityDTO(planFacilityDTO) + .build(); + } + + /** + * This is a helper function to convert an array of string to comma separated string + * + * @param stringList Array of string to be converted + * @return a string + */ + private String convertArrayToString(List stringList) { + return String.join(", ", stringList); + } + + + /** * This method searches for plans based on the search criteria. * diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index 0d4e71a91e3..b393a4946a8 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -9,7 +9,6 @@ import digit.web.models.PlanFacilityResponse; import org.egov.common.utils.ResponseInfoUtil; import digit.web.models.PlanFacilitySearchRequest; -import org.egov.common.utils.ResponseInfoUtil; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; @@ -17,10 +16,10 @@ @Service public class PlanFacilityService { - private final PlanFacilityValidator planFacilityValidator; - private final ResponseInfoFactory responseInfoFactory; - private final PlanFacilityEnricher planFacilityEnricher; - private final PlanFacilityRepository planFacilityRepository; + private PlanFacilityValidator planFacilityValidator; + private ResponseInfoFactory responseInfoFactory; + private PlanFacilityEnricher planFacilityEnricher; + private PlanFacilityRepository planFacilityRepository; public PlanFacilityService(PlanFacilityValidator planFacilityValidator, ResponseInfoFactory responseInfoFactory, PlanFacilityEnricher planFacilityEnricher, PlanFacilityRepository planFacilityRepository) { this.planFacilityValidator = planFacilityValidator; @@ -46,8 +45,10 @@ public PlanFacilityResponse createPlanFacility(PlanFacilityRequest planFacilityR planFacilityRepository.create(planFacilityRequest); // Build and return response back to controller - PlanFacilityResponse response = PlanFacilityResponse.builder().planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())).responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), true)).build(); - return response; + return PlanFacilityResponse.builder() + .planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), Boolean.TRUE)) + .build(); } /** diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 57bce010fa1..42bbc00b85d 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -19,19 +19,16 @@ public class PlanFacilityEnricher { * @param planFacilityRequest */ public void enrichPlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { - if (planFacilityRequest.getPlanFacility() == null) { - throw new IllegalArgumentException("Plan Facility details are missing in the request."); - } - // Generate id for plan facility UUIDEnrichmentUtil.enrichRandomUuid(planFacilityRequest.getPlanFacility(), "id"); // Enrich audit details planFacilityRequest.getPlanFacility().setAuditDetails(AuditDetailsEnrichmentUtil - .prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.TRUE)); + .prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), + planFacilityRequest.getRequestInfo(), Boolean.TRUE)); //Set Active - planFacilityRequest.getPlanFacility().setActive(true); + planFacilityRequest.getPlanFacility().setActive(Boolean.TRUE); } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index d6373d9d0bf..cdaa3a58a23 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -9,9 +9,7 @@ import digit.web.models.projectFactory.CampaignDetail; import digit.web.models.projectFactory.CampaignResponse; import jakarta.validation.Valid; -import jakarta.validation.constraints.Size; import lombok.extern.slf4j.Slf4j; -import org.egov.common.contract.request.RequestInfo; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -31,16 +29,14 @@ public class PlanFacilityValidator { private MultiStateInstanceUtil centralInstanceUtil; private MdmsUtil mdmsUtil; private FacilityUtil facilityUtil; - private CommonUtil commonUtil; - public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil, CommonUtil commonUtil) { + public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil) { this.planFacilityRepository = planFacilityRepository; this.planConfigurationRepository = planConfigurationRepository; this.campaignUtil = campaignUtil; this.centralInstanceUtil = centralInstanceUtil; this.mdmsUtil = mdmsUtil; this.facilityUtil = facilityUtil; - this.commonUtil = commonUtil; } /** @@ -51,18 +47,17 @@ public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, Plan * @param planFacilityRequest */ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { + // Retrieve the root-level tenant ID (state-level) based on the facility's tenant ID String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); - List planConfigurations = getPlanConfigurationData(planFacilityRequest.getPlanFacility().getPlanConfigurationId(),rootTenantId); - - // Validate plan configuration existence - validatePlanConfigurationExistence(planFacilityRequest); + // Validate PlanConfiguration Existence and fetch the plan configuration details using the PlanConfigurationId + List planConfigurations = fetchPlanConfigurationById(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); // Validate facility existence validateFacilityExistence(planFacilityRequest); - //validate service boundaries and residing boundaries with campaign id - validateCampaignDetails(planConfigurations.get(0).getCampaignId(),rootTenantId,planFacilityRequest); + // Validate service boundaries and residing boundaries with campaign id + validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, planFacilityRequest); } /** @@ -78,7 +73,7 @@ public void validatePlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) //validate plan facility existence validatePlanFacilityExistence(planFacilityRequest); - List planConfigurations = getPlanConfigurationData(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); + List planConfigurations = fetchPlanConfigurationById(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); //validate service boundaries and residing boundaries with campaign id validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, planFacilityRequest); @@ -96,18 +91,18 @@ private void validateCampaignDetails(String campaignId, String rootTenantId, Pla Object mdmsData = mdmsUtil.fetchMdmsData(planFacilityRequest.getRequestInfo(), rootTenantId); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planFacilityRequest.getRequestInfo(), campaignId, rootTenantId); - // validate hierarchy type for campaign + // Validate hierarchy type for campaign String lowestHierarchy = validateHierarchyType(campaignResponse, mdmsData); // Collect all boundary code for the campaign Set boundaryCodes = fetchBoundaryCodes(campaignResponse.getCampaignDetails().get(0), lowestHierarchy); - //validate service boundaries - validateServiceBoundaries(boundaryCodes, planFacility); - - //validate residing boundaries + // Validate residing boundaries validateResidingBoundaries(boundaryCodes, planFacility); + // Validate service boundaries + validateServiceBoundaries(boundaryCodes, planFacility); + } /** @@ -159,19 +154,23 @@ private void validateServiceBoundaries(Set boundaryCodes, PlanFacility p * @param mdmsData */ private String validateHierarchyType(CampaignResponse campaignResponse, Object mdmsData) { + // Get the hierarchy type from the campaign response String hierarchyType = campaignResponse.getCampaignDetails().get(0).getHierarchyType(); + + // Define the JSON path to fetch hierarchy configurations from MDMS data final String jsonPathForHierarchy = JSON_ROOT_PATH + MDMS_HCM_ADMIN_CONSOLE + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + "[*]"; List> hierarchyConfigList = null; - System.out.println("Jsonpath for hierarchy config -> " + jsonPathForHierarchy); try { hierarchyConfigList = JsonPath.read(mdmsData, jsonPathForHierarchy); } catch (Exception e) { throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } + // Iterate through the hierarchy configuration list for (Map hierarchyConfig : hierarchyConfigList) { if (hierarchyType.equals(hierarchyConfig.get(MDMS_MASTER_HIERARCHY))) { + // Return the lowest hierarchy value from the configuration return (String) hierarchyConfig.get(MDMS_MASTER_LOWEST_HIERARCHY); } } @@ -200,12 +199,14 @@ private void validatePlanFacilityExistence(PlanFacilityRequest planFacilityReque * @param tenantId * @return */ - public List getPlanConfigurationData(String planConfigurationId, String tenantId) { + public List fetchPlanConfigurationById(String planConfigurationId, String tenantId) { List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() .id(planConfigurationId) .tenantId(tenantId) .build()); + log.info("planConfigurations: "+planConfigurations); + // Validate planConfiguration exists if (CollectionUtils.isEmpty(planConfigurations)) { throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); } @@ -219,32 +220,12 @@ public List getPlanConfigurationData(String planConfiguration * @param planFacilityRequest */ private void validateFacilityExistence(PlanFacilityRequest planFacilityRequest) { - String facilityId = planFacilityRequest.getPlanFacility().getFacilityId(); - String tenantId = planFacilityRequest.getPlanFacility().getTenantId(); - RequestInfo requestInfo = planFacilityRequest.getRequestInfo(); - - FacilityResponse facilityResponse = facilityUtil.fetchFacilityData(requestInfo, facilityId, tenantId); + FacilityResponse facilityResponse = facilityUtil.fetchFacilityData(planFacilityRequest); // Use ObjectUtils and CollectionUtils to handle null or empty checks if (ObjectUtils.isEmpty(facilityResponse) || CollectionUtils.isEmpty(facilityResponse.getFacilities())) { - throw new CustomException("FACILITY_NOT_FOUND", "Facility with ID " + facilityId + " not found in the system."); + throw new CustomException("FACILITY_NOT_FOUND", "Facility with ID " + planFacilityRequest.getPlanFacility().getFacilityId() + " not found in the system."); } } - - /** - * Validates if the plan configuration ID provided in the request exists. - * - * @param request The request object containing the plan configuration ID. - */ - private void validatePlanConfigurationExistence(PlanFacilityRequest request) { - // If plan configuration id provided is invalid, throw an exception - if(!ObjectUtils.isEmpty(request.getPlanFacility().getPlanConfigurationId()) && CollectionUtils.isEmpty( - planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() - .id(request.getPlanFacility().getPlanConfigurationId()) - .tenantId(request.getPlanFacility().getTenantId()) - .build()))) { - throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); - } - } } diff --git a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java index d8879ad1113..10d40314df1 100644 --- a/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java @@ -33,10 +33,11 @@ public CampaignUtil(RestTemplate restTemplate, Configuration configs) { * @param tenantId */ public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campaignId, String tenantId) { - StringBuilder uri = new StringBuilder(); - uri = uri.append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndPoint()); + // Build the URI for calling the Project Factory service + String uri = buildCampaignSearchUri(); - CampaignSearchReq campaignSearchReq = getSearchReq(requestInfo, campaignId, tenantId); + // Prepare the search request object with required campaign ID, tenant ID, and request information + CampaignSearchReq campaignSearchReq = getCampaignSearchRequest(requestInfo, campaignId, tenantId); CampaignResponse campaignResponse = null; try { campaignResponse = restTemplate.postForObject(uri.toString(), campaignSearchReq, CampaignResponse.class); @@ -44,6 +45,7 @@ public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campai throw new CustomException(NO_CAMPAIGN_RESPONSE_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE,NO_CAMPAIGN_RESPONSE_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); } + // Validate that the response contains campaign details, otherwise throw an exception if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); } @@ -51,7 +53,27 @@ public CampaignResponse fetchCampaignData(RequestInfo requestInfo, String campai return campaignResponse; } - private CampaignSearchReq getSearchReq(RequestInfo requestInfo, String campaignId, String tenantId) { + /** + * Constructs the URI for the external service to fetch campaign data. + * + * @return The complete URI as a String. + */ + private String buildCampaignSearchUri() { + return new StringBuilder() + .append(configs.getProjectFactoryHost()) + .append(configs.getProjectFactorySearchEndPoint()) + .toString(); + } + + /** + * Creates the request object for fetching campaign data. + * + * @param requestInfo Information about the request such as user details and correlation ID. + * @param campaignId The ID of the campaign to be searched. + * @param tenantId The tenant identifier (for multi-tenant support). + * @return CampaignSearchReq The request object containing the search criteria and request info. + */ + private CampaignSearchReq getCampaignSearchRequest(RequestInfo requestInfo, String campaignId, String tenantId) { Pagination pagination = Pagination.builder().limit(configs.getDefaultLimit()).offset(configs.getDefaultOffset()).build(); CampaignSearchCriteria searchCriteria = CampaignSearchCriteria.builder() .ids(Collections.singletonList(campaignId)) diff --git a/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java b/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java index d864f98bad5..025d4ea6bb6 100644 --- a/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import digit.config.Configuration; +import digit.web.models.PlanFacilityRequest; import digit.web.models.facility.FacilityResponse; import digit.web.models.facility.FacilitySearchCriteria; import digit.web.models.facility.FacilitySearchRequest; @@ -24,17 +25,20 @@ public class FacilityUtil { private RestTemplate restTemplate; private Configuration configs; - @Autowired private ObjectMapper mapper; - public FacilityUtil(RestTemplate restTemplate, Configuration configs) { + public FacilityUtil(RestTemplate restTemplate, Configuration configs, ObjectMapper mapper) { this.restTemplate = restTemplate; this.configs = configs; + this.mapper = mapper; } - public FacilityResponse fetchFacilityData(RequestInfo requestInfo, String facilityId, String tenantId) { + public FacilityResponse fetchFacilityData(PlanFacilityRequest planFacilityRequest) { String baseUri = configs.getFacilityHost()+ configs.getFacilitySearchEndPoint(); + // Retrieve tenantId from planFacilityRequest + String tenantId = planFacilityRequest.getPlanFacility().getTenantId(); + // Retrieve the limit and offset from the configuration int limit = configs.getDefaultLimit(); int offset = configs.getDefaultOffset(); @@ -46,7 +50,7 @@ public FacilityResponse fetchFacilityData(RequestInfo requestInfo, String facili .queryParam("offset", offset) .toUriString(); - FacilitySearchRequest facilitySearchRequest = getSearchReq(requestInfo, facilityId); + FacilitySearchRequest facilitySearchRequest = getFacilitySearchRequest(planFacilityRequest); FacilityResponse facilityResponse = new FacilityResponse(); Object response = new HashMap<>(); try { @@ -60,7 +64,11 @@ public FacilityResponse fetchFacilityData(RequestInfo requestInfo, String facili return facilityResponse; } - private FacilitySearchRequest getSearchReq(RequestInfo requestInfo, String facilityId) { + private FacilitySearchRequest getFacilitySearchRequest(PlanFacilityRequest planFacilityRequest) { + // Retrieve facilityId,requestInfo from planFacilityRequest + String facilityId = planFacilityRequest.getPlanFacility().getFacilityId(); + RequestInfo requestInfo = planFacilityRequest.getRequestInfo(); + FacilitySearchCriteria searchCriteria = FacilitySearchCriteria.builder() .id(Collections.singletonList(facilityId)) .build(); diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java index fc543ced50d..fdfb713f1b9 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -3,7 +3,6 @@ import digit.service.PlanFacilityService; import digit.web.models.*; import jakarta.validation.Valid; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -17,7 +16,7 @@ @RequestMapping("plan") public class PlanFacilityController { - private final PlanFacilityService planFacilityService; + private PlanFacilityService planFacilityService; public PlanFacilityController(PlanFacilityService planFacilityService) { this.planFacilityService = planFacilityService; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 15312d4f104..f7a8d2a35a5 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -50,7 +50,7 @@ public class PlanFacility { @JsonProperty("serviceBoundaries") @NotNull @Valid - private List serviceBoundaries = null; + private List serviceBoundaries; @JsonProperty("additionalDetails") private Object additionalDetails = null; @@ -69,4 +69,6 @@ public PlanFacility addServiceBoundariesItem(String serviceBoundariesItem) { return this; } + + } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java new file mode 100644 index 00000000000..6780974b8a8 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java @@ -0,0 +1,64 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import java.util.ArrayList; +import java.util.List; + +/** + * Plan Facility DTO + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityDTO { + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @NotNull + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("facilityId") + @NotNull + @Size(max = 64) + private String facilityId = null; + + @JsonProperty("residingBoundary") + @NotNull + @Size(min = 1, max = 64) + private String residingBoundary = null; + + // Changed List to String to store as JSON + @JsonProperty("serviceBoundaries") + @NotNull + @Size(min = 1) + private String serviceBoundaries = null; // Store as JSON string + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + private Boolean active = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java index 061acb30ceb..9eb2652d0a7 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -21,10 +22,12 @@ public class PlanFacilityRequest { @JsonProperty("RequestInfo") @Valid + @NotNull private RequestInfo requestInfo; @JsonProperty("PlanFacility") @Valid + @NotNull private PlanFacility planFacility; -} +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequestDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequestDTO.java new file mode 100644 index 00000000000..a78b2ba0047 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequestDTO.java @@ -0,0 +1,33 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanFacilityRequestDTO + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityRequestDTO { + + @JsonProperty("RequestInfo") + @Valid + @NotNull + private RequestInfo requestInfo; + + @JsonProperty("PlanFacility") + @Valid + @NotNull + private PlanFacilityDTO planFacilityDTO; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/AdditionalFields.java b/health-services/plan-service/src/main/java/digit/web/models/facility/AdditionalFields.java new file mode 100644 index 00000000000..e3b7f19cd31 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/AdditionalFields.java @@ -0,0 +1,25 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AdditionalFields { + + @JsonProperty("schema") + private String schema; + + @JsonProperty("version") + private int version; + + @JsonProperty("fields") + private List fields; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/Address.java b/health-services/plan-service/src/main/java/digit/web/models/facility/Address.java new file mode 100644 index 00000000000..f6a5e2c8c0b --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/Address.java @@ -0,0 +1,62 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Address { + + @JsonProperty("id") + private String id; + + @JsonProperty("tenantId") + private String tenantId; + + @JsonProperty("clientReferenceId") + private String clientReferenceId; + + @JsonProperty("doorNo") + private String doorNo; + + @JsonProperty("latitude") + private Double latitude; + + @JsonProperty("longitude") + private Double longitude; + + @JsonProperty("locationAccuracy") + private Double locationAccuracy; + + @JsonProperty("type") + private String type; + + @JsonProperty("addressLine1") + private String addressLine1; + + @JsonProperty("addressLine2") + private String addressLine2; + + @JsonProperty("landmark") + private String landmark; + + @JsonProperty("city") + private String city; + + @JsonProperty("pincode") + private String pincode; + + @JsonProperty("buildingName") + private String buildingName; + + @JsonProperty("street") + private String street; + + @JsonProperty("locality") + private Locality locality; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java b/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java index 66794a24940..fcfec9b1ee9 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java @@ -7,6 +7,8 @@ import lombok.NoArgsConstructor; import org.egov.common.contract.models.AuditDetails; +import java.util.Map; + @Data @Builder @NoArgsConstructor @@ -31,7 +33,7 @@ public class Facility { private boolean hasErrors; @JsonProperty("additionalFields") - private String additionalFields; + private AdditionalFields additionalFields; @JsonProperty("auditDetails") private AuditDetails auditDetails; @@ -55,7 +57,7 @@ public class Facility { private Integer storageCapacity; @JsonProperty("address") - private String address; + private Address address; @JsonProperty("isDeleted") private boolean isDeleted; diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/Field.java b/health-services/plan-service/src/main/java/digit/web/models/facility/Field.java new file mode 100644 index 00000000000..3cbd343bf76 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/Field.java @@ -0,0 +1,20 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Field { + + @JsonProperty("key") + private String key; + + @JsonProperty("value") + private String value; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/facility/Locality.java b/health-services/plan-service/src/main/java/digit/web/models/facility/Locality.java new file mode 100644 index 00000000000..68552c0898a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/Locality.java @@ -0,0 +1,33 @@ +package digit.web.models.facility; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Locality { + + @JsonProperty("id") + private String id; + + @JsonProperty("tenantId") + private String tenantId; + + @JsonProperty("code") + private String code; + + @JsonProperty("geometry") + private String geometry; // Assuming geometry is a string, adjust based on your actual data + + @JsonProperty("auditDetails") + private AuditDetails auditDetails; + + @JsonProperty("additionalDetails") + private String additionalDetails; +} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 6bd89c4b0ef..26dc031eaf6 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -7,19 +7,19 @@ app.timezone=UTC #DATABASE CONFIGURATION spring.datasource.driver-class-name=org.postgresql.Driver -spring.datasource.url=jdbc:postgresql://localhost:5432/plandb +spring.datasource.url=jdbc:postgresql://localhost:5432/plandbupdate spring.datasource.username=postgres spring.datasource.password=postgres #FLYWAY CONFIGURATION -spring.flyway.url=jdbc:postgresql://localhost:5432/plandb +spring.flyway.url=jdbc:postgresql://localhost:5432/plandbupdate spring.flyway.user=postgres spring.flyway.password=postgres spring.flyway.table=public spring.flyway.baseline-on-migrate=true spring.flyway.outOfOrder=true spring.flyway.locations=classpath:/db/migration/main -spring.flyway.enabled=false +spring.flyway.enabled=true # KAFKA SERVER CONFIGURATIONS kafka.config.bootstrap_server_config=localhost:9092 @@ -52,16 +52,16 @@ plan.facility.update.topic=update-plan-facility plan.facility.create.topic=save-plan-facility #mdms urls -egov.mdms.host=https://unified-dev.digit.org +egov.mdms.host=http://localhost:8083 egov.mdms.search.endpoint=/egov-mdms-service/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search #facility urls -egov.facility.host=https://unified-dev.digit.org +egov.facility.host=http://localhost:8092 egov.facility.search.endpoint=/facility/v1/_search #project factory urls -egov.project.factory.host=https://unified-dev.digit.org +egov.project.factory.host=http://localhost:8086 egov.project.factory.search.endpoint=/project-factory/v1/project-type/search # Pagination config diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql new file mode 100644 index 00000000000..51b8acf6eed --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql @@ -0,0 +1,2 @@ +ALTER TABLE plan_facility_linkage +ALTER COLUMN service_boundaries TYPE TEXT; From 1f4b0f2395a54fe6dd650984e7d0e819dd70d95f Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Tue, 1 Oct 2024 16:28:43 +0530 Subject: [PATCH 091/351] updated application.properties --- .../src/main/resources/application.properties | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 26dc031eaf6..06a7c284545 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -7,19 +7,19 @@ app.timezone=UTC #DATABASE CONFIGURATION spring.datasource.driver-class-name=org.postgresql.Driver -spring.datasource.url=jdbc:postgresql://localhost:5432/plandbupdate +spring.datasource.url=jdbc:postgresql://localhost:5432/plandb spring.datasource.username=postgres spring.datasource.password=postgres #FLYWAY CONFIGURATION -spring.flyway.url=jdbc:postgresql://localhost:5432/plandbupdate +spring.flyway.url=jdbc:postgresql://localhost:5432/plandb spring.flyway.user=postgres spring.flyway.password=postgres spring.flyway.table=public spring.flyway.baseline-on-migrate=true spring.flyway.outOfOrder=true spring.flyway.locations=classpath:/db/migration/main -spring.flyway.enabled=true +spring.flyway.enabled=false # KAFKA SERVER CONFIGURATIONS kafka.config.bootstrap_server_config=localhost:9092 @@ -52,16 +52,16 @@ plan.facility.update.topic=update-plan-facility plan.facility.create.topic=save-plan-facility #mdms urls -egov.mdms.host=http://localhost:8083 +egov.mdms.host=http://localhost:8080 egov.mdms.search.endpoint=/egov-mdms-service/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search #facility urls -egov.facility.host=http://localhost:8092 +egov.facility.host=http://localhost:8080 egov.facility.search.endpoint=/facility/v1/_search #project factory urls -egov.project.factory.host=http://localhost:8086 +egov.project.factory.host=http://localhost:8080 egov.project.factory.search.endpoint=/project-factory/v1/project-type/search # Pagination config From 1343b6c1235d5e1dc779d08de8c51009ffa96fd1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 1 Oct 2024 16:30:10 +0530 Subject: [PATCH 092/351] count query --- .../PlanEmployeeAssignmentRepository.java | 2 ++ .../repository/impl/PlanEmployeeAssignmentImpl.java | 13 +++++++++++++ .../java/digit/service/PlanEmployeeService.java | 1 + .../web/models/PlanEmployeeAssignmentResponse.java | 4 ++++ 4 files changed, 20 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java index e900e1b41a2..370141a8697 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java @@ -11,4 +11,6 @@ public interface PlanEmployeeAssignmentRepository { public List search(PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria); public void update(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest); + + public Integer count(PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index 2e6619e6ae9..210cb5d0040 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -75,6 +75,19 @@ public List search(PlanEmployeeAssignmentSearchCriteria return planEmployeeAssignments; } + /** + * Counts the number of plan employee assignments based on the provided search criteria. + * + * @param searchCriteria The search criteria for filtering plan employee assignments. + * @return The total count of plan employee assignment matching the search criteria. + */ + @Override + public Integer count(PlanEmployeeAssignmentSearchCriteria searchCriteria) { + // TODO : YET TO BE IMPLEMENTED + List preparedStmtList = new ArrayList<>(); + return 0; + } + /** * Pushes an updated existing plan employee assignment to persister kafka topic. * diff --git a/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java index 05117fb221e..996b0384e30 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java @@ -65,6 +65,7 @@ public PlanEmployeeAssignmentResponse search(PlanEmployeeAssignmentSearchRequest return PlanEmployeeAssignmentResponse.builder() .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) .planEmployeeAssignment(repository.search(request.getPlanEmployeeAssignmentSearchCriteria())) + .totalCount(repository.count(request.getPlanEmployeeAssignmentSearchCriteria())) .build(); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java index 9c2c71dae60..6c6ecdc516c 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java @@ -28,5 +28,9 @@ public class PlanEmployeeAssignmentResponse { @JsonProperty("PlanEmployeeAssignment") @Valid private List planEmployeeAssignment = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; } From ac957b2c5fe3f94189f5bc45314eccb85e794179 Mon Sep 17 00:00:00 2001 From: Saloni-eGov Date: Tue, 1 Oct 2024 16:36:37 +0530 Subject: [PATCH 093/351] changed update call --- .../java/digit/repository/impl/PlanFacilityRepositoryImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index f999a943462..9b5c43e8447 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -109,7 +109,8 @@ public List search(PlanFacilitySearchCriteria planFacilitySearchCr @Override public void update(PlanFacilityRequest planFacilityRequest) { try { - producer.push(config.getPlanFacilityUpdateTopic(), planFacilityRequest); + PlanFacilityRequestDTO requestDTO = convertToDTO(planFacilityRequest); + producer.push(config.getPlanFacilityUpdateTopic(), requestDTO); log.info("Successfully pushed update for plan facility: {}", planFacilityRequest.getPlanFacility().getId()); } catch (Exception e) { throw new CustomException(FAILED_MESSAGE,config.getPlanFacilityUpdateTopic()); From ac8792e598ffaab1b125a50a0deb1ccddf7751f9 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Thu, 3 Oct 2024 10:21:51 +0530 Subject: [PATCH 094/351] added not null for active --- .../digit/repository/impl/PlanFacilityRepositoryImpl.java | 5 +---- .../src/main/java/digit/web/models/PlanFacility.java | 1 + .../src/main/java/digit/web/models/PlanFacilityDTO.java | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 9b5c43e8447..08a01b0e513 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -29,15 +29,12 @@ public class PlanFacilityRepositoryImpl implements PlanFacilityRepository { private Configuration config; - private ObjectMapper mapper; - - public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, PlanFacilityQueryBuilder planFacilityQueryBuilder, PlanFacilityRowMapper planFacilityRowMapper, Configuration config, ObjectMapper mapper) { + public PlanFacilityRepositoryImpl(Producer producer, JdbcTemplate jdbcTemplate, PlanFacilityQueryBuilder planFacilityQueryBuilder, PlanFacilityRowMapper planFacilityRowMapper, Configuration config) { this.producer = producer; this.jdbcTemplate = jdbcTemplate; this.planFacilityQueryBuilder = planFacilityQueryBuilder; this.planFacilityRowMapper = planFacilityRowMapper; this.config = config; - this.mapper = mapper; } /** diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index f7a8d2a35a5..54aa0fcbcc2 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -56,6 +56,7 @@ public class PlanFacility { private Object additionalDetails = null; @JsonProperty("active") + @NotNull private Boolean active = null; @JsonProperty("auditDetails") diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java index 6780974b8a8..0270be18d5e 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java @@ -56,6 +56,7 @@ public class PlanFacilityDTO { private Object additionalDetails = null; @JsonProperty("active") + @NotNull private Boolean active = null; @JsonProperty("auditDetails") From db4637ab447908cd68639c96a9afd3eb73e6ebb5 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 3 Oct 2024 10:42:52 +0530 Subject: [PATCH 095/351] Added validation --- .../java/digit/config/ServiceConstants.java | 8 +++ .../PlanEmployeeAssignmentEnricher.java | 5 +- .../PlanEmployeeAssignmentValidator.java | 55 ++++++++++++++++++- .../src/main/java/digit/util/MdmsUtil.java | 37 ++++++++++++- 4 files changed, 99 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 21c3e7090f3..8ae9a39757e 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -20,6 +20,8 @@ public class ServiceConstants { public static final String SUCCESSFUL = "successful"; public static final String FAILED = "failed"; + public static final String NATIONAL_ROLE = "NATIONAL"; + public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; @@ -157,6 +159,8 @@ public class ServiceConstants { //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; + public static final String MDMS_ADMIN_CONSOLE_MODULE_NAME = "HCM-ADMIN-CONSOLE"; + public static final String MDMS_MASTER_HIERARCHY_CONFIG = "hierarchyConfig"; public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions"; public static final String MDMS_MASTER_UPLOAD_CONFIGURATION = "UploadConfiguration"; public static final String MDMS_MASTER_RULE_CONFIGURE_INPUTS = "RuleConfigureInputs"; @@ -200,6 +204,10 @@ public class ServiceConstants { public static final String FILTER_ALL_ASSUMPTIONS = "[*].assumptionCategories[*].assumptions[*]"; + public static final String HIERARCHY_CONFIG_FOR_MICROPLAN = "[?(@.hierarchy == 'MICROPLAN')]"; + + public static final String HIGHEST_HIERARCHY_FOR_MICROPLAN = "highestHierarchy"; + public static final String NAME_VALIDATION_DATA = "Data"; public static final String VEHICLE_ID_FIELD = "vehicleIds"; diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java index 96121ac318f..6850d22357b 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -11,7 +11,7 @@ public class PlanEmployeeAssignmentEnricher { /** - * Enriches the PlanEmployeeAssignmentRequest with id and audit details. + * Enriches the PlanEmployeeAssignmentRequest with id and audit details and sets active as true. * * @param request The PlanEmployeeAssignmentRequest body to be enriched */ @@ -21,6 +21,9 @@ public void enrichCreate(PlanEmployeeAssignmentRequest request) { // Generate id for Plan employee assignment body UUIDEnrichmentUtil.enrichRandomUuid(planEmployeeAssignment, "id"); + // Set active true + planEmployeeAssignment.setActive(Boolean.TRUE); + // Set Audit Details for Plan employee assignment planEmployeeAssignment.setAuditDetails(prepareAuditDetails(planEmployeeAssignment.getAuditDetails(), request.getRequestInfo(), diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 6c01b28ba49..105a958cb41 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -1,10 +1,12 @@ package digit.service.validator; +import com.jayway.jsonpath.JsonPath; import digit.config.Configuration; import digit.repository.PlanEmployeeAssignmentRepository; import digit.util.CampaignUtil; import digit.util.CommonUtil; import digit.util.HrmsUtil; +import digit.util.MdmsUtil; import digit.web.models.*; import digit.web.models.hrms.EmployeeResponse; import digit.web.models.projectFactory.Boundary; @@ -29,6 +31,8 @@ public class PlanEmployeeAssignmentValidator { private MultiStateInstanceUtil centralInstanceUtil; + private MdmsUtil mdmsUtil; + private HrmsUtil hrmsUtil; private CommonUtil commonUtil; @@ -39,8 +43,9 @@ public class PlanEmployeeAssignmentValidator { private Configuration config; - public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, HrmsUtil hrmsUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeAssignmentRepository repository, Configuration config) { + public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, HrmsUtil hrmsUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeAssignmentRepository repository, Configuration config) { this.centralInstanceUtil = centralInstanceUtil; + this.mdmsUtil = mdmsUtil; this.hrmsUtil = hrmsUtil; this.commonUtil = commonUtil; this.campaignUtil = campaignUtil; @@ -71,8 +76,49 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { // Validate if role of employee is a conflicting role validateRoleConflict(planEmployeeAssignment); - // Validate campaign id and employee jurisdiction + // Validate campaign id, employee jurisdiction and highest root jurisdiction in case of National role validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); + + } + + /** + * Validates that employee with National role is assigned to the highest root jurisdiction only against MDMS + * + * @param planEmployeeAssignment The plan employee assignment provided in request + * @param mdmsData mdms data from mdms v2 + * @param campaignDetail the campaign details for the corresponding campaign id + */ + private void validateNationalRole(PlanEmployeeAssignment planEmployeeAssignment, Object mdmsData, CampaignDetail campaignDetail) { + if (planEmployeeAssignment.getRole().contains(NATIONAL_ROLE)) { + List jurisdiction = planEmployeeAssignment.getJurisdiction(); + + // Validate that National role employee should not have more than one jurisdiction assigned + if (jurisdiction.size() > 1) { + throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); + } + + // Fetch the highest hierarchy for Microplan from MDMS + String jsonPathForHighestHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN + DOT_SEPARATOR + HIGHEST_HIERARCHY_FOR_MICROPLAN; + + List highestHirarchyForPlan = null; + try { + log.info(jsonPathForHighestHierarchy); + highestHirarchyForPlan = JsonPath.read(mdmsData, jsonPathForHighestHierarchy); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + // Filter out the boundary details for the jurisdiction assigned to employee + Boundary jurisdictionBoundary = campaignDetail.getBoundaries().stream() + .filter(boundary -> boundary.getCode().equals(planEmployeeAssignment.getJurisdiction().get(0))) + .findFirst().get(); + + // Throw exception if jurisdiction assigned to National role employee is not the highest hierarchy + if (!jurisdictionBoundary.getType().equals(highestHirarchyForPlan.get(0))) { + throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); + } + } } /** @@ -122,6 +168,7 @@ private void validateRoleAgainstHRMS(PlanEmployeeAssignment planEmployeeAssignme /** * This method validates campaign id and employee's jurisdiction against project factory + * If the employee has a national role, it validates that the employee has the highest root jurisdiction only * * @param campaignId the campaign id corresponding to the plan config id provided in the request * @param tenantId the tenant id provided in the request @@ -130,12 +177,16 @@ private void validateRoleAgainstHRMS(PlanEmployeeAssignment planEmployeeAssignme private void validateCampaignDetails(String campaignId, String tenantId, PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentRequest.getPlanEmployeeAssignment(); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(planEmployeeAssignmentRequest.getRequestInfo(), campaignId, tenantId); + Object mdmsData = mdmsUtil.fetchMdmsData(planEmployeeAssignmentRequest.getRequestInfo(), tenantId); // Validate if campaign id exists against project factory validateCampaignId(campaignResponse); // Validate the provided jurisdiction for employee validateEmployeeJurisdiction(campaignResponse.getCampaignDetails().get(0), planEmployeeAssignment); + + // Validates highest root jurisdiction for National roles against MDMS + validateNationalRole(planEmployeeAssignment, mdmsData, campaignResponse.getCampaignDetails().get(0)); } /** diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java index fb0f6560908..e9b87d3d5df 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java @@ -2,7 +2,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import digit.config.Configuration; + import java.util.LinkedList; + import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.egov.mdms.model.*; @@ -38,11 +40,11 @@ public Object fetchMdmsData(RequestInfo requestInfo, String tenantId) { StringBuilder uri = new StringBuilder(); uri.append(configs.getMdmsHost()).append(configs.getMdmsEndPoint()); MdmsCriteriaReq mdmsCriteriaReq = getMdmsRequest(requestInfo, tenantId); - Object mdmsResponseMap = new HashMap<>(); + Object mdmsResponseMap = new HashMap<>(); MdmsResponse mdmsResponse = new MdmsResponse(); try { - mdmsResponseMap = restTemplate.postForObject(uri.toString(), mdmsCriteriaReq, Map.class); - mdmsResponse = mapper.convertValue(mdmsResponseMap , MdmsResponse.class); + mdmsResponseMap = restTemplate.postForObject(uri.toString(), mdmsCriteriaReq, Map.class); + mdmsResponse = mapper.convertValue(mdmsResponseMap, MdmsResponse.class); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); } @@ -55,18 +57,47 @@ public Object fetchMdmsData(RequestInfo requestInfo, String tenantId) { return result; } + /** + * This method constructs the criteria request for MDMS Api call + * + * @param requestInfo requestInfo from the provided request + * @param tenantId tenant id from the provided request + * @return Returns the mdms criteria request + */ public MdmsCriteriaReq getMdmsRequest(RequestInfo requestInfo, String tenantId) { ModuleDetail assumptionModuleDetail = getPlanModuleDetail(); + ModuleDetail adminConsoleModuleDetail = getAdminConsoleModuleDetail(); List moduleDetails = new LinkedList<>(); moduleDetails.add(assumptionModuleDetail); + moduleDetails.add(adminConsoleModuleDetail); MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId).build(); return MdmsCriteriaReq.builder().mdmsCriteria(mdmsCriteria).requestInfo(requestInfo).build(); } + /** + * This method constructs module detail object for 'HCM-ADMIN-CONSOLE' module + * + * @return Returns the module details for 'HCM-ADMIN-CONSOLE' module + */ + private ModuleDetail getAdminConsoleModuleDetail() { + List adminConsoleMasterDetails = new ArrayList<>(); + + MasterDetail hierarchyConfig = MasterDetail.builder().name(MDMS_MASTER_HIERARCHY_CONFIG).build(); + + adminConsoleMasterDetails.add(hierarchyConfig); + + return ModuleDetail.builder().masterDetails(adminConsoleMasterDetails).moduleName(MDMS_ADMIN_CONSOLE_MODULE_NAME).build(); + } + + /** + * This method constructs module detail object for 'hcm-microplanning' module + * + * @return Returns the module details for 'hcm-microplanning' module + */ private ModuleDetail getPlanModuleDetail() { List assumptionMasterDetails = new ArrayList<>(); From 2e1aefe870c97d72db2f3d09dd3e1d5f1a0e5adb Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 3 Oct 2024 12:54:15 +0530 Subject: [PATCH 096/351] enrich search with total count --- .../impl/PlanEmployeeAssignmentImpl.java | 73 +++++++++---------- .../PlanEmployeeAssignmentQueryBuilder.java | 38 +++++++++- .../PlanEmployeeAssignmentRowMapper.java | 2 +- .../src/main/java/digit/util/CommonUtil.java | 38 ---------- 4 files changed, 69 insertions(+), 82 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index 210cb5d0040..e0b004a9218 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -5,21 +5,15 @@ import digit.repository.PlanEmployeeAssignmentRepository; import digit.repository.querybuilder.PlanEmployeeAssignmentQueryBuilder; import digit.repository.rowmapper.PlanEmployeeAssignmentRowMapper; -import digit.util.CommonUtil; -import digit.web.models.PlanEmployeeAssignment; -import digit.web.models.PlanEmployeeAssignmentRequestDTO; -import digit.web.models.PlanEmployeeAssignmentRequest; -import digit.web.models.PlanEmployeeAssignmentSearchCriteria; +import digit.web.models.*; +import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; -import org.springframework.util.CollectionUtils; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; +@Slf4j @Repository public class PlanEmployeeAssignmentImpl implements PlanEmployeeAssignmentRepository { @@ -33,15 +27,12 @@ public class PlanEmployeeAssignmentImpl implements PlanEmployeeAssignmentReposit private PlanEmployeeAssignmentRowMapper rowMapper; - private CommonUtil commonUtil; - - public PlanEmployeeAssignmentImpl(Producer producer, Configuration config, PlanEmployeeAssignmentQueryBuilder queryBuilder, JdbcTemplate jdbcTemplate, PlanEmployeeAssignmentRowMapper rowMapper, CommonUtil commonUtil) { + public PlanEmployeeAssignmentImpl(Producer producer, Configuration config, PlanEmployeeAssignmentQueryBuilder queryBuilder, JdbcTemplate jdbcTemplate, PlanEmployeeAssignmentRowMapper rowMapper) { this.producer = producer; this.config = config; this.queryBuilder = queryBuilder; this.jdbcTemplate = jdbcTemplate; this.rowMapper = rowMapper; - this.commonUtil = commonUtil; } /** @@ -51,7 +42,7 @@ public PlanEmployeeAssignmentImpl(Producer producer, Configuration config, PlanE */ @Override public void create(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { - PlanEmployeeAssignmentRequestDTO requestDTO = commonUtil.convertToReqDTO(planEmployeeAssignmentRequest); + PlanEmployeeAssignmentRequestDTO requestDTO = convertToReqDTO(planEmployeeAssignmentRequest); producer.push(config.getPlanEmployeeAssignmentCreateTopic(), requestDTO); } @@ -67,11 +58,6 @@ public List search(PlanEmployeeAssignmentSearchCriteria String searchQuery = queryBuilder.getPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); List planEmployeeAssignments = jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); - // If searchCriteria has jurisdiction, filter the list of planEmployeeAssignments by jurisdiction - if (!CollectionUtils.isEmpty(searchCriteria.getJurisdiction())) { - planEmployeeAssignments = filterByJurisdiction(planEmployeeAssignments, searchCriteria.getJurisdiction()); - } - return planEmployeeAssignments; } @@ -83,9 +69,11 @@ public List search(PlanEmployeeAssignmentSearchCriteria */ @Override public Integer count(PlanEmployeeAssignmentSearchCriteria searchCriteria) { - // TODO : YET TO BE IMPLEMENTED List preparedStmtList = new ArrayList<>(); - return 0; + String query = queryBuilder.getPlanEmployeeAssignmentCountQuery(searchCriteria, preparedStmtList); + Integer count = jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); + + return count; } /** @@ -95,29 +83,36 @@ public Integer count(PlanEmployeeAssignmentSearchCriteria searchCriteria) { */ @Override public void update(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { - PlanEmployeeAssignmentRequestDTO requestDTO = commonUtil.convertToReqDTO(planEmployeeAssignmentRequest); + PlanEmployeeAssignmentRequestDTO requestDTO = convertToReqDTO(planEmployeeAssignmentRequest); producer.push(config.getPlanEmployeeAssignmentUpdateTopic(), requestDTO); } /** - * This is a helper method to filter out list of PlanEmployeeAssignment by jurisdiction provided + * Converts the PlanEmployeeAssignmentRequest to a data transfer object (DTO) * - * @param planEmployeeAssignments List of planEmployeeAssignment based on search criteria - * @param jurisdictionFromSearchCriteria jurisdiction provided in search criteria - * @return a list of planEmployeeAssignment filtered by jurisdiction + * @param planEmployeeAssignmentRequest The request to be converted to DTO + * @return a DTO for PlanEmployeeAssignmentRequest */ - private List filterByJurisdiction(List planEmployeeAssignments, List jurisdictionFromSearchCriteria) { - - // Convert jurisdictionFromSearchCriteria to a Set - Set jurisdictionSet = new HashSet<>(jurisdictionFromSearchCriteria); - - return planEmployeeAssignments.stream().filter(assignment -> { - for (String jurisdiction : assignment.getJurisdiction()) { - if (jurisdictionSet.contains(jurisdiction)) { - return true; - } - } - return false; - }).collect(Collectors.toList()); + public PlanEmployeeAssignmentRequestDTO convertToReqDTO(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { + PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentRequest.getPlanEmployeeAssignment(); + + // Creating a new data transfer object (DTO) for PlanEmployeeAssignment + PlanEmployeeAssignmentDTO planEmployeeAssignmentDTO = PlanEmployeeAssignmentDTO.builder() + .id(planEmployeeAssignment.getId()) + .tenantId(planEmployeeAssignment.getTenantId()) + .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) + .employeeId(planEmployeeAssignment.getEmployeeId()) + .role(planEmployeeAssignment.getRole()) + .jurisdiction(String.join(",", planEmployeeAssignment.getJurisdiction())) + .additionalDetails(planEmployeeAssignment.getAdditionalDetails()) + .active(planEmployeeAssignment.getActive()) + .auditDetails(planEmployeeAssignment.getAuditDetails()) + .build(); + + return PlanEmployeeAssignmentRequestDTO.builder() + .requestInfo(planEmployeeAssignmentRequest.getRequestInfo()) + .planEmployeeAssignmentDTO(planEmployeeAssignmentDTO) + .build(); } + } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index dab17739c42..2f1809b3da1 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -1,10 +1,11 @@ package digit.repository.querybuilder; -import digit.config.Configuration; import digit.util.QueryUtil; import digit.web.models.PlanEmployeeAssignmentSearchCriteria; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import java.util.HashSet; import java.util.List; @Component @@ -20,6 +21,8 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. @@ -29,20 +32,33 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { * @return A complete SQL query string for searching PlanEmployeeAssignment objects. */ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { - String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); + String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); query = queryUtil.getPaginatedQuery(query, preparedStmtList); return query; } + /** + * Constructs the count query to get the total count of plan employee assignments based on search criteria + * + * @param searchCriteria The criteria used for filtering PlanEmployeeAssignment objects. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A SQL query string to get the total count of plan employee assignments + */ + public String getPlanEmployeeAssignmentCountQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { + String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList, Boolean.TRUE); + return query; + } + /** * Constructs query based on the provided search criteria * * @param searchCriteria The criteria used for filtering PlanEmployeeAssignment objects. * @param preparedStmtList A list to store prepared statement parameters. + * @param isCount is true if count query is required for the provided search criteria * @return A SQL query string for searching planEmployeeAssignment */ - private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { + private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList, Boolean isCount) { StringBuilder builder = new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); if (searchCriteria.getId() != null) { @@ -81,7 +97,21 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit preparedStmtList.add(searchCriteria.getActive()); } + if (!CollectionUtils.isEmpty(searchCriteria.getJurisdiction())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ").append(queryUtil.createQuery(searchCriteria.getJurisdiction().size())).append(" ]").append("::text[] "); + builder.append(" && string_to_array(jurisdiction, ',') "); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(searchCriteria.getJurisdiction())); + } + + StringBuilder countQuery = new StringBuilder(); + if (isCount) { + countQuery.append(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER).append(builder); + countQuery.append(") AS subquery"); + + return countQuery.toString(); + } + return builder.toString(); } - } diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java index 284d7df19ff..fb7dfee05ba 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -41,7 +41,7 @@ public List extractData(ResultSet rs) throws SQLExceptio // Converting jurisdiction from comma separated string to a list of string String jurisdiction = rs.getString("jurisdiction"); - List jurisdictionList = Arrays.asList(jurisdiction.split(", ")); + List jurisdictionList = Arrays.asList(jurisdiction.split(",")); // Prepare PlanEmployeeAssignment object planEmployeeAssignment.setId(planEmployeeAssignmentId); diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 3c49209d861..de8d6ac6127 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -87,42 +87,4 @@ public List searchPlanConfigId(String planConfigId, String te return planConfigurations; } - /** - * Converts the PlanEmployeeAssignmentRequest to a data transfer object (DTO) - * - * @param planEmployeeAssignmentRequest The request to be converted to DTO - * @return a DTO for PlanEmployeeAssignmentRequest - */ - public PlanEmployeeAssignmentRequestDTO convertToReqDTO(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) { - PlanEmployeeAssignment planEmployeeAssignment = planEmployeeAssignmentRequest.getPlanEmployeeAssignment(); - - // Creating a new data transfer object (DTO) for PlanEmployeeAssignment - PlanEmployeeAssignmentDTO planEmployeeAssignmentDTO = PlanEmployeeAssignmentDTO.builder() - .id(planEmployeeAssignment.getId()) - .tenantId(planEmployeeAssignment.getTenantId()) - .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) - .employeeId(planEmployeeAssignment.getEmployeeId()) - .role(planEmployeeAssignment.getRole()) - .jurisdiction(convertArrayToString(planEmployeeAssignment.getJurisdiction())) - .additionalDetails(planEmployeeAssignment.getAdditionalDetails()) - .active(planEmployeeAssignment.getActive()) - .auditDetails(planEmployeeAssignment.getAuditDetails()) - .build(); - - return PlanEmployeeAssignmentRequestDTO.builder() - .requestInfo(planEmployeeAssignmentRequest.getRequestInfo()) - .planEmployeeAssignmentDTO(planEmployeeAssignmentDTO) - .build(); - } - - /** - * This is a helper function to convert an array of string to comma separated string - * - * @param stringList Array of string to be converted - * @return a string - */ - private String convertArrayToString(List stringList) { - return String.join(", ", stringList); - } - } \ No newline at end of file From 9bd33cdc5eda980db6f400a65ee433109a8cab10 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 3 Oct 2024 13:48:11 +0530 Subject: [PATCH 097/351] modified changes --- .../java/org/egov/project/config/ProjectConfiguration.java | 3 +++ .../org/egov/project/validator/project/ProjectValidator.java | 2 +- .../project/src/main/resources/application.properties | 5 ++++- .../src/main/resources/db/Dockerfile | 2 +- .../src/main/resources/db/migrate.sh | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java index 26759e381e2..67ee5a87af6 100644 --- a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java +++ b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java @@ -222,4 +222,7 @@ public class ProjectConfiguration { @Value("${project.task.no.resource.validation.status}") private List noResourceStatuses; + + @Value("${project.attendance.feature.enabled:true}") + private Boolean isAttendanceFeatureEnabled; } diff --git a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java index 266f664312d..9aaba88a427 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java @@ -75,7 +75,7 @@ public void validateCreateProjectRequest(ProjectRequest request) { //Verify MDMS Data // TODO: Uncomment and fix as per HCM once we get clarity // validateRequestMDMSData(request, tenantId, errorMap); - validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); + if(config.getIsAttendanceFeatureEnabled()) validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); //Get boundaries in list from all Projects in request body for validation Map> boundariesForValidation = getBoundaryForValidation(request.getProjects()); diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index 93f601466a9..71af8eab0d3 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -180,4 +180,7 @@ project.location.capture.kafka.create.topic=save-location-capture-project-topic project.location.capture.consumer.bulk.create.topic=save-location-capture-project-bulk-topic #---------No resource statuses ------------# -project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED \ No newline at end of file +project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED + +#---------Attendance Feature ------------# +project.attendance.feature.enabled=true diff --git a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile b/health-services/resource-estimation-service/src/main/resources/db/Dockerfile index 60fc07ce69f..f5241a8f861 100644 --- a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile +++ b/health-services/resource-estimation-service/src/main/resources/db/Dockerfile @@ -1,4 +1,4 @@ -FROM egovio/flyway:4.1.2 +FROM egovio/flyway:10.7.1 COPY ./migration/main /flyway/sql diff --git a/health-services/resource-estimation-service/src/main/resources/db/migrate.sh b/health-services/resource-estimation-service/src/main/resources/db/migrate.sh index 43960b25cdb..c58d6f91e3f 100644 --- a/health-services/resource-estimation-service/src/main/resources/db/migrate.sh +++ b/health-services/resource-estimation-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true -ignoreMissingMigrations=true migrate \ No newline at end of file +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate \ No newline at end of file From 1024b8814a333d76752c6cd3e172138068377839 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 3 Oct 2024 14:30:40 +0530 Subject: [PATCH 098/351] persister kafka topic --- .../src/main/resources/application.properties | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index d3332f5b476..689b8a675a8 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -41,45 +41,53 @@ kafka.producer.config.batch_size_config=16384 kafka.producer.config.linger_ms_config=1 kafka.producer.config.buffer_memory_config=33554432 +#PERSISTER KAFKA TOPICS +census.create.topic=census-create-topic +census.update.topic=census-update-topic + +egov.sms.notification.topic=egov.core.notification.sms +kafka.topics.receipt.create=dss-collection + #Localization config -egov.localization.host=https://dev.digit.org +egov.localization.host=https://unified-dev.digit.org egov.localization.workDir.path=/localization/messages/v1 egov.localization.context.path=/localization/messages/v1 egov.localization.search.endpoint=/_search egov.localization.statelevel=true #mdms urls -egov.mdms.host=https://dev.digit.org +egov.mdms.host=https://unified-dev.digit.org egov.mdms.search.endpoint=/egov-mdms-service/v1/_search #hrms urls -egov.hrms.host=https://dev.digit.org +egov.hrms.host=https://unified-dev.digit.org egov.hrms.search.endpoint=/egov-hrms/employees/_search #User config -egov.user.host=https://dev.digit.org +egov.user.host=https://unified-dev.digit.org egov.user.context.path=/user/users egov.user.create.path=/_createnovalidate egov.user.search.path=/user/_search egov.user.update.path=/_updatenovalidate #Idgen Config -egov.idgen.host=https://dev.digit.org/ +egov.idgen.host=https://unified-dev.digit.org/ egov.idgen.path=egov-idgen/id/_generate #Workflow config is.workflow.enabled=true -egov.workflow.host=https://dev.digit.org +egov.workflow.host=https://unified-dev.digit.org egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition egov.workflow.businessservice.search.path=/egov-workflow-v2/egov-wf/businessservice/_search egov.workflow.processinstance.search.path=/egov-workflow-v2/egov-wf/process/_search #url shortner -egov.url.shortner.host=https://dev.digit.org +egov.url.shortner.host=https://unified-dev.digit.org egov.url.shortner.endpoint=/egov-url-shortening/shortener -egov.sms.notification.topic=egov.core.notification.sms -kafka.topics.receipt.create=dss-collection +#Pagination config +census.default.offset=0 +census.default.limit=10 -# The value of the following field should be changed to service specific name +#The value of the following field should be changed to service specific name kafka.topics.consumer=service-consumer-topic \ No newline at end of file From e6bbc0b84ba73dbb70834f3de4ce64bb376b5a29 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 3 Oct 2024 14:56:29 +0530 Subject: [PATCH 099/351] HCMPRE-493 Workflow integration changes for plan config --- .../main/java/digit/config/Configuration.java | 7 + .../java/digit/config/ServiceConstants.java | 12 ++ .../repository/ServiceRequestRepository.java | 3 +- .../rowmapper/PlanConfigRowMapper.java | 2 +- .../service/PlanConfigurationService.java | 8 +- .../service/enrichment/EnrichmentService.java | 5 + .../service/workflow/WorkflowService.java | 135 ++++++++++++++++++ .../digit/web/models/PlanConfiguration.java | 13 +- .../src/main/resources/application.properties | 6 +- 9 files changed, 177 insertions(+), 14 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 03ea5c05d16..a5a2bc9a57d 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -50,4 +50,11 @@ public class Configuration { @Value("${plan.default.limit}") private Integer defaultLimit; + //Workflow + @Value("${egov.workflow.host}") + private String wfHost; + + @Value("${egov.workflow.transition.path}") + private String wfTransitionPath; + } diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 1528951de9c..c223e66ff32 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -130,6 +130,11 @@ public class ServiceConstants { public static final String DUPLICATE_ACTIVITY_UUIDS_CODE = "DUPLICATE_ACTIVITY_UUIDS"; public static final String DUPLICATE_ACTIVITY_UUIDS_MESSAGE = "Activity UUIDs should be unique"; + public static final String WORKFLOW_INTEGRATION_ERROR_CODE = "WORKFLOW_INTEGRATION_ERROR"; + public static final String WORKFLOW_INTEGRATION_ERROR_MESSAGE = "Exception occured while integrating with workflow : "; + + public static final String PROCESS_INSTANCE_NOT_FOUND_CODE = "PROCESS_INSTANCE_NOT_FOUND"; + public static final String PROCESS_INSTANCE_NOT_FOUND_MESSAGE = "No process instance found with businessId: "; //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; @@ -180,4 +185,11 @@ public class ServiceConstants { public static final String VEHICLE_ID_FIELD = "vehicleIds"; + // Workflow Constants + public static final String PLAN_CONFIGURATION_BUSINESS_SERVICE = "PLAN_CONFIGURATION"; + + public static final String MODULE_NAME_VALUE = "plan-service"; + + public static final String DRAFT_STATUS = "DRAFT"; + } diff --git a/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java b/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java index d09d230e4fa..90256d5a131 100644 --- a/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java @@ -4,8 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.CustomException; import org.egov.tracer.model.ServiceCallException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; @@ -38,6 +38,7 @@ public Object fetchResult(StringBuilder uri, Object request) { throw new ServiceCallException(e.getResponseBodyAsString()); } catch (Exception e) { log.error(SEARCHER_SERVICE_EXCEPTION, e); + throw new CustomException(EXTERNAL_SERVICE_EXCEPTION, e.getMessage()); } return response; diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index 31ce9002c1e..5256855329b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java @@ -46,7 +46,7 @@ public List extractData(ResultSet rs) throws SQLException, Da planConfigEntry.setTenantId(rs.getString("plan_configuration_tenant_id")); planConfigEntry.setName(rs.getString("plan_configuration_name")); planConfigEntry.setCampaignId(rs.getString("plan_configuration_campaign_id")); - planConfigEntry.setStatus(PlanConfiguration.StatusEnum.valueOf(rs.getString("plan_configuration_status").toUpperCase())); + planConfigEntry.setStatus(rs.getString("plan_configuration_status").toUpperCase()); planConfigEntry.setAuditDetails(auditDetails); } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java index 85238f723a5..7fe2ef0176e 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java @@ -3,9 +3,9 @@ import digit.config.Configuration; import digit.kafka.Producer; import digit.repository.PlanConfigurationRepository; -import digit.repository.impl.PlanConfigurationRepositoryImpl; import digit.service.enrichment.EnrichmentService; import digit.service.validator.PlanConfigurationValidator; +import digit.service.workflow.WorkflowService; import digit.util.ResponseInfoFactory; import digit.web.models.PlanConfigurationRequest; import digit.web.models.PlanConfigurationResponse; @@ -31,14 +31,17 @@ public class PlanConfigurationService { private ResponseInfoFactory responseInfoFactory; + private WorkflowService workflowService; + public PlanConfigurationService(Producer producer, EnrichmentService enrichmentService, Configuration config - , PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory) { + , PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService) { this.producer = producer; this.enrichmentService = enrichmentService; this.config = config; this.validator = validator; this.repository = repository; this.responseInfoFactory = responseInfoFactory; + this.workflowService = workflowService; } /** @@ -82,6 +85,7 @@ public PlanConfigurationResponse search(PlanConfigurationSearchRequest request) */ public PlanConfigurationResponse update(PlanConfigurationRequest request) { validator.validateUpdateRequest(request); + workflowService.integrateWithWorkflow(request); enrichmentService.enrichUpdate(request); repository.update(request); diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index 86c1fdb4b81..a855fae3be7 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java @@ -11,6 +11,8 @@ import org.springframework.stereotype.Component; import java.util.List; + +import static digit.config.ServiceConstants.DRAFT_STATUS; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; import org.springframework.util.ObjectUtils; @@ -35,6 +37,9 @@ public void enrichCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); log.info("Enriching plan config with generated IDs"); + //set Draft status on create + planConfiguration.setStatus(DRAFT_STATUS); + // Generate id for plan configuration UUIDEnrichmentUtil.enrichRandomUuid(planConfiguration, "id"); diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java new file mode 100644 index 00000000000..8b50d0e6147 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -0,0 +1,135 @@ +package digit.service.workflow; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.config.Configuration; +import digit.repository.ServiceRequestRepository; +import digit.web.models.PlanConfiguration; +import digit.web.models.PlanConfigurationRequest; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.models.Workflow; +import org.egov.common.contract.request.User; +import org.egov.common.contract.workflow.*; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; + +import static digit.config.ServiceConstants.*; +import static java.util.stream.Collectors.toList; + +@Service +@Slf4j +public class WorkflowService { + + private ServiceRequestRepository serviceRequestRepository; + + private Configuration config; + + private ObjectMapper mapper; + + @Autowired + public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper) { + this.serviceRequestRepository = serviceRequestRepository; + this.config = config; + this.mapper = mapper; + } + + /** + * Integrates with the workflow for the given plan configuration request. + * If the action is null, it does not proceed with integration. + * + * @param planConfigurationRequest The request containing the plan configuration to integrate with the workflow. + */ + public void integrateWithWorkflow(PlanConfigurationRequest planConfigurationRequest) { + if (planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction() == null) { + return; + } + + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planConfigurationRequest); + ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); + + String businessId = planConfigurationRequest.getPlanConfiguration().getId(); + ProcessInstance processInstanceAfterTransition = processInstanceResponse.getProcessInstances().stream() + .filter(processInstance -> businessId.equals(processInstance.getBusinessId())) + .findFirst() + .orElseThrow(() -> new CustomException(PROCESS_INSTANCE_NOT_FOUND_CODE, PROCESS_INSTANCE_NOT_FOUND_MESSAGE + businessId)); + + // Setting the status back to the plan configuration object from workflow response + planConfigurationRequest.getPlanConfiguration().setStatus(processInstanceAfterTransition.getState().getApplicationStatus()); + } + + /** + * Calls the workflow transition service and retrieves the process instance response. + * + * @param processInstanceRequest The request containing process instance details for the workflow transition. + * @return The response containing details of the process instances after the transition. + * @throws CustomException if there is an error during the workflow integration. + */ + public ProcessInstanceResponse callWorkflowTransition(ProcessInstanceRequest processInstanceRequest) { + ProcessInstanceResponse processInstanceResponse; + try { + Object response = serviceRequestRepository.fetchResult(getWorkflowTransitionUri(), processInstanceRequest); + processInstanceResponse = mapper.convertValue(response, ProcessInstanceResponse.class); + } catch (Exception e) { + throw new CustomException(WORKFLOW_INTEGRATION_ERROR_CODE, WORKFLOW_INTEGRATION_ERROR_MESSAGE + e); + } + + return processInstanceResponse; + } + + /** + * Creates a workflow request from the given plan configuration request. + * + * @param planConfigurationRequest The request containing the plan configuration to create a workflow request. + * @return The constructed process instance request for the workflow. + */ + public ProcessInstanceRequest createWorkflowRequest(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + ProcessInstance processInstance = ProcessInstance.builder() + .businessId(planConfig.getId()) + .tenantId(planConfig.getTenantId()) + .businessService(PLAN_CONFIGURATION_BUSINESS_SERVICE) + .moduleName(MODULE_NAME_VALUE) + .action(planConfig.getWorkflow().getAction()) + .comment(planConfig.getWorkflow().getComments()) + .documents(planConfig.getWorkflow().getDocuments()) + .build(); + + enrichAssignesInWorkflow(processInstance, planConfig.getWorkflow()); + + return ProcessInstanceRequest.builder() + .requestInfo(planConfigurationRequest.getRequestInfo()) + .processInstances(Collections.singletonList(processInstance)) + .build(); + } + + /** + * Enriches the process instance with assignees from the given workflow. + * + * @param processInstance The process instance to enrich with assignees. + * @param workflow The workflow containing assignees to be added to the process instance. + */ + public void enrichAssignesInWorkflow(ProcessInstance processInstance, Workflow workflow) { + List userUuidList = CollectionUtils.isEmpty(workflow.getAssignes()) + ? new LinkedList<>() + : workflow.getAssignes().stream() + .map(assignee -> User.builder().uuid(assignee).build()) + .collect(toList()); + + processInstance.setAssignes(userUuidList); + } + + /** + * Constructs the URI for the workflow service transition API. + * + * @return The StringBuilder containing the constructed workflow transition URI. + */ + private StringBuilder getWorkflowTransitionUri() { + StringBuilder uri = new StringBuilder(); + return uri.append(config.getWfHost()).append(config.getWfTransitionPath()); + } + + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index 135f4991a88..175c6ec08e8 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -11,6 +11,7 @@ import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Pattern; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @@ -49,7 +50,7 @@ public class PlanConfiguration { @JsonProperty("status") @NotNull - private StatusEnum status = null; + private String status = null; @JsonProperty("files") @NotNull @@ -81,13 +82,7 @@ public class PlanConfiguration { @JsonProperty("additionalDetails") private Object additionalDetails = null; - /** - * The status used in the Plan Configuration - */ - public enum StatusEnum { - DRAFT , - GENERATED, - INVALID_DATA - } + @JsonProperty("workflow") + private Workflow workflow; } diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 25456401843..59426d5bb6b 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -51,9 +51,13 @@ plan.update.topic=update-plan #mdms urls egov.mdms.host=https://unified-dev.digit.org -egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +egov.mdms.search.endpoint=/mdms-v2/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search +# Workflow +egov.workflow.host=http://localhost:8083 +egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition + # Pagination config plan.default.offset=0 plan.default.limit=10 From 54de3a84bbbb7c425d7919f8f93d12960b64439f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 3 Oct 2024 16:02:37 +0530 Subject: [PATCH 100/351] HCMPRE-493 coderabbit review comments --- .../main/java/digit/service/PlanConfigurationService.java | 2 +- .../main/java/digit/service/workflow/WorkflowService.java | 8 ++++---- .../src/main/java/digit/web/models/PlanConfiguration.java | 1 + .../src/main/resources/application.properties | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java index 7fe2ef0176e..2cfecf9e6cd 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java @@ -85,8 +85,8 @@ public PlanConfigurationResponse search(PlanConfigurationSearchRequest request) */ public PlanConfigurationResponse update(PlanConfigurationRequest request) { validator.validateUpdateRequest(request); - workflowService.integrateWithWorkflow(request); enrichmentService.enrichUpdate(request); + workflowService.integrateWithWorkflow(request); repository.update(request); // Build and return response back to controller diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 8b50d0e6147..08e9b815883 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -43,7 +43,8 @@ public WorkflowService(ServiceRequestRepository serviceRequestRepository, Config * @param planConfigurationRequest The request containing the plan configuration to integrate with the workflow. */ public void integrateWithWorkflow(PlanConfigurationRequest planConfigurationRequest) { - if (planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction() == null) { + if (planConfigurationRequest.getPlanConfiguration().getWorkflow() == null || + planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction() == null) { return; } @@ -73,7 +74,7 @@ public ProcessInstanceResponse callWorkflowTransition(ProcessInstanceRequest pro Object response = serviceRequestRepository.fetchResult(getWorkflowTransitionUri(), processInstanceRequest); processInstanceResponse = mapper.convertValue(response, ProcessInstanceResponse.class); } catch (Exception e) { - throw new CustomException(WORKFLOW_INTEGRATION_ERROR_CODE, WORKFLOW_INTEGRATION_ERROR_MESSAGE + e); + throw new CustomException(WORKFLOW_INTEGRATION_ERROR_CODE, WORKFLOW_INTEGRATION_ERROR_MESSAGE + e.getMessage()); } return processInstanceResponse; @@ -127,8 +128,7 @@ public void enrichAssignesInWorkflow(ProcessInstance processInstance, Workflow w * @return The StringBuilder containing the constructed workflow transition URI. */ private StringBuilder getWorkflowTransitionUri() { - StringBuilder uri = new StringBuilder(); - return uri.append(config.getWfHost()).append(config.getWfTransitionPath()); + return new StringBuilder().append(config.getWfHost()).append(config.getWfTransitionPath()); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index 175c6ec08e8..22b5118b30f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -83,6 +83,7 @@ public class PlanConfiguration { private Object additionalDetails = null; @JsonProperty("workflow") + @Valid private Workflow workflow; } diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 59426d5bb6b..3dd7adffb6f 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -55,7 +55,7 @@ egov.mdms.search.endpoint=/mdms-v2/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search # Workflow -egov.workflow.host=http://localhost:8083 +egov.workflow.host=https://unified-dev.digit.org egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition # Pagination config From bf0ef782b34862b8db9e9bd57eea2af42e758e55 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 3 Oct 2024 16:57:43 +0530 Subject: [PATCH 101/351] HCMPRE-493 code review comments --- .../service/PlanConfigurationService.java | 2 +- .../service/workflow/WorkflowService.java | 24 ++++++------------- .../digit/web/models/PlanConfiguration.java | 1 - 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java index 2cfecf9e6cd..99bd71dc35a 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java @@ -86,7 +86,7 @@ public PlanConfigurationResponse search(PlanConfigurationSearchRequest request) public PlanConfigurationResponse update(PlanConfigurationRequest request) { validator.validateUpdateRequest(request); enrichmentService.enrichUpdate(request); - workflowService.integrateWithWorkflow(request); + workflowService.invokeWorkflowForStatusUpdate(request); repository.update(request); // Build and return response back to controller diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 08e9b815883..0da3314c727 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -10,14 +10,13 @@ import org.egov.common.contract.request.User; import org.egov.common.contract.workflow.*; import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.*; import static digit.config.ServiceConstants.*; -import static java.util.stream.Collectors.toList; @Service @Slf4j @@ -29,7 +28,6 @@ public class WorkflowService { private ObjectMapper mapper; - @Autowired public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; @@ -42,23 +40,15 @@ public WorkflowService(ServiceRequestRepository serviceRequestRepository, Config * * @param planConfigurationRequest The request containing the plan configuration to integrate with the workflow. */ - public void integrateWithWorkflow(PlanConfigurationRequest planConfigurationRequest) { - if (planConfigurationRequest.getPlanConfiguration().getWorkflow() == null || - planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction() == null) { + public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigurationRequest) { + if (ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow())) return; - } ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planConfigurationRequest); ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); - String businessId = planConfigurationRequest.getPlanConfiguration().getId(); - ProcessInstance processInstanceAfterTransition = processInstanceResponse.getProcessInstances().stream() - .filter(processInstance -> businessId.equals(processInstance.getBusinessId())) - .findFirst() - .orElseThrow(() -> new CustomException(PROCESS_INSTANCE_NOT_FOUND_CODE, PROCESS_INSTANCE_NOT_FOUND_MESSAGE + businessId)); - // Setting the status back to the plan configuration object from workflow response - planConfigurationRequest.getPlanConfiguration().setStatus(processInstanceAfterTransition.getState().getApplicationStatus()); + planConfigurationRequest.getPlanConfiguration().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); } /** @@ -113,13 +103,13 @@ public ProcessInstanceRequest createWorkflowRequest(PlanConfigurationRequest pla * @param workflow The workflow containing assignees to be added to the process instance. */ public void enrichAssignesInWorkflow(ProcessInstance processInstance, Workflow workflow) { - List userUuidList = CollectionUtils.isEmpty(workflow.getAssignes()) + List userList = CollectionUtils.isEmpty(workflow.getAssignes()) ? new LinkedList<>() : workflow.getAssignes().stream() .map(assignee -> User.builder().uuid(assignee).build()) - .collect(toList()); + .toList(); - processInstance.setAssignes(userUuidList); + processInstance.setAssignes(userList); } /** diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index 22b5118b30f..07afaff00db 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java @@ -49,7 +49,6 @@ public class PlanConfiguration { private String campaignId = null; @JsonProperty("status") - @NotNull private String status = null; @JsonProperty("files") From b4c28a6affc303b9ca6a549ea2393ef2c8dee658 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 3 Oct 2024 18:37:36 +0530 Subject: [PATCH 102/351] search api --- .../main/java/digit/config/Configuration.java | 21 +-- .../digit/repository/CensusRepository.java | 16 +++ .../repository/impl/CensusRepositoryImpl.java | 113 ++++++++++++++++ .../querybuilder/CensusQueryBuilder.java | 127 ++++++++++++++++++ .../repository/rowmapper/CensusRowMapper.java | 7 + .../java/digit/service/CensusService.java | 19 +++ .../service/enrichment/CensusEnrichment.java | 7 + .../service/validator/CensusValidator.java | 7 + .../src/main/java/digit/util/QueryUtil.java | 98 ++++++++++++++ .../main/java/digit/web/models/Census.java | 75 ++++++----- .../web/models/CensusSearchCriteria.java | 13 +- .../V20240925155908__census_create_ddl.sql | 47 ++++--- 12 files changed, 484 insertions(+), 66 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/repository/CensusRepository.java create mode 100644 health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java create mode 100644 health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java create mode 100644 health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java create mode 100644 health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java create mode 100644 health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java create mode 100644 health-services/census-service/src/main/java/digit/util/QueryUtil.java diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 6a9c1d422b0..02e629b0fce 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -1,19 +1,11 @@ package digit.config; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.*; import org.egov.tracer.config.TracerConfiguration; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Component; -import jakarta.annotation.PostConstruct; - -import java.util.TimeZone; - @Component @Data @Import({TracerConfiguration.class}) @@ -23,6 +15,12 @@ @Getter public class Configuration { + //Persister Topic + @Value("${census.create.topic}") + private String censusCreateTopic; + + @Value("${census.update.topic}") + private String censusUpdateTopic; // User Config @Value("${egov.user.host}") @@ -90,4 +88,11 @@ public class Configuration { //SMSNotification @Value("${egov.sms.notification.topic}") private String smsNotificationTopic; + + //Pagination + @Value("${census.default.offset}") + private Integer defaultOffset; + + @Value("${census.default.limit}") + private Integer defaultLimit; } diff --git a/health-services/census-service/src/main/java/digit/repository/CensusRepository.java b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java new file mode 100644 index 00000000000..06ef3a8317e --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java @@ -0,0 +1,16 @@ +package digit.repository; + +import digit.web.models.*; + +import java.util.List; + +public interface CensusRepository { + + public void create(CensusRequest censusRequest); + + public List search(CensusSearchCriteria censusSearchCriteria); + + public void update(CensusRequest censusRequest); + + public Integer count(CensusSearchCriteria censusSearchCriteria); +} diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java new file mode 100644 index 00000000000..37dd3e2377d --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -0,0 +1,113 @@ +package digit.repository.impl; + +import digit.config.Configuration; +import digit.kafka.Producer; +import digit.repository.CensusRepository; +import digit.repository.querybuilder.CensusQueryBuilder; +import digit.repository.rowmapper.CensusRowMapper; +import digit.web.models.Census; +import digit.web.models.CensusRequest; +import digit.web.models.CensusSearchCriteria; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.SingleColumnRowMapper; +import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Repository +public class CensusRepositoryImpl implements CensusRepository { + + private Producer producer; + + private Configuration config; + + private CensusQueryBuilder queryBuilder; + + private CensusRowMapper rowMapper; + + private JdbcTemplate jdbcTemplate; + + public CensusRepositoryImpl(Producer producer, Configuration config, CensusQueryBuilder queryBuilder, CensusRowMapper rowMapper, JdbcTemplate jdbcTemplate) { + this.producer = producer; + this.config = config; + this.queryBuilder = queryBuilder; + this.rowMapper = rowMapper; + this.jdbcTemplate = jdbcTemplate; + } + + /** + * Pushes a new census record to persister kafka topic. + * + * @param censusRequest The request containing the census details + */ + @Override + public void create(CensusRequest censusRequest) { + producer.push(config.getCensusCreateTopic(), censusRequest); + } + + /** + * Searches for census records based on the provided search criteria. + * + * @param censusSearchCriteria The criteria to use for searching census records. + * @return A list of census records that match the search criteria. + */ + @Override + public List search(CensusSearchCriteria censusSearchCriteria) { + + // Fetch census ids from database + List censusIds = queryDatabaseForCensusIds(censusSearchCriteria); + + // Return empty list back as response if no census ids are found + if (CollectionUtils.isEmpty(censusIds)) { + log.info("No census ids found for provided census search criteria."); + return new ArrayList<>(); + } + + return searchCensusByIds(censusIds); + } + + /** + * Helper method to search for census records based on the provided census ids. + * + * @param censusIds list of census ids to search for census records. + * @return a list of census records. + */ + private List searchCensusByIds(List censusIds) { + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getCensusQuery(censusIds, preparedStmtList); + log.info("Census query: " + query); + return jdbcTemplate.query(query, rowMapper, preparedStmtList.toArray()); + } + + /** + * Helper method to query database for census ids based on the provided search criteria. + * + * @param censusSearchCriteria The criteria to use for searching census records. + * @return a list of census ids that matches the provided search criteria + */ + private List queryDatabaseForCensusIds(CensusSearchCriteria censusSearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getCensusSearchQuery(censusSearchCriteria, preparedStmtList); + log.info("Census search query: " + query); + return jdbcTemplate.query(query, new SingleColumnRowMapper<>(String.class), preparedStmtList.toArray()); + } + + @Override + public Integer count(CensusSearchCriteria censusSearchCriteria) { + return 0; + } + + /** + * Pushes an updated existing census record to persister kafka topic. + * + * @param censusRequest The request containing the updated census details + */ + @Override + public void update(CensusRequest censusRequest) { + producer.push(config.getCensusUpdateTopic(), censusRequest); + } +} diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java new file mode 100644 index 00000000000..f6b4b743d8a --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -0,0 +1,127 @@ +package digit.repository.querybuilder; + +import digit.util.QueryUtil; +import digit.web.models.CensusSearchCriteria; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.HashSet; +import java.util.List; + +@Component +public class CensusQueryBuilder { + + private QueryUtil queryUtil; + + public CensusQueryBuilder(QueryUtil queryUtil) { + this.queryUtil = queryUtil; + } + + private static final String CENSUS_ID_SEARCH_BASE_QUERY = "SELECT id FROM census cen "; + + private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_code_ancestral_materialized_path as census_boundary_code_ancestral_materialized_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time,\n" + + "\t FROM census cen \n" + + "\t LEFT JOIN population_by_demographics pbd ON cen.id = pbd.census_id"; + + private static final String CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY cen.last_modified_time DESC"; + + private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + + /** + * Constructs a SQL query string for searching Census records based on the provided search criteria. + * Also adds an ORDER BY clause and handles pagination. + * + * @param censusSearchCriteria The criteria used for filtering Census records. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A complete SQL query string for searching Census records. + */ + public String getCensusSearchQuery(CensusSearchCriteria censusSearchCriteria, List preparedStmtList) { + String query = buildCensusSearchQuery(censusSearchCriteria, preparedStmtList, Boolean.FALSE); + query = queryUtil.addOrderByClause(query, CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = queryUtil.getPaginatedQuery(query, preparedStmtList); + + return query; + } + + /** + * Constructs query based on the provided search criteria + * + * @param criteria The criteria used for filtering Census records. + * @param preparedStmtList A list to store prepared statement parameters. + * @return SQL query string for searching Census records + */ + private String buildCensusSearchQuery(CensusSearchCriteria criteria, List preparedStmtList, Boolean isCount) { + StringBuilder builder = new StringBuilder(CENSUS_ID_SEARCH_BASE_QUERY); + + if (criteria.getId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.id = ?"); + preparedStmtList.add(criteria.getId()); + } + + if (criteria.getTenantId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.tenant_id = ?"); + preparedStmtList.add(criteria.getTenantId()); + } + + if (criteria.getStatus() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.status = ?"); + preparedStmtList.add(criteria.getStatus()); + } + + if (criteria.getAssignee() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.assignee = ?"); + preparedStmtList.add(criteria.getAssignee()); + } + + if (!CollectionUtils.isEmpty(criteria.getAreaCodes())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.boundary_code IN ( ").append(queryUtil.createQuery(criteria.getAreaCodes().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(criteria.getAreaCodes())); + } + + if (!CollectionUtils.isEmpty(criteria.getMaterializedPath())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ").append(queryUtil.createQuery(criteria.getMaterializedPath().size())).append(" ]").append("::text[] "); + builder.append(" && string_to_array(boundary_code_ancestral_materialized_path, ',') "); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(criteria.getMaterializedPath())); + } + + return builder.toString(); + } + + /** + * Constructs a SQL query string for searching Census records based on the provided list of Census Ids. + * + * @param censusIds The list of census ids for searching census records + * @param preparedStmtList A list to store prepared statement parameters. + * @return A complete SQL query string for searching Census records. + */ + public String getCensusQuery(List censusIds, List preparedStmtList) { + return buildCensusQuery(censusIds, preparedStmtList); + } + + /** + * Constructs query based on the list of Census id provided. + * + * @param censusIds The list of census ids for searching census records + * @param preparedStmtList A list to store prepared statement parameters. + * @return A complete SQL query string for searching Census records. + */ + private String buildCensusQuery(List censusIds, List preparedStmtList) { + StringBuilder builder = new StringBuilder(CENSUS_SEARCH_BASE_QUERY); + + if (!CollectionUtils.isEmpty(censusIds)) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.id IN ( ").append(queryUtil.createQuery(censusIds.size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(censusIds)); + } + + return queryUtil.addOrderByClause(builder.toString(), CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); + } + +} diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java new file mode 100644 index 00000000000..dbcb21bfbee --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -0,0 +1,7 @@ +package digit.repository.rowmapper; + +import org.springframework.stereotype.Component; + +@Component +public class CensusRowMapper { +} diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index 1043246e644..0b4746c80de 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -1,5 +1,8 @@ package digit.service; +import digit.repository.CensusRepository; +import digit.service.enrichment.CensusEnrichment; +import digit.service.validator.CensusValidator; import digit.util.ResponseInfoFactory; import digit.web.models.CensusRequest; import digit.web.models.CensusResponse; @@ -13,6 +16,19 @@ public class CensusService { private ResponseInfoFactory responseInfoFactory; + private CensusRepository repository; + + private CensusValidator validator; + + private CensusEnrichment enrichment; + + public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository repository, CensusValidator validator, CensusEnrichment enrichment) { + this.responseInfoFactory = responseInfoFactory; + this.repository = repository; + this.validator = validator; + this.enrichment = enrichment; + } + /** * Creates a new census record based on the provided request. * @@ -20,6 +36,7 @@ public class CensusService { * @return The created census reponse. */ public CensusResponse create(CensusRequest request) { + repository.create(request); CensusResponse response = CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) @@ -36,6 +53,7 @@ public CensusResponse create(CensusRequest request) { public CensusResponse search(CensusSearchRequest request) { CensusResponse response = CensusResponse.builder() .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .census(repository.search(request.getCensusSearchCriteria())) .build(); return response; @@ -48,6 +66,7 @@ public CensusResponse search(CensusSearchRequest request) { * @return The updated census response. */ public CensusResponse update(CensusRequest request) { + repository.update(request); CensusResponse response = CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java new file mode 100644 index 00000000000..df10fdf049d --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -0,0 +1,7 @@ +package digit.service.enrichment; + +import org.springframework.stereotype.Component; + +@Component +public class CensusEnrichment { +} diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java new file mode 100644 index 00000000000..165d4d2f0ab --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -0,0 +1,7 @@ +package digit.service.validator; + +import org.springframework.stereotype.Component; + +@Component +public class CensusValidator { +} diff --git a/health-services/census-service/src/main/java/digit/util/QueryUtil.java b/health-services/census-service/src/main/java/digit/util/QueryUtil.java new file mode 100644 index 00000000000..824dc654b25 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/QueryUtil.java @@ -0,0 +1,98 @@ +package digit.util; + +import digit.config.Configuration; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Set; +import java.util.stream.IntStream; + +@Component +public class QueryUtil { + + private Configuration config; + + private QueryUtil(Configuration config) { + this.config = config; + } + + /** + * This method adds "WHERE" clause and "AND" condition depending on preparedStatementList i.e., + * if preparedStatementList is empty, it will understand that it is the first clause being added so it + * will add "WHERE" to the query and otherwise it will + * + * @param query + * @param preparedStmtList + */ + public void addClauseIfRequired(StringBuilder query, List preparedStmtList) { + if (preparedStmtList.isEmpty()) { + query.append(" WHERE "); + } else { + query.append(" AND "); + } + } + + /** + * This method returns a string with placeholders equal to the number of values that need to be put inside + * "IN" clause + * + * @param size + * @return + */ + public String createQuery(Integer size) { + StringBuilder builder = new StringBuilder(); + + IntStream.range(0, size).forEach(i -> { + builder.append(" ?"); + if (i != size - 1) + builder.append(","); + }); + + return builder.toString(); + } + + /** + * This method adds a set of String values into preparedStatementList + * + * @param preparedStmtList + * @param ids + */ + public void addToPreparedStatement(List preparedStmtList, Set ids) { + ids.forEach(id -> { + preparedStmtList.add(id); + }); + } + + /** + * This method appends order by clause to the query + * + * @param query + * @param orderByClause + * @return + */ + public String addOrderByClause(String query, String orderByClause) { + return query + orderByClause; + } + + /** + * This method appends pagination i.e. limit and offset to the query + * + * @param query + * @param preparedStmtList + * @return + */ + public String getPaginatedQuery(String query, List preparedStmtList) { + StringBuilder paginatedQuery = new StringBuilder(query); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(config.getDefaultOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(config.getDefaultLimit()); + + return paginatedQuery.toString(); + } + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 88b8a594ba0..220f4c369fb 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -1,12 +1,9 @@ package digit.web.models; -import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import digit.web.models.PopulationByDemographic; -import io.swagger.v3.oas.annotations.media.Schema; import java.util.ArrayList; import java.util.List; @@ -14,10 +11,7 @@ import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; +import lombok.*; /** * Census @@ -46,6 +40,48 @@ public class Census { @NotNull private String boundaryCode = null; + @JsonProperty("assignee") + @NotNull + private String assignee = null; + + @JsonProperty("status") + @NotNull + private StatusEnum status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("effectiveFrom") + private Long effectiveFrom = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("source") + @NotNull + private String source = null; + + @JsonProperty("materializedPath") + @NotNull + private List materializedPath = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + /** + * The status used in the Census + */ + public enum StatusEnum {} + /** * Gets or Sets type */ @@ -81,31 +117,6 @@ public static TypeEnum fromValue(String text) { } } - @JsonProperty("type") - @NotNull - private TypeEnum type = null; - - @JsonProperty("totalPopulation") - @NotNull - private Long totalPopulation = null; - - @JsonProperty("populationByDemographics") - @Valid - private List populationByDemographics = null; - - @JsonProperty("effectiveFrom") - private Long effectiveFrom = null; - - @JsonProperty("effectiveTo") - private Long effectiveTo = null; - - @JsonProperty("source") - @NotNull - private String source = null; - - @JsonProperty("additionalDetails") - private Object additionalDetails = null; - public Census addPopulationByDemographicsItem(PopulationByDemographic populationByDemographicsItem) { if (this.populationByDemographics == null) { diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index c51a8eb8356..ec7ba89728c 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -1,16 +1,12 @@ package digit.web.models; -import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import io.swagger.v3.oas.annotations.media.Schema; import java.util.ArrayList; import java.util.List; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; import jakarta.validation.constraints.*; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @@ -37,6 +33,15 @@ public class CensusSearchCriteria { @JsonProperty("areaCodes") private List areaCodes = null; + @JsonProperty("status") + private String status = null; + + @JsonProperty("assignee") + private String assignee = null; + + @JsonProperty("boundaryCodeAncestralMaterializedPath") + private List materializedPath = null; + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql index 14900e23d5a..c334620f514 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -1,32 +1,35 @@ -- Table: census CREATE TABLE census ( - id character varying(64), - tenant_id character varying(64), - hierarchy_type character varying(64), - boundary_code character varying(64), - type character varying(64), - total_population bigint, - effective_from bigint, - effective_to bigint, - source character varying(255), - additional_details JSONB, - created_by character varying(64), - created_time bigint, - last_modified_by character varying(64), - last_modified_time bigint, + id character varying(64), + tenant_id character varying(64), + hierarchy_type character varying(64), + boundary_code character varying(64), + type character varying(64), + total_population bigint, + effective_from bigint, + effective_to bigint, + source character varying(255), + status character varying(255), + assignee character varying(255), + boundary_code_ancestral_materialized_path TEXT + additional_details JSONB, + created_by character varying(64), + created_time bigint, + last_modified_by character varying(64), + last_modified_time bigint, CONSTRAINT uk_census_id PRIMARY KEY (id) ); -- Table: population_by_demographics CREATE TABLE population_by_demographics ( - id character varying(64), - census_id character varying(64), - demographic_variable character varying(64), - population_distribution JSONB, - created_by character varying(64), - created_time bigint, - last_modified_by character varying(64), - last_modified_time bigint, + id character varying(64), + census_id character varying(64), + demographic_variable character varying(64), + population_distribution JSONB, + created_by character varying(64), + created_time bigint, + last_modified_by character varying(64), + last_modified_time bigint, CONSTRAINT uk_population_by_demographics_id PRIMARY KEY (id), FOREIGN KEY (census_id) REFERENCES census(id) ); From 74f7c81f79ece1fb47117c321033c908f4c5b791 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 4 Oct 2024 12:17:18 +0530 Subject: [PATCH 103/351] removed service util --- .../src/main/java/digit/util/ServiceUtil.java | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 health-services/plan-service/src/main/java/digit/util/ServiceUtil.java diff --git a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java deleted file mode 100644 index 51959990534..00000000000 --- a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java +++ /dev/null @@ -1,23 +0,0 @@ -package digit.util; - -import org.springframework.stereotype.Component; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -@Component -public class ServiceUtil { - - /** - * Validates the given input string against the provided regex pattern. - * - * @param patternString the regex pattern to validate against - * @param inputString the input string to be validated - * @return true if the input string matches the regex pattern, false otherwise - */ - public Boolean validateStringAgainstRegex(String patternString, String inputString) { - Pattern pattern = Pattern.compile(patternString); - Matcher matcher = pattern.matcher(inputString); - return matcher.matches(); - } -} From bc177b0032ed9a0ae8389381ab3cc6ac6602c444 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 4 Oct 2024 12:34:44 +0530 Subject: [PATCH 104/351] resolved comment --- .../digit/repository/querybuilder/PlanConfigQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index f5a38b53c1d..5106f016796 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -9,7 +9,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import static digit.config.ServiceConstants.*; +import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; @Component public class PlanConfigQueryBuilder { From ce1c239147a4602b366b5ab6629e57bcfaa64d8a Mon Sep 17 00:00:00 2001 From: Palak Garg <86659286+palak-egov@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:07:59 +0530 Subject: [PATCH 105/351] repair to migrate --- health-services/plan-service/src/main/resources/db/migrate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migrate.sh b/health-services/plan-service/src/main/resources/db/migrate.sh index 0f00dd9153a..f9d6617822c 100644 --- a/health-services/plan-service/src/main/resources/db/migrate.sh +++ b/health-services/plan-service/src/main/resources/db/migrate.sh @@ -1,3 +1,3 @@ #!/bin/sh -flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true repair +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate From 3bcea3e79de9d1402a59d917b261a20269c1172c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 4 Oct 2024 14:00:12 +0530 Subject: [PATCH 106/351] search API --- .../java/digit/config/ServiceConstants.java | 4 +- .../repository/impl/CensusRepositoryImpl.java | 44 +++++- .../repository/rowmapper/CensusRowMapper.java | 104 +++++++++++++- .../src/main/java/digit/util/QueryUtil.java | 67 ++++++--- .../main/java/digit/web/models/Census.java | 14 +- .../main/java/digit/web/models/CensusDTO.java | 127 ++++++++++++++++++ .../digit/web/models/CensusRequestDTO.java | 31 +++++ .../web/models/PopulationByDemographic.java | 16 +-- 8 files changed, 373 insertions(+), 34 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusDTO.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusRequestDTO.java diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 6b0c4a6f9ab..ea509513ad5 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -38,7 +38,9 @@ public class ServiceConstants { public static final String CITIZEN_LOWER = "Citizen"; public static final String USER = "user"; - public static final String PARSING_ERROR = "PARSING ERROR"; + public static final String PARSING_ERROR_CODE = "PARSING ERROR"; + public static final String PARSING_ERROR_MESSAGE = "Failed to parse JSON data from PGobject"; + public static final String FAILED_TO_PARSE_BUSINESS_SERVICE_SEARCH = "Failed to parse response of workflow business service search"; public static final String BUSINESS_SERVICE_NOT_FOUND = "BUSINESSSERVICE_NOT_FOUND"; public static final String THE_BUSINESS_SERVICE = "The businessService "; diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 37dd3e2377d..53b9b78f385 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -5,9 +5,7 @@ import digit.repository.CensusRepository; import digit.repository.querybuilder.CensusQueryBuilder; import digit.repository.rowmapper.CensusRowMapper; -import digit.web.models.Census; -import digit.web.models.CensusRequest; -import digit.web.models.CensusSearchCriteria; +import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SingleColumnRowMapper; @@ -46,7 +44,8 @@ public CensusRepositoryImpl(Producer producer, Configuration config, CensusQuery */ @Override public void create(CensusRequest censusRequest) { - producer.push(config.getCensusCreateTopic(), censusRequest); + CensusRequestDTO requestDTO = convertToReqDTO(censusRequest); + producer.push(config.getCensusCreateTopic(), requestDTO); } /** @@ -108,6 +107,41 @@ public Integer count(CensusSearchCriteria censusSearchCriteria) { */ @Override public void update(CensusRequest censusRequest) { - producer.push(config.getCensusUpdateTopic(), censusRequest); + CensusRequestDTO requestDTO = convertToReqDTO(censusRequest); + producer.push(config.getCensusUpdateTopic(), requestDTO); + } + + /** + * Converts the CensusRequest to a data transfer object (DTO) + * + * @param censusRequest The request to be converted to DTO + * @return a DTO for CensusRequest + */ + private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { + Census census = censusRequest.getCensus(); + + // Creating a new data transfer object (DTO) for Census + CensusDTO censusDTO = CensusDTO.builder() + .id(census.getId()) + .tenantId(census.getTenantId()) + .hierarchyType(census.getHierarchyType()) + .boundaryCode(census.getBoundaryCode()) + .assignee(census.getAssignee()) + .status(CensusDTO.StatusEnum.valueOf(census.getStatus().toString())) + .type(CensusDTO.TypeEnum.valueOf(census.getType().toString())) + .totalPopulation(census.getTotalPopulation()) + .populationByDemographics(census.getPopulationByDemographics()) + .effectiveFrom(census.getEffectiveFrom()) + .effectiveTo(census.getEffectiveTo()) + .source(census.getSource()) + .materializedPath(String.join(",", census.getMaterializedPath())) + .additionalDetails(census.getAdditionalDetails()) + .auditDetails(census.getAuditDetails()) + .build(); + + return CensusRequestDTO.builder() + .requestInfo(censusRequest.getRequestInfo()) + .censusDTO(censusDTO) + .build(); } } diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index dbcb21bfbee..65a5ec95b54 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -1,7 +1,109 @@ package digit.repository.rowmapper; +import digit.util.QueryUtil; +import digit.web.models.Census; +import digit.web.models.PopulationByDemographic; +import org.egov.common.contract.models.AuditDetails; +import org.postgresql.util.PGobject; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; @Component -public class CensusRowMapper { +public class CensusRowMapper implements ResultSetExtractor> { + + private QueryUtil queryUtil; + + public CensusRowMapper(QueryUtil queryUtil) { + this.queryUtil = queryUtil; + } + + /** + * Creates a list of Census record based on the ResultSet. + * + * @param rs the ResultSet containing data. + * @return a list of Census record + * @throws SQLException + * @throws DataAccessException + */ + @Override + public List extractData(ResultSet rs) throws SQLException, DataAccessException { + Map censusMap = new LinkedHashMap<>(); + Map populationByDemographicMap = new LinkedHashMap<>(); + + while (rs.next()) { + String censusId = rs.getString("census_id"); + Census censusEntry = censusMap.get(censusId); + + if (ObjectUtils.isEmpty(censusEntry)) { + censusEntry = new Census(); + + // Prepare audit details + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("census_created_by")).createdTime(rs.getLong("census_created_time")).lastModifiedBy(rs.getString("census_last_modified_by")).lastModifiedTime(rs.getLong("census_last_modified_time")).build(); + + // Converting materialized path from comma separated string to a list of string + String materializedPath = rs.getString("census_boundary_code_ancestral_materialized_path"); + List materializedPathList = Arrays.asList(materializedPath.split(",")); + + // Prepare census entry + censusEntry.setId(rs.getString("census_id")); + censusEntry.setTenantId(rs.getString("census_tenant_id")); + censusEntry.setHierarchyType(rs.getString("census_hierarchy_type")); + censusEntry.setBoundaryCode(rs.getString("census_boundary_code")); + censusEntry.setType(Census.TypeEnum.valueOf(rs.getString("census_type").toUpperCase())); + censusEntry.setTotalPopulation(rs.getLong("census_total_population")); + censusEntry.setEffectiveFrom(rs.getLong("census_effective_from")); + censusEntry.setEffectiveTo(rs.getLong("census_effective_to")); + censusEntry.setSource(rs.getString("census_source")); + censusEntry.setStatus(Census.StatusEnum.valueOf(rs.getString("census_status").toUpperCase())); + censusEntry.setAssignee(rs.getString("census_assignee")); + censusEntry.setMaterializedPath(materializedPathList); + censusEntry.setAdditionalDetails(queryUtil.parseJson((PGobject) rs.getObject("census_additional_details"))); + censusEntry.setAuditDetails(auditDetails); + } + addPopulationByDemographic(rs, populationByDemographicMap, censusEntry); + + censusMap.put(censusId, censusEntry); + } + + return new ArrayList<>(censusMap.values()); + } + + + /** + * Adds a PopulationByDemographics object to the census entry based on the result set. + * + * @param rs The ResultSet containing the data. + * @param populationByDemographicMap A map to keep track of added PopulationByDemographics objects. + * @param censusEntry The Census entry to which the PopulationByDemographics object will be added. + * @throws SQLException If an SQL error occurs. + */ + private void addPopulationByDemographic(ResultSet rs, Map populationByDemographicMap, Census censusEntry) throws SQLException { + String populationByDemographicId = rs.getString("population_by_demographics_id"); + + if (ObjectUtils.isEmpty(populationByDemographicId) || populationByDemographicMap.containsKey(populationByDemographicId)) { + return; + } + + PopulationByDemographic populationByDemographic = new PopulationByDemographic(); + populationByDemographic.setId(rs.getString("population_by_demographics_id")); + populationByDemographic.setDemographicVariable(PopulationByDemographic.DemographicVariableEnum.valueOf(rs.getString("population_by_demographics_demographic_variable"))); + populationByDemographic.setPopulationDistribution(queryUtil.parseJson((PGobject) rs.getObject("population_by_demographics_population_distribution"))); + + if (CollectionUtils.isEmpty(censusEntry.getPopulationByDemographics())) { + List populationByDemographicList = new ArrayList<>(); + populationByDemographicList.add(populationByDemographic); + censusEntry.setPopulationByDemographics(populationByDemographicList); + } else { + censusEntry.getPopulationByDemographics().add(populationByDemographic); + } + + populationByDemographicMap.put(populationByDemographicId, populationByDemographic); + } } diff --git a/health-services/census-service/src/main/java/digit/util/QueryUtil.java b/health-services/census-service/src/main/java/digit/util/QueryUtil.java index 824dc654b25..1139f06d47a 100644 --- a/health-services/census-service/src/main/java/digit/util/QueryUtil.java +++ b/health-services/census-service/src/main/java/digit/util/QueryUtil.java @@ -1,19 +1,32 @@ package digit.util; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import digit.config.Configuration; +import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.CustomException; +import org.postgresql.util.PGobject; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import java.io.IOException; import java.util.List; import java.util.Set; import java.util.stream.IntStream; +import static digit.config.ServiceConstants.*; + +@Slf4j @Component public class QueryUtil { private Configuration config; - private QueryUtil(Configuration config) { + private ObjectMapper objectMapper; + + private QueryUtil(Configuration config, ObjectMapper objectMapper) { this.config = config; + this.objectMapper = objectMapper; } /** @@ -21,8 +34,8 @@ private QueryUtil(Configuration config) { * if preparedStatementList is empty, it will understand that it is the first clause being added so it * will add "WHERE" to the query and otherwise it will * - * @param query - * @param preparedStmtList + * @param query query to which Clause is to be added. + * @param preparedStmtList prepared statement list to check which clause to add. */ public void addClauseIfRequired(StringBuilder query, List preparedStmtList) { if (preparedStmtList.isEmpty()) { @@ -36,8 +49,8 @@ public void addClauseIfRequired(StringBuilder query, List preparedStmtLi * This method returns a string with placeholders equal to the number of values that need to be put inside * "IN" clause * - * @param size - * @return + * @param size number of placeholders to be added. + * @return a string with provided number of placeholders. */ public String createQuery(Integer size) { StringBuilder builder = new StringBuilder(); @@ -52,10 +65,10 @@ public String createQuery(Integer size) { } /** - * This method adds a set of String values into preparedStatementList + * This method adds a set of String values into preparedStatementList. * - * @param preparedStmtList - * @param ids + * @param preparedStmtList prepared statement list to add Ids. + * @param ids set of Ids to be added. */ public void addToPreparedStatement(List preparedStmtList, Set ids) { ids.forEach(id -> { @@ -64,22 +77,22 @@ public void addToPreparedStatement(List preparedStmtList, Set id } /** - * This method appends order by clause to the query + * This method appends order by clause to the query. * - * @param query - * @param orderByClause - * @return + * @param query the query to which orderBy clause is to be added. + * @param orderByClause the orderBy clause to be added. + * @return a query with orderBy clause. */ public String addOrderByClause(String query, String orderByClause) { return query + orderByClause; } /** - * This method appends pagination i.e. limit and offset to the query + * This method appends pagination i.e. limit and offset to the query. * - * @param query - * @param preparedStmtList - * @return + * @param query the query to which pagination is to be added. + * @param preparedStmtList prepared statement list to add limit and offset. + * @return a query with pagination */ public String getPaginatedQuery(String query, List preparedStmtList) { StringBuilder paginatedQuery = new StringBuilder(query); @@ -95,4 +108,26 @@ public String getPaginatedQuery(String query, List preparedStmtList) { return paginatedQuery.toString(); } + /** + * This method is used to extract and parse JSON data into a JsonNode object. + * + * @param pgObject postgreSQL specific object. + * @return returns a JsonNode. + */ + public JsonNode parseJson(PGobject pgObject) { + + try { + if (!ObjectUtils.isEmpty(pgObject)) { + return objectMapper.readTree(pgObject.getValue()); + } + } catch (IOException e) { + log.error("Error parsing PGobject value: " + pgObject, e); + throw new CustomException(PARSING_ERROR_CODE, PARSING_ERROR_MESSAGE); + } + + // Return empty JsonNode if pgObject is empty + return objectMapper.createObjectNode(); + } + + } diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 220f4c369fb..142047fb719 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -8,10 +8,17 @@ import java.util.ArrayList; import java.util.List; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; -import jakarta.validation.constraints.*; -import lombok.*; + + /** * Census @@ -77,6 +84,9 @@ public class Census { @JsonProperty("additionalDetails") private Object additionalDetails = null; + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; + /** * The status used in the Census */ diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java new file mode 100644 index 00000000000..65eb718f4c1 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -0,0 +1,127 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; + + +/** + * CensusDTO + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusDTO { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("hierarchyType") + @NotNull + private String hierarchyType = null; + + @JsonProperty("boundaryCode") + @NotNull + private String boundaryCode = null; + + @JsonProperty("assignee") + @NotNull + private String assignee = null; + + @JsonProperty("status") + @NotNull + private StatusEnum status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("effectiveFrom") + private Long effectiveFrom = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("source") + @NotNull + private String source = null; + + @JsonProperty("materializedPath") + @NotNull + private String materializedPath = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; + + /** + * The status used in the Census + */ + public enum StatusEnum {} + + /** + * Gets or Sets type + */ + public enum TypeEnum { + PEOPLE("people"), + + ANIMALS("animals"), + + PLANTS("plants"), + + OTHER("other"); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String text) { + for (TypeEnum b : TypeEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } +} diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusRequestDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusRequestDTO.java new file mode 100644 index 00000000000..7b1ced9a7db --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusRequestDTO.java @@ -0,0 +1,31 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusRequestDTO + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusRequestDTO { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Census") + @Valid + private CensusDTO censusDTO = null; + + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java b/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java index 6b5a1da5a03..8b984e06d89 100644 --- a/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java +++ b/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java @@ -1,14 +1,12 @@ package digit.web.models; -import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Size; import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; -import jakarta.validation.constraints.*; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.Data; @@ -29,6 +27,12 @@ public class PopulationByDemographic { @Size(min = 2, max = 64) private String id = null; + @JsonProperty("demographicVariable") + private DemographicVariableEnum demographicVariable = null; + + @JsonProperty("populationDistribution") + private Object populationDistribution = null; + /** * Gets or Sets demographicVariable */ @@ -62,10 +66,4 @@ public static DemographicVariableEnum fromValue(String text) { } } - @JsonProperty("demographicVariable") - private DemographicVariableEnum demographicVariable = null; - - @JsonProperty("populationDistribution") - private Object populationDistribution = null; - } From b4493430e96216217275bfe3849cfb5254291f46 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 4 Oct 2024 15:49:22 +0530 Subject: [PATCH 107/351] search API --- .../digit/repository/querybuilder/CensusQueryBuilder.java | 4 ++-- .../main/java/digit/repository/rowmapper/CensusRowMapper.java | 2 +- .../census-service/src/main/java/digit/web/models/Census.java | 2 +- .../src/main/java/digit/web/models/CensusDTO.java | 2 +- .../db/migration/main/V20240925155908__census_create_ddl.sql | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index f6b4b743d8a..0537d19a617 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -19,7 +19,7 @@ public CensusQueryBuilder(QueryUtil queryUtil) { private static final String CENSUS_ID_SEARCH_BASE_QUERY = "SELECT id FROM census cen "; - private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_code_ancestral_materialized_path as census_boundary_code_ancestral_materialized_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + + private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.materialized_path as census_materialized_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time,\n" + "\t FROM census cen \n" + "\t LEFT JOIN population_by_demographics pbd ON cen.id = pbd.census_id"; @@ -87,7 +87,7 @@ private String buildCensusSearchQuery(CensusSearchCriteria criteria, List(criteria.getMaterializedPath())); } diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 65a5ec95b54..0a127be74ac 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -48,7 +48,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("census_created_by")).createdTime(rs.getLong("census_created_time")).lastModifiedBy(rs.getString("census_last_modified_by")).lastModifiedTime(rs.getLong("census_last_modified_time")).build(); // Converting materialized path from comma separated string to a list of string - String materializedPath = rs.getString("census_boundary_code_ancestral_materialized_path"); + String materializedPath = rs.getString("census_materialized_path"); List materializedPathList = Arrays.asList(materializedPath.split(",")); // Prepare census entry diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 142047fb719..61be8a73219 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -77,7 +77,7 @@ public class Census { @NotNull private String source = null; - @JsonProperty("materializedPath") + @JsonProperty("boundaryCodeAncestralMaterializedPath") @NotNull private List materializedPath = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 65eb718f4c1..89aa8813011 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -75,7 +75,7 @@ public class CensusDTO { @NotNull private String source = null; - @JsonProperty("materializedPath") + @JsonProperty("boundaryCodeAncestralMaterializedPath") @NotNull private String materializedPath = null; diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql index c334620f514..4e3d72716e5 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -11,7 +11,7 @@ CREATE TABLE census ( source character varying(255), status character varying(255), assignee character varying(255), - boundary_code_ancestral_materialized_path TEXT + materialized_path TEXT additional_details JSONB, created_by character varying(64), created_time bigint, From dc5460dd1866756419e7d4b715d73a9df3495300 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 4 Oct 2024 16:10:51 +0530 Subject: [PATCH 108/351] role map --- .../plan-service/src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 9900545324a..6a4f485ca0b 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -73,4 +73,4 @@ resource.config.consumer.plan.create.topic=resource-microplan-create-topic resource.update.plan.config.consumer.topic=resource-plan-config-update-topic # Role Map -role.map = {NATIONAL_FACILITY_CATCHMENT_ASSIGNER:'FACILITY_CATCHMENT_ASSIGNER', FACILITY_CATCHMENT_ASSIGNER:'NATIONAL_FACILITY_CATCHMENT_ASSIGNER', NATIONAL_POPULATION_DATA_APPROVER:'POPULATION_DATA_APPROVER', POPULATION_DATA_APPROVER:'NATIONAL_POPULATION_DATA_APPROVER', NATIONAL_MICROPLAN_APPROVER:'MICROPLAN_APPROVER', MICROPLAN_APPROVER:'NATIONAL_MICROPLAN_APPROVER'} \ No newline at end of file +role.map = {ROOT_FACILITY_CATCHMENT_ASSIGNER:'FACILITY_CATCHMENT_ASSIGNER', FACILITY_CATCHMENT_ASSIGNER:'ROOT_FACILITY_CATCHMENT_ASSIGNER', ROOT_POPULATION_DATA_APPROVER:'POPULATION_DATA_APPROVER', POPULATION_DATA_APPROVER:'ROOT_POPULATION_DATA_APPROVER', ROOT_MICROPLAN_APPROVER:'MICROPLAN_APPROVER', MICROPLAN_APPROVER:'ROOT_MICROPLAN_APPROVER'} \ No newline at end of file From 1a1ed8f99969916418567c038f1d447f91ac60db Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 5 Oct 2024 12:19:18 +0530 Subject: [PATCH 109/351] added employee's uuid to search criteria --- .../plan-service/src/main/java/digit/util/HrmsUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java index efe12295630..614b9b4be4c 100644 --- a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java @@ -64,7 +64,7 @@ public EmployeeResponse fetchHrmsData(RequestInfo requestInfo, String employeeId */ private StringBuilder getHrmsUri(Map uriParameters, String tenantId, String employeeId) { StringBuilder uri = new StringBuilder(); - uri.append(configs.getHrmsHost()).append(configs.getHrmsEndPoint()).append("?limit={limit}&tenantId={tenantId}&offset={offset}&ids={employeeId}"); + uri.append(configs.getHrmsHost()).append(configs.getHrmsEndPoint()).append("?limit={limit}&tenantId={tenantId}&offset={offset}&uuids={employeeId}"); uriParameters.put("limit", configs.getDefaultLimit().toString()); uriParameters.put("tenantId", tenantId); From c71c0a54827793996b9d9ff6dc74d1099cfed554 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 5 Oct 2024 12:20:15 +0530 Subject: [PATCH 110/351] added employee's uuid to search criteria --- .../plan-service/src/main/java/digit/util/ServiceUtil.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 health-services/plan-service/src/main/java/digit/util/ServiceUtil.java diff --git a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java deleted file mode 100644 index e69de29bb2d..00000000000 From edeb33a87e53b01a923c68eb22505b1a434bc955 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 7 Oct 2024 10:53:12 +0530 Subject: [PATCH 111/351] flyway disabled --- .../census-service/src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 689b8a675a8..69d08c8b227 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -18,7 +18,7 @@ spring.flyway.table=public spring.flyway.baseline-on-migrate=true spring.flyway.outOfOrder=true spring.flyway.locations=classpath:/db/migration/main -spring.flyway.enabled=true +spring.flyway.enabled=false # KAFKA SERVER CONFIGURATIONS kafka.config.bootstrap_server_config=localhost:9092 From 01568a262ef1722b677cf2847437fcd10cacf6f1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 7 Oct 2024 12:12:53 +0530 Subject: [PATCH 112/351] modified enum --- .../repository/impl/CensusRepositoryImpl.java | 4 +- .../main/java/digit/util/WorkflowUtil.java | 2 +- .../main/java/digit/web/models/Census.java | 23 +++++---- .../main/java/digit/web/models/CensusDTO.java | 47 +------------------ .../src/main/resources/application.properties | 4 +- .../V20240925155908__census_create_ddl.sql | 2 +- 6 files changed, 19 insertions(+), 63 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 53b9b78f385..718a64a78a8 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -127,8 +127,8 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .hierarchyType(census.getHierarchyType()) .boundaryCode(census.getBoundaryCode()) .assignee(census.getAssignee()) - .status(CensusDTO.StatusEnum.valueOf(census.getStatus().toString())) - .type(CensusDTO.TypeEnum.valueOf(census.getType().toString())) + .status(census.getStatus().toString()) + .type(census.getType().toString()) .totalPopulation(census.getTotalPopulation()) .populationByDemographics(census.getPopulationByDemographics()) .effectiveFrom(census.getEffectiveFrom()) diff --git a/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java b/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java index ed996e01813..6cea1a4a6a0 100644 --- a/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java +++ b/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java @@ -47,7 +47,7 @@ public BusinessService getBusinessService(RequestInfo requestInfo, String tenant try { response = mapper.convertValue(result, BusinessServiceResponse.class); } catch (IllegalArgumentException e) { - throw new CustomException(PARSING_ERROR, FAILED_TO_PARSE_BUSINESS_SERVICE_SEARCH); + throw new CustomException(PARSING_ERROR_CODE, FAILED_TO_PARSE_BUSINESS_SERVICE_SEARCH); } if (CollectionUtils.isEmpty(response.getBusinessServices())) diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 61be8a73219..fd3f96b0adf 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonValue; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import jakarta.validation.constraints.NotNull; @@ -19,7 +20,6 @@ import jakarta.validation.Valid; - /** * Census */ @@ -90,18 +90,19 @@ public class Census { /** * The status used in the Census */ - public enum StatusEnum {} + public enum StatusEnum { + DRAFT, + GENERATED, + INVALID_DATA + } /** * Gets or Sets type */ public enum TypeEnum { PEOPLE("people"), - ANIMALS("animals"), - PLANTS("plants"), - OTHER("other"); private String value; @@ -113,17 +114,15 @@ public enum TypeEnum { @Override @JsonValue public String toString() { - return String.valueOf(value); + return String.valueOf(value); // Return the exact value as lowercase } @JsonCreator public static TypeEnum fromValue(String text) { - for (TypeEnum b : TypeEnum.values()) { - if (String.valueOf(b.value).equals(text)) { - return b; - } - } - return null; + return Arrays.stream(TypeEnum.values()) + .filter(b -> String.valueOf(b.value).equals(text)) + .findFirst() + .orElse(null); } } diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 89aa8813011..940ba382aee 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -1,10 +1,7 @@ package digit.web.models; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import java.util.ArrayList; import java.util.List; import jakarta.validation.constraints.NotNull; @@ -51,11 +48,11 @@ public class CensusDTO { @JsonProperty("status") @NotNull - private StatusEnum status = null; + private String status = null; @JsonProperty("type") @NotNull - private TypeEnum type = null; + private String type = null; @JsonProperty("totalPopulation") @NotNull @@ -84,44 +81,4 @@ public class CensusDTO { @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; - - /** - * The status used in the Census - */ - public enum StatusEnum {} - - /** - * Gets or Sets type - */ - public enum TypeEnum { - PEOPLE("people"), - - ANIMALS("animals"), - - PLANTS("plants"), - - OTHER("other"); - - private String value; - - TypeEnum(String value) { - this.value = value; - } - - @Override - @JsonValue - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static TypeEnum fromValue(String text) { - for (TypeEnum b : TypeEnum.values()) { - if (String.valueOf(b.value).equals(text)) { - return b; - } - } - return null; - } - } } diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 69d08c8b227..295281ac0ea 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -1,5 +1,5 @@ -server.contextPath=/census-serivce -server.servlet.context-path=/census-serivce +server.contextPath=/census-service +server.servlet.context-path=/census-service management.endpoints.web.base-path=/ server.port=8080 app.timezone=UTC diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql index 4e3d72716e5..10c57479245 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -11,7 +11,7 @@ CREATE TABLE census ( source character varying(255), status character varying(255), assignee character varying(255), - materialized_path TEXT + materialized_path TEXT, additional_details JSONB, created_by character varying(64), created_time bigint, From 71e58bb278f42c27a7f00d7357691b46caec5bf5 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 7 Oct 2024 13:29:00 +0530 Subject: [PATCH 113/351] search api --- .../querybuilder/CensusQueryBuilder.java | 2 +- .../repository/rowmapper/CensusRowMapper.java | 4 +-- .../java/digit/service/CensusService.java | 1 + .../service/enrichment/CensusEnrichment.java | 30 +++++++++++++++++++ .../main/java/digit/web/models/Census.java | 12 ++++---- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 0537d19a617..4713fc7c741 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -20,7 +20,7 @@ public CensusQueryBuilder(QueryUtil queryUtil) { private static final String CENSUS_ID_SEARCH_BASE_QUERY = "SELECT id FROM census cen "; private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.materialized_path as census_materialized_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + - "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time,\n" + + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time \n" + "\t FROM census cen \n" + "\t LEFT JOIN population_by_demographics pbd ON cen.id = pbd.census_id"; diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 0a127be74ac..b7b63b4dc9f 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -56,7 +56,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setTenantId(rs.getString("census_tenant_id")); censusEntry.setHierarchyType(rs.getString("census_hierarchy_type")); censusEntry.setBoundaryCode(rs.getString("census_boundary_code")); - censusEntry.setType(Census.TypeEnum.valueOf(rs.getString("census_type").toUpperCase())); + censusEntry.setType(Census.TypeEnum.fromValue(rs.getString("census_type").toUpperCase())); censusEntry.setTotalPopulation(rs.getLong("census_total_population")); censusEntry.setEffectiveFrom(rs.getLong("census_effective_from")); censusEntry.setEffectiveTo(rs.getLong("census_effective_to")); @@ -93,7 +93,7 @@ private void addPopulationByDemographic(ResultSet rs, Map { + UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id"); + }); + + census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); + } } diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index fd3f96b0adf..b3db4fe6452 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -114,15 +114,17 @@ public enum TypeEnum { @Override @JsonValue public String toString() { - return String.valueOf(value); // Return the exact value as lowercase + return String.valueOf(value); } @JsonCreator public static TypeEnum fromValue(String text) { - return Arrays.stream(TypeEnum.values()) - .filter(b -> String.valueOf(b.value).equals(text)) - .findFirst() - .orElse(null); + for (TypeEnum b : TypeEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; } } From 0d96a63f46b68bd67f4fb6c8fca382395be14170 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 7 Oct 2024 13:55:58 +0530 Subject: [PATCH 114/351] enrichment --- .../java/digit/service/CensusService.java | 1 + .../service/enrichment/CensusEnrichment.java | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index 9740abf2f80..9857ad07391 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -67,6 +67,7 @@ public CensusResponse search(CensusSearchRequest request) { * @return The updated census response. */ public CensusResponse update(CensusRequest request) { + enrichment.enrichUpdate(request); repository.update(request); CensusResponse response = CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index da9445e11a6..f9204f7f3b0 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -3,8 +3,8 @@ import digit.web.models.Census; import digit.web.models.CensusRequest; import org.egov.common.utils.UUIDEnrichmentUtil; -import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @@ -34,4 +34,24 @@ public void enrichCreate(CensusRequest request) { census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); } + + /** + * Enriches the CensusRequest for updating an existing census record. + * This method enriches the census record for update and enriches audit details for update operation. + * + * @param request The CensusRequest to be enriched. + */ + public void enrichUpdate(CensusRequest request) { + Census census = request.getCensus(); + + // Generate id for populationByDemographics + census.getPopulationByDemographics().forEach(populationByDemographics -> { + if (ObjectUtils.isEmpty(populationByDemographics.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id"); + } + }); + + census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); + } + } From 64a4ee1b51cc4abe077128f38f31ff69f07251d6 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 7 Oct 2024 14:16:08 +0530 Subject: [PATCH 115/351] enrichment --- .../java/digit/service/enrichment/CensusEnrichment.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index f9204f7f3b0..a9fa21a5404 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -3,6 +3,7 @@ import digit.web.models.Census; import digit.web.models.CensusRequest; import org.egov.common.utils.UUIDEnrichmentUtil; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; @@ -17,9 +18,10 @@ public CensusEnrichment() { /** * Enriches the CensusRequest for creating a new census record. * Enriches the given census record with generated IDs for Census and PopulationByDemographics. - * Enriches audit details for create operation. + * Validates user information and enriches audit details for create operation. * * @param request The CensusRequest to be enriched. + * @throws CustomException if user information is missing in the request. */ public void enrichCreate(CensusRequest request) { Census census = request.getCensus(); @@ -37,9 +39,10 @@ public void enrichCreate(CensusRequest request) { /** * Enriches the CensusRequest for updating an existing census record. - * This method enriches the census record for update and enriches audit details for update operation. + * This method enriches the census record for update, validates user information and enriches audit details for update operation. * * @param request The CensusRequest to be enriched. + * @throws CustomException if user information is missing in the request. */ public void enrichUpdate(CensusRequest request) { Census census = request.getCensus(); From cc89066edde001a9c588877331795c4487646146 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 7 Oct 2024 16:53:04 +0530 Subject: [PATCH 116/351] resolved comments --- .../src/main/java/digit/config/ServiceConstants.java | 3 ++- .../service/validator/PlanEmployeeAssignmentValidator.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 17488ce130c..408e13a308e 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -69,6 +69,7 @@ public class ServiceConstants { public static final String INVALID_EMPLOYEE_ID_CODE = "INVALID_EMPLOYEE_ID"; public static final String INVALID_EMPLOYEE_ID_MESSAGE = "Invalid or incorrect employee id."; + public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; @@ -211,7 +212,7 @@ public class ServiceConstants { public static final String HIERARCHY_CONFIG_FOR_MICROPLAN = "[?(@.hierarchy == 'MICROPLAN')]"; - public static final String HIGHEST_HIERARCHY_FOR_MICROPLAN = "highestHierarchy"; + public static final String HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN = "highestHierarchy"; public static final String NAME_VALIDATION_DATA = "Data"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 105a958cb41..4d592075040 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -98,7 +98,7 @@ private void validateNationalRole(PlanEmployeeAssignment planEmployeeAssignment, } // Fetch the highest hierarchy for Microplan from MDMS - String jsonPathForHighestHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN + DOT_SEPARATOR + HIGHEST_HIERARCHY_FOR_MICROPLAN; + String jsonPathForHighestHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN + DOT_SEPARATOR + HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN; List highestHirarchyForPlan = null; try { From 5ef8d1eba8ab8b8cb947f9fa71c7b161ee9a656c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 8 Oct 2024 10:58:04 +0530 Subject: [PATCH 117/351] removed materialized path from search criteria --- .../digit/repository/querybuilder/CensusQueryBuilder.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 4713fc7c741..af38b69fc53 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -84,13 +84,6 @@ private String buildCensusSearchQuery(CensusSearchCriteria criteria, List(criteria.getAreaCodes())); } - if (!CollectionUtils.isEmpty(criteria.getMaterializedPath())) { - queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" ARRAY [ ").append(queryUtil.createQuery(criteria.getMaterializedPath().size())).append(" ]").append("::text[] "); - builder.append(" && string_to_array(census_materialized_path, ',') "); - queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(criteria.getMaterializedPath())); - } - return builder.toString(); } From dc917a83a39193e82897dcc947290f964c4effbb Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 8 Oct 2024 14:57:26 +0530 Subject: [PATCH 118/351] HCMPRE-771 cleaning up DB migration scripts for plan-service --- ...5113045__plan_configuration_create_ddl.sql | 35 ++++++++++++------- .../main/V20240305113047__plan_create_ddl.sql | 5 ++- ...plan_configuration_add_filestoreid_ddl.sql | 1 - ...figuration_add_template_identifier_ddl.sql | 1 - ...0__rename_execution_id_campaign_id_ddl.sql | 8 ----- ...000__plan_configuration_add_status_ddl.sql | 2 -- ...000__plan_configuration_add_active_ddl.sql | 11 ------ ...nfiguration_add_additional_details_ddl.sql | 1 - 8 files changed, 26 insertions(+), 38 deletions(-) delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240404113045__plan_configuration_add_filestoreid_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240404150000__plan_configuration_add_template_identifier_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241604150000__plan_configuration_add_status_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242105150000__plan_configuration_add_active_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql index e9630421bcb..00bf8f03232 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql @@ -1,9 +1,11 @@ -- Table: plan_configuration CREATE TABLE plan_configuration ( id character varying(64), - tenant_id character varying(64), - name character varying(128), - execution_plan_id character varying(64), + tenant_id character varying(64) not null, + name character varying(128) not null, + campaign_id character varying(64) not null, + status character varying(64) not null, + additional_details JSONB, created_by character varying(64), created_time bigint, last_modified_by character varying(64), @@ -16,8 +18,10 @@ CREATE TABLE plan_configuration ( CREATE TABLE plan_configuration_files ( id character varying(64), plan_configuration_id character varying(64), - filestore_id character varying(128), - input_file_type character varying(64), + filestore_id character varying(128) not null, + input_file_type character varying(64) not null, + template_identifier character varying(128) not null, + active boolean not null, created_by character varying(64), created_time bigint, last_modified_by character varying(64), @@ -30,9 +34,10 @@ CREATE TABLE plan_configuration_files ( -- Table: plan_configuration_assumptions CREATE TABLE plan_configuration_assumptions ( id character varying(64), - key character varying(256), - value numeric(12,2), + key character varying(256) not null, + value numeric(12,2) not null, plan_configuration_id character varying(64), + active boolean not null, created_by character varying(64), created_time bigint, last_modified_by character varying(64), @@ -45,10 +50,12 @@ CREATE TABLE plan_configuration_assumptions ( -- Table: plan_configuration_operations CREATE TABLE plan_configuration_operations ( id character varying(64), - input character varying(256), - operator character varying(64), - assumption_value character varying(256), - output character varying(64), + input character varying(256) not null, + operator character varying(64) not null, + assumption_value character varying(256) not null, + output character varying(64) not null, + show_on_estimation_dashboard boolean, + active boolean not null, plan_configuration_id character varying(64), created_by character varying(64), created_time bigint, @@ -62,8 +69,10 @@ CREATE TABLE plan_configuration_operations ( -- Table: plan_configuration_mapping CREATE TABLE plan_configuration_mapping ( id character varying(64), - mapped_from character varying(256), - mapped_to character varying(256), + mapped_from character varying(256) not null, + mapped_to character varying(256) not null, + filestore_id character varying(128) not null, + active boolean not null, plan_configuration_id character varying(64), created_by character varying(64), created_time bigint, diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240305113047__plan_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240305113047__plan_create_ddl.sql index 942cc36af38..b8a194f4afa 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240305113047__plan_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240305113047__plan_create_ddl.sql @@ -2,7 +2,10 @@ CREATE TABLE plan ( id varchar(64), tenant_id varchar(64), locality varchar(64), - execution_plan_id varchar(64), + campaign_id varchar(64), + status character varying(64) not null, + assignee varchar(64), + boundary_ancestral_path TEXT, plan_configuration_id varchar(64), additional_details JSONB, created_by varchar(64), diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240404113045__plan_configuration_add_filestoreid_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240404113045__plan_configuration_add_filestoreid_ddl.sql deleted file mode 100644 index fcd7cfe2bbc..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240404113045__plan_configuration_add_filestoreid_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE plan_configuration_mapping ADD filestore_id character varying(128); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240404150000__plan_configuration_add_template_identifier_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240404150000__plan_configuration_add_template_identifier_ddl.sql deleted file mode 100644 index e1c67ff2696..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240404150000__plan_configuration_add_template_identifier_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE plan_configuration_files ADD template_identifier character varying(128); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql deleted file mode 100644 index 33c6ebccf89..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20241109150000__rename_execution_id_campaign_id_ddl.sql +++ /dev/null @@ -1,8 +0,0 @@ -ALTER TABLE plan_configuration -RENAME COLUMN execution_plan_id TO campaign_id; - -ALTER TABLE plan -RENAME COLUMN execution_plan_id TO campaign_id; - -ALTER TABLE plan_configuration_operations ADD show_on_estimation_dashboard boolean; -UPDATE plan_configuration_operations SET show_on_estimation_dashboard = true WHERE show_on_estimation_dashboard IS NULL; \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241604150000__plan_configuration_add_status_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241604150000__plan_configuration_add_status_ddl.sql deleted file mode 100644 index 8683e34faef..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20241604150000__plan_configuration_add_status_ddl.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE plan_configuration ADD status character varying(64); -UPDATE plan_configuration SET status = 'DRAFT' WHERE status IS NULL; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242105150000__plan_configuration_add_active_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242105150000__plan_configuration_add_active_ddl.sql deleted file mode 100644 index 3586cd4cb45..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242105150000__plan_configuration_add_active_ddl.sql +++ /dev/null @@ -1,11 +0,0 @@ -ALTER TABLE plan_configuration_files ADD active boolean; -UPDATE plan_configuration_files SET active = true WHERE active IS NULL; - -ALTER TABLE plan_configuration_assumptions ADD active boolean; -UPDATE plan_configuration_assumptions SET active = true WHERE active IS NULL; - -ALTER TABLE plan_configuration_operations ADD active boolean; -UPDATE plan_configuration_operations SET active = true WHERE active IS NULL; - -ALTER TABLE plan_configuration_mapping ADD active boolean; -UPDATE plan_configuration_mapping SET active = true WHERE active IS NULL; \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql deleted file mode 100644 index 3437a0862d4..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242708150000__plan_configuration_add_additional_details_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE plan_configuration ADD additional_details JSONB; From c854ed4dbb1113393a3937a5c5b6ae13630cd46a Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 8 Oct 2024 16:32:37 +0530 Subject: [PATCH 119/351] changed materializedPath to boundaryAncestralPath --- .../java/digit/repository/impl/CensusRepositoryImpl.java | 2 +- .../digit/repository/querybuilder/CensusQueryBuilder.java | 2 +- .../java/digit/repository/rowmapper/CensusRowMapper.java | 8 ++++---- .../src/main/java/digit/web/models/Census.java | 4 ++-- .../src/main/java/digit/web/models/CensusDTO.java | 4 ++-- .../main/java/digit/web/models/CensusSearchCriteria.java | 5 ++--- .../migration/main/V20240925155908__census_create_ddl.sql | 2 +- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 718a64a78a8..90dd07f581f 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -134,7 +134,7 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .effectiveFrom(census.getEffectiveFrom()) .effectiveTo(census.getEffectiveTo()) .source(census.getSource()) - .materializedPath(String.join(",", census.getMaterializedPath())) + .boundaryAncestralPath(String.join(",", census.getBoundaryAncestralPath())) .additionalDetails(census.getAdditionalDetails()) .auditDetails(census.getAuditDetails()) .build(); diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index af38b69fc53..52f574172ca 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -19,7 +19,7 @@ public CensusQueryBuilder(QueryUtil queryUtil) { private static final String CENSUS_ID_SEARCH_BASE_QUERY = "SELECT id FROM census cen "; - private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.materialized_path as census_materialized_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + + private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_ancestral_path as census_boundary_ancestral_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time \n" + "\t FROM census cen \n" + "\t LEFT JOIN population_by_demographics pbd ON cen.id = pbd.census_id"; diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index b7b63b4dc9f..1f7be7b1445 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -47,9 +47,9 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc // Prepare audit details AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("census_created_by")).createdTime(rs.getLong("census_created_time")).lastModifiedBy(rs.getString("census_last_modified_by")).lastModifiedTime(rs.getLong("census_last_modified_time")).build(); - // Converting materialized path from comma separated string to a list of string - String materializedPath = rs.getString("census_materialized_path"); - List materializedPathList = Arrays.asList(materializedPath.split(",")); + // Converting boundaryAncestralPath from comma separated string to a list of string + String boundaryAncestralPath = rs.getString("census_boundary_ancestral_path"); + List boundaryAncestralPathList = Arrays.asList(boundaryAncestralPath.split(",")); // Prepare census entry censusEntry.setId(rs.getString("census_id")); @@ -63,7 +63,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setSource(rs.getString("census_source")); censusEntry.setStatus(Census.StatusEnum.valueOf(rs.getString("census_status").toUpperCase())); censusEntry.setAssignee(rs.getString("census_assignee")); - censusEntry.setMaterializedPath(materializedPathList); + censusEntry.setBoundaryAncestralPath(boundaryAncestralPathList); censusEntry.setAdditionalDetails(queryUtil.parseJson((PGobject) rs.getObject("census_additional_details"))); censusEntry.setAuditDetails(auditDetails); } diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index b3db4fe6452..a615ae6d387 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -77,9 +77,9 @@ public class Census { @NotNull private String source = null; - @JsonProperty("boundaryCodeAncestralMaterializedPath") + @JsonProperty("boundaryAncestralPath") @NotNull - private List materializedPath = null; + private List boundaryAncestralPath = null; @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 940ba382aee..689c879d3cb 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -72,9 +72,9 @@ public class CensusDTO { @NotNull private String source = null; - @JsonProperty("boundaryCodeAncestralMaterializedPath") + @JsonProperty("boundaryAncestralPath") @NotNull - private String materializedPath = null; + private String boundaryAncestralPath = null; @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index ec7ba89728c..f8fef679fe0 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -39,9 +39,8 @@ public class CensusSearchCriteria { @JsonProperty("assignee") private String assignee = null; - @JsonProperty("boundaryCodeAncestralMaterializedPath") - private List materializedPath = null; - + @JsonProperty("jurisdiction") + private List jurisdiction = null; public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql index 10c57479245..227ffd4ff7c 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -11,7 +11,7 @@ CREATE TABLE census ( source character varying(255), status character varying(255), assignee character varying(255), - materialized_path TEXT, + boundary_ancestral_path TEXT, additional_details JSONB, created_by character varying(64), created_time bigint, From 94a88d026eb2026490a904becb52db9e797596fe Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 8 Oct 2024 17:58:07 +0530 Subject: [PATCH 120/351] vehicleId validation --- .../java/digit/config/ServiceConstants.java | 6 +- .../validator/PlanConfigurationValidator.java | 121 ++++++++++-------- .../src/main/java/digit/util/CommonUtil.java | 109 +++++++++++++--- .../src/main/resources/application.properties | 22 +++- 4 files changed, 190 insertions(+), 68 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 3c2996121bf..92e81aa6057 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -229,7 +229,11 @@ public class ServiceConstants { public static final String BOUNDARY_CODE = "boundaryCode"; - public static final String FILTER_ALL_ASSUMPTIONS = "[*].assumptionCategories[*].assumptions[*]"; + public static final String FILTER_ALL_ASSUMPTIONS = ".assumptionCategories[*].assumptions[*]"; + + public static final String HIERARCHY_CONFIG_FOR_MICROPLAN = "[?(@.hierarchy == 'MICROPLAN')]"; + + public static final String HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN = "highestHierarchy"; public static final String NAME_VALIDATION_DATA = "Data"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 65f45534032..52027522a39 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -3,6 +3,7 @@ import com.jayway.jsonpath.JsonPath; import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; +import digit.util.CampaignUtil; import digit.util.MdmsUtil; import digit.util.MdmsV2Util; import digit.util.CommonUtil; @@ -12,6 +13,7 @@ import java.util.stream.Collectors; import digit.web.models.mdmsV2.Mdms; +import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.egov.common.utils.MultiStateInstanceUtil; @@ -36,12 +38,15 @@ public class PlanConfigurationValidator { private MultiStateInstanceUtil centralInstanceUtil; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil) { + private CampaignUtil campaignUtil; + + public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil) { this.mdmsUtil = mdmsUtil; this.mdmsV2Util = mdmsV2Util; this.planConfigRepository = planConfigRepository; this.commonUtil = commonUtil; this.centralInstanceUtil = centralInstanceUtil; + this.campaignUtil = campaignUtil; } /** @@ -54,6 +59,7 @@ public void validateCreate(PlanConfigurationRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); @@ -85,6 +91,19 @@ public void validateCreate(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + } + + /** + * Validates campaign ID from request against project factory + * + * @param campaignResponse The campaign details response from project factory + */ + private void validateCampaignId(CampaignResponse campaignResponse) { + if (CollectionUtils.isEmpty(campaignResponse.getCampaignDetails())) { + throw new CustomException(NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE, NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE); + } } /** @@ -115,7 +134,6 @@ public void validatePlanConfigName(PlanConfigurationRequest request, Object mdms if (!commonUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) { throw new CustomException(NAME_VALIDATION_FAILED_CODE, NAME_VALIDATION_FAILED_MESSAGE); } - } @@ -158,8 +176,17 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { - final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + FILTER_ALL_ASSUMPTIONS; + Object additionalDetails = request.getPlanConfiguration().getAdditionalDetails(); + if (additionalDetails == null) { + throw new CustomException(ADDITIONAL_DETAILS_MISSING_CODE, ADDITIONAL_DETAILS_MISSING_MESSAGE); + } + + String jsonPathForAssumption = commonUtil.createJsonPathForAssumption(commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE), + commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); List assumptionListFromMDMS = null; try { log.info(jsonPathForAssumption); @@ -195,7 +222,7 @@ public void validateFilestoreId(PlanConfiguration planConfiguration) { .map(File::getFilestoreId) .collect(Collectors.toSet()); - planConfiguration.getResourceMapping().stream().forEach(mapping -> { + planConfiguration.getResourceMapping().forEach(mapping -> { if (!fileStoreIds.contains(mapping.getFilestoreId())) { log.error("Resource Mapping " + mapping.getMappedTo() + " does not have valid fileStoreId " + mapping.getFilestoreId()); throw new CustomException(FILESTORE_ID_INVALID_CODE, FILESTORE_ID_INVALID_MESSAGE); @@ -252,14 +279,12 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque } // Ensure at least one active file for each required template identifier - requiredTemplateIdentifierSetFromMDMS - .stream() - .forEach(requiredTemplate -> { - if (!activeRequiredTemplates.contains(requiredTemplate)) { - log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); - throw new CustomException(REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE, REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE); - } - }); + requiredTemplateIdentifierSetFromMDMS.forEach(requiredTemplate -> { + if (!activeRequiredTemplates.contains(requiredTemplate)) { + log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); + throw new CustomException(REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE, REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE); + } + }); } } @@ -304,7 +329,7 @@ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, .map(Operation::getOutput) .forEach(allowedColumns::add); - planConfiguration.getOperations().stream().forEach(operation -> { + planConfiguration.getOperations().forEach(operation -> { if (!allowedColumns.contains(operation.getInput())) { log.error("Input Value " + operation.getInput() + " is not present in MDMS Input List"); throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE); @@ -322,8 +347,7 @@ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, * @param templateIds The list of template identifiers from request object * @param inputFileTypes The list of input file type from request object */ - public static HashSet getColumnsFromSchemaThatAreRuleInputs - (HashSet schemas, List templateIds, List inputFileTypes) { + public static HashSet getColumnsFromSchemaThatAreRuleInputs(HashSet schemas, List templateIds, List inputFileTypes) { if (schemas == null) { return new HashSet<>(); } @@ -334,13 +358,12 @@ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, continue; LinkedHashMap columns = (LinkedHashMap) ((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); if (columns == null) return new HashSet<>(); - columns.entrySet().stream() - .forEach(column -> { - LinkedHashMap data = column.getValue(); - if (data.get(MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT)) { - finalData.add(column.getKey()); - } - }); // Add the keys to finalData + columns.forEach((key, value) -> { + LinkedHashMap data = value; + if (data.get(MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT)) { + finalData.add(key); + } + }); // Add the keys to finalData } return finalData; } @@ -356,7 +379,7 @@ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, public static void validateMappedToUniqueness(List resourceMappings) { if (!CollectionUtils.isEmpty(resourceMappings)) { Set uniqueMappedToSet = new HashSet<>(); - resourceMappings.stream().forEach(mapping -> { + resourceMappings.forEach(mapping -> { String uniqueKey = mapping.getFilestoreId() + "-" + mapping.getMappedTo(); if (!uniqueMappedToSet.add(uniqueKey)) { log.error("Duplicate MappedTo " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); @@ -397,6 +420,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); // Validate the existence of the plan configuration in the request validatePlanConfigExistence(request); @@ -433,6 +457,9 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); + + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); } /** @@ -440,7 +467,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { * * @param request The request containing the plan configuration to validate. */ - public PlanConfiguration validatePlanConfigExistence(PlanConfigurationRequest request) { + public void validatePlanConfigExistence(PlanConfigurationRequest request) { // If plan id provided is invalid, throw an exception List planConfigurationList = planConfigRepository.search(PlanConfigurationSearchCriteria.builder() .id(request.getPlanConfiguration().getId()) @@ -450,7 +477,6 @@ public PlanConfiguration validatePlanConfigExistence(PlanConfigurationRequest re throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); } - return planConfigurationList.get(0); } /** @@ -469,7 +495,7 @@ public static void validateOperationDependencies(PlanConfiguration planConfigura .collect(Collectors.toSet()); // Check for each inactive operation - planConfiguration.getOperations().stream().forEach(operation -> { + planConfiguration.getOperations().forEach(operation -> { if (!operation.getActive() && activeInputs.contains(operation.getOutput())) { log.error(INACTIVE_OPERATION_USED_AS_INPUT_MESSAGE + operation.getOutput()); throw new CustomException(INACTIVE_OPERATION_USED_AS_INPUT_CODE, INACTIVE_OPERATION_USED_AS_INPUT_MESSAGE + operation.getOutput()); @@ -536,22 +562,21 @@ public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request, * @param inputFileTypes The list of input file type from request object * @return List of Columns that are required */ - public static HashSet getRequiredColumnsFromSchema - (HashSet schemas, List templateIds, List inputFileTypes) { + public static HashSet getRequiredColumnsFromSchema(HashSet schemas, List templateIds, List inputFileTypes) { if (CollectionUtils.isEmpty(schemas)) { return new HashSet<>(); } HashSet finalData = new HashSet<>(); for (Object item : schemas) { - LinkedHashMap schemaEntity = (LinkedHashMap) item; + LinkedHashMap schemaEntity = (LinkedHashMap) item; if (!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) continue; LinkedHashMap columns = (LinkedHashMap) ((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); if (columns == null) return new HashSet<>(); - columns.entrySet().stream().forEach(column -> { - LinkedHashMap data = column.getValue(); + columns.forEach((key, value) -> { + LinkedHashMap data = value; if (data.get(MDMS_SCHEMA_PROPERTIES_IS_REQUIRED)) { - finalData.add(column.getKey()); + finalData.add(key); } }); } @@ -578,55 +603,51 @@ public void validateUserInfo(PlanConfigurationRequest request) { * @param mdmsV2Data mdms v2 data object */ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfigurationRequest request, List mdmsV2Data) { - List vehicleIdsLinkedWithPlanConfig = commonUtil.extractVehicleIdsFromAdditionalDetails(request.getPlanConfiguration().getAdditionalDetails()); - - if (!CollectionUtils.isEmpty(vehicleIdsLinkedWithPlanConfig)) { + List vehicleIdsfromAdditionalDetails = commonUtil.extractFieldsFromJsonObject(request.getPlanConfiguration().getAdditionalDetails(), JSON_FIELD_VEHICLE_ID, List.class); + if (!CollectionUtils.isEmpty(vehicleIdsfromAdditionalDetails)) { List vehicleIdsFromMdms = mdmsV2Data.stream() .map(Mdms::getId) - .collect(Collectors.toList()); + .toList(); - List finalVehicleIdsFromMdms = vehicleIdsFromMdms; - vehicleIdsLinkedWithPlanConfig.stream() - .forEach(vehicleId -> { - if (!finalVehicleIdsFromMdms.contains(vehicleId)) { - log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); - throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE); - } - }); + vehicleIdsfromAdditionalDetails.forEach(vehicleId -> { + if (!vehicleIdsFromMdms.contains(vehicleId)) { + log.error("Vehicle Id " + vehicleId + " is not present in MDMS"); + throw new CustomException(VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE, VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE); + } + }); } - } public boolean isSetupCompleted(PlanConfiguration planConfiguration) { - return planConfiguration.getStatus() == PlanConfiguration.StatusEnum.SETUP_COMPLETED; + return Objects.equals(planConfiguration.getStatus(), SETUP_COMPLETED_STATUS); } // Checks for whether file, assumption, operation or resource mapping is empty or null at a certain status private void checkForEmptyFiles(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getFiles())) { - log.error("Files cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + log.error("Files cannot be empty at status = " + SETUP_COMPLETED_STATUS); throw new CustomException(FILES_NOT_FOUND_CODE, FILES_NOT_FOUND_MESSAGE); } } private void checkForEmptyAssumption(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { - log.error("Assumptions cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + log.error("Assumptions cannot be empty at status = " + SETUP_COMPLETED_STATUS); throw new CustomException(ASSUMPTIONS_NOT_FOUND_CODE, ASSUMPTIONS_NOT_FOUND_MESSAGE); } } private void checkForEmptyOperation(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getOperations())) { - log.error("Operations cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + log.error("Operations cannot be empty at status = " + SETUP_COMPLETED_STATUS); throw new CustomException(OPERATIONS_NOT_FOUND_CODE, OPERATIONS_NOT_FOUND_MESSAGE); } } private void checkForEmptyResourceMapping(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { - log.error("Resource mapping cannot be empty at status = " + PlanConfiguration.StatusEnum.SETUP_COMPLETED); + log.error("Resource mapping cannot be empty at status = " + SETUP_COMPLETED_STATUS); throw new CustomException(RESOURCE_MAPPING_NOT_FOUND_CODE, RESOURCE_MAPPING_NOT_FOUND_MESSAGE); } } diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 07d2f01d7cd..df644dc1c33 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -2,7 +2,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import digit.repository.PlanConfigurationRepository; +import digit.web.models.*; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.text.StringEscapeUtils; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -10,17 +13,18 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; - import static digit.config.ServiceConstants.*; @Component @Slf4j public class CommonUtil { + private PlanConfigurationRepository planConfigurationRepository; + private ObjectMapper objectMapper; - public CommonUtil(ObjectMapper objectMapper) - { + public CommonUtil(PlanConfigurationRepository planConfigurationRepository, ObjectMapper objectMapper) { + this.planConfigurationRepository = planConfigurationRepository; this.objectMapper = objectMapper; } @@ -39,28 +43,103 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri /** - * Extracts the list of vehicle Ids provided in additional details object + * Extracts provided field from the additional details object * * @param additionalDetails the additionalDetails object from PlanConfigurationRequest - * @return a list of vehicle Ids from additional details + * @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 List extractVehicleIdsFromAdditionalDetails(Object additionalDetails) { + public String extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract) { try { String jsonString = objectMapper.writeValueAsString(additionalDetails); JsonNode rootNode = objectMapper.readTree(jsonString); - List vehicleIds = new ArrayList<>(); - JsonNode vehicleIdsNode = rootNode.get(VEHICLE_ID_FIELD); - if (vehicleIdsNode != null && vehicleIdsNode.isArray()) { - for (JsonNode idNode : vehicleIdsNode) { - vehicleIds.add(idNode.asText()); - } + JsonNode node = rootNode.get(fieldToExtract); + if (node != null) { + // Convert the node to a String + return objectMapper.convertValue(node, String.class); } + // Return null if the node is empty + 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); + } + } - return vehicleIds; + /** + * 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 list of string + * @throws CustomException if the field does not exist + */ + public List extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract, Class valueType) { + try { + String jsonString = objectMapper.writeValueAsString(additionalDetails); + JsonNode rootNode = objectMapper.readTree(jsonString); + + JsonNode node = rootNode.get(fieldToExtract); + List list = new ArrayList<>(); + if (node != null && node.isArray()) { + for (JsonNode idNode : node) { + list.add(idNode.asText()); + } + } + return list; } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + 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); } } + + /** + * Constructs a JSONPath expression used to filter assumptions based on the given parameters - + * campaign type, distribution process, registration process, resource distribution strategy, + * and whether registration and distribution are together match the provided values. + * + * @param campaignType The type of campaign to filter by (e.g., "Health", "Education"). + * @param distributionProcess The process of distribution to filter by (e.g., "Central", "Decentralized"). + * @param registrationProcess The registration process to filter by (e.g., "Online", "In-Person"). + * @param resourceDistributionStrategyCode The strategy code for resource distribution to filter by (e.g., "Strategy1"). + * @param isRegistrationAndDistributionTogether Whether registration and distribution are combined, to filter by ("true"/"false"). + * @return A JSONPath expression string that filters assumptions based on the given criteria. + */ + public String createJsonPathForAssumption( + String campaignType, + String distributionProcess, + String registrationProcess, + String resourceDistributionStrategyCode, + String isRegistrationAndDistributionTogether + ) { + + StringBuilder jsonPathFilters = new StringBuilder(JSONPATH_FILTER_PREFIX); + jsonPathFilters.append(JSON_PATH_FILTER_CAMPAIGN_TYPE).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(campaignType)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_DISTRIBUTION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(distributionProcess)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_REGISTRATION_PROCESS).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(registrationProcess)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_RESOURCE_DISTRIBUTION_STRATEGY_CODE).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(resourceDistributionStrategyCode)).append(SINGLE_QUOTE) + .append(AND).append(JSON_PATH_FILTER_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER).append(EQUALS).append(SINGLE_QUOTE).append(StringEscapeUtils.escapeJson(isRegistrationAndDistributionTogether)).append(SINGLE_QUOTE) + .append(JSONPATH_FILTER_SUFFIX); + + return JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + jsonPathFilters + FILTER_ALL_ASSUMPTIONS; + } + + + /** + * Searches the plan config based on the plan config id provided + * + * @param planConfigId the plan config id to validate + * @param tenantId the tenant id of the plan config + * @return list of planConfiguration for the provided plan config id + */ + public List searchPlanConfigId(String planConfigId, String tenantId) { + List planConfigurations = planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() + .id(planConfigId) + .tenantId(tenantId) + .build()); + + return planConfigurations; + } } diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 25456401843..651f554b851 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -49,14 +49,32 @@ plan.configuration.update.topic=plan-config-update-topic plan.create.topic=save-plan plan.update.topic=update-plan +plan.employee.assignment.create.topic=plan-employee-assignment-create-topic +plan.employee.assignment.update.topic=plan-employee-assignment-update-topic + #mdms urls egov.mdms.host=https://unified-dev.digit.org -egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +egov.mdms.search.endpoint=/mdms-v2/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search +#hrms urls +egov.hrms.host=https://unified-dev.digit.org +egov.hrms.search.endpoint=/health-hrms/employees/_search + +#project factory urls +egov.project.factory.host=https://unified-dev.digit.org +egov.project.factory.search.endpoint=/project-factory/v1/project-type/search + +# Workflow +egov.workflow.host=https://unified-dev.digit.org +egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition + # Pagination config plan.default.offset=0 plan.default.limit=10 resource.config.consumer.plan.create.topic=resource-microplan-create-topic -resource.update.plan.config.consumer.topic=resource-plan-config-update-topic \ No newline at end of file +resource.update.plan.config.consumer.topic=resource-plan-config-update-topic + +# Role Map +role.map = {ROOT_FACILITY_CATCHMENT_ASSIGNER:'FACILITY_CATCHMENT_ASSIGNER', FACILITY_CATCHMENT_ASSIGNER:'ROOT_FACILITY_CATCHMENT_ASSIGNER', ROOT_POPULATION_DATA_APPROVER:'POPULATION_DATA_APPROVER', POPULATION_DATA_APPROVER:'ROOT_POPULATION_DATA_APPROVER', ROOT_MICROPLAN_APPROVER:'MICROPLAN_APPROVER', MICROPLAN_APPROVER:'ROOT_MICROPLAN_APPROVER'} \ No newline at end of file From 391cd75bab2660679f58708305580b5d298f215e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 8 Oct 2024 19:07:16 +0530 Subject: [PATCH 121/351] resolved comments --- .../repository/impl/CensusRepositoryImpl.java | 2 +- .../java/digit/service/CensusService.java | 23 +++++++++---------- .../service/enrichment/CensusEnrichment.java | 4 +--- .../web/controllers/CensusController.java | 13 +++-------- .../main/java/digit/web/models/Census.java | 11 --------- .../main/java/digit/web/models/CensusDTO.java | 1 - 6 files changed, 16 insertions(+), 38 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 90dd07f581f..37974bdb768 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -134,7 +134,7 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .effectiveFrom(census.getEffectiveFrom()) .effectiveTo(census.getEffectiveTo()) .source(census.getSource()) - .boundaryAncestralPath(String.join(",", census.getBoundaryAncestralPath())) + .boundaryAncestralPath(census.getBoundaryAncestralPath().get(0)) .additionalDetails(census.getAdditionalDetails()) .auditDetails(census.getAuditDetails()) .build(); diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index 9857ad07391..f51a2a5a333 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -4,12 +4,14 @@ import digit.service.enrichment.CensusEnrichment; import digit.service.validator.CensusValidator; import digit.util.ResponseInfoFactory; +import digit.web.models.Census; import digit.web.models.CensusRequest; import digit.web.models.CensusResponse; import digit.web.models.CensusSearchRequest; import org.springframework.stereotype.Service; import java.util.Collections; +import java.util.List; @Service public class CensusService { @@ -36,13 +38,12 @@ public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository r * @return The created census reponse. */ public CensusResponse create(CensusRequest request) { - enrichment.enrichCreate(request); - repository.create(request); - CensusResponse response = CensusResponse.builder() + enrichment.enrichCreate(request); // Enrich census create request + repository.create(request); // Delegate creation request to repository + return CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .build(); - return response; } /** @@ -52,12 +53,11 @@ public CensusResponse create(CensusRequest request) { * @return A list of census record that matches the search criteria. */ public CensusResponse search(CensusSearchRequest request) { - CensusResponse response = CensusResponse.builder() + List censusList = repository.search(request.getCensusSearchCriteria()); // Delegate search request to repository + return CensusResponse.builder() .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) - .census(repository.search(request.getCensusSearchCriteria())) + .census(censusList) .build(); - - return response; } /** @@ -67,12 +67,11 @@ public CensusResponse search(CensusSearchRequest request) { * @return The updated census response. */ public CensusResponse update(CensusRequest request) { - enrichment.enrichUpdate(request); - repository.update(request); - CensusResponse response = CensusResponse.builder() + enrichment.enrichUpdate(request); // Enrich census update request + repository.update(request); // Delegate update request to repository + return CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .build(); - return response; } } diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index a9fa21a5404..b0c4d7915ac 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -30,9 +30,7 @@ public void enrichCreate(CensusRequest request) { UUIDEnrichmentUtil.enrichRandomUuid(census, "id"); // Generate id for PopulationByDemographics - census.getPopulationByDemographics().forEach(populationByDemographics -> { - UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id"); - }); + census.getPopulationByDemographics().forEach(populationByDemographics -> UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id")); census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); } diff --git a/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java index 4e1a668a1fb..17c6a975c08 100644 --- a/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java +++ b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java @@ -1,15 +1,12 @@ package digit.web.controllers; -import com.fasterxml.jackson.databind.ObjectMapper; import digit.service.CensusService; -import digit.util.ResponseInfoFactory; import digit.web.models.CensusRequest; import digit.web.models.CensusResponse; import digit.web.models.CensusSearchRequest; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -18,7 +15,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import java.io.IOException; @Controller public class CensusController { @@ -36,8 +32,7 @@ public CensusController(CensusService censusService) { * @return */ @RequestMapping(value = "/_create", method = RequestMethod.POST) - public ResponseEntity censusCreatePost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusRequest body) { - + public ResponseEntity create(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusRequest body) { CensusResponse response = censusService.create(body); return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); } @@ -49,8 +44,7 @@ public ResponseEntity censusCreatePost(@Parameter(in = Parameter * @return */ @RequestMapping(value = "/_search", method = RequestMethod.POST) - public ResponseEntity censusSearchPost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusSearchRequest body) { - + public ResponseEntity search(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusSearchRequest body) { CensusResponse response = censusService.search(body); return ResponseEntity.status(HttpStatus.OK).body(response); } @@ -62,8 +56,7 @@ public ResponseEntity censusSearchPost(@Parameter(in = Parameter * @return */ @RequestMapping(value = "/_update", method = RequestMethod.POST) - public ResponseEntity censusUpdatePost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusRequest body) { - + public ResponseEntity update(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusRequest body) { CensusResponse response = censusService.update(body); return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); } diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index a615ae6d387..87f6ce17332 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonValue; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import jakarta.validation.constraints.NotNull; @@ -78,7 +77,6 @@ public class Census { private String source = null; @JsonProperty("boundaryAncestralPath") - @NotNull private List boundaryAncestralPath = null; @JsonProperty("additionalDetails") @@ -128,13 +126,4 @@ public static TypeEnum fromValue(String text) { } } - - public Census addPopulationByDemographicsItem(PopulationByDemographic populationByDemographicsItem) { - if (this.populationByDemographics == null) { - this.populationByDemographics = new ArrayList<>(); - } - this.populationByDemographics.add(populationByDemographicsItem); - return this; - } - } diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 689c879d3cb..730c5299408 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -73,7 +73,6 @@ public class CensusDTO { private String source = null; @JsonProperty("boundaryAncestralPath") - @NotNull private String boundaryAncestralPath = null; @JsonProperty("additionalDetails") From 4ccbd1e59bd8804a0f610b7f89c23914bbcf4d04 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 9 Oct 2024 12:50:31 +0530 Subject: [PATCH 122/351] added jurisdiction in search criteria --- .../repository/impl/CensusRepositoryImpl.java | 44 +++---------- .../querybuilder/CensusQueryBuilder.java | 65 +++++++++---------- .../repository/rowmapper/CensusRowMapper.java | 6 +- .../main/java/digit/web/models/Census.java | 4 +- 4 files changed, 42 insertions(+), 77 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 37974bdb768..40e663f1220 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -56,48 +56,24 @@ public void create(CensusRequest censusRequest) { */ @Override public List search(CensusSearchCriteria censusSearchCriteria) { - - // Fetch census ids from database - List censusIds = queryDatabaseForCensusIds(censusSearchCriteria); - - // Return empty list back as response if no census ids are found - if (CollectionUtils.isEmpty(censusIds)) { - log.info("No census ids found for provided census search criteria."); - return new ArrayList<>(); - } - - return searchCensusByIds(censusIds); - } - - /** - * Helper method to search for census records based on the provided census ids. - * - * @param censusIds list of census ids to search for census records. - * @return a list of census records. - */ - private List searchCensusByIds(List censusIds) { List preparedStmtList = new ArrayList<>(); - String query = queryBuilder.getCensusQuery(censusIds, preparedStmtList); - log.info("Census query: " + query); - return jdbcTemplate.query(query, rowMapper, preparedStmtList.toArray()); + String searchQuery = queryBuilder.getCensusQuery(censusSearchCriteria, preparedStmtList); + + return jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); } /** - * Helper method to query database for census ids based on the provided search criteria. + * Counts the number of census records based on the provided search criteria. * - * @param censusSearchCriteria The criteria to use for searching census records. - * @return a list of census ids that matches the provided search criteria + * @param censusSearchCriteria The search criteria for filtering census records. + * @return The total count of census matching the search criteria. */ - private List queryDatabaseForCensusIds(CensusSearchCriteria censusSearchCriteria) { - List preparedStmtList = new ArrayList<>(); - String query = queryBuilder.getCensusSearchQuery(censusSearchCriteria, preparedStmtList); - log.info("Census search query: " + query); - return jdbcTemplate.query(query, new SingleColumnRowMapper<>(String.class), preparedStmtList.toArray()); - } - @Override public Integer count(CensusSearchCriteria censusSearchCriteria) { - return 0; + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getCensusCountQuery(censusSearchCriteria, preparedStmtList); + + return jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); } /** diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 52f574172ca..64c637426fe 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -17,8 +17,6 @@ public CensusQueryBuilder(QueryUtil queryUtil) { this.queryUtil = queryUtil; } - private static final String CENSUS_ID_SEARCH_BASE_QUERY = "SELECT id FROM census cen "; - private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_ancestral_path as census_boundary_ancestral_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time \n" + "\t FROM census cen \n" + @@ -32,18 +30,28 @@ public CensusQueryBuilder(QueryUtil queryUtil) { * Constructs a SQL query string for searching Census records based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. * - * @param censusSearchCriteria The criteria used for filtering Census records. - * @param preparedStmtList A list to store prepared statement parameters. + * @param searchCriteria The criteria used for filtering Census records. + * @param preparedStmtList A list to store prepared statement parameters. * @return A complete SQL query string for searching Census records. */ - public String getCensusSearchQuery(CensusSearchCriteria censusSearchCriteria, List preparedStmtList) { - String query = buildCensusSearchQuery(censusSearchCriteria, preparedStmtList, Boolean.FALSE); + public String getCensusQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { + String query = buildCensusQuery(searchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); query = queryUtil.getPaginatedQuery(query, preparedStmtList); - return query; } + /** + * Constructs the count query to get the total count of census based on search criteria. + * + * @param searchCriteria The criteria used for filtering Census records. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A SQL query string to get the total count of Census records for a given search criteria. + */ + public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { + return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.TRUE); + } + /** * Constructs query based on the provided search criteria * @@ -51,8 +59,8 @@ public String getCensusSearchQuery(CensusSearchCriteria censusSearchCriteria, Li * @param preparedStmtList A list to store prepared statement parameters. * @return SQL query string for searching Census records */ - private String buildCensusSearchQuery(CensusSearchCriteria criteria, List preparedStmtList, Boolean isCount) { - StringBuilder builder = new StringBuilder(CENSUS_ID_SEARCH_BASE_QUERY); + private String buildCensusQuery(CensusSearchCriteria criteria, List preparedStmtList, Boolean isCount) { + StringBuilder builder = new StringBuilder(CENSUS_SEARCH_BASE_QUERY); if (criteria.getId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); @@ -84,37 +92,22 @@ private String buildCensusSearchQuery(CensusSearchCriteria criteria, List(criteria.getAreaCodes())); } - return builder.toString(); - } - - /** - * Constructs a SQL query string for searching Census records based on the provided list of Census Ids. - * - * @param censusIds The list of census ids for searching census records - * @param preparedStmtList A list to store prepared statement parameters. - * @return A complete SQL query string for searching Census records. - */ - public String getCensusQuery(List censusIds, List preparedStmtList) { - return buildCensusQuery(censusIds, preparedStmtList); - } + if (!CollectionUtils.isEmpty(criteria.getJurisdiction())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ").append(queryUtil.createQuery(criteria.getJurisdiction().size())).append(" ]").append("::text[] "); + builder.append(" && string_to_array(boundary_ancestral_path, '|') "); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(criteria.getJurisdiction())); + } - /** - * Constructs query based on the list of Census id provided. - * - * @param censusIds The list of census ids for searching census records - * @param preparedStmtList A list to store prepared statement parameters. - * @return A complete SQL query string for searching Census records. - */ - private String buildCensusQuery(List censusIds, List preparedStmtList) { - StringBuilder builder = new StringBuilder(CENSUS_SEARCH_BASE_QUERY); + StringBuilder countQuery = new StringBuilder(); + if (isCount) { + countQuery.append(CENSUS_SEARCH_QUERY_COUNT_WRAPPER).append(builder); + countQuery.append(") AS subquery"); - if (!CollectionUtils.isEmpty(censusIds)) { - queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.id IN ( ").append(queryUtil.createQuery(censusIds.size())).append(" )"); - queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(censusIds)); + return countQuery.toString(); } - return queryUtil.addOrderByClause(builder.toString(), CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); + return builder.toString(); } } diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 1f7be7b1445..7b4db395480 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -47,10 +47,6 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc // Prepare audit details AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("census_created_by")).createdTime(rs.getLong("census_created_time")).lastModifiedBy(rs.getString("census_last_modified_by")).lastModifiedTime(rs.getLong("census_last_modified_time")).build(); - // Converting boundaryAncestralPath from comma separated string to a list of string - String boundaryAncestralPath = rs.getString("census_boundary_ancestral_path"); - List boundaryAncestralPathList = Arrays.asList(boundaryAncestralPath.split(",")); - // Prepare census entry censusEntry.setId(rs.getString("census_id")); censusEntry.setTenantId(rs.getString("census_tenant_id")); @@ -63,7 +59,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setSource(rs.getString("census_source")); censusEntry.setStatus(Census.StatusEnum.valueOf(rs.getString("census_status").toUpperCase())); censusEntry.setAssignee(rs.getString("census_assignee")); - censusEntry.setBoundaryAncestralPath(boundaryAncestralPathList); + censusEntry.setBoundaryAncestralPath(Collections.singletonList(rs.getString("census_boundary_ancestral_path"))); censusEntry.setAdditionalDetails(queryUtil.parseJson((PGobject) rs.getObject("census_additional_details"))); censusEntry.setAuditDetails(auditDetails); } diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 87f6ce17332..7c118eaae22 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -1,11 +1,11 @@ package digit.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import java.util.ArrayList; import java.util.List; import jakarta.validation.constraints.NotNull; @@ -76,7 +76,7 @@ public class Census { @NotNull private String source = null; - @JsonProperty("boundaryAncestralPath") + @JsonIgnore private List boundaryAncestralPath = null; @JsonProperty("additionalDetails") From a477c1f36403678431d04cc0c9c9b560d9148119 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 9 Oct 2024 14:09:56 +0530 Subject: [PATCH 123/351] formatting --- .../service/PlanConfigurationService.java | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java index 118d7dd1ca7..a6c9af454d3 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java @@ -1,7 +1,5 @@ package digit.service; -import digit.config.Configuration; -import digit.kafka.Producer; import digit.repository.PlanConfigurationRepository; import digit.service.enrichment.EnrichmentService; import digit.service.validator.PlanConfigurationValidator; @@ -21,12 +19,8 @@ @Slf4j public class PlanConfigurationService { - private Producer producer; - private EnrichmentService enrichmentService; - private Configuration config; - private PlanConfigurationValidator validator; private PlanConfigurationRepository repository; @@ -35,11 +29,8 @@ public class PlanConfigurationService { private WorkflowService workflowService; - public PlanConfigurationService(Producer producer, EnrichmentService enrichmentService, Configuration config - , PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService) { - this.producer = producer; + public PlanConfigurationService(EnrichmentService enrichmentService, PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService) { this.enrichmentService = enrichmentService; - this.config = config; this.validator = validator; this.repository = repository; this.responseInfoFactory = responseInfoFactory; @@ -57,12 +48,11 @@ public PlanConfigurationResponse create(PlanConfigurationRequest request) { validator.validateCreate(request); enrichmentService.enrichCreate(request); repository.create(request); - PlanConfigurationResponse response = PlanConfigurationResponse.builder() + + return PlanConfigurationResponse.builder() .planConfiguration(Collections.singletonList(request.getPlanConfiguration())) - .responseInfo(responseInfoFactory - .createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .build(); - return response; } /** @@ -73,13 +63,12 @@ public PlanConfigurationResponse create(PlanConfigurationRequest request) { */ public PlanConfigurationResponse search(PlanConfigurationSearchRequest request) { validator.validateSearchRequest(request); - PlanConfigurationResponse response = PlanConfigurationResponse.builder(). + + return PlanConfigurationResponse.builder(). responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .planConfiguration(repository.search(request.getPlanConfigurationSearchCriteria())) .totalCount(repository.count(request.getPlanConfigurationSearchCriteria())) .build(); - - return response; } /** @@ -94,11 +83,9 @@ public PlanConfigurationResponse update(PlanConfigurationRequest request) { workflowService.invokeWorkflowForStatusUpdate(request); repository.update(request); - PlanConfigurationResponse response = PlanConfigurationResponse.builder() + return PlanConfigurationResponse.builder() .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) .planConfiguration(Collections.singletonList(request.getPlanConfiguration())) .build(); - - return response; } } \ No newline at end of file From 1f404c54bac8f61b4a4a1cb092d902eaea01b3f8 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 10 Oct 2024 13:34:40 +0530 Subject: [PATCH 124/351] validations for census --- health-services/census-service/pom.xml | 11 ++ .../main/java/digit/config/Configuration.java | 22 ++- .../java/digit/config/ServiceConstants.java | 12 ++ .../java/digit/service/CensusService.java | 3 + .../service/validator/CensusValidator.java | 128 +++++++++++++ .../main/java/digit/util/BoundaryUtil.java | 82 +++++++++ .../util/PlanEmployeeAssignmnetUtil.java | 92 ++++++++++ .../src/main/java/digit/web/models/User.java | 170 ------------------ .../main/java/digit/web/models/UserInfo.java | 72 -------- .../boundary/BoundarySearchResponse.java | 42 +++++ .../web/models/boundary/EnrichedBoundary.java | 42 +++++ .../models/boundary/HierarchyRelation.java | 34 ++++ .../models/plan/PlanEmployeeAssignment.java | 63 +++++++ .../plan/PlanEmployeeAssignmentResponse.java | 37 ++++ .../PlanEmployeeAssignmentSearchCriteria.java | 50 ++++++ .../PlanEmployeeAssignmentSearchRequest.java | 29 +++ 16 files changed, 646 insertions(+), 243 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/util/BoundaryUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/web/models/User.java delete mode 100644 health-services/census-service/src/main/java/digit/web/models/UserInfo.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignment.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchRequest.java diff --git a/health-services/census-service/pom.xml b/health-services/census-service/pom.xml index e4342a7b1b1..64ebc35ab54 100644 --- a/health-services/census-service/pom.xml +++ b/health-services/census-service/pom.xml @@ -36,6 +36,17 @@ org.springframework.boot spring-boot-starter-web + + org.egov.common + health-services-common + 1.0.18-SNAPSHOT + + + org.egov.common + health-services-models + 1.0.21-SNAPSHOT + compile + junit junit diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 02e629b0fce..9a4b2352c27 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -6,6 +6,8 @@ import org.springframework.context.annotation.Import; import org.springframework.stereotype.Component; +import java.util.List; + @Component @Data @Import({TracerConfiguration.class}) @@ -15,13 +17,31 @@ @Getter public class Configuration { - //Persister Topic + // Allowed roles for census + @Value("#{${allowed.census.roles}}") + private List allowedCensusRoles; + + // Persister Topic @Value("${census.create.topic}") private String censusCreateTopic; @Value("${census.update.topic}") private String censusUpdateTopic; + // Boundary Service + @Value("${egov.boundary.service.host}") + private String boundaryServiceHost; + + @Value("${egov.boundary.relationship.search.endpoint}") + private String boundaryRelationshipSearchEndpoint; + + // Plan Service + @Value("${egov.plan.service.host}") + private String planServiceHost; + + @Value("${egov.plan.employee.assignment.search.endpoint}") + private String planEmployeeAssignmentSearchEndpoint; + // User Config @Value("${egov.user.host}") private String userHost; diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index ea509513ad5..b266cd5d50a 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -15,6 +15,10 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; + public static final String ERROR_WHILE_FETCHING_BOUNDARY_DETAILS = "Exception occurred while fetching boundary relationship from boundary service: "; + + public static final String ERROR_WHILE_FETCHING_EMPLOYEE_ASSIGNMENT_DETAILS = "Exception occurred while fetching plan employee assignment details from plan service: "; + public static final String RES_MSG_ID = "uief87324"; public static final String SUCCESSFUL = "successful"; public static final String FAILED = "failed"; @@ -48,5 +52,13 @@ public class ServiceConstants { public static final String TENANTID = "?tenantId="; public static final String BUSINESS_SERVICES = "&businessServices="; + public static final String NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_CODE = "NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE"; + public static final String NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_MESSAGE = "Invalid or incorrect boundaryCode. No boundary data found."; + + public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; + public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; + + public static final String INVALID_PARTNER_CODE = "INVALID_PARTNER"; + public static final String INVALID_PARTNER_MESSAGE = "Invalid partner assignment or invalid jurisdiction of the assigned partner"; } diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index f51a2a5a333..a125ef06162 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -38,6 +38,7 @@ public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository r * @return The created census reponse. */ public CensusResponse create(CensusRequest request) { + validator.validateCreate(request); // Validate census create request enrichment.enrichCreate(request); // Enrich census create request repository.create(request); // Delegate creation request to repository return CensusResponse.builder() @@ -53,6 +54,7 @@ public CensusResponse create(CensusRequest request) { * @return A list of census record that matches the search criteria. */ public CensusResponse search(CensusSearchRequest request) { + validator.validateSearch(request); // Validate census search request List censusList = repository.search(request.getCensusSearchCriteria()); // Delegate search request to repository return CensusResponse.builder() .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) @@ -67,6 +69,7 @@ public CensusResponse search(CensusSearchRequest request) { * @return The updated census response. */ public CensusResponse update(CensusRequest request) { + validator.validateUpdate(request); // Validate census update request enrichment.enrichUpdate(request); // Enrich census update request repository.update(request); // Delegate update request to repository return CensusResponse.builder() diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 165d4d2f0ab..ecf4a97c011 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -1,7 +1,135 @@ package digit.service.validator; +import digit.config.Configuration; +import digit.util.BoundaryUtil; +import digit.util.PlanEmployeeAssignmnetUtil; +import digit.web.models.Census; +import digit.web.models.CensusRequest; +import digit.web.models.CensusSearchRequest; +import digit.web.models.boundary.BoundarySearchResponse; +import digit.web.models.boundary.EnrichedBoundary; +import digit.web.models.boundary.HierarchyRelation; +import digit.web.models.plan.PlanEmployeeAssignmentResponse; +import org.egov.common.contract.request.User; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.*; + +import static digit.config.ServiceConstants.*; +import static digit.config.ServiceConstants.USERINFO_MISSING_MESSAGE; @Component public class CensusValidator { + + private BoundaryUtil boundaryUtil; + + private PlanEmployeeAssignmnetUtil employeeAssignmnetUtil; + + private Configuration configs; + + public CensusValidator(BoundaryUtil boundaryUtil, PlanEmployeeAssignmnetUtil employeeAssignmnetUtil, Configuration configs) { + this.boundaryUtil = boundaryUtil; + this.employeeAssignmnetUtil = employeeAssignmnetUtil; + this.configs = configs; + } + + /** + * Validates boundary cade, partner assignment and jurisdiction for census create request + * + * @param request The create request for census + */ + public void validateCreate(CensusRequest request) { + Census census = request.getCensus(); + BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), census.getBoundaryCode(), census.getTenantId(), census.getHierarchyType(), Boolean.TRUE, Boolean.FALSE); + boolean flag = true; + + // Validate boundary code against boundary service + validateBoundaryCode(boundarySearchResponse, census); + + // Validate the user information in the request + validateUserInfo(request); + + // Validate partner assignment and jurisdiction against plan service + validatePartnerForCensus(request, flag); + } + + /** + * Validates the boundary code provided in census request against boundary service. + * + * @param boundarySearchResponse response from the boundary service. + * @param census Census record whose boundary code is to be validated. + */ + private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, Census census) { + HierarchyRelation tenantBoundary = boundarySearchResponse.getTenantBoundary().get(0); + + if (CollectionUtils.isEmpty(tenantBoundary.getBoundary())) { + throw new CustomException(NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_CODE, NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_MESSAGE); + } + + // Enrich the boundary ancestral path for the provided boundary code + enrichBoundaryPath(census, tenantBoundary); + } + + /** + * Validates the user information within the provided CensusRequest. + * + * @param request the CensusRequest containing the user information to be validated + * @throws CustomException if the user information is missing in the request + */ + public void validateUserInfo(CensusRequest request) { + if (ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) { + throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); + } + } + + /** + * Validates partner assignment and jurisdiction against plan service + * + * @param request the request whose partner assignment is to be validated + * @param flag Validates only when flag is true + */ + private void validatePartnerForCensus(CensusRequest request, boolean flag) { + if (flag) { + User userInfo = request.getRequestInfo().getUserInfo(); + Census census = request.getCensus(); + List jurisdiction = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); + PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(request.getRequestInfo(), userInfo.getUuid(), census.getSource(), census.getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); + + if (CollectionUtils.isEmpty(employeeAssignmentResponse.getPlanEmployeeAssignment())) { + throw new CustomException(INVALID_PARTNER_CODE, INVALID_PARTNER_MESSAGE); + } + } + } + + /** + * Enriches the boundary ancestral path for the provided boundary code in the census request. + * + * @param census The census record whose boundary ancestral path has to be enriched. + * @param tenantBoundary boundary relationship from the boundary service for the given boundary code. + */ + private void enrichBoundaryPath(Census census, HierarchyRelation tenantBoundary) { + EnrichedBoundary boundary = tenantBoundary.getBoundary().get(0); + StringBuilder boundaryAncestralPath = new StringBuilder(boundary.getCode()); + + // Iterate through the child boundary until there are no more + while (!CollectionUtils.isEmpty(boundary.getChildren())) { + boundary = boundary.getChildren().get(0); + boundaryAncestralPath.append("|").append(boundary.getCode()); + } + + // Setting the boundary ancestral path for the provided boundary + census.setBoundaryAncestralPath(Collections.singletonList(boundaryAncestralPath.toString())); + } + + public void validateSearch(CensusSearchRequest request) { + + } + + public void validateUpdate(CensusRequest request) { + + } + } diff --git a/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java b/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java new file mode 100644 index 00000000000..42f7b86fee7 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java @@ -0,0 +1,82 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.RequestInfoWrapper; +import digit.web.models.boundary.BoundarySearchResponse; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_BOUNDARY_DETAILS; + +@Slf4j +@Component +public class BoundaryUtil { + + private RestTemplate restTemplate; + + private Configuration configs; + + public BoundaryUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + /** + * This method fetches boundary relationships from Boundary service for the provided boundaryCode and hierarchyType. + * + * @param requestInfo request info from the request. + * @param boundaryCode boundary code from the request. + * @param tenantId tenant id from the request. + * @param hierarchyType hierarchy type from the request. + * @param includeParents is true if you want to include parent boundary. + * @param includeChildren is true if you want to include child boundary. + * @return returns the response from boundary service + */ + public BoundarySearchResponse fetchBoundaryData(RequestInfo requestInfo, String boundaryCode, String tenantId, String hierarchyType, Boolean includeParents, Boolean includeChildren) { + + // Create Boundary Relationship search uri + Map uriParameters = new HashMap<>(); + StringBuilder uri = getBoundaryRelationshipSearchUri(uriParameters, boundaryCode, tenantId, hierarchyType, includeParents, includeChildren); + + // Create request body + RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); + BoundarySearchResponse boundarySearchResponse = new BoundarySearchResponse(); + + try { + boundarySearchResponse = restTemplate.postForObject(uri.toString(), requestInfoWrapper, BoundarySearchResponse.class, uriParameters); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_BOUNDARY_DETAILS, e); + } + + return boundarySearchResponse; + } + + /** + * This method creates Boundary service uri with query parameters + * + * @param uriParameters map that stores values corresponding to the placeholder in uri + * @param boundaryCode boundary code from the request. + * @param tenantId tenant id from the request. + * @param hierarchyType hierarchy type from the request. + * @param includeParents is true if you want to include parent boundary. + * @param includeChildren is true if you want to include child boundary. + * @return a complete boundary service uri + */ + private StringBuilder getBoundaryRelationshipSearchUri(Map uriParameters, String boundaryCode, String tenantId, String hierarchyType, Boolean includeParents, Boolean includeChildren) { + StringBuilder uri = new StringBuilder(); + uri.append(configs.getBoundaryServiceHost()).append(configs.getBoundaryRelationshipSearchEndpoint()).append("?codes={boundaryCode}&includeParents={includeParents}&includeChildren={includeChildren}&tenantId={tenantId}&hierarchyType={hierarchyType}"); + + uriParameters.put("boundaryCode", boundaryCode); + uriParameters.put("tenantId", tenantId); + uriParameters.put("includeParents", includeParents.toString()); + uriParameters.put("includeChildren", includeChildren.toString()); + uriParameters.put("hierarchyType", hierarchyType); + + return uri; + } +} diff --git a/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java b/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java new file mode 100644 index 00000000000..3da17a87287 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java @@ -0,0 +1,92 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.plan.PlanEmployeeAssignmentResponse; +import digit.web.models.plan.PlanEmployeeAssignmentSearchCriteria; +import digit.web.models.plan.PlanEmployeeAssignmentSearchRequest; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.List; + +import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_EMPLOYEE_ASSIGNMENT_DETAILS; + +@Slf4j +@Component +public class PlanEmployeeAssignmnetUtil { + + private RestTemplate restTemplate; + + private Configuration configs; + + public PlanEmployeeAssignmnetUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + /** + * This method fetches plan employee assignment from plan service for provided employeeID. + * + * @param requestInfo request info from the request. + * @param employeeId employee id from the request. + * @param planConfigId plan configuration id from the request. + * @param tenantId tenant id from the request. + * @param roles allowed roles for census + * @param jurisdiction list of ancestral boundary codes for the given boundary + * @return returns planEmployeeAssignment for provided search criteria. + */ + public PlanEmployeeAssignmentResponse fetchPlanEmployeeAssignment(RequestInfo requestInfo, String employeeId, String planConfigId, String tenantId, List roles, List jurisdiction) { + // Get plan employee assignment uri + StringBuilder uri = getPlanEmployeeAssignmentUri(); + + // Get search request body for plan employee assignment + PlanEmployeeAssignmentSearchRequest searchRequest = getPlanEmployeeAssignmentRequest(requestInfo, employeeId, planConfigId, tenantId, roles, jurisdiction); + PlanEmployeeAssignmentResponse response = new PlanEmployeeAssignmentResponse(); + + try { + response = restTemplate.postForObject(uri.toString(), searchRequest, PlanEmployeeAssignmentResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_EMPLOYEE_ASSIGNMENT_DETAILS, e); + } + + return response; + } + + /** + * This method builds the search request body for plan employee assignment search + * + * @param requestInfo request info from the request. + * @param employeeId employee id from the request. + * @param planConfigId plan configuration id from the request. + * @param tenantId tenant id from the request. + * @param roles allowed roles for census + * @param jurisdiction list of ancestral boundary codes for the given boundary + * @return the search request for pln employee assignment search + */ + private PlanEmployeeAssignmentSearchRequest getPlanEmployeeAssignmentRequest(RequestInfo requestInfo, String employeeId, String planConfigId, String tenantId, List roles, List jurisdiction) { + PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(tenantId) + .planConfigurationId(planConfigId) + .employeeId(employeeId) + .role(roles) + .jurisdiction(jurisdiction) + .build(); + + return PlanEmployeeAssignmentSearchRequest.builder() + .requestInfo(requestInfo) + .planEmployeeAssignmentSearchCriteria(searchCriteria) + .build(); + } + + /** + * This method creates the uri for plan employee assignment search + * + * @return uri for plan employee assignment search + */ + private StringBuilder getPlanEmployeeAssignmentUri() { + StringBuilder uri = new StringBuilder(); + return uri.append(configs.getPlanServiceHost()).append(configs.getPlanEmployeeAssignmentSearchEndpoint()); + } +} diff --git a/health-services/census-service/src/main/java/digit/web/models/User.java b/health-services/census-service/src/main/java/digit/web/models/User.java deleted file mode 100644 index 3d82a69903e..00000000000 --- a/health-services/census-service/src/main/java/digit/web/models/User.java +++ /dev/null @@ -1,170 +0,0 @@ -package digit.web.models; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; - -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; - -import org.egov.common.contract.request.Role; -import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; - -/** - * This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server. - */ -@Schema(description = "This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server.") -@Validated -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class User { - - @JsonProperty("tenantId") - @NotNull - private String tenantId = null; - - @JsonProperty("id") - private Integer id = null; - - @JsonProperty("uuid") - private String uuid = null; - - @JsonProperty("userName") - @NotNull - private String userName = null; - - @JsonProperty("mobileNumber") - private String mobileNumber = null; - - @JsonProperty("emailId") - private String emailId = null; - - @JsonProperty("roles") - @NotNull - @Valid - private List roles = new ArrayList<>(); - - @JsonProperty("salutation") - private String salutation = null; - - @JsonProperty("name") - private String name = null; - - @JsonProperty("gender") - private String gender = null; - - @JsonProperty("alternateMobileNumber") - private String alternateMobileNumber = null; - - @JsonProperty("altContactNumber") - private String altContactNumber = null; - - @JsonProperty("pan") - private String pan = null; - - @JsonProperty("aadhaarNumber") - private String aadhaarNumber = null; - - @JsonProperty("permanentAddress") - @Size(max = 300) - private String permanentAddress = null; - - @JsonProperty("permanentCity") - @Size(max = 300) - private String permanentCity = null; - - @JsonProperty("permanentPincode") - @Size(max = 6) - private String permanentPincode = null; - - @JsonProperty("correspondenceCity") - @Size(max = 50) - private String correspondenceCity = null; - - @JsonProperty("correspondencePincode") - @Size(max = 6) - private String correspondencePincode = null; - - @JsonProperty("correspondenceAddress") - @Size(max = 300) - private String correspondenceAddress = null; - - @JsonProperty("active") - private Boolean active = null; - - @JsonProperty("locale") - @Size(max = 10) - private String locale = null; - - @JsonProperty("type") - @Size(max = 20) - private String type = null; - - @JsonProperty("accountLocked") - private Boolean accountLocked = null; - - @JsonProperty("accountLockedDate") - private Long accountLockedDate = null; - - @JsonProperty("fatherOrHusbandName") - @Size(max = 100) - private String fatherOrHusbandName = null; - - @JsonProperty("relationship") - @Size(max = 20) - private String relationship = null; - - @JsonProperty("signature") - private String signature = null; - - @JsonProperty("bloodGroup") - @Size(max = 3) - private String bloodGroup = null; - - @JsonProperty("photo") - private String photo = null; - - @JsonProperty("identificationMark") - private String identificationMark = null; - - @JsonProperty("createdBy") - private Long createdBy = null; - - @JsonProperty("password") - private String password = null; - - @JsonProperty("otpReference") - private String otpReference = null; - - @JsonProperty("lastModifiedBy") - private Long lastModifiedBy = null; - - @JsonProperty("createdDate") - @Valid - private LocalDate createdDate = null; - - @JsonProperty("lastModifiedDate") - @Valid - private LocalDate lastModifiedDate = null; - - @JsonProperty("dob") - private Long dob = null; - - @JsonProperty("pwdExpiryDate") - private Long pwdExpiryDate = null; - - - public User addRolesItem(Role rolesItem) { - this.roles.add(rolesItem); - return this; - } - -} diff --git a/health-services/census-service/src/main/java/digit/web/models/UserInfo.java b/health-services/census-service/src/main/java/digit/web/models/UserInfo.java deleted file mode 100644 index 057d0750b6b..00000000000 --- a/health-services/census-service/src/main/java/digit/web/models/UserInfo.java +++ /dev/null @@ -1,72 +0,0 @@ -package digit.web.models; - -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import digit.web.models.Role1; -import digit.web.models.TenantRole; -import io.swagger.v3.oas.annotations.media.Schema; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; - -/** - * This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server. - */ -@Schema(description = "This is acting ID token of the authenticated user on the server. Any value provided by the clients will be ignored and actual user based on authtoken will be used on the server.") -@Validated -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class UserInfo { - @JsonProperty("tenantId") - @NotNull - private String tenantId = null; - - @JsonProperty("id") - private Integer id = null; - - @JsonProperty("userName") - @NotNull - private String userName = null; - - @JsonProperty("mobile") - private String mobile = null; - - @JsonProperty("email") - private String email = null; - - @JsonProperty("primaryrole") - @NotNull - @Valid - private List primaryrole = new ArrayList<>(); - - @JsonProperty("additionalroles") - @Valid - private List additionalroles = null; - - - public UserInfo addPrimaryroleItem(Role1 primaryroleItem) { - this.primaryrole.add(primaryroleItem); - return this; - } - - public UserInfo addAdditionalrolesItem(TenantRole additionalrolesItem) { - if (this.additionalroles == null) { - this.additionalroles = new ArrayList<>(); - } - this.additionalroles.add(additionalrolesItem); - return this; - } - -} diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java new file mode 100644 index 00000000000..7f92e1f53c8 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java @@ -0,0 +1,42 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + +/** + * BoundarySearchResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundarySearchResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("TenantBoundary") + @Valid + private List tenantBoundary = null; + + + public BoundarySearchResponse addTenantBoundaryItem(HierarchyRelation tenantBoundaryItem) { + if (this.tenantBoundary == null) { + this.tenantBoundary = new ArrayList<>(); + } + this.tenantBoundary.add(tenantBoundaryItem); + return this; + } + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java b/health-services/census-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java new file mode 100644 index 00000000000..c42af3737ce --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java @@ -0,0 +1,42 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonIgnore; +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 javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * EnrichedBoundary + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class EnrichedBoundary { + + @JsonProperty("id") + private String id; + + @JsonProperty("code") + @NotNull + private String code; + + @JsonProperty("boundaryType") + private String boundaryType; + + @JsonProperty("children") + @Valid + private List children = null; + + @JsonIgnore + private String parent = null; + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java b/health-services/census-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java new file mode 100644 index 00000000000..7a3e26f6595 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java @@ -0,0 +1,34 @@ +package digit.web.models.boundary; + +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 javax.validation.Valid; +import java.util.List; + +/** + * HierarchyRelation + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class HierarchyRelation { + + @JsonProperty("tenantId") + private String tenantId = null; + + @JsonProperty("hierarchyType") + private String hierarchyType = null; + + @JsonProperty("boundary") + @Valid + private List boundary = null; + + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignment.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignment.java new file mode 100644 index 00000000000..1cec6f46300 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignment.java @@ -0,0 +1,63 @@ +package digit.web.models.plan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * PlanEmployeeAssignment + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignment { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @NotNull + @Size(min = 2, max = 64) + private String planConfigurationId = null; + + @JsonProperty("employeeId") + @NotNull + @Size(min = 2, max = 64) + private String employeeId = null; + + @JsonProperty("role") + @NotNull + @Size(min = 2, max = 64) + private String role = null; + + @JsonProperty("jurisdiction") + @Valid + @NotEmpty + private List jurisdiction = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + private Boolean active = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; +} diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentResponse.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentResponse.java new file mode 100644 index 00000000000..8e6e0260116 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentResponse.java @@ -0,0 +1,37 @@ +package digit.web.models.plan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + + +/** + * PlanEmployeeAssignmentResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("PlanEmployeeAssignment") + @Valid + private List planEmployeeAssignment = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; +} + diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java new file mode 100644 index 00000000000..d7a1d867273 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java @@ -0,0 +1,50 @@ +package digit.web.models.plan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * PlanEmployeeAssignmentSearchCriteria + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentSearchCriteria { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @Size(min = 2, max = 100) + @NotNull + private String tenantId = null; + + @JsonProperty("employeeId") + private String employeeId = null; + + @JsonProperty("planConfigurationId") + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("role") + @Size(min = 2, max = 64) + private List role = null; + + @JsonProperty("jurisdiction") + @Valid + private List jurisdiction = null; + + @JsonProperty("active") + private Boolean active = null; +} diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchRequest.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchRequest.java new file mode 100644 index 00000000000..4a343fb8e45 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchRequest.java @@ -0,0 +1,29 @@ +package digit.web.models.plan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanEmployeeAssignmentSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanEmployeeAssignmentSearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanEmployeeAssignmentSearchCriteria") + @Valid + private PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = null; +} From 9d39b24c8a011a5ff74b31444f52a7e56afa12af Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 10 Oct 2024 13:37:27 +0530 Subject: [PATCH 125/351] validations for census --- .../src/main/resources/application.properties | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 295281ac0ea..53dc48dbfc5 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -59,6 +59,14 @@ egov.localization.statelevel=true egov.mdms.host=https://unified-dev.digit.org egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +#Boundary service urls +egov.boundary.service.host=https://unified-dev.digit.org +egov.boundary.relationship.search.endpoint=/boundary-service/boundary-relationships/_search + +#Plan service urls +egov.plan.service.host=https://unified-dev.digit.org +egov.plan.employee.assignment.search.endpoint=/plan-service/employee/_search + #hrms urls egov.hrms.host=https://unified-dev.digit.org egov.hrms.search.endpoint=/egov-hrms/employees/_search @@ -90,4 +98,7 @@ census.default.offset=0 census.default.limit=10 #The value of the following field should be changed to service specific name -kafka.topics.consumer=service-consumer-topic \ No newline at end of file +kafka.topics.consumer=service-consumer-topic + +#Roles for census +allowed.census.roles={'POPULATION_DATA_APPROVER','ROOT_POPULATION_DATA_APPROVER'} \ No newline at end of file From 802de7af738805503afd471c49082df2d28d6a4a Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 10 Oct 2024 14:08:36 +0530 Subject: [PATCH 126/351] validations for census --- .../java/digit/config/ServiceConstants.java | 2 + .../service/validator/CensusValidator.java | 51 ++++++++++++++++--- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index b266cd5d50a..98b0215b881 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -61,4 +61,6 @@ public class ServiceConstants { public static final String INVALID_PARTNER_CODE = "INVALID_PARTNER"; public static final String INVALID_PARTNER_MESSAGE = "Invalid partner assignment or invalid jurisdiction of the assigned partner"; + public static final String INVALID_CENSUS_CODE = "INVALID_CENSUS"; + public static final String INVALID_CENSUS_MESSAGE = "Provided census does not exist"; } diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index ecf4a97c011..82fd70198c5 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -1,15 +1,18 @@ package digit.service.validator; import digit.config.Configuration; +import digit.repository.CensusRepository; import digit.util.BoundaryUtil; import digit.util.PlanEmployeeAssignmnetUtil; import digit.web.models.Census; import digit.web.models.CensusRequest; +import digit.web.models.CensusSearchCriteria; import digit.web.models.CensusSearchRequest; import digit.web.models.boundary.BoundarySearchResponse; import digit.web.models.boundary.EnrichedBoundary; import digit.web.models.boundary.HierarchyRelation; import digit.web.models.plan.PlanEmployeeAssignmentResponse; +import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.request.User; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -30,10 +33,13 @@ public class CensusValidator { private Configuration configs; - public CensusValidator(BoundaryUtil boundaryUtil, PlanEmployeeAssignmnetUtil employeeAssignmnetUtil, Configuration configs) { + private CensusRepository repository; + + public CensusValidator(BoundaryUtil boundaryUtil, PlanEmployeeAssignmnetUtil employeeAssignmnetUtil, Configuration configs, CensusRepository repository) { this.boundaryUtil = boundaryUtil; this.employeeAssignmnetUtil = employeeAssignmnetUtil; this.configs = configs; + this.repository = repository; } /** @@ -53,7 +59,7 @@ public void validateCreate(CensusRequest request) { validateUserInfo(request); // Validate partner assignment and jurisdiction against plan service - validatePartnerForCensus(request, flag); + validatePartnerForCensus(request.getRequestInfo(), census, flag); } /** @@ -88,15 +94,15 @@ public void validateUserInfo(CensusRequest request) { /** * Validates partner assignment and jurisdiction against plan service * - * @param request the request whose partner assignment is to be validated - * @param flag Validates only when flag is true + * @param requestInfo the requestInfo from the request + * @param census the census to be validated + * @param flag Validates only when flag is true */ - private void validatePartnerForCensus(CensusRequest request, boolean flag) { + private void validatePartnerForCensus(RequestInfo requestInfo, Census census, boolean flag) { if (flag) { - User userInfo = request.getRequestInfo().getUserInfo(); - Census census = request.getCensus(); + User userInfo = requestInfo.getUserInfo(); List jurisdiction = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); - PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(request.getRequestInfo(), userInfo.getUuid(), census.getSource(), census.getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); + PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(requestInfo, userInfo.getUuid(), census.getSource(), census.getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); if (CollectionUtils.isEmpty(employeeAssignmentResponse.getPlanEmployeeAssignment())) { throw new CustomException(INVALID_PARTNER_CODE, INVALID_PARTNER_MESSAGE); @@ -129,7 +135,36 @@ public void validateSearch(CensusSearchRequest request) { } public void validateUpdate(CensusRequest request) { + boolean flag = true; + + // Validate if Census record to be updated exists + Census census = validateCensusExistence(request); + + // Validate partner assignment and jurisdiction against plan service + validatePartnerForCensus(request.getRequestInfo(), census, flag); + } + + /** + * Validates the existence of census record in the repository + * + * @param request The request containing the census to be validated + * @return the census that exist in the repository + */ + private Census validateCensusExistence(CensusRequest request) { + Census census = request.getCensus(); + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() + .id(census.getId()) + .tenantId(census.getTenantId()) + .areaCodes(Collections.singletonList(census.getBoundaryCode())) + .build(); + + List censusList = repository.search(searchCriteria); + + if (CollectionUtils.isEmpty(censusList)) { + throw new CustomException(INVALID_CENSUS_CODE, INVALID_CENSUS_MESSAGE); + } + return censusList.get(0); } } From bb46e2ba38db367cda134dc1aa874d16df5d98e5 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 9 Oct 2024 15:18:13 +0530 Subject: [PATCH 127/351] HCMPRE-832 adding status and category for plan config assumptions and operation tables. --- .../querybuilder/PlanConfigQueryBuilder.java | 4 ++-- .../repository/rowmapper/PlanConfigRowMapper.java | 11 ++++++----- .../src/main/java/digit/web/models/Assumption.java | 9 +++++++++ .../src/main/java/digit/web/models/Operation.java | 9 +++++++++ .../src/main/java/digit/web/models/Source.java | 5 +++++ ...00__plan_configuration_add_source_category_ddl.sql | 10 ++++++++++ 6 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/Source.java create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index f84d884ee31..608e0257def 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -29,8 +29,8 @@ public PlanConfigQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_CONFIG_QUERY = "SELECT pc.id as plan_configuration_id, pc.tenant_id as plan_configuration_tenant_id, pc.name as plan_configuration_name, pc.campaign_id as plan_configuration_campaign_id, pc.status as plan_configuration_status, pc.additional_details as plan_configuration_additional_details, pc.created_by as plan_configuration_created_by, pc.created_time as plan_configuration_created_time, pc.last_modified_by as plan_configuration_last_modified_by, pc.last_modified_time as plan_configuration_last_modified_time, \n" + "\t pcf.id as plan_configuration_files_id, pcf.plan_configuration_id as plan_configuration_files_plan_configuration_id, pcf.filestore_id as plan_configuration_files_filestore_id, pcf.input_file_type as plan_configuration_files_input_file_type, pcf.template_identifier as plan_configuration_files_template_identifier, pcf.active as plan_configuration_files_active, pcf.created_by as plan_configuration_files_created_by, pcf.created_time as plan_configuration_files_created_time, pcf.last_modified_by as plan_configuration_files_last_modified_by, pcf.last_modified_time as plan_configuration_files_last_modified_time,\n" + - "\t pca.id as plan_configuration_assumptions_id, pca.key as plan_configuration_assumptions_key, pca.value as plan_configuration_assumptions_value, pca.active as plan_configuration_assumptions_active, pca.plan_configuration_id as plan_configuration_assumptions_plan_configuration_id, pca.created_by as plan_configuration_assumptions_created_by, pca.created_time as plan_configuration_assumptions_created_time, pca.last_modified_by as plan_configuration_assumptions_last_modified_by, pca.last_modified_time as plan_configuration_assumptions_last_modified_time,\n" + - "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.active as plan_configuration_operations_active, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + + "\t pca.id as plan_configuration_assumptions_id, pca.key as plan_configuration_assumptions_key, pca.value as plan_configuration_assumptions_value, pca.source as plan_configuration_assumptions_source, pca.category as plan_configuration_assumptions_category, pca.active as plan_configuration_assumptions_active, pca.plan_configuration_id as plan_configuration_assumptions_plan_configuration_id, pca.created_by as plan_configuration_assumptions_created_by, pca.created_time as plan_configuration_assumptions_created_time, pca.last_modified_by as plan_configuration_assumptions_last_modified_by, pca.last_modified_time as plan_configuration_assumptions_last_modified_time,\n" + + "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.source as plan_configuration_operations_source, pco.category as plan_configuration_operations_category, pco.active as plan_configuration_operations_active, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + "\t pcm.id as plan_configuration_mapping_id, pcm.filestore_id as plan_configuration_mapping_filestore_id, pcm.mapped_from as plan_configuration_mapping_mapped_from, pcm.mapped_to as plan_configuration_mapping_mapped_to, pcm.active as plan_configuration_mapping_active, pcm.plan_configuration_id as plan_configuration_mapping_plan_configuration_id, pcm.created_by as plan_configuration_mapping_created_by, pcm.created_time as plan_configuration_mapping_created_time, pcm.last_modified_by as plan_configuration_mapping_last_modified_by, pcm.last_modified_time as plan_configuration_mapping_last_modified_time\n" + "\t FROM plan_configuration pc\n" + "\t LEFT JOIN plan_configuration_files pcf ON pc.id = pcf.plan_configuration_id\n" + diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index fc3305b5f77..9d331888d0f 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java @@ -1,11 +1,8 @@ package digit.repository.rowmapper; import digit.util.QueryUtil; -import digit.web.models.Assumption; -import digit.web.models.File; -import digit.web.models.Operation; -import digit.web.models.PlanConfiguration; -import digit.web.models.ResourceMapping; +import digit.web.models.*; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; @@ -122,6 +119,8 @@ private void addAssumptions(ResultSet rs, PlanConfiguration planConfigEntry, Map assumption.setKey(rs.getString("plan_configuration_assumptions_key")); assumption.setValue(rs.getBigDecimal("plan_configuration_assumptions_value")); assumption.setActive(rs.getBoolean("plan_configuration_assumptions_active")); + assumption.setSource(Source.valueOf(rs.getString("plan_configuration_assumptions_source"))); + assumption.setCategory(rs.getString("plan_configuration_assumptions_category")); if (CollectionUtils.isEmpty(planConfigEntry.getAssumptions())) { List assumptionList = new ArrayList<>(); @@ -157,6 +156,8 @@ private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Map< operation.setOutput(rs.getString("plan_configuration_operations_output")); operation.setActive(rs.getBoolean("plan_configuration_operations_active")); operation.setShowOnEstimationDashboard(rs.getBoolean("plan_configuration_operations_show_on_estimation_dashboard")); + operation.setSource(Source.valueOf(rs.getString("plan_configuration_operations_source"))); + operation.setCategory(rs.getString("plan_configuration_operations_category")); if (CollectionUtils.isEmpty(planConfigEntry.getOperations())) { List operationList = new ArrayList<>(); diff --git a/health-services/plan-service/src/main/java/digit/web/models/Assumption.java b/health-services/plan-service/src/main/java/digit/web/models/Assumption.java index a4b7e3ad01f..7d2cd52286a 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Assumption.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Assumption.java @@ -42,6 +42,15 @@ public class Assumption { @Digits(integer = 10, fraction = 2, message = "The Assumption value must have up to 10 digits and up to 2 decimal points") private BigDecimal value = null; + @JsonProperty("source") + @NotNull(message = "Source cannot be null. Please specify a valid source.") + private Source source = null; + + @JsonProperty("category") + @NotNull + @Size(min = 2, max = 64) + private String category = null; + @JsonProperty("active") @NotNull private Boolean active = true; diff --git a/health-services/plan-service/src/main/java/digit/web/models/Operation.java b/health-services/plan-service/src/main/java/digit/web/models/Operation.java index a515261aec3..20eabc1d8b3 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Operation.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Operation.java @@ -52,6 +52,15 @@ public class Operation { @NotNull private Boolean showOnEstimationDashboard = true; + @JsonProperty("source") + @NotNull(message = "Source cannot be null. Please specify a valid source.") + private Source source = null; + + @JsonProperty("category") + @NotNull + @Size(min = 2, max = 64) + private String category = null; + @JsonProperty("active") @NotNull private Boolean active = true; diff --git a/health-services/plan-service/src/main/java/digit/web/models/Source.java b/health-services/plan-service/src/main/java/digit/web/models/Source.java new file mode 100644 index 00000000000..e58bfba27be --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/Source.java @@ -0,0 +1,5 @@ +package digit.web.models; + +public enum Source { + MDMS, CUSTOM, VEHICLE; +} diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql new file mode 100644 index 00000000000..6776dec892c --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql @@ -0,0 +1,10 @@ +ALTER TABLE plan_configuration_assumptions +ADD COLUMN source varchar(64), +ADD COLUMN category varchar(64); +UPDATE plan_configuration_assumptions SET source = 'MDMS' WHERE source IS NULL; +UPDATE plan_configuration_assumptions SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; + +ALTER TABLE plan_configuration_operations +ADD COLUMN source varchar(64), +ADD COLUMN category varchar(64); +UPDATE plan_configuration_operations SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; \ No newline at end of file From f39394743d465401f79f9229690e6a956f4a700d Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 9 Oct 2024 16:08:19 +0530 Subject: [PATCH 128/351] HCMPRE-832 changes for assumption key uniqueness and validation against MDMS only when source is MDMS --- .../java/digit/config/ServiceConstants.java | 3 ++ .../validator/PlanConfigurationValidator.java | 33 ++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 92e81aa6057..0f0396c42b0 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -34,6 +34,9 @@ public class ServiceConstants { public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE = "ASSUMPTION_KEY_NOT_FOUND_IN_MDMS"; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS "; + public static final String DUPLICATE_ASSUMPTION_KEY_CODE = "DUPLICATE_ASSUMPTION_KEY"; + public static final String DUPLICATE_ASSUMPTION_KEY_MESSAGE = "Duplicate Assumption key found : "; + public static final String VEHICLE_ID_NOT_FOUND_IN_MDMS_CODE = "VEHICLE_ID_NOT_FOUND_IN_MDMS"; public static final String VEHICLE_ID_NOT_FOUND_IN_MDMS_MESSAGE = "Vehicle Id is not present in MDMS"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 52027522a39..bafcb068b79 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -64,6 +64,9 @@ public void validateCreate(PlanConfigurationRequest request) { // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); + // Validate that the assumption keys in the request are unique + validateAssumptionUniqueness(planConfiguration); + // Validate that the assumption values in the plan configuration are correct validateAssumptionValue(planConfiguration); @@ -198,13 +201,30 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O HashSet assumptionSetFromMDMS = new HashSet<>(assumptionListFromMDMS); planConfiguration.getAssumptions().forEach(assumption -> { - if (!assumptionSetFromMDMS.contains(assumption.getKey())) { - log.error(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey()); - throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); - } + if (assumption.getSource() == Source.MDMS) { + if (!assumptionSetFromMDMS.contains(assumption.getKey())) { + log.error(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey()); + throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); } - ); + } + }); + } + } + /** + * Validates the uniqueness of assumption keys in the provided PlanConfiguration. + * If any duplicate keys are found, a CustomException is thrown. + * + * @param planConfig the PlanConfiguration object containing a list of Assumptions to validate + * @throws CustomException if a duplicate assumption key is found + */ + public void validateAssumptionUniqueness(PlanConfiguration planConfig) { + Set assumptionKeys = new HashSet<>(); + + for (Assumption assumption : planConfig.getAssumptions()) { + if (!assumptionKeys.add(assumption.getKey())) { + throw new CustomException(DUPLICATE_ASSUMPTION_KEY_CODE, DUPLICATE_ASSUMPTION_KEY_MESSAGE + assumption.getKey()); + } } } @@ -428,6 +448,9 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); + // Validate that the assumption keys in the request are unique + validateAssumptionUniqueness(planConfiguration); + // Validate that the assumption values in the plan configuration are correct validateAssumptionValue(planConfiguration); From 72f7b0e83880a949f4bafd80b8a5478b7f575035 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 9 Oct 2024 17:06:07 +0530 Subject: [PATCH 129/351] HCMPRE-832 code rabbit review comments --- .../repository/rowmapper/PlanConfigRowMapper.java | 2 +- .../validator/PlanConfigurationValidator.java | 6 ++++-- ...__plan_configuration_add_source_category_ddl.sql | 13 ++++++++----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index 9d331888d0f..83ca049b8cb 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java @@ -51,7 +51,7 @@ public List extractData(ResultSet rs) throws SQLException, Da planConfigEntry.setTenantId(rs.getString("plan_configuration_tenant_id")); planConfigEntry.setName(rs.getString("plan_configuration_name")); planConfigEntry.setCampaignId(rs.getString("plan_configuration_campaign_id")); - planConfigEntry.setStatus(rs.getString("plan_configuration_status").toUpperCase()); + planConfigEntry.setStatus(rs.getString("plan_configuration_status")); planConfigEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_configuration_additional_details"))); planConfigEntry.setAuditDetails(auditDetails); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index bafcb068b79..73c4adbc181 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -222,8 +222,10 @@ public void validateAssumptionUniqueness(PlanConfiguration planConfig) { Set assumptionKeys = new HashSet<>(); for (Assumption assumption : planConfig.getAssumptions()) { - if (!assumptionKeys.add(assumption.getKey())) { - throw new CustomException(DUPLICATE_ASSUMPTION_KEY_CODE, DUPLICATE_ASSUMPTION_KEY_MESSAGE + assumption.getKey()); + if (assumption.getActive() != Boolean.FALSE) { + if (!assumptionKeys.add(assumption.getKey())) { + throw new CustomException(DUPLICATE_ASSUMPTION_KEY_CODE, DUPLICATE_ASSUMPTION_KEY_MESSAGE + assumption.getKey()); + } } } } diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql index 6776dec892c..20540b91bcb 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql @@ -1,10 +1,13 @@ ALTER TABLE plan_configuration_assumptions -ADD COLUMN source varchar(64), -ADD COLUMN category varchar(64); +ADD COLUMN source varchar(64) NOT NULL, +ADD COLUMN category varchar(64) NOT NULL; + UPDATE plan_configuration_assumptions SET source = 'MDMS' WHERE source IS NULL; UPDATE plan_configuration_assumptions SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; ALTER TABLE plan_configuration_operations -ADD COLUMN source varchar(64), -ADD COLUMN category varchar(64); -UPDATE plan_configuration_operations SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; \ No newline at end of file +ADD COLUMN source varchar(64) NOT NULL, +ADD COLUMN category varchar(64) NOT NULL; + +UPDATE plan_configuration_operations SET source = 'MDMS' WHERE source IS NULL; +UPDATE plan_configuration_operations SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; From f3518a40154b50f0cab864cbcd5ef9e590cd7b0e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 9 Oct 2024 17:15:03 +0530 Subject: [PATCH 130/351] HCMPRE-832 code rabbit review comments --- ...150000__plan_configuration_add_source_category_ddl.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql index 20540b91bcb..96e962faf12 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql @@ -1,13 +1,13 @@ ALTER TABLE plan_configuration_assumptions -ADD COLUMN source varchar(64) NOT NULL, -ADD COLUMN category varchar(64) NOT NULL; +ADD COLUMN source varchar(64), +ADD COLUMN category varchar(64); UPDATE plan_configuration_assumptions SET source = 'MDMS' WHERE source IS NULL; UPDATE plan_configuration_assumptions SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; ALTER TABLE plan_configuration_operations -ADD COLUMN source varchar(64) NOT NULL, -ADD COLUMN category varchar(64) NOT NULL; +ADD COLUMN source varchar(64), +ADD COLUMN category varchar(64); UPDATE plan_configuration_operations SET source = 'MDMS' WHERE source IS NULL; UPDATE plan_configuration_operations SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; From a8c48df86b638b8ee725840a3befc58ab9cd3524 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 10 Oct 2024 14:22:46 +0530 Subject: [PATCH 131/351] removed unused urls --- .../main/java/digit/config/Configuration.java | 63 ------------------- .../src/main/resources/application.properties | 37 ----------- 2 files changed, 100 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 02e629b0fce..9f0ff4c23ee 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -22,69 +22,6 @@ public class Configuration { @Value("${census.update.topic}") private String censusUpdateTopic; - // User Config - @Value("${egov.user.host}") - private String userHost; - - @Value("${egov.user.context.path}") - private String userContextPath; - - @Value("${egov.user.create.path}") - private String userCreateEndpoint; - - @Value("${egov.user.search.path}") - private String userSearchEndpoint; - - @Value("${egov.user.update.path}") - private String userUpdateEndpoint; - - - //Idgen Config - @Value("${egov.idgen.host}") - private String idGenHost; - - @Value("${egov.idgen.path}") - private String idGenPath; - - - //Workflow Config - @Value("${egov.workflow.host}") - private String wfHost; - - @Value("${egov.workflow.transition.path}") - private String wfTransitionPath; - - @Value("${egov.workflow.businessservice.search.path}") - private String wfBusinessServiceSearchPath; - - @Value("${egov.workflow.processinstance.search.path}") - private String wfProcessInstanceSearchPath; - - - //MDMS - @Value("${egov.mdms.host}") - private String mdmsHost; - - @Value("${egov.mdms.search.endpoint}") - private String mdmsEndPoint; - - - //HRMS - @Value("${egov.hrms.host}") - private String hrmsHost; - - @Value("${egov.hrms.search.endpoint}") - private String hrmsEndPoint; - - - //URLShortening - @Value("${egov.url.shortner.host}") - private String urlShortnerHost; - - @Value("${egov.url.shortner.endpoint}") - private String urlShortnerEndpoint; - - //SMSNotification @Value("${egov.sms.notification.topic}") private String smsNotificationTopic; diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 295281ac0ea..4ecb5dd80a0 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -48,43 +48,6 @@ census.update.topic=census-update-topic egov.sms.notification.topic=egov.core.notification.sms kafka.topics.receipt.create=dss-collection -#Localization config -egov.localization.host=https://unified-dev.digit.org -egov.localization.workDir.path=/localization/messages/v1 -egov.localization.context.path=/localization/messages/v1 -egov.localization.search.endpoint=/_search -egov.localization.statelevel=true - -#mdms urls -egov.mdms.host=https://unified-dev.digit.org -egov.mdms.search.endpoint=/egov-mdms-service/v1/_search - -#hrms urls -egov.hrms.host=https://unified-dev.digit.org -egov.hrms.search.endpoint=/egov-hrms/employees/_search - -#User config -egov.user.host=https://unified-dev.digit.org -egov.user.context.path=/user/users -egov.user.create.path=/_createnovalidate -egov.user.search.path=/user/_search -egov.user.update.path=/_updatenovalidate - -#Idgen Config -egov.idgen.host=https://unified-dev.digit.org/ -egov.idgen.path=egov-idgen/id/_generate - -#Workflow config -is.workflow.enabled=true -egov.workflow.host=https://unified-dev.digit.org -egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition -egov.workflow.businessservice.search.path=/egov-workflow-v2/egov-wf/businessservice/_search -egov.workflow.processinstance.search.path=/egov-workflow-v2/egov-wf/process/_search - -#url shortner -egov.url.shortner.host=https://unified-dev.digit.org -egov.url.shortner.endpoint=/egov-url-shortening/shortener - #Pagination config census.default.offset=0 census.default.limit=10 From a452d344b6ebd87153b0c4653134c85f30a6627f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 10 Oct 2024 15:12:35 +0530 Subject: [PATCH 132/351] HCMPRE-832 adding contains method for readability --- .../digit/service/validator/PlanConfigurationValidator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 73c4adbc181..f42acae238b 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -223,9 +223,10 @@ public void validateAssumptionUniqueness(PlanConfiguration planConfig) { for (Assumption assumption : planConfig.getAssumptions()) { if (assumption.getActive() != Boolean.FALSE) { - if (!assumptionKeys.add(assumption.getKey())) { + if (assumptionKeys.contains(assumption.getKey())) { throw new CustomException(DUPLICATE_ASSUMPTION_KEY_CODE, DUPLICATE_ASSUMPTION_KEY_MESSAGE + assumption.getKey()); } + assumptionKeys.add(assumption.getKey()); } } } From 6d9b6de6a34b83de9ce576c36bcfe3f3e3c7382c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 10 Oct 2024 15:32:51 +0530 Subject: [PATCH 133/351] resource config consumer topic --- .../census-service/src/main/resources/application.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 4ecb5dd80a0..73a2cc7dc09 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -52,5 +52,5 @@ kafka.topics.receipt.create=dss-collection census.default.offset=0 census.default.limit=10 -#The value of the following field should be changed to service specific name -kafka.topics.consumer=service-consumer-topic \ No newline at end of file +resource.config.consumer.census.create.topic=resource-census-create-topic +resource.config.consumer.census.update.topic=resource-census-update-topic \ No newline at end of file From 0c4da44776024881bff924be48df82e065fec0d0 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 10 Oct 2024 15:45:56 +0530 Subject: [PATCH 134/351] validations --- .../java/digit/config/ServiceConstants.java | 7 +++++ .../service/validator/CensusValidator.java | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 98b0215b881..6b0ea54ce65 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -63,4 +63,11 @@ public class ServiceConstants { public static final String INVALID_CENSUS_CODE = "INVALID_CENSUS"; public static final String INVALID_CENSUS_MESSAGE = "Provided census does not exist"; + + public static final String SEARCH_CRITERIA_EMPTY_CODE = "SEARCH_CRITERIA_EMPTY"; + public static final String SEARCH_CRITERIA_EMPTY_MESSAGE = "Search criteria cannot be empty"; + + public static final String TENANT_ID_EMPTY_CODE = "TENANT_ID_EMPTY"; + public static final String TENANT_ID_EMPTY_MESSAGE = "Tenant Id cannot be empty, TenantId should be present"; + } diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 82fd70198c5..b09728b5348 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -12,6 +12,7 @@ import digit.web.models.boundary.EnrichedBoundary; import digit.web.models.boundary.HierarchyRelation; import digit.web.models.plan.PlanEmployeeAssignmentResponse; +import org.apache.commons.lang3.StringUtils; import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.request.User; import org.egov.tracer.model.CustomException; @@ -130,10 +131,35 @@ private void enrichBoundaryPath(Census census, HierarchyRelation tenantBoundary) census.setBoundaryAncestralPath(Collections.singletonList(boundaryAncestralPath.toString())); } + /** + * Validates the search request for Census. + * + * @param request The search request for Census + */ public void validateSearch(CensusSearchRequest request) { + validateSearchCriteria(request.getCensusSearchCriteria()); + } + /** + * Validates the census search criteria. + * + * @param searchCriteria the search criteria for census search + */ + private void validateSearchCriteria(CensusSearchCriteria searchCriteria) { + if (ObjectUtils.isEmpty(searchCriteria)) { + throw new CustomException(SEARCH_CRITERIA_EMPTY_CODE, SEARCH_CRITERIA_EMPTY_MESSAGE); + } + + if (StringUtils.isEmpty(searchCriteria.getTenantId())) { + throw new CustomException(TENANT_ID_EMPTY_CODE, TENANT_ID_EMPTY_MESSAGE); + } } + /** + * Validates partner assignment and jurisdiction for census update request. + * + * @param request the update request for Census. + */ public void validateUpdate(CensusRequest request) { boolean flag = true; From 3182ca254c69c5484c146eeaa0962c2540446770 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 10 Oct 2024 16:03:59 +0530 Subject: [PATCH 135/351] HCMPRE-832 code review comment --- .../digit/service/validator/PlanConfigurationValidator.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index f42acae238b..e8ab8c8fcbd 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -199,14 +199,12 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - HashSet assumptionSetFromMDMS = new HashSet<>(assumptionListFromMDMS); + Set assumptionSetFromMDMS = new HashSet<>(assumptionListFromMDMS); planConfiguration.getAssumptions().forEach(assumption -> { - if (assumption.getSource() == Source.MDMS) { - if (!assumptionSetFromMDMS.contains(assumption.getKey())) { + if (assumption.getSource() == Source.MDMS && !assumptionSetFromMDMS.contains(assumption.getKey())) { log.error(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey()); throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); } - } }); } } From ccd588813e631fb89c5970f751cf4b90efa04bd4 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 10 Oct 2024 16:08:51 +0530 Subject: [PATCH 136/351] updated StatusEnum --- .../src/main/java/digit/web/models/Census.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 7c118eaae22..7f409efd822 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -89,9 +89,10 @@ public class Census { * The status used in the Census */ public enum StatusEnum { - DRAFT, - GENERATED, - INVALID_DATA + VALIDATED, + APPROVED, + PENDING_FOR_APPROVAL, + PENDING_FOR_VALIDATION } /** From 01023e2edb77d589d6e824ebba969177a9b26a08 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 11 Oct 2024 11:00:40 +0530 Subject: [PATCH 137/351] Status count --- .../digit/repository/CensusRepository.java | 3 + .../repository/impl/CensusRepositoryImpl.java | 21 ++- .../querybuilder/CensusQueryBuilder.java | 18 +- .../service/validator/CensusValidator.java | 2 +- .../src/main/java/digit/util/IdgenUtil.java | 51 ------ .../src/main/java/digit/util/MdmsUtil.java | 81 --------- .../java/digit/util/UrlShortenerUtil.java | 39 ---- .../src/main/java/digit/util/UserUtil.java | 136 -------------- .../main/java/digit/util/WorkflowUtil.java | 172 ------------------ .../main/java/digit/web/models/Census.java | 7 +- .../src/main/resources/application.properties | 4 +- 11 files changed, 43 insertions(+), 491 deletions(-) delete mode 100644 health-services/census-service/src/main/java/digit/util/IdgenUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/MdmsUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/UserUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/WorkflowUtil.java diff --git a/health-services/census-service/src/main/java/digit/repository/CensusRepository.java b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java index 06ef3a8317e..5693f385939 100644 --- a/health-services/census-service/src/main/java/digit/repository/CensusRepository.java +++ b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java @@ -3,6 +3,7 @@ import digit.web.models.*; import java.util.List; +import java.util.Map; public interface CensusRepository { @@ -13,4 +14,6 @@ public interface CensusRepository { public void update(CensusRequest censusRequest); public Integer count(CensusSearchCriteria censusSearchCriteria); + + public Map statusCount(CensusSearchCriteria censusSearchCriteria); } diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 40e663f1220..d89ece1a146 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -8,12 +8,11 @@ import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.stereotype.Repository; -import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; +import java.util.Map; @Slf4j @Repository @@ -57,9 +56,9 @@ public void create(CensusRequest censusRequest) { @Override public List search(CensusSearchCriteria censusSearchCriteria) { List preparedStmtList = new ArrayList<>(); - String searchQuery = queryBuilder.getCensusQuery(censusSearchCriteria, preparedStmtList); + String query = queryBuilder.getCensusQuery(censusSearchCriteria, preparedStmtList); - return jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); + return jdbcTemplate.query(query, rowMapper, preparedStmtList.toArray()); } /** @@ -76,6 +75,20 @@ public Integer count(CensusSearchCriteria censusSearchCriteria) { return jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); } + /** + * Counts the census record based on their current status for the provided search criteria. + * + * @param censusSearchCriteria The search criteria for filtering census records. + * @return The status count of census records for the given search criteria. + */ + @Override + public Map statusCount(CensusSearchCriteria censusSearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getCensusStatusCountQuery(censusSearchCriteria, preparedStmtList); + + return jdbcTemplate.query(query, rowMapper, preparedStmtList.toArray()); + } + /** * Pushes an updated existing census record to persister kafka topic. * diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 64c637426fe..dc198def479 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -49,7 +49,17 @@ public String getCensusQuery(CensusSearchCriteria searchCriteria, List p * @return A SQL query string to get the total count of Census records for a given search criteria. */ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { - return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.TRUE); + return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.TRUE, Boolean.FALSE); + } + + /** + * Constructs the status count query to get the count of census based on their current status for the given search criteria + * @param searchCriteria The criteria used for filtering Census records. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A SQL query string to get the status count of Census records for a given search criteria. + */ + public String getCensusStatusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { + return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); } /** @@ -59,7 +69,7 @@ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList, Boolean isCount) { + private String buildCensusQuery(CensusSearchCriteria criteria, List preparedStmtList, Boolean isCount, Boolean isStatusCount) { StringBuilder builder = new StringBuilder(CENSUS_SEARCH_BASE_QUERY); if (criteria.getId() != null) { @@ -107,6 +117,10 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep return countQuery.toString(); } + if(isStatusCount) { + //TODO + } + return builder.toString(); } diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index b09728b5348..8912b3d70b7 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -100,7 +100,7 @@ public void validateUserInfo(CensusRequest request) { * @param flag Validates only when flag is true */ private void validatePartnerForCensus(RequestInfo requestInfo, Census census, boolean flag) { - if (flag) { + if (!flag) { User userInfo = requestInfo.getUserInfo(); List jurisdiction = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(requestInfo, userInfo.getUuid(), census.getSource(), census.getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); diff --git a/health-services/census-service/src/main/java/digit/util/IdgenUtil.java b/health-services/census-service/src/main/java/digit/util/IdgenUtil.java deleted file mode 100644 index 650af00bde8..00000000000 --- a/health-services/census-service/src/main/java/digit/util/IdgenUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.repository.ServiceRequestRepository; -import digit.config.Configuration; -import org.egov.common.contract.idgen.IdGenerationRequest; -import org.egov.common.contract.idgen.IdGenerationResponse; -import org.egov.common.contract.idgen.IdRequest; -import org.egov.common.contract.idgen.IdResponse; -import org.egov.common.contract.request.RequestInfo; -import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import static digit.config.ServiceConstants.*; - -@Component -public class IdgenUtil { - - @Autowired - private ObjectMapper mapper; - - @Autowired - private ServiceRequestRepository restRepo; - - @Autowired - private Configuration configs; - - public List getIdList(RequestInfo requestInfo, String tenantId, String idName, String idformat, Integer count) { - List reqList = new ArrayList<>(); - for (int i = 0; i < count; i++) { - reqList.add(IdRequest.builder().idName(idName).format(idformat).tenantId(tenantId).build()); - } - - IdGenerationRequest request = IdGenerationRequest.builder().idRequests(reqList).requestInfo(requestInfo).build(); - StringBuilder uri = new StringBuilder(configs.getIdGenHost()).append(configs.getIdGenPath()); - IdGenerationResponse response = mapper.convertValue(restRepo.fetchResult(uri, request), IdGenerationResponse.class); - - List idResponses = response.getIdResponses(); - - if (CollectionUtils.isEmpty(idResponses)) - throw new CustomException(IDGEN_ERROR, NO_IDS_FOUND_ERROR); - - return idResponses.stream().map(IdResponse::getId).collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/MdmsUtil.java b/health-services/census-service/src/main/java/digit/util/MdmsUtil.java deleted file mode 100644 index 5db8d2c4f1d..00000000000 --- a/health-services/census-service/src/main/java/digit/util/MdmsUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.config.Configuration; -import lombok.extern.slf4j.Slf4j; -import net.minidev.json.JSONArray; -import org.egov.common.contract.request.RequestInfo; -import org.egov.mdms.model.*; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static digit.config.ServiceConstants.*; - -@Slf4j -@Component -public class MdmsUtil { - - @Autowired - private RestTemplate restTemplate; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private Configuration configs; - - - - - public Map> fetchMdmsData(RequestInfo requestInfo, String tenantId, String moduleName, - List masterNameList) { - StringBuilder uri = new StringBuilder(); - uri.append(configs.getMdmsHost()).append(configs.getMdmsEndPoint()); - MdmsCriteriaReq mdmsCriteriaReq = getMdmsRequest(requestInfo, tenantId, moduleName, masterNameList); - Object response = new HashMap<>(); - Integer rate = 0; - MdmsResponse mdmsResponse = new MdmsResponse(); - try { - response = restTemplate.postForObject(uri.toString(), mdmsCriteriaReq, Map.class); - mdmsResponse = mapper.convertValue(response, MdmsResponse.class); - }catch(Exception e) { - log.error(ERROR_WHILE_FETCHING_FROM_MDMS,e); - } - - return mdmsResponse.getMdmsRes(); - //log.info(ulbToCategoryListMap.toString()); - } - - private MdmsCriteriaReq getMdmsRequest(RequestInfo requestInfo, String tenantId, - String moduleName, List masterNameList) { - List masterDetailList = new ArrayList<>(); - for(String masterName: masterNameList) { - MasterDetail masterDetail = new MasterDetail(); - masterDetail.setName(masterName); - masterDetailList.add(masterDetail); - } - - ModuleDetail moduleDetail = new ModuleDetail(); - moduleDetail.setMasterDetails(masterDetailList); - moduleDetail.setModuleName(moduleName); - List moduleDetailList = new ArrayList<>(); - moduleDetailList.add(moduleDetail); - - MdmsCriteria mdmsCriteria = new MdmsCriteria(); - mdmsCriteria.setTenantId(tenantId.split("\\.")[0]); - mdmsCriteria.setModuleDetails(moduleDetailList); - - MdmsCriteriaReq mdmsCriteriaReq = new MdmsCriteriaReq(); - mdmsCriteriaReq.setMdmsCriteria(mdmsCriteria); - mdmsCriteriaReq.setRequestInfo(requestInfo); - - return mdmsCriteriaReq; - } -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java b/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java deleted file mode 100644 index efb4d3d3fa3..00000000000 --- a/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java +++ /dev/null @@ -1,39 +0,0 @@ -package digit.util; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; -import java.util.HashMap; -import digit.config.Configuration; -import static digit.config.ServiceConstants.*; - -@Slf4j -@Component -public class UrlShortenerUtil { - - @Autowired - private RestTemplate restTemplate; - - @Autowired - private Configuration configs; - - - public String getShortenedUrl(String url){ - - HashMap body = new HashMap<>(); - body.put(URL,url); - StringBuilder builder = new StringBuilder(configs.getUrlShortnerHost()); - builder.append(configs.getUrlShortnerEndpoint()); - String res = restTemplate.postForObject(builder.toString(), body, String.class); - - if(StringUtils.isEmpty(res)){ - log.error(URL_SHORTENING_ERROR_CODE, URL_SHORTENING_ERROR_MESSAGE + url); ; - return url; - } - else return res; - } - - -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/UserUtil.java b/health-services/census-service/src/main/java/digit/util/UserUtil.java deleted file mode 100644 index 09b8adca5c1..00000000000 --- a/health-services/census-service/src/main/java/digit/util/UserUtil.java +++ /dev/null @@ -1,136 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.config.Configuration; -import static digit.config.ServiceConstants.*; -import org.egov.common.contract.request.Role; -import org.egov.common.contract.request.User; -import org.egov.common.contract.user.UserDetailResponse; -import org.egov.common.contract.user.enums.UserType; -import digit.repository.ServiceRequestRepository; -import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.*; - -@Component -public class UserUtil { - - @Autowired - private ObjectMapper mapper; - - @Autowired - private ServiceRequestRepository serviceRequestRepository; - - @Autowired - private Configuration configs; - - - @Autowired - public UserUtil(ObjectMapper mapper, ServiceRequestRepository serviceRequestRepository) { - this.mapper = mapper; - this.serviceRequestRepository = serviceRequestRepository; - } - - /** - * Returns UserDetailResponse by calling user service with given uri and object - * @param userRequest Request object for user service - * @param uri The address of the endpoint - * @return Response from user service as parsed as userDetailResponse - */ - - public UserDetailResponse userCall(Object userRequest, StringBuilder uri) { - String dobFormat = null; - if(uri.toString().contains(configs.getUserSearchEndpoint()) || uri.toString().contains(configs.getUserUpdateEndpoint())) - dobFormat=DOB_FORMAT_Y_M_D; - else if(uri.toString().contains(configs.getUserCreateEndpoint())) - dobFormat = DOB_FORMAT_D_M_Y; - try{ - LinkedHashMap responseMap = (LinkedHashMap)serviceRequestRepository.fetchResult(uri, userRequest); - parseResponse(responseMap,dobFormat); - UserDetailResponse userDetailResponse = mapper.convertValue(responseMap,UserDetailResponse.class); - return userDetailResponse; - } - catch(IllegalArgumentException e) - { - throw new CustomException(ILLEGAL_ARGUMENT_EXCEPTION_CODE,OBJECTMAPPER_UNABLE_TO_CONVERT); - } - } - - - /** - * Parses date formats to long for all users in responseMap - * @param responseMap LinkedHashMap got from user api response - */ - - public void parseResponse(LinkedHashMap responseMap, String dobFormat){ - List users = (List)responseMap.get(USER); - String format1 = DOB_FORMAT_D_M_Y_H_M_S; - if(users!=null){ - users.forEach( map -> { - map.put(CREATED_DATE,dateTolong((String)map.get(CREATED_DATE),format1)); - if((String)map.get(LAST_MODIFIED_DATE)!=null) - map.put(LAST_MODIFIED_DATE,dateTolong((String)map.get(LAST_MODIFIED_DATE),format1)); - if((String)map.get(DOB)!=null) - map.put(DOB,dateTolong((String)map.get(DOB),dobFormat)); - if((String)map.get(PWD_EXPIRY_DATE)!=null) - map.put(PWD_EXPIRY_DATE,dateTolong((String)map.get(PWD_EXPIRY_DATE),format1)); - } - ); - } - } - - /** - * Converts date to long - * @param date date to be parsed - * @param format Format of the date - * @return Long value of date - */ - private Long dateTolong(String date,String format){ - SimpleDateFormat f = new SimpleDateFormat(format); - Date d = null; - try { - d = f.parse(date); - } catch (ParseException e) { - throw new CustomException(INVALID_DATE_FORMAT_CODE,INVALID_DATE_FORMAT_MESSAGE); - } - return d.getTime(); - } - - /** - * enriches the userInfo with statelevel tenantId and other fields - * The function creates user with username as mobile number. - * @param mobileNumber - * @param tenantId - * @param userInfo - */ - public void addUserDefaultFields(String mobileNumber,String tenantId, User userInfo, UserType userType){ - Role role = getCitizenRole(tenantId); - userInfo.setRoles((List) Collections.singleton(role)); - userInfo.setType(String.valueOf(userType)); -// userInfo.setUsername(mobileNumber); - userInfo.setTenantId(getStateLevelTenant(tenantId)); -// userInfo.setActive(true); - } - - /** - * Returns role object for citizen - * @param tenantId - * @return - */ - private Role getCitizenRole(String tenantId){ - Role role = Role.builder().build(); - role.setCode(CITIZEN_UPPER); - role.setName(CITIZEN_LOWER); - role.setTenantId(getStateLevelTenant(tenantId)); - return role; - } - - public String getStateLevelTenant(String tenantId){ - return tenantId.split("\\.")[0]; - } - -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java b/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java deleted file mode 100644 index 6cea1a4a6a0..00000000000 --- a/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java +++ /dev/null @@ -1,172 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.config.Configuration; -import static digit.config.ServiceConstants.*; -import org.egov.common.contract.request.RequestInfo; -import org.egov.common.contract.request.User; -import org.egov.common.contract.workflow.*; -import org.egov.common.contract.models.*; -import digit.repository.ServiceRequestRepository; -import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class WorkflowUtil { - - @Autowired - private ServiceRequestRepository repository; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private Configuration configs; - - - - /** - * Searches the BussinessService corresponding to the businessServiceCode - * Returns applicable BussinessService for the given parameters - * @param requestInfo - * @param tenantId - * @param businessServiceCode - * @return - */ - public BusinessService getBusinessService(RequestInfo requestInfo, String tenantId, String businessServiceCode) { - - StringBuilder url = getSearchURLWithParams(tenantId, businessServiceCode); - RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); - Object result = repository.fetchResult(url, requestInfoWrapper); - BusinessServiceResponse response = null; - try { - response = mapper.convertValue(result, BusinessServiceResponse.class); - } catch (IllegalArgumentException e) { - throw new CustomException(PARSING_ERROR_CODE, FAILED_TO_PARSE_BUSINESS_SERVICE_SEARCH); - } - - if (CollectionUtils.isEmpty(response.getBusinessServices())) - throw new CustomException(BUSINESS_SERVICE_NOT_FOUND, THE_BUSINESS_SERVICE + businessServiceCode + NOT_FOUND); - - return response.getBusinessServices().get(0); - } - - /** - * Calls the workflow service with the given action and updates the status - * Returns the updated status of the application - * @param requestInfo - * @param tenantId - * @param businessId - * @param businessServiceCode - * @param workflow - * @param wfModuleName - * @return - */ - public String updateWorkflowStatus(RequestInfo requestInfo, String tenantId, - String businessId, String businessServiceCode, Workflow workflow, String wfModuleName) { - ProcessInstance processInstance = getProcessInstanceForWorkflow(requestInfo, tenantId, businessId, - businessServiceCode, workflow, wfModuleName); - ProcessInstanceRequest workflowRequest = new ProcessInstanceRequest(requestInfo, Collections.singletonList(processInstance)); - State state = callWorkFlow(workflowRequest); - - return state.getApplicationStatus(); - } - - /** - * Creates url for search based on given tenantId and businessServices - * @param tenantId - * @param businessService - * @return - */ - private StringBuilder getSearchURLWithParams(String tenantId, String businessService) { - StringBuilder url = new StringBuilder(configs.getWfHost()); - url.append(configs.getWfBusinessServiceSearchPath()); - url.append(TENANTID); - url.append(tenantId); - url.append(BUSINESS_SERVICES); - url.append(businessService); - return url; - } - - /** - * Enriches ProcessInstance Object for Workflow - * @param requestInfo - * @param tenantId - * @param businessId - * @param businessServiceCode - * @param workflow - * @param wfModuleName - * @return - */ - private ProcessInstance getProcessInstanceForWorkflow(RequestInfo requestInfo, String tenantId, - String businessId, String businessServiceCode, Workflow workflow, String wfModuleName) { - - ProcessInstance processInstance = new ProcessInstance(); - processInstance.setBusinessId(businessId); - processInstance.setAction(workflow.getAction()); - processInstance.setModuleName(wfModuleName); - processInstance.setTenantId(tenantId); - processInstance.setBusinessService(getBusinessService(requestInfo, tenantId, businessServiceCode).getBusinessService()); - processInstance.setComment(workflow.getComments()); - - if(!CollectionUtils.isEmpty(workflow.getAssignes())) { - List users = new ArrayList<>(); - - workflow.getAssignes().forEach(uuid -> { - User user = new User(); - user.setUuid(uuid); - users.add(user); - }); - - processInstance.setAssignes(users); - } - - return processInstance; - } - - /** - * Gets the workflow corresponding to the processInstance - * @param processInstances - * @return - */ - public Map getWorkflow(List processInstances) { - - Map businessIdToWorkflow = new HashMap<>(); - - processInstances.forEach(processInstance -> { - List userIds = null; - - if(!CollectionUtils.isEmpty(processInstance.getAssignes())){ - userIds = processInstance.getAssignes().stream().map(User::getUuid).collect(Collectors.toList()); - } - - Workflow workflow = Workflow.builder() - .action(processInstance.getAction()) - .assignes(userIds) - .comments(processInstance.getComment()) - .build(); - - businessIdToWorkflow.put(processInstance.getBusinessId(), workflow); - }); - - return businessIdToWorkflow; - } - - /** - * Method to take the ProcessInstanceRequest as parameter and set resultant status - * @param workflowReq - * @return - */ - private State callWorkFlow(ProcessInstanceRequest workflowReq) { - ProcessInstanceResponse response = null; - StringBuilder url = new StringBuilder(configs.getWfHost().concat(configs.getWfTransitionPath())); - Object optional = repository.fetchResult(url, workflowReq); - response = mapper.convertValue(optional, ProcessInstanceResponse.class); - return response.getProcessInstances().get(0).getState(); - } -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 7c118eaae22..7f409efd822 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -89,9 +89,10 @@ public class Census { * The status used in the Census */ public enum StatusEnum { - DRAFT, - GENERATED, - INVALID_DATA + VALIDATED, + APPROVED, + PENDING_FOR_APPROVAL, + PENDING_FOR_VALIDATION } /** diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 9ba70a6d054..f047efd2d21 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -60,8 +60,8 @@ egov.plan.employee.assignment.search.endpoint=/plan-service/employee/_search census.default.offset=0 census.default.limit=10 -#The value of the following field should be changed to service specific name -kafka.topics.consumer=service-consumer-topic +resource.config.consumer.census.create.topic=resource-census-create-topic +resource.config.consumer.census.update.topic=resource-census-update-topic #Roles for census allowed.census.roles={'POPULATION_DATA_APPROVER','ROOT_POPULATION_DATA_APPROVER'} \ No newline at end of file From fb35208042a98b0c62fa0f7d7aa761698a7a87a2 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 11 Oct 2024 13:06:48 +0530 Subject: [PATCH 138/351] HCMPRE-832 changes for only validating active assumptions from mdms on update --- .../digit/service/validator/PlanConfigurationValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index e8ab8c8fcbd..1cec3168cdf 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -201,7 +201,7 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O Set assumptionSetFromMDMS = new HashSet<>(assumptionListFromMDMS); planConfiguration.getAssumptions().forEach(assumption -> { - if (assumption.getSource() == Source.MDMS && !assumptionSetFromMDMS.contains(assumption.getKey())) { + if (assumption.getActive() && assumption.getSource() == Source.MDMS && !assumptionSetFromMDMS.contains(assumption.getKey())) { log.error(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey()); throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); } From 2ea2decc0073c11aaa83c926c93d5a0c281cfdb0 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 11 Oct 2024 13:11:56 +0530 Subject: [PATCH 139/351] HCMPRE-832 enhancing exception message --- .../src/main/java/digit/config/ServiceConstants.java | 2 +- .../digit/service/validator/PlanConfigurationValidator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 0f0396c42b0..0f6f825b5aa 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -32,7 +32,7 @@ public class ServiceConstants { public static final String FILESTORE_ID_INVALID_MESSAGE = " Resource mapping does not have a Valid File Store Id "; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE = "ASSUMPTION_KEY_NOT_FOUND_IN_MDMS"; - public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS "; + public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS - "; public static final String DUPLICATE_ASSUMPTION_KEY_CODE = "DUPLICATE_ASSUMPTION_KEY"; public static final String DUPLICATE_ASSUMPTION_KEY_MESSAGE = "Duplicate Assumption key found : "; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 1cec3168cdf..a67fc0c4b1b 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -203,7 +203,7 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O planConfiguration.getAssumptions().forEach(assumption -> { if (assumption.getActive() && assumption.getSource() == Source.MDMS && !assumptionSetFromMDMS.contains(assumption.getKey())) { log.error(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey()); - throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); + throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey() + " at JSONPath: " + jsonPathForAssumption); } }); } From 625379ca4c2c81a07852767fa5561f6fae9ee398 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 11 Oct 2024 17:12:41 +0530 Subject: [PATCH 140/351] HCMPRE-710: backupdate timeframe --- .../querybuilder/CensusQueryBuilder.java | 10 ++++ .../repository/rowmapper/CensusRowMapper.java | 2 +- .../java/digit/service/CensusService.java | 7 ++- .../service/enrichment/CensusEnrichment.java | 6 ++- .../enrichment/CensusTimeframeEnrichment.java | 47 +++++++++++++++++++ .../web/models/CensusSearchCriteria.java | 3 ++ 6 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/service/enrichment/CensusTimeframeEnrichment.java diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index ee57eeb4723..f3081154013 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -99,6 +99,16 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep preparedStmtList.add(criteria.getAssignee()); } + if (criteria.getEffectiveTo() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + if (criteria.getEffectiveTo() == 0) { + builder.append(" cen.effective_to IS NULL "); + } else { + builder.append(" cen.effective_to = ?"); + preparedStmtList.add(criteria.getEffectiveTo()); + } + } + if (!CollectionUtils.isEmpty(criteria.getAreaCodes())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.boundary_code IN ( ").append(queryUtil.createQuery(criteria.getAreaCodes().size())).append(" )"); diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 7b4db395480..393a04c6684 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -52,7 +52,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setTenantId(rs.getString("census_tenant_id")); censusEntry.setHierarchyType(rs.getString("census_hierarchy_type")); censusEntry.setBoundaryCode(rs.getString("census_boundary_code")); - censusEntry.setType(Census.TypeEnum.fromValue(rs.getString("census_type").toUpperCase())); + censusEntry.setType(Census.TypeEnum.fromValue(rs.getString("census_type"))); censusEntry.setTotalPopulation(rs.getLong("census_total_population")); censusEntry.setEffectiveFrom(rs.getLong("census_effective_from")); censusEntry.setEffectiveTo(rs.getLong("census_effective_to")); diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index 88ec9c6da63..d7f5583713d 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -2,6 +2,7 @@ import digit.repository.CensusRepository; import digit.service.enrichment.CensusEnrichment; +import digit.service.enrichment.CensusTimeframeEnrichment; import digit.service.validator.CensusValidator; import digit.util.ResponseInfoFactory; import digit.web.models.CensusRequest; @@ -22,11 +23,14 @@ public class CensusService { private CensusEnrichment enrichment; - public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository repository, CensusValidator validator, CensusEnrichment enrichment) { + private CensusTimeframeEnrichment timeframeEnrichment; + + public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository repository, CensusValidator validator, CensusEnrichment enrichment, CensusTimeframeEnrichment timeframeEnrichment) { this.responseInfoFactory = responseInfoFactory; this.repository = repository; this.validator = validator; this.enrichment = enrichment; + this.timeframeEnrichment = timeframeEnrichment; } /** @@ -38,6 +42,7 @@ public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository r public CensusResponse create(CensusRequest request) { validator.validateCreate(request); // Validate census create request enrichment.enrichCreate(request); // Enrich census create request + timeframeEnrichment.enrichPreviousTimeframe(request); // Enrich timeframe for previous census repository.create(request); // Delegate creation request to repository return CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index b0c4d7915ac..f83dd45e5ee 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -18,7 +18,7 @@ public CensusEnrichment() { /** * Enriches the CensusRequest for creating a new census record. * Enriches the given census record with generated IDs for Census and PopulationByDemographics. - * Validates user information and enriches audit details for create operation. + * Validates user information, enriches audit details and effectiveFrom for create operation. * * @param request The CensusRequest to be enriched. * @throws CustomException if user information is missing in the request. @@ -32,7 +32,11 @@ public void enrichCreate(CensusRequest request) { // Generate id for PopulationByDemographics census.getPopulationByDemographics().forEach(populationByDemographics -> UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id")); + // Set audit details for census record census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); + + // Enrich effectiveFrom for the census record + census.setEffectiveFrom(census.getAuditDetails().getCreatedTime()); } /** diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusTimeframeEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusTimeframeEnrichment.java new file mode 100644 index 00000000000..fdd131957df --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusTimeframeEnrichment.java @@ -0,0 +1,47 @@ +package digit.service.enrichment; + +import digit.repository.CensusRepository; +import digit.web.models.Census; +import digit.web.models.CensusRequest; +import digit.web.models.CensusSearchCriteria; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; + +@Component +public class CensusTimeframeEnrichment { + + private CensusRepository repository; + + public CensusTimeframeEnrichment(CensusRepository repository) { + this.repository = repository; + } + + /** + * Enriches the effectiveTo of previous census records for the same boundary. + * + * @param request The census request. + */ + public void enrichPreviousTimeframe(CensusRequest request) { + Census census = request.getCensus(); + List censusList = repository.search(CensusSearchCriteria.builder().tenantId(census.getTenantId()).areaCodes(Collections.singletonList(census.getBoundaryCode())).effectiveTo(0L).build()); + + if (!CollectionUtils.isEmpty(censusList)) { + censusList.forEach(censusData -> { + censusData.setEffectiveTo(census.getAuditDetails().getCreatedTime()); + updatePreviousCensus(CensusRequest.builder().requestInfo(request.getRequestInfo()).census(censusData).build()); + }); + } + } + + /** + * Updates the timeframe of the previous census records. + * + * @param request the census to be updated. + */ + private void updatePreviousCensus(CensusRequest request) { + repository.update(request); + } +} diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index f8fef679fe0..5736b5f553b 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -42,6 +42,9 @@ public class CensusSearchCriteria { @JsonProperty("jurisdiction") private List jurisdiction = null; + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { this.areaCodes = new ArrayList<>(); From f07da555e12432807ce92623e2aad9cf74faeb08 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 11 Oct 2024 17:13:55 +0530 Subject: [PATCH 141/351] rowmapper --- .../main/java/digit/repository/rowmapper/CensusRowMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 7b4db395480..393a04c6684 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -52,7 +52,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setTenantId(rs.getString("census_tenant_id")); censusEntry.setHierarchyType(rs.getString("census_hierarchy_type")); censusEntry.setBoundaryCode(rs.getString("census_boundary_code")); - censusEntry.setType(Census.TypeEnum.fromValue(rs.getString("census_type").toUpperCase())); + censusEntry.setType(Census.TypeEnum.fromValue(rs.getString("census_type"))); censusEntry.setTotalPopulation(rs.getLong("census_total_population")); censusEntry.setEffectiveFrom(rs.getLong("census_effective_from")); censusEntry.setEffectiveTo(rs.getLong("census_effective_to")); From b41914d475c1bc5620d784c709063e5db6116bd6 Mon Sep 17 00:00:00 2001 From: Taniya-eGov Date: Fri, 11 Oct 2024 20:33:56 +0530 Subject: [PATCH 142/351] [HCMPRE-841] - Provided validation for duplicate service boundaries --- .../digit/service/validator/PlanFacilityValidator.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index cdaa3a58a23..ed2af1fdbc3 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -140,6 +140,14 @@ private void validateResidingBoundaries(Set boundaryCodes, PlanFacility * @param planFacility */ private void validateServiceBoundaries(Set boundaryCodes, PlanFacility planFacility) { + List serviceBoundaries = planFacility.getServiceBoundaries(); + + // Check for duplicate service boundaries + Set uniqueBoundaries = new HashSet<>(serviceBoundaries); + if (uniqueBoundaries.size() != serviceBoundaries.size()) { + throw new CustomException(INVALID_SERVICE_BOUNDARY_CODE, "Duplicate service boundaries are not allowed"); + } + planFacility.getServiceBoundaries().forEach(serviceBoundary -> { if (!boundaryCodes.contains(serviceBoundary)) { throw new CustomException(INVALID_SERVICE_BOUNDARY_CODE, INVALID_SERVICE_BOUNDARY_MESSAGE); From 3b3f2b81b865d8a4502a68760bb3485ff0c847fc Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 14 Oct 2024 10:56:22 +0530 Subject: [PATCH 143/351] employee assignment existence validation --- .../java/digit/config/ServiceConstants.java | 3 +++ .../PlanEmployeeAssignmentValidator.java | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 0f0396c42b0..f0b2364ff97 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -94,6 +94,9 @@ public class ServiceConstants { public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE = "INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID"; public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE = "Plan employee assignment id provided is invalid"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_MESSAGE = "Plan employee assignment for the provided details already exists"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE = "Plan employee assignment id cannot be empty"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 4d592075040..0c71535a261 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -64,6 +64,9 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); + // Validate if a same assignment already exists + validateEmployeeAssignmentExistence(request); + // Validate if plan config id exists validatePlanConfigId(planConfigurations); @@ -81,6 +84,26 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { } + /** + * Validates if the plan employee assignment for the provided details already exists + * @param request the employee assignment create request + */ + private void validateEmployeeAssignmentExistence(PlanEmployeeAssignmentRequest request) { + PlanEmployeeAssignment employeeAssignment = request.getPlanEmployeeAssignment(); + + List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(employeeAssignment.getTenantId()) + .planConfigurationId(employeeAssignment.getPlanConfigurationId()) + .employeeId(employeeAssignment.getEmployeeId()) + .role(employeeAssignment.getRole()) + .jurisdiction(employeeAssignment.getJurisdiction()) + .build()); + + if (!CollectionUtils.isEmpty(planEmployeeAssignments)) { + throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_MESSAGE); + } + } + /** * Validates that employee with National role is assigned to the highest root jurisdiction only against MDMS * From 8bec49d8012f520f1b9e39fac59bf32c7b75339f Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 14 Oct 2024 10:56:43 +0530 Subject: [PATCH 144/351] employee assignment existence validation --- .../digit/service/validator/PlanEmployeeAssignmentValidator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 0c71535a261..ad3db1c5b03 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -86,6 +86,7 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { /** * Validates if the plan employee assignment for the provided details already exists + * * @param request the employee assignment create request */ private void validateEmployeeAssignmentExistence(PlanEmployeeAssignmentRequest request) { From a5f70df6e369cfaaf4bb847aad59899c320332aa Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 14 Oct 2024 11:29:56 +0530 Subject: [PATCH 145/351] employee assignment existence validation --- .../digit/service/validator/PlanEmployeeAssignmentValidator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index ad3db1c5b03..0de60e64dd3 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -97,7 +97,6 @@ private void validateEmployeeAssignmentExistence(PlanEmployeeAssignmentRequest r .planConfigurationId(employeeAssignment.getPlanConfigurationId()) .employeeId(employeeAssignment.getEmployeeId()) .role(employeeAssignment.getRole()) - .jurisdiction(employeeAssignment.getJurisdiction()) .build()); if (!CollectionUtils.isEmpty(planEmployeeAssignments)) { From e5b75d4b416b193d34d727147539e787bd9597cc Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 14 Oct 2024 12:08:02 +0530 Subject: [PATCH 146/351] employee assignment existence validation --- .../src/main/java/digit/config/ServiceConstants.java | 4 ++-- .../service/validator/PlanEmployeeAssignmentValidator.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 838df706d4e..8017724da5b 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -94,8 +94,8 @@ public class ServiceConstants { public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE = "INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID"; public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE = "Plan employee assignment id provided is invalid"; - public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST"; - public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_MESSAGE = "Plan employee assignment for the provided details already exists"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_MESSAGE = "Plan employee assignment for the provided details already exists"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE = "Plan employee assignment id cannot be empty"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 0de60e64dd3..7e0814b82e6 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -92,15 +92,15 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { private void validateEmployeeAssignmentExistence(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment employeeAssignment = request.getPlanEmployeeAssignment(); - List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + List planEmployeeSearchResponse = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() .tenantId(employeeAssignment.getTenantId()) .planConfigurationId(employeeAssignment.getPlanConfigurationId()) .employeeId(employeeAssignment.getEmployeeId()) .role(employeeAssignment.getRole()) .build()); - if (!CollectionUtils.isEmpty(planEmployeeAssignments)) { - throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXIST_MESSAGE); + if (!CollectionUtils.isEmpty(planEmployeeSearchResponse)) { + throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_MESSAGE); } } From b884f512190595ca8ebd75eded348360e7772490 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 14 Oct 2024 12:11:04 +0530 Subject: [PATCH 147/351] renamed variable --- .../service/validator/PlanEmployeeAssignmentValidator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 7e0814b82e6..8e9a25f1df9 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -92,14 +92,14 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { private void validateEmployeeAssignmentExistence(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment employeeAssignment = request.getPlanEmployeeAssignment(); - List planEmployeeSearchResponse = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + List planEmployeeAssignmentsFromSearch = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() .tenantId(employeeAssignment.getTenantId()) .planConfigurationId(employeeAssignment.getPlanConfigurationId()) .employeeId(employeeAssignment.getEmployeeId()) .role(employeeAssignment.getRole()) .build()); - if (!CollectionUtils.isEmpty(planEmployeeSearchResponse)) { + if (!CollectionUtils.isEmpty(planEmployeeAssignmentsFromSearch)) { throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_MESSAGE); } } From e7560e43c9e4ef1674375c4cf26079f6bc53dd34 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 14 Oct 2024 15:02:23 +0530 Subject: [PATCH 148/351] validating employee against user service --- .../main/java/digit/config/Configuration.java | 7 ++ .../java/digit/config/ServiceConstants.java | 2 + .../PlanEmployeeAssignmentValidator.java | 85 +++++++++---------- .../src/main/java/digit/util/UserUtil.java | 78 +++++++++++++++++ .../src/main/resources/application.properties | 4 + 5 files changed, 131 insertions(+), 45 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/util/UserUtil.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 9f364a2c716..b716965d840 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -45,6 +45,13 @@ public class Configuration { @Value("${egov.project.factory.search.endpoint}") private String projectFactorySearchEndPoint; + //User Service + @Value("${egov.user.service.host}") + private String userServiceHost; + + @Value("${egov.user.search.endpoint}") + private String userSearchEndPoint; + //Persister Topic @Value("${plan.configuration.create.topic}") private String planConfigCreateTopic; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 8017724da5b..c543f446d20 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -12,6 +12,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; + public static final String ERROR_WHILE_FETCHING_FROM_USER_SERVICE = "Exception occurred while fetching user details from user service: "; + public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from project factory: "; public static final String ERROR_WHILE_FETCHING_DATA_FROM_HRMS = "Exception occurred while fetching employee from hrms: "; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 8e9a25f1df9..2e3b37f96cc 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -3,18 +3,15 @@ import com.jayway.jsonpath.JsonPath; import digit.config.Configuration; import digit.repository.PlanEmployeeAssignmentRepository; -import digit.util.CampaignUtil; -import digit.util.CommonUtil; -import digit.util.HrmsUtil; -import digit.util.MdmsUtil; +import digit.util.*; import digit.web.models.*; -import digit.web.models.hrms.EmployeeResponse; import digit.web.models.projectFactory.Boundary; import digit.web.models.projectFactory.CampaignDetail; import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.egov.common.contract.request.Role; +import org.egov.common.contract.user.UserDetailResponse; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -33,7 +30,7 @@ public class PlanEmployeeAssignmentValidator { private MdmsUtil mdmsUtil; - private HrmsUtil hrmsUtil; + private UserUtil userUtil; private CommonUtil commonUtil; @@ -43,10 +40,10 @@ public class PlanEmployeeAssignmentValidator { private Configuration config; - public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, HrmsUtil hrmsUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeAssignmentRepository repository, Configuration config) { + public PlanEmployeeAssignmentValidator(MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, UserUtil userUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeAssignmentRepository repository, Configuration config) { this.centralInstanceUtil = centralInstanceUtil; this.mdmsUtil = mdmsUtil; - this.hrmsUtil = hrmsUtil; + this.userUtil = userUtil; this.commonUtil = commonUtil; this.campaignUtil = campaignUtil; this.repository = repository; @@ -62,7 +59,7 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); - EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); + UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); // Validate if a same assignment already exists validateEmployeeAssignmentExistence(request); @@ -70,11 +67,11 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { // Validate if plan config id exists validatePlanConfigId(planConfigurations); - // Validate if employee exists against HRMS - validateEmployeeAgainstHRMS(employeeResponse); + // Validate if employee exists against User Service + validateEmployeeAgainstUserService(userDetailResponse); - // Validate role of employee against HRMS - validateRoleAgainstHRMS(planEmployeeAssignment, employeeResponse); + // Validate role of employee against User Service + validateRoleAgainstUserService(planEmployeeAssignment, userDetailResponse); // Validate if role of employee is a conflicting role validateRoleConflict(planEmployeeAssignment); @@ -84,6 +81,33 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { } + /** + * This method validates the provided roles of the employee against User Service + * + * @param planEmployeeAssignment The plan employee assignment provided in request + * @param userDetailResponse The user detail response from user service for the provided employeeId + */ + private void validateRoleAgainstUserService(PlanEmployeeAssignment planEmployeeAssignment, UserDetailResponse userDetailResponse) { + Set userRolesFromUserService = userDetailResponse.getUser().get(0).getRoles().stream() + .map(Role::getCode) + .collect(Collectors.toSet()); + + if (!userRolesFromUserService.contains(planEmployeeAssignment.getRole())) { + throw new CustomException(INVALID_EMPLOYEE_ROLE_CODE, INVALID_EMPLOYEE_ROLE_MESSAGE); + } + } + + /** + * This method validates if the employee provided in plan employee assignment request exist in User Service + * + * @param userDetailResponse The user detail response from User Service for provided employeeId + */ + private void validateEmployeeAgainstUserService(UserDetailResponse userDetailResponse) { + if (CollectionUtils.isEmpty(userDetailResponse.getUser())) { + throw new CustomException(INVALID_EMPLOYEE_ID_CODE, INVALID_EMPLOYEE_ID_MESSAGE); + } + } + /** * Validates if the plan employee assignment for the provided details already exists * @@ -172,23 +196,6 @@ private void validateRoleConflict(PlanEmployeeAssignment planEmployeeAssignment) } } - /** - * This method validates the provided roles of the employee against HRMS - * - * @param planEmployeeAssignment The plan employee assignment provided in request - * @param employeeResponse The employee response from HRMS for the provided employeeId - */ - private void validateRoleAgainstHRMS(PlanEmployeeAssignment planEmployeeAssignment, EmployeeResponse employeeResponse) { - Set rolesFromHRMS = employeeResponse.getEmployees().get(0).getUser().getRoles().stream() - .map(Role::getCode) - .collect(Collectors.toSet()); - - if (!rolesFromHRMS.contains(planEmployeeAssignment.getRole())) { - throw new CustomException(INVALID_EMPLOYEE_ROLE_CODE, INVALID_EMPLOYEE_ROLE_MESSAGE); - } - } - - /** * This method validates campaign id and employee's jurisdiction against project factory * If the employee has a national role, it validates that the employee has the highest root jurisdiction only @@ -245,18 +252,6 @@ private void validateCampaignId(CampaignResponse campaignResponse) { } } - /** - * This method validates if the employee provided in plan employee assignment request exist in HRMS - * - * @param employeeResponse The employee response from HRMS for provided employeeId - */ - private void validateEmployeeAgainstHRMS(EmployeeResponse employeeResponse) { - if (CollectionUtils.isEmpty(employeeResponse.getEmployees())) { - throw new CustomException(INVALID_EMPLOYEE_ID_CODE, INVALID_EMPLOYEE_ID_MESSAGE); - } - } - - /** * This method validates if the plan configuration id provided in the request exists * @@ -297,7 +292,7 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); - EmployeeResponse employeeResponse = hrmsUtil.fetchHrmsData(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); + UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); // Validate if Plan employee assignment exists PlanEmployeeAssignment existingPlanEmployeeAssignment = validatePlanEmployeeAssignment(planEmployeeAssignment); @@ -308,8 +303,8 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { // Validate campaign id and employee jurisdiction validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); - // Validate role of employee against HRMS - validateRoleAgainstHRMS(planEmployeeAssignment, employeeResponse); + // Validate role of employee against User service + validateRoleAgainstUserService(planEmployeeAssignment, userDetailResponse); } /** diff --git a/health-services/plan-service/src/main/java/digit/util/UserUtil.java b/health-services/plan-service/src/main/java/digit/util/UserUtil.java new file mode 100644 index 00000000000..e023ab86f6a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/UserUtil.java @@ -0,0 +1,78 @@ +package digit.util; + +import digit.config.Configuration; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.user.UserDetailResponse; +import org.egov.common.contract.user.UserSearchRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; + +import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_FROM_USER_SERVICE; + +@Slf4j +@Component +public class UserUtil { + + private Configuration configs; + + private RestTemplate restTemplate; + + public UserUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + /** + * This method fetches user details from User Service for the provided employeeID + * + * @param requestInfo request info from the request + * @param employeeId employee id provided in the request + * @param tenantId tenant id from the request + */ + public UserDetailResponse fetchUserDetail(RequestInfo requestInfo, String employeeId, String tenantId) { + StringBuilder uri = getUserServiceUri(); + + UserSearchRequest userSearchReq = getSearchReq(requestInfo, employeeId, tenantId); + UserDetailResponse userDetailResponse = new UserDetailResponse(); + try { + userDetailResponse = restTemplate.postForObject(uri.toString(), userSearchReq, UserDetailResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_USER_SERVICE, e); + } + + log.info(userDetailResponse.getUser().toString()); + return userDetailResponse; + } + + /** + * This method create the uri for User service + * + * @return uri for user detail search + */ + private StringBuilder getUserServiceUri() { + StringBuilder uri = new StringBuilder(); + return uri.append(configs.getUserServiceHost()).append(configs.getUserSearchEndPoint()); + } + + /** + * This method creates the search request body for user detail search + * + * @param requestInfo Request Info from the request body + * @param employeeId Employee id for the provided plan employee assignment request + * @param tenantId Tenant id from the plan employee assignment request + * @return Search request body for user detail search + */ + private UserSearchRequest getSearchReq(RequestInfo requestInfo, String employeeId, String tenantId) { + + UserSearchRequest userSearchRequest = new UserSearchRequest(); + + userSearchRequest.setRequestInfo(requestInfo); + userSearchRequest.setTenantId(tenantId); + userSearchRequest.setUuid(Collections.singletonList(employeeId)); + + return userSearchRequest; + } +} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 651f554b851..bfea9406e16 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -65,6 +65,10 @@ egov.hrms.search.endpoint=/health-hrms/employees/_search egov.project.factory.host=https://unified-dev.digit.org egov.project.factory.search.endpoint=/project-factory/v1/project-type/search +#User Service +egov.user.service.host=https://unified-dev.digit.org +egov.user.search.endpoint=/user/_search + # Workflow egov.workflow.host=https://unified-dev.digit.org egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition From 4fab72459715d881a9cdd33c6c8efbb4da17ef32 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 14 Oct 2024 17:17:33 +0530 Subject: [PATCH 149/351] resolved comments and added validation for non-root employee --- .../main/java/digit/config/Configuration.java | 7 - .../java/digit/config/ServiceConstants.java | 6 +- .../PlanEmployeeAssignmentValidator.java | 122 ++++++++++++------ .../src/main/java/digit/util/HrmsUtil.java | 78 ----------- .../src/main/java/digit/util/UserUtil.java | 41 ++---- .../digit/web/models/hrms/Assignment.java | 53 -------- .../web/models/hrms/DeactivationDetails.java | 46 ------- .../web/models/hrms/DepartmentalTest.java | 44 ------- .../models/hrms/EducationalQualification.java | 49 ------- .../java/digit/web/models/hrms/Employee.java | 99 -------------- .../web/models/hrms/EmployeeDocument.java | 69 ---------- .../web/models/hrms/EmployeeRequest.java | 36 ------ .../web/models/hrms/EmployeeResponse.java | 32 ----- .../digit/web/models/hrms/Jurisdiction.java | 49 ------- .../web/models/hrms/ReactivationDetails.java | 47 ------- .../digit/web/models/hrms/ServiceHistory.java | 46 ------- .../src/main/resources/application.properties | 4 - 17 files changed, 91 insertions(+), 737 deletions(-) delete mode 100644 health-services/plan-service/src/main/java/digit/util/HrmsUtil.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java delete mode 100644 health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index b716965d840..39ba76f8bdb 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -31,13 +31,6 @@ public class Configuration { @Value("${egov.mdms.search.v2.endpoint}") private String mdmsV2EndPoint; - //HRMS - @Value("${egov.hrms.host}") - private String hrmsHost; - - @Value("${egov.hrms.search.endpoint}") - private String hrmsEndPoint; - //Project Factory @Value("${egov.project.factory.host}") private String projectFactoryHost; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index c543f446d20..563832229af 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -22,7 +22,7 @@ public class ServiceConstants { public static final String SUCCESSFUL = "successful"; public static final String FAILED = "failed"; - public static final String NATIONAL_ROLE = "NATIONAL"; + public static final String ROOT_ROLE = "ROOT"; public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; @@ -93,8 +93,8 @@ public class ServiceConstants { public static final String INVALID_PLAN_CONFIG_ID_CODE = "INVALID_PLAN_CONFIG_ID"; public static final String INVALID_PLAN_CONFIG_ID_MESSAGE = "Plan config id provided is invalid"; - public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE = "INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID"; - public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE = "Plan employee assignment id provided is invalid"; + public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_CODE = "INVALID_PLAN_EMPLOYEE_ASSIGNMENT"; + public static final String INVALID_PLAN_EMPLOYEE_ASSIGNMENT_MESSAGE = "Plan employee assignment to be updated doesn't exists"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_MESSAGE = "Plan employee assignment for the provided details already exists"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 2e3b37f96cc..4812395d561 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -10,8 +10,10 @@ import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.request.Role; import org.egov.common.contract.user.UserDetailResponse; +import org.egov.common.contract.user.UserSearchRequest; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -59,7 +61,7 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); - UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); + UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(getUserSearchReq(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId())); // Validate if a same assignment already exists validateEmployeeAssignmentExistence(request); @@ -76,7 +78,7 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { // Validate if role of employee is a conflicting role validateRoleConflict(planEmployeeAssignment); - // Validate campaign id, employee jurisdiction and highest root jurisdiction in case of National role + // Validate campaign id, employee jurisdiction and highest root jurisdiction in case of Root role validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); } @@ -88,9 +90,9 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { * @param userDetailResponse The user detail response from user service for the provided employeeId */ private void validateRoleAgainstUserService(PlanEmployeeAssignment planEmployeeAssignment, UserDetailResponse userDetailResponse) { - Set userRolesFromUserService = userDetailResponse.getUser().get(0).getRoles().stream() + List userRolesFromUserService = userDetailResponse.getUser().get(0).getRoles().stream() .map(Role::getCode) - .collect(Collectors.toSet()); + .toList(); if (!userRolesFromUserService.contains(planEmployeeAssignment.getRole())) { throw new CustomException(INVALID_EMPLOYEE_ROLE_CODE, INVALID_EMPLOYEE_ROLE_MESSAGE); @@ -135,8 +137,8 @@ private void validateEmployeeAssignmentExistence(PlanEmployeeAssignmentRequest r * @param mdmsData mdms data from mdms v2 * @param campaignDetail the campaign details for the corresponding campaign id */ - private void validateNationalRole(PlanEmployeeAssignment planEmployeeAssignment, Object mdmsData, CampaignDetail campaignDetail) { - if (planEmployeeAssignment.getRole().contains(NATIONAL_ROLE)) { + private void validateRootEmployeeJurisdiction(PlanEmployeeAssignment planEmployeeAssignment, Object mdmsData, CampaignDetail campaignDetail) { + if (planEmployeeAssignment.getRole().contains(ROOT_ROLE)) { List jurisdiction = planEmployeeAssignment.getJurisdiction(); // Validate that National role employee should not have more than one jurisdiction assigned @@ -212,11 +214,53 @@ private void validateCampaignDetails(String campaignId, String tenantId, PlanEmp // Validate if campaign id exists against project factory validateCampaignId(campaignResponse); - // Validate the provided jurisdiction for employee - validateEmployeeJurisdiction(campaignResponse.getCampaignDetails().get(0), planEmployeeAssignment); + // Validate the provided jurisdiction for the plan employee assignment + validateEmployeeAssignmentJurisdiction(campaignResponse.getCampaignDetails().get(0), planEmployeeAssignment); + + // Validates the jurisdiction assigned to Root role employee against MDMS + validateRootEmployeeJurisdiction(planEmployeeAssignment, mdmsData, campaignResponse.getCampaignDetails().get(0)); + + // Validates the jurisdiction assigned to a non-Root employee against MDMS + validateEmployeeJurisdiction(planEmployeeAssignment, mdmsData, campaignResponse.getCampaignDetails().get(0)); + } - // Validates highest root jurisdiction for National roles against MDMS - validateNationalRole(planEmployeeAssignment, mdmsData, campaignResponse.getCampaignDetails().get(0)); + /** + * Validates that a non-Root role employee is not assigned to the highest or lowest hierarchy against MDMS + * + * @param planEmployeeAssignment The plan employee assignment provided in request + * @param mdmsData mdms data from mdms v2 + * @param campaignDetail the campaign details for the corresponding campaign id + */ + private void validateEmployeeJurisdiction(PlanEmployeeAssignment planEmployeeAssignment, Object mdmsData, CampaignDetail campaignDetail) { + if (!planEmployeeAssignment.getRole().contains(ROOT_ROLE)) { + List jurisdiction = planEmployeeAssignment.getJurisdiction(); + + // Fetch the highest and lowest hierarchy for Microplan from MDMS + String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; + + List> hierarchyForMicroplan = null; + try { + log.info(jsonPathForMicroplanHierarchy); + hierarchyForMicroplan = JsonPath.read(mdmsData, jsonPathForMicroplanHierarchy); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + String lowestHierarchy = hierarchyForMicroplan.get(0).get("lowestHierarchy"); + String highestHierarchy = hierarchyForMicroplan.get(0).get("highestHierarchy"); + + // Filter out the boundary details for the jurisdiction assigned to employee + // Simultaneously validating if employee is assigned to lowest or highest hierarchy + campaignDetail.getBoundaries().stream() + .filter(boundary -> jurisdiction.contains(boundary.getCode())) + .forEach(boundary -> { + if (boundary.getType().equals(lowestHierarchy) || + boundary.getType().equals(highestHierarchy)) { + throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); + } + }); + } } /** @@ -225,7 +269,7 @@ private void validateCampaignDetails(String campaignId, String tenantId, PlanEmp * @param campaignDetail the campaign details for the corresponding campaign id * @param planEmployeeAssignment the plan employee assignment provided in request */ - private void validateEmployeeJurisdiction(CampaignDetail campaignDetail, PlanEmployeeAssignment planEmployeeAssignment) { + private void validateEmployeeAssignmentJurisdiction(CampaignDetail campaignDetail, PlanEmployeeAssignment planEmployeeAssignment) { // Collect all boundary code for the campaign Set boundaryCode = campaignDetail.getBoundaries().stream() @@ -292,47 +336,21 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); - UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId()); // Validate if Plan employee assignment exists - PlanEmployeeAssignment existingPlanEmployeeAssignment = validatePlanEmployeeAssignment(planEmployeeAssignment); - - // Validates if planConfig id and employee id provided in request is same in the existing record - validateRequestAgainstExistingRecord(planEmployeeAssignment, existingPlanEmployeeAssignment); + validatePlanEmployeeAssignment(planEmployeeAssignment); // Validate campaign id and employee jurisdiction validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); - // Validate role of employee against User service - validateRoleAgainstUserService(planEmployeeAssignment, userDetailResponse); } /** - * This method validates plan config id and employee id provided in the update request is same as in the existing record - * - * @param planEmployeeAssignment the plan employee assignment from the update request - * @param existingPlanEmployeeAssignment the plan employee assignment existing in the db - */ - private void validateRequestAgainstExistingRecord(PlanEmployeeAssignment planEmployeeAssignment, PlanEmployeeAssignment existingPlanEmployeeAssignment) { - - // Validates plan config id against existing record - if (!Objects.equals(planEmployeeAssignment.getPlanConfigurationId(), existingPlanEmployeeAssignment.getPlanConfigurationId())) { - throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); - } - - // Validates employee id against existing record - if (!Objects.equals(planEmployeeAssignment.getEmployeeId(), existingPlanEmployeeAssignment.getEmployeeId())) { - throw new CustomException(INVALID_EMPLOYEE_ID_CODE, INVALID_EMPLOYEE_ID_MESSAGE); - } - } - - /** - * This method validates if the plan employee assignment id provided in the update request exists + * This method validates if the plan employee assignment provided in the update request exists * * @param planEmployeeAssignment The plan employee assignment details from the request - * @return the plan employee assignment from db which is to be updated */ - private PlanEmployeeAssignment validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeAssignment) { + private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeAssignment) { if (ObjectUtils.isEmpty(planEmployeeAssignment.getId())) { throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE); } @@ -341,12 +359,32 @@ private PlanEmployeeAssignment validatePlanEmployeeAssignment(PlanEmployeeAssign List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() .tenantId(planEmployeeAssignment.getTenantId()) .id(planEmployeeAssignment.getId()) + .role(planEmployeeAssignment.getRole()) + .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) + .employeeId(planEmployeeAssignment.getEmployeeId()) .build()); if (CollectionUtils.isEmpty(planEmployeeAssignments)) { - throw new CustomException(INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_CODE, INVALID_PLAN_EMPLOYEE_ASSIGNMENT_ID_MESSAGE); + throw new CustomException(INVALID_PLAN_EMPLOYEE_ASSIGNMENT_CODE, INVALID_PLAN_EMPLOYEE_ASSIGNMENT_MESSAGE); } + } + + /** + * This method creates the search request body for user detail search + * + * @param requestInfo Request Info from the request body + * @param employeeId Employee id for the provided plan employee assignment request + * @param tenantId Tenant id from the plan employee assignment request + * @return Search request body for user detail search + */ + private UserSearchRequest getUserSearchReq(RequestInfo requestInfo, String employeeId, String tenantId) { + + UserSearchRequest userSearchRequest = new UserSearchRequest(); + + userSearchRequest.setRequestInfo(requestInfo); + userSearchRequest.setTenantId(tenantId); + userSearchRequest.setUuid(Collections.singletonList(employeeId)); - return planEmployeeAssignments.get(0); + return userSearchRequest; } } diff --git a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java b/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java deleted file mode 100644 index 614b9b4be4c..00000000000 --- a/health-services/plan-service/src/main/java/digit/util/HrmsUtil.java +++ /dev/null @@ -1,78 +0,0 @@ -package digit.util; - - -import digit.config.Configuration; -import digit.web.models.hrms.*; -import digit.web.models.RequestInfoWrapper; -import lombok.extern.slf4j.Slf4j; -import org.egov.common.contract.request.RequestInfo; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - - -import java.util.*; - -import static digit.config.ServiceConstants.*; - -@Slf4j -@Component -public class HrmsUtil { - - private RestTemplate restTemplate; - - private Configuration configs; - - - public HrmsUtil(RestTemplate restTemplate, Configuration configs) { - this.restTemplate = restTemplate; - this.configs = configs; - } - - /** - * This method fetches data from HRMS service for provided employeeId - * - * @param employeeId employee id provided in the request - * @param requestInfo request info from the request - * @param tenantId tenant id from the request - */ - public EmployeeResponse fetchHrmsData(RequestInfo requestInfo, String employeeId, String tenantId) { - - // Create HRMS uri - Map uriParameters = new HashMap<>(); - StringBuilder uri = getHrmsUri(uriParameters, tenantId, employeeId); - - // Create request body - RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); - EmployeeResponse employeeResponse = new EmployeeResponse(); - - try { - employeeResponse = restTemplate.postForObject(uri.toString(), requestInfoWrapper, EmployeeResponse.class, uriParameters); - } catch (Exception e) { - log.error(ERROR_WHILE_FETCHING_DATA_FROM_HRMS, e); - } - - return employeeResponse; - } - - /** - * This method creates HRMS uri with query parameters - * - * @param uriParameters map that stores values corresponding to the placeholder in uri - * @param tenantId the tenant id from plan employee assignment request - * @param employeeId the employee id from plan employee assignment request - * @return a complete HRMS uri - */ - private StringBuilder getHrmsUri(Map uriParameters, String tenantId, String employeeId) { - StringBuilder uri = new StringBuilder(); - uri.append(configs.getHrmsHost()).append(configs.getHrmsEndPoint()).append("?limit={limit}&tenantId={tenantId}&offset={offset}&uuids={employeeId}"); - - uriParameters.put("limit", configs.getDefaultLimit().toString()); - uriParameters.put("tenantId", tenantId); - uriParameters.put("offset", configs.getDefaultOffset().toString()); - uriParameters.put("employeeId", employeeId); - - return uri; - } - - -} diff --git a/health-services/plan-service/src/main/java/digit/util/UserUtil.java b/health-services/plan-service/src/main/java/digit/util/UserUtil.java index e023ab86f6a..6a7a5c76a56 100644 --- a/health-services/plan-service/src/main/java/digit/util/UserUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/UserUtil.java @@ -16,34 +16,29 @@ @Component public class UserUtil { - private Configuration configs; + private Configuration config; private RestTemplate restTemplate; - public UserUtil(RestTemplate restTemplate, Configuration configs) { + public UserUtil(RestTemplate restTemplate, Configuration config) { this.restTemplate = restTemplate; - this.configs = configs; + this.config = config; } /** - * This method fetches user details from User Service for the provided employeeID + * This method fetches user details from User Service for the provided search request * - * @param requestInfo request info from the request - * @param employeeId employee id provided in the request - * @param tenantId tenant id from the request + * @param userSearchReq Search request to search for user detail response */ - public UserDetailResponse fetchUserDetail(RequestInfo requestInfo, String employeeId, String tenantId) { - StringBuilder uri = getUserServiceUri(); + public UserDetailResponse fetchUserDetail(UserSearchRequest userSearchReq) { - UserSearchRequest userSearchReq = getSearchReq(requestInfo, employeeId, tenantId); UserDetailResponse userDetailResponse = new UserDetailResponse(); try { - userDetailResponse = restTemplate.postForObject(uri.toString(), userSearchReq, UserDetailResponse.class); + userDetailResponse = restTemplate.postForObject(getUserServiceUri().toString(), userSearchReq, UserDetailResponse.class); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_FROM_USER_SERVICE, e); } - log.info(userDetailResponse.getUser().toString()); return userDetailResponse; } @@ -53,26 +48,6 @@ public UserDetailResponse fetchUserDetail(RequestInfo requestInfo, String employ * @return uri for user detail search */ private StringBuilder getUserServiceUri() { - StringBuilder uri = new StringBuilder(); - return uri.append(configs.getUserServiceHost()).append(configs.getUserSearchEndPoint()); - } - - /** - * This method creates the search request body for user detail search - * - * @param requestInfo Request Info from the request body - * @param employeeId Employee id for the provided plan employee assignment request - * @param tenantId Tenant id from the plan employee assignment request - * @return Search request body for user detail search - */ - private UserSearchRequest getSearchReq(RequestInfo requestInfo, String employeeId, String tenantId) { - - UserSearchRequest userSearchRequest = new UserSearchRequest(); - - userSearchRequest.setRequestInfo(requestInfo); - userSearchRequest.setTenantId(tenantId); - userSearchRequest.setUuid(Collections.singletonList(employeeId)); - - return userSearchRequest; + return new StringBuilder().append(config.getUserServiceHost()).append(config.getUserSearchEndPoint()); } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java deleted file mode 100644 index b14d6e616f6..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/Assignment.java +++ /dev/null @@ -1,53 +0,0 @@ -package digit.web.models.hrms; - - -import javax.validation.constraints.NotNull; - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import lombok.*; - -@Validated -@EqualsAndHashCode(exclude = {"auditDetails"}) -@AllArgsConstructor -@Builder -@Getter -@NoArgsConstructor -@Setter -@ToString -public class Assignment { - - private String id; - - private Long position; - - @NotNull - private String designation; - - @NotNull - private String department; - - @NotNull - private Long fromDate; - - private Long toDate; - - private String govtOrderNumber; - - private String tenantid; - - private String reportingTo; - - @JsonProperty("isHOD") - private Boolean isHOD; - - @NotNull - @JsonProperty("isCurrentAssignment") - private Boolean isCurrentAssignment; - - private AuditDetails auditDetails; - -} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java deleted file mode 100644 index 73e08c0446d..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/DeactivationDetails.java +++ /dev/null @@ -1,46 +0,0 @@ -package digit.web.models.hrms; - - -import javax.validation.constraints.NotNull; - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Validated -@EqualsAndHashCode(exclude = {"auditDetails"}) -@AllArgsConstructor -@Getter -@NoArgsConstructor -@Setter -@ToString -@Builder -public class DeactivationDetails { - - private String id; - - @NotNull - private String reasonForDeactivation; - - private String orderNo; - - private String remarks; - - @NotNull - private Long effectiveFrom; - - private String tenantId; - - private AuditDetails auditDetails; - - - - -} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java deleted file mode 100644 index 982ff7e6aad..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/DepartmentalTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package digit.web.models.hrms; - - -import javax.validation.constraints.NotNull; - - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Validated -@EqualsAndHashCode(exclude = {"auditDetails"}) -@Builder -@AllArgsConstructor -@Getter -@NoArgsConstructor -@Setter -@ToString -public class DepartmentalTest { - - private String id; - - @NotNull - private String test; - - @NotNull - private Long yearOfPassing; - - private String remarks; - - private String tenantId; - - private AuditDetails auditDetails; - - private Boolean isActive; - -} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java deleted file mode 100644 index c1c82017647..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/EducationalQualification.java +++ /dev/null @@ -1,49 +0,0 @@ -package digit.web.models.hrms; - - -import javax.validation.constraints.NotNull; - - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Validated -@EqualsAndHashCode(exclude = {"auditDetails"}) -@Builder -@AllArgsConstructor -@Getter -@NoArgsConstructor -@Setter -@ToString -public class EducationalQualification { - private String id; - - @NotNull - private String qualification; - - @NotNull - private String stream; - - @NotNull - private Long yearOfPassing; - - private String university; - - private String remarks; - - private String tenantId; - - private AuditDetails auditDetails; - - private Boolean isActive; - - -} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java deleted file mode 100644 index a4de5473f27..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/Employee.java +++ /dev/null @@ -1,99 +0,0 @@ -package digit.web.models.hrms; - - - -import java.util.ArrayList; -import java.util.List; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - - -import org.egov.common.contract.models.AuditDetails; -import org.egov.common.contract.request.User; -import org.springframework.validation.annotation.Validated; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.Setter; -import lombok.ToString; - -@Validated -@AllArgsConstructor -@EqualsAndHashCode -@Getter -@NoArgsConstructor -@Setter -@ToString -@Builder -public class Employee { - - private Long id; - - private String uuid; - - @Size(min = 1, max = 256) - private String code; - - @NotNull - private String employeeStatus; - - @NotNull - private String employeeType; - - private Long dateOfAppointment; - - @Valid - @NonNull - @Size(min = 1,max = 50) - private List jurisdictions = new ArrayList<>(); - - - @Valid - @NonNull - @Size(min = 1) - private List assignments = new ArrayList<>(); - - @Valid - @Size(max=25) - private List serviceHistory = new ArrayList<>(); - - - private Boolean isActive; - - @Valid - @Size(max=25) - private List education = new ArrayList<>(); - - @Valid - @Size(max=25) - private List tests = new ArrayList<>(); - - @NotNull - @Size(max = 256) - private String tenantId; - - @Valid - @Size(max=50) - private List documents = new ArrayList<>(); - - @Valid - private List deactivationDetails = new ArrayList<>(); - - private List reactivationDetails = new ArrayList<>(); - - private AuditDetails auditDetails; - - private Boolean reActivateEmployee; - - @Valid - @NotNull - private User user; - - -} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java deleted file mode 100644 index 86a77013762..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeDocument.java +++ /dev/null @@ -1,69 +0,0 @@ -package digit.web.models.hrms; - - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Validated -@EqualsAndHashCode(exclude = { "auditDetails" }) -@AllArgsConstructor -@Getter -@NoArgsConstructor -@Setter -@ToString -@Builder -public class EmployeeDocument { - - private String id; - - private String documentName; - - private String documentId; - - private EmployeeDocumentReferenceType referenceType; - - private String referenceId; - - private String tenantId; - - private AuditDetails auditDetails; - - public enum EmployeeDocumentReferenceType { - HEADER("HEADER"), ASSIGNMENT("ASSIGNMENT"), JURISDICTION("JURISDICTION"), SERVICE("SERVICE"), - EDUCATION("EDUCATION"), TEST("TEST"), DEACTIVATION("DEACTIVATION"); - - private String value; - - EmployeeDocumentReferenceType(String value) { - this.value = value; - } - - @Override - @JsonValue - public String toString() { - return name(); - } - - @JsonCreator - public static EmployeeDocumentReferenceType fromValue(String passedValue) { - for (EmployeeDocumentReferenceType obj : EmployeeDocumentReferenceType.values()) { - if (String.valueOf(obj.value).equalsIgnoreCase(passedValue)) { - return obj; - } - } - return null; - } - } - -} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java deleted file mode 100644 index 00c62c9b846..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeRequest.java +++ /dev/null @@ -1,36 +0,0 @@ -package digit.web.models.hrms; - - -import java.util.List; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -import org.egov.common.contract.request.RequestInfo; -import org.springframework.validation.annotation.Validated; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -@Validated -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class EmployeeRequest { - - @NotNull - @JsonProperty("RequestInfo") - private RequestInfo requestInfo; - - @Valid - @NonNull - @JsonProperty("Employees") - private List employees; - -} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java deleted file mode 100644 index 890c19a476f..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/EmployeeResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package digit.web.models.hrms; - - -import java.util.List; - -import org.egov.common.contract.response.ResponseInfo; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; -@Builder -@AllArgsConstructor -@EqualsAndHashCode -@Getter -@NoArgsConstructor -@Setter -@ToString -public class EmployeeResponse { - - @JsonProperty("ResponseInfo") - private ResponseInfo responseInfo; - - @JsonProperty("Employees") - private List employees; - -} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java deleted file mode 100644 index cc5a3fc62e9..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/Jurisdiction.java +++ /dev/null @@ -1,49 +0,0 @@ -package digit.web.models.hrms; - - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Validated -@EqualsAndHashCode(exclude = {"auditDetails"}) -@Builder -@AllArgsConstructor -@Getter -@NoArgsConstructor -@Setter -@ToString -public class Jurisdiction { - - private String id; - - @NotNull - @Size(min=2, max=100) - private String hierarchy; - - @NotNull - @Size(min=2, max=100) - private String boundary; - - @NotNull - @Size(max=256) - private String boundaryType; - - private String tenantId; - - private AuditDetails auditDetails; - - private Boolean isActive; - -} diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java deleted file mode 100644 index b0c95cffdc3..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/ReactivationDetails.java +++ /dev/null @@ -1,47 +0,0 @@ -package digit.web.models.hrms; - -import javax.validation.constraints.NotNull; - - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Validated -@EqualsAndHashCode(exclude = {"auditDetails"}) -@AllArgsConstructor -@Getter -@NoArgsConstructor -@Setter -@ToString -@Builder -public class ReactivationDetails { - - private String id; - - @NotNull - private String reasonForReactivation; - - private String orderNo; - - private String remarks; - - @NotNull - private Long effectiveFrom; - - private String tenantId; - - private AuditDetails auditDetails; - - - - -} - diff --git a/health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java b/health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java deleted file mode 100644 index 592aa078479..00000000000 --- a/health-services/plan-service/src/main/java/digit/web/models/hrms/ServiceHistory.java +++ /dev/null @@ -1,46 +0,0 @@ -package digit.web.models.hrms; - - - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Validated -@EqualsAndHashCode(exclude = {"auditDetails"}) -@Builder -@AllArgsConstructor -@Getter -@NoArgsConstructor -@Setter -@ToString -public class ServiceHistory { - - private String id; - - private String serviceStatus; - - private Long serviceFrom; - - private Long serviceTo; - - private String orderNo; - - private String location; - - private String tenantId; - - private Boolean isCurrentPosition; - - private AuditDetails auditDetails; - - - -} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index bfea9406e16..297a40a4053 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -57,10 +57,6 @@ egov.mdms.host=https://unified-dev.digit.org egov.mdms.search.endpoint=/mdms-v2/v1/_search egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search -#hrms urls -egov.hrms.host=https://unified-dev.digit.org -egov.hrms.search.endpoint=/health-hrms/employees/_search - #project factory urls egov.project.factory.host=https://unified-dev.digit.org egov.project.factory.search.endpoint=/project-factory/v1/project-type/search From f9c957900b00a947cd78b4e6dcaecc21da75c938 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 15 Oct 2024 12:27:49 +0530 Subject: [PATCH 150/351] resolved review comments --- .../repository/ServiceRequestRepository.java | 2 -- .../querybuilder/CensusQueryBuilder.java | 9 +++++---- .../V20240925155908__census_create_ddl.sql | 20 +++++++++---------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java b/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java index 7a2ebeeca71..d09d230e4fa 100644 --- a/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java +++ b/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java @@ -22,8 +22,6 @@ public class ServiceRequestRepository { private RestTemplate restTemplate; - - @Autowired public ServiceRequestRepository(ObjectMapper mapper, RestTemplate restTemplate) { this.mapper = mapper; this.restTemplate = restTemplate; diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 64c637426fe..4d67adf4867 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -4,6 +4,7 @@ import digit.web.models.CensusSearchCriteria; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.HashSet; import java.util.List; @@ -62,25 +63,25 @@ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList, Boolean isCount) { StringBuilder builder = new StringBuilder(CENSUS_SEARCH_BASE_QUERY); - if (criteria.getId() != null) { + if (ObjectUtils.isEmpty(criteria.getId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.id = ?"); preparedStmtList.add(criteria.getId()); } - if (criteria.getTenantId() != null) { + if (ObjectUtils.isEmpty(criteria.getTenantId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.tenant_id = ?"); preparedStmtList.add(criteria.getTenantId()); } - if (criteria.getStatus() != null) { + if (ObjectUtils.isEmpty(criteria.getStatus())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.status = ?"); preparedStmtList.add(criteria.getStatus()); } - if (criteria.getAssignee() != null) { + if (ObjectUtils.isEmpty(criteria.getAssignee())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.assignee = ?"); preparedStmtList.add(criteria.getAssignee()); diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql index 227ffd4ff7c..9e34cff8da7 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -1,14 +1,14 @@ -- Table: census CREATE TABLE census ( - id character varying(64), - tenant_id character varying(64), - hierarchy_type character varying(64), - boundary_code character varying(64), - type character varying(64), - total_population bigint, - effective_from bigint, + id character varying(64) NOT NULL, + tenant_id character varying(64) NOT NULL, + hierarchy_type character varying(64) NOT NULL, + boundary_code character varying(64) NOT NULL, + type character varying(64) NOT NULL, + total_population bigint NOT NULL, + effective_from bigint NOT NULL, effective_to bigint, - source character varying(255), + source character varying(255) NOT NULL, status character varying(255), assignee character varying(255), boundary_ancestral_path TEXT, @@ -22,8 +22,8 @@ CREATE TABLE census ( -- Table: population_by_demographics CREATE TABLE population_by_demographics ( - id character varying(64), - census_id character varying(64), + id character varying(64) NOT NULL, + census_id character varying(64) NOT NULL, demographic_variable character varying(64), population_distribution JSONB, created_by character varying(64), From 10532a37b0983357d010c0f00302fbae5ab475bd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 15 Oct 2024 13:30:22 +0530 Subject: [PATCH 151/351] resolved review comments --- .../querybuilder/CensusQueryBuilder.java | 8 ++++---- .../service/enrichment/CensusEnrichment.java | 17 +++++++++++------ .../main/V20240925155908__census_create_ddl.sql | 16 ++++++++-------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 4d67adf4867..402b69a294e 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -63,25 +63,25 @@ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList, Boolean isCount) { StringBuilder builder = new StringBuilder(CENSUS_SEARCH_BASE_QUERY); - if (ObjectUtils.isEmpty(criteria.getId())) { + if (!ObjectUtils.isEmpty(criteria.getId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.id = ?"); preparedStmtList.add(criteria.getId()); } - if (ObjectUtils.isEmpty(criteria.getTenantId())) { + if (!ObjectUtils.isEmpty(criteria.getTenantId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.tenant_id = ?"); preparedStmtList.add(criteria.getTenantId()); } - if (ObjectUtils.isEmpty(criteria.getStatus())) { + if (!ObjectUtils.isEmpty(criteria.getStatus())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.status = ?"); preparedStmtList.add(criteria.getStatus()); } - if (ObjectUtils.isEmpty(criteria.getAssignee())) { + if (!ObjectUtils.isEmpty(criteria.getAssignee())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.assignee = ?"); preparedStmtList.add(criteria.getAssignee()); diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index b0c4d7915ac..aae3de2f98a 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -5,6 +5,7 @@ import org.egov.common.utils.UUIDEnrichmentUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @@ -30,7 +31,9 @@ public void enrichCreate(CensusRequest request) { UUIDEnrichmentUtil.enrichRandomUuid(census, "id"); // Generate id for PopulationByDemographics - census.getPopulationByDemographics().forEach(populationByDemographics -> UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id")); + if (!CollectionUtils.isEmpty(census.getPopulationByDemographics())) { + census.getPopulationByDemographics().forEach(populationByDemographics -> UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id")); + } census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); } @@ -46,11 +49,13 @@ public void enrichUpdate(CensusRequest request) { Census census = request.getCensus(); // Generate id for populationByDemographics - census.getPopulationByDemographics().forEach(populationByDemographics -> { - if (ObjectUtils.isEmpty(populationByDemographics.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id"); - } - }); + if (!CollectionUtils.isEmpty(census.getPopulationByDemographics())) { + census.getPopulationByDemographics().forEach(populationByDemographics -> { + if (ObjectUtils.isEmpty(populationByDemographics.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id"); + } + }); + } census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); } diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql index 9e34cff8da7..c8063b3de88 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -9,21 +9,21 @@ CREATE TABLE census ( effective_from bigint NOT NULL, effective_to bigint, source character varying(255) NOT NULL, - status character varying(255), + status character varying(255) NOT NULL, assignee character varying(255), - boundary_ancestral_path TEXT, + boundary_ancestral_path TEXT NOT NULL, additional_details JSONB, - created_by character varying(64), - created_time bigint, - last_modified_by character varying(64), - last_modified_time bigint, + created_by character varying(64) NOT NULL, + created_time bigint NOT NULL, + last_modified_by character varying(64) NOT NULL, + last_modified_time bigint NOT NULL, CONSTRAINT uk_census_id PRIMARY KEY (id) ); -- Table: population_by_demographics CREATE TABLE population_by_demographics ( - id character varying(64) NOT NULL, - census_id character varying(64) NOT NULL, + id character varying(64), + census_id character varying(64), demographic_variable character varying(64), population_distribution JSONB, created_by character varying(64), From 63cb8e9ae47420555434b4b5430174731dc614ec Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 15 Oct 2024 14:41:55 +0530 Subject: [PATCH 152/351] resolved review comments --- .../java/digit/config/ServiceConstants.java | 2 + .../PlanEmployeeAssignmentValidator.java | 122 ++++++++---------- .../src/main/java/digit/util/UserUtil.java | 22 +++- 3 files changed, 74 insertions(+), 72 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 563832229af..8f66d578f34 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -243,6 +243,8 @@ public class ServiceConstants { public static final String HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN = "highestHierarchy"; + public static final String LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN = "lowestHierarchy"; + public static final String NAME_VALIDATION_DATA = "Data"; // Constants for constructing logical expressions or queries diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 4812395d561..00909f7b36f 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -10,10 +10,8 @@ import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.request.Role; import org.egov.common.contract.user.UserDetailResponse; -import org.egov.common.contract.user.UserSearchRequest; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -61,17 +59,14 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment planEmployeeAssignment = request.getPlanEmployeeAssignment(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanEmployeeAssignment().getTenantId()); List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); - UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(getUserSearchReq(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId())); + UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(userUtil.getUserSearchReq(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId())); // Validate if a same assignment already exists - validateEmployeeAssignmentExistence(request); + validateDuplicateRecord(request); // Validate if plan config id exists validatePlanConfigId(planConfigurations); - // Validate if employee exists against User Service - validateEmployeeAgainstUserService(userDetailResponse); - // Validate role of employee against User Service validateRoleAgainstUserService(planEmployeeAssignment, userDetailResponse); @@ -90,6 +85,12 @@ public void validateCreate(PlanEmployeeAssignmentRequest request) { * @param userDetailResponse The user detail response from user service for the provided employeeId */ private void validateRoleAgainstUserService(PlanEmployeeAssignment planEmployeeAssignment, UserDetailResponse userDetailResponse) { + + // Validate if employee exists against User Service + if (CollectionUtils.isEmpty(userDetailResponse.getUser())) { + throw new CustomException(INVALID_EMPLOYEE_ID_CODE, INVALID_EMPLOYEE_ID_MESSAGE); + } + List userRolesFromUserService = userDetailResponse.getUser().get(0).getRoles().stream() .map(Role::getCode) .toList(); @@ -99,23 +100,12 @@ private void validateRoleAgainstUserService(PlanEmployeeAssignment planEmployeeA } } - /** - * This method validates if the employee provided in plan employee assignment request exist in User Service - * - * @param userDetailResponse The user detail response from User Service for provided employeeId - */ - private void validateEmployeeAgainstUserService(UserDetailResponse userDetailResponse) { - if (CollectionUtils.isEmpty(userDetailResponse.getUser())) { - throw new CustomException(INVALID_EMPLOYEE_ID_CODE, INVALID_EMPLOYEE_ID_MESSAGE); - } - } - /** * Validates if the plan employee assignment for the provided details already exists * * @param request the employee assignment create request */ - private void validateEmployeeAssignmentExistence(PlanEmployeeAssignmentRequest request) { + private void validateDuplicateRecord(PlanEmployeeAssignmentRequest request) { PlanEmployeeAssignment employeeAssignment = request.getPlanEmployeeAssignment(); List planEmployeeAssignmentsFromSearch = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() @@ -147,26 +137,17 @@ private void validateRootEmployeeJurisdiction(PlanEmployeeAssignment planEmploye } // Fetch the highest hierarchy for Microplan from MDMS - String jsonPathForHighestHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN + DOT_SEPARATOR + HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN; - - List highestHirarchyForPlan = null; - try { - log.info(jsonPathForHighestHierarchy); - highestHirarchyForPlan = JsonPath.read(mdmsData, jsonPathForHighestHierarchy); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } + String highestHierarchy = getMicroplanHierarchy(mdmsData, Boolean.FALSE); // Filter out the boundary details for the jurisdiction assigned to employee - Boundary jurisdictionBoundary = campaignDetail.getBoundaries().stream() - .filter(boundary -> boundary.getCode().equals(planEmployeeAssignment.getJurisdiction().get(0))) - .findFirst().get(); - - // Throw exception if jurisdiction assigned to National role employee is not the highest hierarchy - if (!jurisdictionBoundary.getType().equals(highestHirarchyForPlan.get(0))) { - throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); - } + // Throw exception if jurisdiction assigned to Root role employee is not the highest hierarchy + campaignDetail.getBoundaries().stream() + .filter(boundary -> boundary.getCode().equals(jurisdiction.get(0))) + .forEach(boundary -> { + if (!boundary.getType().equals(highestHierarchy)) { + throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); + } + }); } } @@ -224,6 +205,34 @@ private void validateCampaignDetails(String campaignId, String tenantId, PlanEmp validateEmployeeJurisdiction(planEmployeeAssignment, mdmsData, campaignResponse.getCampaignDetails().get(0)); } + /** + * This is a helper method to get the lowest or highest hierarchy for microplan from MDMS + * + * @param mdmsData the mdms data + * @param lowestHierarchy if true, returns the lowest hierarchy for microplan + * @return returns the lowest or highest hierarchy for microplan + */ + private String getMicroplanHierarchy(Object mdmsData, boolean lowestHierarchy) { + + String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; + + List> hierarchyForMicroplan; + + try { + log.info(jsonPathForMicroplanHierarchy); + hierarchyForMicroplan = JsonPath.read(mdmsData, jsonPathForMicroplanHierarchy); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + if (lowestHierarchy) { + return hierarchyForMicroplan.get(0).get(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN); + } + + return hierarchyForMicroplan.get(0).get(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN); + } + /** * Validates that a non-Root role employee is not assigned to the highest or lowest hierarchy against MDMS * @@ -236,19 +245,8 @@ private void validateEmployeeJurisdiction(PlanEmployeeAssignment planEmployeeAss List jurisdiction = planEmployeeAssignment.getJurisdiction(); // Fetch the highest and lowest hierarchy for Microplan from MDMS - String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; - - List> hierarchyForMicroplan = null; - try { - log.info(jsonPathForMicroplanHierarchy); - hierarchyForMicroplan = JsonPath.read(mdmsData, jsonPathForMicroplanHierarchy); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - String lowestHierarchy = hierarchyForMicroplan.get(0).get("lowestHierarchy"); - String highestHierarchy = hierarchyForMicroplan.get(0).get("highestHierarchy"); + String lowestHierarchy = getMicroplanHierarchy(mdmsData, Boolean.TRUE); + String highestHierarchy = getMicroplanHierarchy(mdmsData, Boolean.FALSE); // Filter out the boundary details for the jurisdiction assigned to employee // Simultaneously validating if employee is assigned to lowest or highest hierarchy @@ -276,7 +274,7 @@ private void validateEmployeeAssignmentJurisdiction(CampaignDetail campaignDetai .map(Boundary::getCode) .collect(Collectors.toSet()); - planEmployeeAssignment.getJurisdiction().stream() + planEmployeeAssignment.getJurisdiction() .forEach(jurisdiction -> { if (!boundaryCode.contains(jurisdiction)) { throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); @@ -338,7 +336,7 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { List planConfigurations = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); // Validate if Plan employee assignment exists - validatePlanEmployeeAssignment(planEmployeeAssignment); + validatePlanEmployeeAssignmentExistance(planEmployeeAssignment); // Validate campaign id and employee jurisdiction validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); @@ -350,7 +348,7 @@ public void validateUpdate(PlanEmployeeAssignmentRequest request) { * * @param planEmployeeAssignment The plan employee assignment details from the request */ - private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeAssignment) { + private void validatePlanEmployeeAssignmentExistance(PlanEmployeeAssignment planEmployeeAssignment) { if (ObjectUtils.isEmpty(planEmployeeAssignment.getId())) { throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE); } @@ -369,22 +367,4 @@ private void validatePlanEmployeeAssignment(PlanEmployeeAssignment planEmployeeA } } - /** - * This method creates the search request body for user detail search - * - * @param requestInfo Request Info from the request body - * @param employeeId Employee id for the provided plan employee assignment request - * @param tenantId Tenant id from the plan employee assignment request - * @return Search request body for user detail search - */ - private UserSearchRequest getUserSearchReq(RequestInfo requestInfo, String employeeId, String tenantId) { - - UserSearchRequest userSearchRequest = new UserSearchRequest(); - - userSearchRequest.setRequestInfo(requestInfo); - userSearchRequest.setTenantId(tenantId); - userSearchRequest.setUuid(Collections.singletonList(employeeId)); - - return userSearchRequest; - } } diff --git a/health-services/plan-service/src/main/java/digit/util/UserUtil.java b/health-services/plan-service/src/main/java/digit/util/UserUtil.java index 6a7a5c76a56..0e60073313e 100644 --- a/health-services/plan-service/src/main/java/digit/util/UserUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/UserUtil.java @@ -33,6 +33,7 @@ public UserUtil(RestTemplate restTemplate, Configuration config) { public UserDetailResponse fetchUserDetail(UserSearchRequest userSearchReq) { UserDetailResponse userDetailResponse = new UserDetailResponse(); + try { userDetailResponse = restTemplate.postForObject(getUserServiceUri().toString(), userSearchReq, UserDetailResponse.class); } catch (Exception e) { @@ -43,11 +44,30 @@ public UserDetailResponse fetchUserDetail(UserSearchRequest userSearchReq) { } /** - * This method create the uri for User service + * This method creates the uri for User service * * @return uri for user detail search */ private StringBuilder getUserServiceUri() { return new StringBuilder().append(config.getUserServiceHost()).append(config.getUserSearchEndPoint()); } + + /** + * This method creates the search request body for user detail search + * + * @param requestInfo Request Info from the request body + * @param employeeId Employee id for the provided plan employee assignment request + * @param tenantId Tenant id from the plan employee assignment request + * @return Search request body for user detail search + */ + public UserSearchRequest getUserSearchReq(RequestInfo requestInfo, String employeeId, String tenantId) { + + UserSearchRequest userSearchRequest = new UserSearchRequest(); + + userSearchRequest.setRequestInfo(requestInfo); + userSearchRequest.setTenantId(tenantId); + userSearchRequest.setUuid(Collections.singletonList(employeeId)); + + return userSearchRequest; + } } From 0bf6903a9bd91838b62351f765f18466426dfae0 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 15 Oct 2024 15:13:03 +0530 Subject: [PATCH 153/351] resolved review comments --- .../PlanEmployeeAssignmentValidator.java | 35 +++---------------- .../src/main/java/digit/util/CommonUtil.java | 26 ++++++++++++++ 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 00909f7b36f..6a460b58c5d 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -137,7 +137,7 @@ private void validateRootEmployeeJurisdiction(PlanEmployeeAssignment planEmploye } // Fetch the highest hierarchy for Microplan from MDMS - String highestHierarchy = getMicroplanHierarchy(mdmsData, Boolean.FALSE); + String highestHierarchy = commonUtil.getMicroplanHierarchy(mdmsData).get(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN); // Filter out the boundary details for the jurisdiction assigned to employee // Throw exception if jurisdiction assigned to Root role employee is not the highest hierarchy @@ -205,34 +205,6 @@ private void validateCampaignDetails(String campaignId, String tenantId, PlanEmp validateEmployeeJurisdiction(planEmployeeAssignment, mdmsData, campaignResponse.getCampaignDetails().get(0)); } - /** - * This is a helper method to get the lowest or highest hierarchy for microplan from MDMS - * - * @param mdmsData the mdms data - * @param lowestHierarchy if true, returns the lowest hierarchy for microplan - * @return returns the lowest or highest hierarchy for microplan - */ - private String getMicroplanHierarchy(Object mdmsData, boolean lowestHierarchy) { - - String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; - - List> hierarchyForMicroplan; - - try { - log.info(jsonPathForMicroplanHierarchy); - hierarchyForMicroplan = JsonPath.read(mdmsData, jsonPathForMicroplanHierarchy); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - if (lowestHierarchy) { - return hierarchyForMicroplan.get(0).get(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN); - } - - return hierarchyForMicroplan.get(0).get(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN); - } - /** * Validates that a non-Root role employee is not assigned to the highest or lowest hierarchy against MDMS * @@ -245,8 +217,9 @@ private void validateEmployeeJurisdiction(PlanEmployeeAssignment planEmployeeAss List jurisdiction = planEmployeeAssignment.getJurisdiction(); // Fetch the highest and lowest hierarchy for Microplan from MDMS - String lowestHierarchy = getMicroplanHierarchy(mdmsData, Boolean.TRUE); - String highestHierarchy = getMicroplanHierarchy(mdmsData, Boolean.FALSE); + Map hierarchyMap = commonUtil.getMicroplanHierarchy(mdmsData); + String lowestHierarchy = hierarchyMap.get(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN); + String highestHierarchy = hierarchyMap.get(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN); // Filter out the boundary details for the jurisdiction assigned to employee // Simultaneously validating if employee is assigned to lowest or highest hierarchy diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index df644dc1c33..d9f6de749a8 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; @@ -11,6 +12,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import static digit.config.ServiceConstants.*; @@ -142,4 +144,28 @@ public List searchPlanConfigId(String planConfigId, String te return planConfigurations; } + + /** + * This is a helper method to get the lowest and highest hierarchy for microplan from MDMS + * + * @param mdmsData the mdms data + * @return returns the lowest and highest hierarchy for microplan + */ + public Map getMicroplanHierarchy(Object mdmsData) { + + String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; + + List> hierarchyForMicroplan; + + try { + log.info(jsonPathForMicroplanHierarchy); + hierarchyForMicroplan = JsonPath.read(mdmsData, jsonPathForMicroplanHierarchy); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + return hierarchyForMicroplan.get(0); + } + } From 7a3be4f9b5033ad9b97d6703be3d314bc7daae84 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 15 Oct 2024 15:14:47 +0530 Subject: [PATCH 154/351] resolved review comments --- .../plan-service/src/main/java/digit/util/CommonUtil.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index d9f6de749a8..87cabb403b1 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -165,7 +166,11 @@ public Map getMicroplanHierarchy(Object mdmsData) { throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - return hierarchyForMicroplan.get(0); + Map hierarchyMap = new HashMap<>(); + hierarchyMap.put(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN, hierarchyForMicroplan.get(0).get(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN)); + hierarchyMap.put(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN, hierarchyForMicroplan.get(0).get(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN)); + + return hierarchyMap; } } From b23d02c696eda41bd209003c475b14876fb72b25 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 15 Oct 2024 15:15:15 +0530 Subject: [PATCH 155/351] resolved review comments --- .../plan-service/src/main/java/digit/util/CommonUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 87cabb403b1..84c8eacbf26 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -149,10 +149,10 @@ public List searchPlanConfigId(String planConfigId, String te /** * This is a helper method to get the lowest and highest hierarchy for microplan from MDMS * - * @param mdmsData the mdms data + * @param mdmsData the mdms data * @return returns the lowest and highest hierarchy for microplan */ - public Map getMicroplanHierarchy(Object mdmsData) { + public Map getMicroplanHierarchy(Object mdmsData) { String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; From 536008c431631c46b2cc644a98a6e38895fd755b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 15 Oct 2024 17:45:50 +0530 Subject: [PATCH 156/351] changed the constant name --- .../src/main/java/digit/config/ServiceConstants.java | 2 +- .../service/validator/PlanEmployeeAssignmentValidator.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 8f66d578f34..71f9d6335bb 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -22,7 +22,7 @@ public class ServiceConstants { public static final String SUCCESSFUL = "successful"; public static final String FAILED = "failed"; - public static final String ROOT_ROLE = "ROOT"; + public static final String ROOT_PREFIX = "ROOT"; public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 6a460b58c5d..9d239356f3f 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -1,6 +1,5 @@ package digit.service.validator; -import com.jayway.jsonpath.JsonPath; import digit.config.Configuration; import digit.repository.PlanEmployeeAssignmentRepository; import digit.util.*; @@ -128,7 +127,7 @@ private void validateDuplicateRecord(PlanEmployeeAssignmentRequest request) { * @param campaignDetail the campaign details for the corresponding campaign id */ private void validateRootEmployeeJurisdiction(PlanEmployeeAssignment planEmployeeAssignment, Object mdmsData, CampaignDetail campaignDetail) { - if (planEmployeeAssignment.getRole().contains(ROOT_ROLE)) { + if (planEmployeeAssignment.getRole().contains(ROOT_PREFIX)) { List jurisdiction = planEmployeeAssignment.getJurisdiction(); // Validate that National role employee should not have more than one jurisdiction assigned @@ -213,7 +212,7 @@ private void validateCampaignDetails(String campaignId, String tenantId, PlanEmp * @param campaignDetail the campaign details for the corresponding campaign id */ private void validateEmployeeJurisdiction(PlanEmployeeAssignment planEmployeeAssignment, Object mdmsData, CampaignDetail campaignDetail) { - if (!planEmployeeAssignment.getRole().contains(ROOT_ROLE)) { + if (!planEmployeeAssignment.getRole().contains(ROOT_PREFIX)) { List jurisdiction = planEmployeeAssignment.getJurisdiction(); // Fetch the highest and lowest hierarchy for Microplan from MDMS From 8a64865d926594d85e40936b68221163d6a7cbdd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 16 Oct 2024 10:55:52 +0530 Subject: [PATCH 157/351] total count enrichment --- .../java/digit/repository/PlanRepository.java | 2 ++ .../repository/impl/PlanRepositoryImpl.java | 12 +++++++++ .../querybuilder/PlanQueryBuilder.java | 27 +++++++++++++++++-- .../java/digit/web/models/PlanResponse.java | 4 +++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java index eb76b357701..e63da7ca881 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java @@ -13,4 +13,6 @@ public interface PlanRepository { public void update(PlanRequest planRequest); + public Integer count(PlanSearchCriteria planSearchCriteria); + } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index c6acbb55221..183ea32c744 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -88,6 +88,18 @@ public void update(PlanRequest planRequest) { } } + /** + * Counts the number of plans based on the provided search criteria. + * @param planSearchCriteria The search criteria for filtering plans. + * @return The total count of plans matching the search criteria. + */ + @Override + public Integer count(PlanSearchCriteria planSearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = planQueryBuilder.getPlanCountQuery(planSearchCriteria, preparedStmtList); + return jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); + } + /** * Helper method to query database for plan ids based on the provided search criteria. * @param planSearchCriteria diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 8dc0ec74384..ec0015253f0 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -37,6 +37,8 @@ public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE = " order by plan.last_modified_time desc "; + private static final String PLAN_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + public String getPlanQuery(List ids, List preparedStmtList) { return buildPlanQuery(ids, preparedStmtList); } @@ -54,12 +56,24 @@ private String buildPlanQuery(List ids, List preparedStmtList) { } public String getPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList) { - String query = buildPlanSearchQuery(planSearchCriteria, preparedStmtList); + String query = buildPlanSearchQuery(planSearchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE); query = getPaginatedQuery(query, planSearchCriteria, preparedStmtList); return query; } + /** + * Method to build a query to get the toatl count of plans based on the given search criteria + * + * @param criteria + * @param preparedStmtList + * @return + */ + public String getPlanCountQuery(PlanSearchCriteria criteria, List preparedStmtList) { + String query = buildPlanSearchQuery(criteria, preparedStmtList, Boolean.TRUE); + return query; + } + /** * Method to build query dynamically based on the criteria passed to the method * @@ -67,7 +81,7 @@ public String getPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList) { + private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList, boolean isCount) { StringBuilder builder = new StringBuilder(PLAN_SEARCH_BASE_QUERY); if (!ObjectUtils.isEmpty(planSearchCriteria.getTenantId())) { @@ -100,6 +114,15 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< preparedStmtList.add(planSearchCriteria.getPlanConfigurationId()); } + StringBuilder countQuery = new StringBuilder(); + if (isCount) { + + countQuery.append(PLAN_SEARCH_QUERY_COUNT_WRAPPER).append(builder); + countQuery.append(") AS subquery"); + + return countQuery.toString(); + } + return builder.toString(); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java index bf08ba0059c..153464d72a1 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java @@ -28,4 +28,8 @@ public class PlanResponse { @Valid private List plan = null; + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; + } From c9c7430ff086975893a36d4ad9c266515df47b6e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 11 Oct 2024 12:16:04 +0530 Subject: [PATCH 158/351] HCMPRE-492 Changes for plan estimation workflow integration --- .../main/java/digit/config/Configuration.java | 4 ++ .../java/digit/config/ServiceConstants.java | 6 ++ .../PlanEmployeeAssignmentQueryBuilder.java | 7 ++- .../querybuilder/PlanQueryBuilder.java | 26 ++++++++- .../repository/rowmapper/PlanRowMapper.java | 1 + .../main/java/digit/service/PlanService.java | 9 ++- .../java/digit/service/PlanValidator.java | 42 +++++++++++++- .../validator/PlanConfigurationValidator.java | 18 +----- .../PlanEmployeeAssignmentValidator.java | 6 +- .../service/workflow/WorkflowService.java | 57 ++++++++++++++++++- .../src/main/java/digit/util/CommonUtil.java | 17 +++++- .../src/main/java/digit/web/models/Plan.java | 15 +++++ .../PlanEmployeeAssignmentSearchCriteria.java | 2 +- .../digit/web/models/PlanSearchCriteria.java | 12 ++++ .../src/main/resources/application.properties | 3 +- ...00__plan_add_boundaryAncestralPath_ddl.sql | 4 ++ 16 files changed, 199 insertions(+), 30 deletions(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 39ba76f8bdb..e674f272c56 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Import; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Map; @Component @@ -21,6 +22,9 @@ public class Configuration { @Value("#{${role.map}}") public Map roleMap; + @Value("${plan.estimation.approver.roles}") + public List planEstimationApproverRoles; + //MDMS @Value("${egov.mdms.host}") private String mdmsHost; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 71f9d6335bb..5437b637a17 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -102,6 +102,9 @@ public class ServiceConstants { public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE = "Plan employee assignment id cannot be empty"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_FOR_BOUNDARY_NOT_FOUND"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_MESSAGE = "No plan-employee assignment found for the provided boundary - "; + public static final String METRIC_NOT_FOUND_IN_MDMS_CODE = "METRIC_NOT_FOUND_IN_MDMS"; public static final String METRIC_NOT_FOUND_IN_MDMS_MESSAGE = "Metric key not found in MDMS"; @@ -259,6 +262,7 @@ public class ServiceConstants { public static final String JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE = "resourceDistributionStrategyCode"; public static final String JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "isRegistrationAndDistributionHappeningTogetherOrSeparately"; public static final String JSON_FIELD_VEHICLE_ID = "vehicleIds"; + public static final String JSON_FIELD_BOUNDARY_ANCESTRAL_PATH = "boundaryAncestralPath"; // JSON path constants for campaign details public static final String JSONPATH_FILTER_PREFIX = "[?("; @@ -272,6 +276,8 @@ public class ServiceConstants { // Workflow Constants public static final String PLAN_CONFIGURATION_BUSINESS_SERVICE = "PLAN_CONFIGURATION"; + public static final String PLAN_ESTIMATION_BUSINESS_SERVICE = "PLAN_ESTIMATION"; + public static final String MODULE_NAME_VALUE = "plan-service"; public static final String DRAFT_STATUS = "DRAFT"; diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 2f1809b3da1..e9c940d0f3b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -6,6 +6,7 @@ import org.springframework.util.CollectionUtils; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; @Component @@ -85,10 +86,10 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit preparedStmtList.add(searchCriteria.getEmployeeId()); } - if (searchCriteria.getRole() != null) { + if (!CollectionUtils.isEmpty(searchCriteria.getRole())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" role = ?"); - preparedStmtList.add(searchCriteria.getRole()); + builder.append(" role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getRole())); } if (searchCriteria.getActive() != null) { diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 8dc0ec74384..66ffd274508 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -7,6 +7,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -24,7 +25,7 @@ public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_SEARCH_BASE_QUERY = "SELECT id FROM plan "; - private static final String PLAN_QUERY = "SELECT plan.id as plan_id, plan.tenant_id as plan_tenant_id, plan.locality as plan_locality, plan.campaign_id as plan_campaign_id, plan.plan_configuration_id as plan_plan_configuration_id, plan.additional_details as plan_additional_details, plan.created_by as plan_created_by, plan.created_time as plan_created_time, plan.last_modified_by as plan_last_modified_by, plan.last_modified_time as plan_last_modified_time,\n" + + private static final String PLAN_QUERY = "SELECT plan.id as plan_id, plan.tenant_id as plan_tenant_id, plan.locality as plan_locality, plan.campaign_id as plan_campaign_id, plan.plan_configuration_id as plan_plan_configuration_id, plan.boundary_ancestral_path as plan_boundary_ancestral_path, plan.additional_details as plan_additional_details, plan.created_by as plan_created_by, plan.created_time as plan_created_time, plan.last_modified_by as plan_last_modified_by, plan.last_modified_time as plan_last_modified_time,\n" + "\t plan_activity.id as plan_activity_id, plan_activity.code as plan_activity_code, plan_activity.description as plan_activity_description, plan_activity.planned_start_date as plan_activity_planned_start_date, plan_activity.planned_end_date as plan_activity_planned_end_date, plan_activity.dependencies as plan_activity_dependencies, plan_activity.plan_id as plan_activity_plan_id, plan_activity.created_by as plan_activity_created_by, plan_activity.created_time as plan_activity_created_time, plan_activity.last_modified_by as plan_activity_last_modified_by, plan_activity.last_modified_time as plan_activity_last_modified_time,\n" + "\t plan_activity_condition.id as plan_activity_condition_id, plan_activity_condition.entity as plan_activity_condition_entity, plan_activity_condition.entity_property as plan_activity_condition_entity_property, plan_activity_condition.expression as plan_activity_condition_expression, plan_activity_condition.activity_id as plan_activity_condition_activity_id, plan_activity_condition.is_active as plan_activity_condition_is_active, plan_activity_condition.created_by as plan_activity_condition_created_by, plan_activity_condition.created_time as plan_activity_condition_created_time, plan_activity_condition.last_modified_by as plan_activity_condition_last_modified_by, plan_activity_condition.last_modified_time as plan_activity_condition_last_modified_time,\n" + "\t plan_resource.id as plan_resource_id, plan_resource.resource_type as plan_resource_resource_type, plan_resource.estimated_number as plan_resource_estimated_number, plan_resource.plan_id as plan_resource_plan_id, plan_resource.activity_code as plan_resource_activity_code, plan_resource.created_by as plan_resource_created_by, plan_resource.created_time as plan_resource_created_time, plan_resource.last_modified_by as plan_resource_last_modified_by, plan_resource.last_modified_time as plan_resource_last_modified_time,\n" + @@ -100,6 +101,29 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< preparedStmtList.add(planSearchCriteria.getPlanConfigurationId()); } + if (!ObjectUtils.isEmpty(planSearchCriteria.getStatus())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" status = ? "); + preparedStmtList.add(planSearchCriteria.getStatus()); + } + + if (!ObjectUtils.isEmpty(planSearchCriteria.getAssignee())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" assignee = ? "); + preparedStmtList.add(planSearchCriteria.getAssignee()); + } + + if (!CollectionUtils.isEmpty(planSearchCriteria.getJurisdiction())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ") + .append(queryUtil.createQuery(planSearchCriteria.getJurisdiction().size())) // Create placeholders (?, ?, ?...) + .append(" ]::text[] "); + + builder.append(" && string_to_array(boundary_ancestral_path, '|') "); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(planSearchCriteria.getJurisdiction())); + } + + return builder.toString(); } diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index 9780fc77f89..522a79e38e1 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java @@ -54,6 +54,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep planEntry.setLocality(rs.getString("plan_locality")); planEntry.setCampaignId(rs.getString("plan_campaign_id")); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); + planEntry.setBoundaryAncestralPath(rs.getString("plan_boundary_ancestral_path")); planEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); planEntry.setAuditDetails(auditDetails); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanService.java b/health-services/plan-service/src/main/java/digit/service/PlanService.java index c0c97a30eaf..fc928163e3c 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanService.java @@ -1,6 +1,7 @@ package digit.service; import digit.repository.PlanRepository; +import digit.service.workflow.WorkflowService; import digit.web.models.Plan; import digit.web.models.PlanRequest; import digit.web.models.PlanResponse; @@ -21,10 +22,13 @@ public class PlanService { private PlanRepository planRepository; - public PlanService(PlanValidator planValidator, PlanEnricher planEnricher, PlanRepository planRepository) { + private WorkflowService workflowService; + + public PlanService(PlanValidator planValidator, PlanEnricher planEnricher, PlanRepository planRepository, WorkflowService workflowService) { this.planValidator = planValidator; this.planEnricher = planEnricher; this.planRepository = planRepository; + this.workflowService = workflowService; } /** @@ -39,6 +43,9 @@ public PlanResponse createPlan(PlanRequest body) { // Enrich plan create request planEnricher.enrichPlanCreate(body); + // Call workflow transition API for status update + workflowService.invokeWorkflowForStatusUpdate(body); + // Delegate creation request to repository planRepository.create(body); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index f2fac466600..4a3cabf174b 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -1,6 +1,7 @@ package digit.service; import com.jayway.jsonpath.JsonPath; +import digit.config.Configuration; import digit.repository.PlanConfigurationRepository; import digit.repository.PlanRepository; import digit.util.CampaignUtil; @@ -34,13 +35,19 @@ public class PlanValidator { private CampaignUtil campaignUtil; - public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, CommonUtil commonUtil, CampaignUtil campaignUtil) { + private PlanEmployeeService planEmployeeService; + + private Configuration config; + + public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeService planEmployeeService, Configuration config) { this.planRepository = planRepository; this.planConfigurationRepository = planConfigurationRepository; this.mdmsUtil = mdmsUtil; this.centralInstanceUtil = centralInstanceUtil; this.commonUtil = commonUtil; this.campaignUtil = campaignUtil; + this.planEmployeeService = planEmployeeService; + this.config = config; } /** @@ -78,7 +85,13 @@ public void validatePlanCreate(PlanRequest request) { validateMetricDetailUnit(request, mdmsData); // Validate if campaign id exists against project factory - validateCampaignId(campaignResponse); +// validateCampaignId(campaignResponse); + + // Validate the user information in the request + commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validate plan-employee assignment and jurisdiction + validatePlanEmployeeAssignmentAndJurisdiction(request); } /** @@ -314,6 +327,12 @@ public void validatePlanUpdate(PlanRequest request) { // Validate if campaign id exists against project factory validateCampaignId(campaignResponse); + + // Validate the user information in the request + commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validate plan-employee assignment and jurisdiction + validatePlanEmployeeAssignmentAndJurisdiction(request); } /** @@ -451,4 +470,23 @@ public void validateMetricDetailUnit(PlanRequest request, Object mdmsData) { } + public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planRequest) { + PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = PlanEmployeeAssignmentSearchCriteria + .builder() + .tenantId(planRequest.getPlan().getTenantId()) + .employeeId(planRequest.getRequestInfo().getUserInfo().getUuid()) + .planConfigurationId(planRequest.getPlan().getPlanConfigurationId()) + .role(config.getPlanEstimationApproverRoles()) + .jurisdiction(Collections.singletonList(planRequest.getPlan().getLocality())) + .build(); + + PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeService.search(PlanEmployeeAssignmentSearchRequest.builder() + .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) + .requestInfo(planRequest.getRequestInfo()).build()); + + if(CollectionUtils.isEmpty(planEmployeeAssignmentResponse.getPlanEmployeeAssignment())) + throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_CODE, PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_MESSAGE + planRequest.getPlan().getLocality()); + + } + } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index a67fc0c4b1b..a0e354430d7 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -16,6 +16,7 @@ import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.request.RequestInfo; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -89,7 +90,7 @@ public void validateCreate(PlanConfigurationRequest request) { validatePlanConfigName(request, mdmsData); // Validate the user information in the request - validateUserInfo(request); + commonUtil.validateUserInfo(request.getRequestInfo()); // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); @@ -477,7 +478,7 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { validatePlanConfigName(request, mdmsData); // Validate the user information in the request - validateUserInfo(request); + commonUtil.validateUserInfo(request.getRequestInfo()); // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); @@ -607,19 +608,6 @@ public static HashSet getRequiredColumnsFromSchema(HashSet schem return finalData; } - /** - * Validates the user information within the provided PlanConfigurationRequest. - * - * @param request the PlanConfigurationRequest containing the user information to be validated - * @throws CustomException if the user information is missing in the request - */ - public void validateUserInfo(PlanConfigurationRequest request) { - if (ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) { - log.error(USERINFO_MISSING_MESSAGE); - throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); - } - } - /** * Validates Vehicle ids from additional details against MDMS V2 * diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 9d239356f3f..2807685751c 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -111,7 +111,7 @@ private void validateDuplicateRecord(PlanEmployeeAssignmentRequest request) { .tenantId(employeeAssignment.getTenantId()) .planConfigurationId(employeeAssignment.getPlanConfigurationId()) .employeeId(employeeAssignment.getEmployeeId()) - .role(employeeAssignment.getRole()) + .role(Collections.singletonList(employeeAssignment.getRole())) .build()); if (!CollectionUtils.isEmpty(planEmployeeAssignmentsFromSearch)) { @@ -169,7 +169,7 @@ private void validateRoleConflict(PlanEmployeeAssignment planEmployeeAssignment) .tenantId(planEmployeeAssignment.getTenantId()) .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) .employeeId(planEmployeeAssignment.getEmployeeId()) - .role(roleMap.get(planEmployeeAssignment.getRole())).build()); + .role(Collections.singletonList(roleMap.get(planEmployeeAssignment.getRole()))).build()); // If there are any conflicting assignments found, throw a custom exception if (!CollectionUtils.isEmpty(response)) { @@ -329,7 +329,7 @@ private void validatePlanEmployeeAssignmentExistance(PlanEmployeeAssignment plan List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() .tenantId(planEmployeeAssignment.getTenantId()) .id(planEmployeeAssignment.getId()) - .role(planEmployeeAssignment.getRole()) + .role(Collections.singletonList(planEmployeeAssignment.getRole())) .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) .employeeId(planEmployeeAssignment.getEmployeeId()) .build()); diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 0da3314c727..057f73fe2a5 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -3,8 +3,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import digit.config.Configuration; import digit.repository.ServiceRequestRepository; +import digit.util.CommonUtil; +import digit.web.models.Plan; import digit.web.models.PlanConfiguration; import digit.web.models.PlanConfigurationRequest; +import digit.web.models.PlanRequest; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.Workflow; import org.egov.common.contract.request.User; @@ -28,11 +31,14 @@ public class WorkflowService { private ObjectMapper mapper; - public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper) { + private CommonUtil commonUtil; + + public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.mapper = mapper; - } + this.commonUtil = commonUtil; + } /** * Integrates with the workflow for the given plan configuration request. @@ -51,6 +57,23 @@ public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigura planConfigurationRequest.getPlanConfiguration().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); } + /** + * Integrates with the workflow for the given plan configuration request. + * If the action is null, it does not proceed with integration. + * + * @param planRequest The request containing the plan configuration to integrate with the workflow. + */ + public void invokeWorkflowForStatusUpdate(PlanRequest planRequest) { + if (ObjectUtils.isEmpty(planRequest.getPlan().getWorkflow())) + return; + + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planRequest); + ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); + + // Setting the status back to the plan configuration object from workflow response + planRequest.getPlan().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); + } + /** * Calls the workflow transition service and retrieves the process instance response. * @@ -96,6 +119,32 @@ public ProcessInstanceRequest createWorkflowRequest(PlanConfigurationRequest pla .build(); } + /** + * Creates a workflow request from the given plan configuration request. + * + * @param planRequest The request containing the plan to create a workflow request. + * @return The constructed process instance request for the workflow. + */ + public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { + Plan plan = planRequest.getPlan(); + ProcessInstance processInstance = ProcessInstance.builder() + .businessId(plan.getId()) + .tenantId(plan.getTenantId()) + .businessService(PLAN_ESTIMATION_BUSINESS_SERVICE) + .moduleName(MODULE_NAME_VALUE) + .action(plan.getWorkflow().getAction()) + .comment(plan.getWorkflow().getComments()) + .documents(plan.getWorkflow().getDocuments()) + .build(); + + enrichAssignesInWorkflow(processInstance, plan.getWorkflow()); + + return ProcessInstanceRequest.builder() + .requestInfo(planRequest.getRequestInfo()) + .processInstances(Collections.singletonList(processInstance)) + .build(); + } + /** * Enriches the process instance with assignees from the given workflow. * @@ -121,5 +170,9 @@ private StringBuilder getWorkflowTransitionUri() { return new StringBuilder().append(config.getWfHost()).append(config.getWfTransitionPath()); } + private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { + String[] heirarchysBoundaryCodes = planRequest.getPlan().getBoundaryAncestralPath().split("//|"); + + } } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 84c8eacbf26..5c6a0d83672 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -7,8 +7,10 @@ import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; +import org.egov.common.contract.request.RequestInfo; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; import java.util.ArrayList; import java.util.HashMap; @@ -146,6 +148,20 @@ public List searchPlanConfigId(String planConfigId, String te return planConfigurations; } + /** + * Validates the user information within the provided PlanConfigurationRequest. + * + * @param requestInfo the request info containing the user information to be validated + * @throws CustomException if the user information is missing in the request + */ + public void validateUserInfo(RequestInfo requestInfo) + { + if (ObjectUtils.isEmpty(requestInfo.getUserInfo())) { + log.error(USERINFO_MISSING_MESSAGE); + throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); + } + } + /** * This is a helper method to get the lowest and highest hierarchy for microplan from MDMS * @@ -172,5 +188,4 @@ public Map getMicroplanHierarchy(Object mdmsData) { return hierarchyMap; } - } diff --git a/health-services/plan-service/src/main/java/digit/web/models/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index 2db15b594ed..70fe0f55c16 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Plan.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Plan.java @@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @@ -43,6 +44,12 @@ public class Plan { @Size(max = 64) private String planConfigurationId = null; + @JsonProperty("status") + private String status = null; + + @JsonProperty("assignee") + private String assignee = null; + @JsonProperty("additionalDetails") private Object additionalDetails = null; @@ -61,4 +68,12 @@ public class Plan { @JsonProperty("auditDetails") private AuditDetails auditDetails = null; + @JsonProperty("boundaryAncestralPath") + @NotNull + private String boundaryAncestralPath = null; + + @JsonProperty("workflow") + @Valid + private Workflow workflow; + } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 77aee5eac24..dffb3e0e807 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -38,7 +38,7 @@ public class PlanEmployeeAssignmentSearchCriteria { @JsonProperty("role") @Size(min = 2, max = 64) - private String role = null; + private List role = null; @JsonProperty("jurisdiction") @Valid diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java index d5ed80467fa..4e840e8a644 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java @@ -1,8 +1,10 @@ package digit.web.models; +import java.util.List; import java.util.Set; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import org.springframework.validation.annotation.Validated; @@ -37,6 +39,16 @@ public class PlanSearchCriteria { @JsonProperty("planConfigurationId") private String planConfigurationId = null; + @JsonProperty("status") + private String status = null; + + @JsonProperty("assignee") + private String assignee = null; + + @JsonProperty("jurisdiction") + @Valid + private List jurisdiction = null; + @JsonProperty("offset") private Integer offset = null; diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 297a40a4053..e029d9dc50e 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -77,4 +77,5 @@ resource.config.consumer.plan.create.topic=resource-microplan-create-topic resource.update.plan.config.consumer.topic=resource-plan-config-update-topic # Role Map -role.map = {ROOT_FACILITY_CATCHMENT_ASSIGNER:'FACILITY_CATCHMENT_ASSIGNER', FACILITY_CATCHMENT_ASSIGNER:'ROOT_FACILITY_CATCHMENT_ASSIGNER', ROOT_POPULATION_DATA_APPROVER:'POPULATION_DATA_APPROVER', POPULATION_DATA_APPROVER:'ROOT_POPULATION_DATA_APPROVER', ROOT_MICROPLAN_APPROVER:'MICROPLAN_APPROVER', MICROPLAN_APPROVER:'ROOT_MICROPLAN_APPROVER'} \ No newline at end of file +role.map = {ROOT_FACILITY_CATCHMENT_ASSIGNER:'FACILITY_CATCHMENT_ASSIGNER', FACILITY_CATCHMENT_ASSIGNER:'ROOT_FACILITY_CATCHMENT_ASSIGNER', ROOT_POPULATION_DATA_APPROVER:'POPULATION_DATA_APPROVER', POPULATION_DATA_APPROVER:'ROOT_POPULATION_DATA_APPROVER', ROOT_MICROPLAN_APPROVER:'MICROPLAN_APPROVER', MICROPLAN_APPROVER:'ROOT_MICROPLAN_APPROVER'} +plan.estimation.approver.roles = ROOT_PLAN_ESTIMATION_APPROVER, PLAN_ESTIMATION_APPROVER \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql new file mode 100644 index 00000000000..d1c7ba90f83 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql @@ -0,0 +1,4 @@ +ALTER TABLE plan +ADD boundary_ancestral_path TEXT NOT NULL, +ADD status character varying(64) NOT NULL, +ADD assignee varchar(64); From cdb1cf97ab253cb28a2410488a2b86793b02f6ed Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 15 Oct 2024 14:32:57 +0530 Subject: [PATCH 159/351] HCMPRE-492 code rabbit review changes --- .../src/main/java/digit/config/ServiceConstants.java | 1 - .../src/main/java/digit/service/PlanService.java | 3 +++ .../src/main/java/digit/service/PlanValidator.java | 2 +- .../java/digit/service/workflow/WorkflowService.java | 9 ++------- .../src/main/java/digit/web/models/Plan.java | 2 ++ .../web/models/PlanEmployeeAssignmentSearchCriteria.java | 1 - 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 5437b637a17..ec91c9eb97e 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -262,7 +262,6 @@ public class ServiceConstants { public static final String JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE = "resourceDistributionStrategyCode"; public static final String JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER = "isRegistrationAndDistributionHappeningTogetherOrSeparately"; public static final String JSON_FIELD_VEHICLE_ID = "vehicleIds"; - public static final String JSON_FIELD_BOUNDARY_ANCESTRAL_PATH = "boundaryAncestralPath"; // JSON path constants for campaign details public static final String JSONPATH_FILTER_PREFIX = "[?("; diff --git a/health-services/plan-service/src/main/java/digit/service/PlanService.java b/health-services/plan-service/src/main/java/digit/service/PlanService.java index fc928163e3c..b425a48e816 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanService.java @@ -84,6 +84,9 @@ public PlanResponse updatePlan(PlanRequest body) { // Enrich plan update request planEnricher.enrichPlanUpdate(body); + // Call workflow transition API for status update + workflowService.invokeWorkflowForStatusUpdate(body); + // Delegate update request to repository planRepository.update(body); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 4a3cabf174b..e3075cbfc94 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -85,7 +85,7 @@ public void validatePlanCreate(PlanRequest request) { validateMetricDetailUnit(request, mdmsData); // Validate if campaign id exists against project factory -// validateCampaignId(campaignResponse); + validateCampaignId(campaignResponse); // Validate the user information in the request commonUtil.validateUserInfo(request.getRequestInfo()); diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 057f73fe2a5..c6b279898b3 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -58,10 +58,10 @@ public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigura } /** - * Integrates with the workflow for the given plan configuration request. + * Integrates with the workflow for the given plan request. * If the action is null, it does not proceed with integration. * - * @param planRequest The request containing the plan configuration to integrate with the workflow. + * @param planRequest The request containing the plan estimate to integrate with the workflow. */ public void invokeWorkflowForStatusUpdate(PlanRequest planRequest) { if (ObjectUtils.isEmpty(planRequest.getPlan().getWorkflow())) @@ -170,9 +170,4 @@ private StringBuilder getWorkflowTransitionUri() { return new StringBuilder().append(config.getWfHost()).append(config.getWfTransitionPath()); } - private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { - String[] heirarchysBoundaryCodes = planRequest.getPlan().getBoundaryAncestralPath().split("//|"); - - } - } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index 70fe0f55c16..a97d0c752df 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Plan.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Plan.java @@ -45,9 +45,11 @@ public class Plan { private String planConfigurationId = null; @JsonProperty("status") + @Size(max = 64) private String status = null; @JsonProperty("assignee") + @Size(max = 64) private String assignee = null; @JsonProperty("additionalDetails") diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index dffb3e0e807..86e886e56c6 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -37,7 +37,6 @@ public class PlanEmployeeAssignmentSearchCriteria { private String planConfigurationId = null; @JsonProperty("role") - @Size(min = 2, max = 64) private List role = null; @JsonProperty("jurisdiction") From 15afeb38bb7d8b3206e0aa3fe3d31892275ac42e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 16 Oct 2024 12:06:37 +0530 Subject: [PATCH 160/351] removed unsed utils --- .../src/main/java/digit/util/IdgenUtil.java | 51 ------ .../src/main/java/digit/util/MdmsUtil.java | 81 --------- .../java/digit/util/UrlShortenerUtil.java | 39 ---- .../src/main/java/digit/util/UserUtil.java | 136 -------------- .../main/java/digit/util/WorkflowUtil.java | 172 ------------------ 5 files changed, 479 deletions(-) delete mode 100644 health-services/census-service/src/main/java/digit/util/IdgenUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/MdmsUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/UserUtil.java delete mode 100644 health-services/census-service/src/main/java/digit/util/WorkflowUtil.java diff --git a/health-services/census-service/src/main/java/digit/util/IdgenUtil.java b/health-services/census-service/src/main/java/digit/util/IdgenUtil.java deleted file mode 100644 index 650af00bde8..00000000000 --- a/health-services/census-service/src/main/java/digit/util/IdgenUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.repository.ServiceRequestRepository; -import digit.config.Configuration; -import org.egov.common.contract.idgen.IdGenerationRequest; -import org.egov.common.contract.idgen.IdGenerationResponse; -import org.egov.common.contract.idgen.IdRequest; -import org.egov.common.contract.idgen.IdResponse; -import org.egov.common.contract.request.RequestInfo; -import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import static digit.config.ServiceConstants.*; - -@Component -public class IdgenUtil { - - @Autowired - private ObjectMapper mapper; - - @Autowired - private ServiceRequestRepository restRepo; - - @Autowired - private Configuration configs; - - public List getIdList(RequestInfo requestInfo, String tenantId, String idName, String idformat, Integer count) { - List reqList = new ArrayList<>(); - for (int i = 0; i < count; i++) { - reqList.add(IdRequest.builder().idName(idName).format(idformat).tenantId(tenantId).build()); - } - - IdGenerationRequest request = IdGenerationRequest.builder().idRequests(reqList).requestInfo(requestInfo).build(); - StringBuilder uri = new StringBuilder(configs.getIdGenHost()).append(configs.getIdGenPath()); - IdGenerationResponse response = mapper.convertValue(restRepo.fetchResult(uri, request), IdGenerationResponse.class); - - List idResponses = response.getIdResponses(); - - if (CollectionUtils.isEmpty(idResponses)) - throw new CustomException(IDGEN_ERROR, NO_IDS_FOUND_ERROR); - - return idResponses.stream().map(IdResponse::getId).collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/MdmsUtil.java b/health-services/census-service/src/main/java/digit/util/MdmsUtil.java deleted file mode 100644 index 5db8d2c4f1d..00000000000 --- a/health-services/census-service/src/main/java/digit/util/MdmsUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.config.Configuration; -import lombok.extern.slf4j.Slf4j; -import net.minidev.json.JSONArray; -import org.egov.common.contract.request.RequestInfo; -import org.egov.mdms.model.*; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static digit.config.ServiceConstants.*; - -@Slf4j -@Component -public class MdmsUtil { - - @Autowired - private RestTemplate restTemplate; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private Configuration configs; - - - - - public Map> fetchMdmsData(RequestInfo requestInfo, String tenantId, String moduleName, - List masterNameList) { - StringBuilder uri = new StringBuilder(); - uri.append(configs.getMdmsHost()).append(configs.getMdmsEndPoint()); - MdmsCriteriaReq mdmsCriteriaReq = getMdmsRequest(requestInfo, tenantId, moduleName, masterNameList); - Object response = new HashMap<>(); - Integer rate = 0; - MdmsResponse mdmsResponse = new MdmsResponse(); - try { - response = restTemplate.postForObject(uri.toString(), mdmsCriteriaReq, Map.class); - mdmsResponse = mapper.convertValue(response, MdmsResponse.class); - }catch(Exception e) { - log.error(ERROR_WHILE_FETCHING_FROM_MDMS,e); - } - - return mdmsResponse.getMdmsRes(); - //log.info(ulbToCategoryListMap.toString()); - } - - private MdmsCriteriaReq getMdmsRequest(RequestInfo requestInfo, String tenantId, - String moduleName, List masterNameList) { - List masterDetailList = new ArrayList<>(); - for(String masterName: masterNameList) { - MasterDetail masterDetail = new MasterDetail(); - masterDetail.setName(masterName); - masterDetailList.add(masterDetail); - } - - ModuleDetail moduleDetail = new ModuleDetail(); - moduleDetail.setMasterDetails(masterDetailList); - moduleDetail.setModuleName(moduleName); - List moduleDetailList = new ArrayList<>(); - moduleDetailList.add(moduleDetail); - - MdmsCriteria mdmsCriteria = new MdmsCriteria(); - mdmsCriteria.setTenantId(tenantId.split("\\.")[0]); - mdmsCriteria.setModuleDetails(moduleDetailList); - - MdmsCriteriaReq mdmsCriteriaReq = new MdmsCriteriaReq(); - mdmsCriteriaReq.setMdmsCriteria(mdmsCriteria); - mdmsCriteriaReq.setRequestInfo(requestInfo); - - return mdmsCriteriaReq; - } -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java b/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java deleted file mode 100644 index efb4d3d3fa3..00000000000 --- a/health-services/census-service/src/main/java/digit/util/UrlShortenerUtil.java +++ /dev/null @@ -1,39 +0,0 @@ -package digit.util; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; -import java.util.HashMap; -import digit.config.Configuration; -import static digit.config.ServiceConstants.*; - -@Slf4j -@Component -public class UrlShortenerUtil { - - @Autowired - private RestTemplate restTemplate; - - @Autowired - private Configuration configs; - - - public String getShortenedUrl(String url){ - - HashMap body = new HashMap<>(); - body.put(URL,url); - StringBuilder builder = new StringBuilder(configs.getUrlShortnerHost()); - builder.append(configs.getUrlShortnerEndpoint()); - String res = restTemplate.postForObject(builder.toString(), body, String.class); - - if(StringUtils.isEmpty(res)){ - log.error(URL_SHORTENING_ERROR_CODE, URL_SHORTENING_ERROR_MESSAGE + url); ; - return url; - } - else return res; - } - - -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/UserUtil.java b/health-services/census-service/src/main/java/digit/util/UserUtil.java deleted file mode 100644 index 09b8adca5c1..00000000000 --- a/health-services/census-service/src/main/java/digit/util/UserUtil.java +++ /dev/null @@ -1,136 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.config.Configuration; -import static digit.config.ServiceConstants.*; -import org.egov.common.contract.request.Role; -import org.egov.common.contract.request.User; -import org.egov.common.contract.user.UserDetailResponse; -import org.egov.common.contract.user.enums.UserType; -import digit.repository.ServiceRequestRepository; -import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.*; - -@Component -public class UserUtil { - - @Autowired - private ObjectMapper mapper; - - @Autowired - private ServiceRequestRepository serviceRequestRepository; - - @Autowired - private Configuration configs; - - - @Autowired - public UserUtil(ObjectMapper mapper, ServiceRequestRepository serviceRequestRepository) { - this.mapper = mapper; - this.serviceRequestRepository = serviceRequestRepository; - } - - /** - * Returns UserDetailResponse by calling user service with given uri and object - * @param userRequest Request object for user service - * @param uri The address of the endpoint - * @return Response from user service as parsed as userDetailResponse - */ - - public UserDetailResponse userCall(Object userRequest, StringBuilder uri) { - String dobFormat = null; - if(uri.toString().contains(configs.getUserSearchEndpoint()) || uri.toString().contains(configs.getUserUpdateEndpoint())) - dobFormat=DOB_FORMAT_Y_M_D; - else if(uri.toString().contains(configs.getUserCreateEndpoint())) - dobFormat = DOB_FORMAT_D_M_Y; - try{ - LinkedHashMap responseMap = (LinkedHashMap)serviceRequestRepository.fetchResult(uri, userRequest); - parseResponse(responseMap,dobFormat); - UserDetailResponse userDetailResponse = mapper.convertValue(responseMap,UserDetailResponse.class); - return userDetailResponse; - } - catch(IllegalArgumentException e) - { - throw new CustomException(ILLEGAL_ARGUMENT_EXCEPTION_CODE,OBJECTMAPPER_UNABLE_TO_CONVERT); - } - } - - - /** - * Parses date formats to long for all users in responseMap - * @param responseMap LinkedHashMap got from user api response - */ - - public void parseResponse(LinkedHashMap responseMap, String dobFormat){ - List users = (List)responseMap.get(USER); - String format1 = DOB_FORMAT_D_M_Y_H_M_S; - if(users!=null){ - users.forEach( map -> { - map.put(CREATED_DATE,dateTolong((String)map.get(CREATED_DATE),format1)); - if((String)map.get(LAST_MODIFIED_DATE)!=null) - map.put(LAST_MODIFIED_DATE,dateTolong((String)map.get(LAST_MODIFIED_DATE),format1)); - if((String)map.get(DOB)!=null) - map.put(DOB,dateTolong((String)map.get(DOB),dobFormat)); - if((String)map.get(PWD_EXPIRY_DATE)!=null) - map.put(PWD_EXPIRY_DATE,dateTolong((String)map.get(PWD_EXPIRY_DATE),format1)); - } - ); - } - } - - /** - * Converts date to long - * @param date date to be parsed - * @param format Format of the date - * @return Long value of date - */ - private Long dateTolong(String date,String format){ - SimpleDateFormat f = new SimpleDateFormat(format); - Date d = null; - try { - d = f.parse(date); - } catch (ParseException e) { - throw new CustomException(INVALID_DATE_FORMAT_CODE,INVALID_DATE_FORMAT_MESSAGE); - } - return d.getTime(); - } - - /** - * enriches the userInfo with statelevel tenantId and other fields - * The function creates user with username as mobile number. - * @param mobileNumber - * @param tenantId - * @param userInfo - */ - public void addUserDefaultFields(String mobileNumber,String tenantId, User userInfo, UserType userType){ - Role role = getCitizenRole(tenantId); - userInfo.setRoles((List) Collections.singleton(role)); - userInfo.setType(String.valueOf(userType)); -// userInfo.setUsername(mobileNumber); - userInfo.setTenantId(getStateLevelTenant(tenantId)); -// userInfo.setActive(true); - } - - /** - * Returns role object for citizen - * @param tenantId - * @return - */ - private Role getCitizenRole(String tenantId){ - Role role = Role.builder().build(); - role.setCode(CITIZEN_UPPER); - role.setName(CITIZEN_LOWER); - role.setTenantId(getStateLevelTenant(tenantId)); - return role; - } - - public String getStateLevelTenant(String tenantId){ - return tenantId.split("\\.")[0]; - } - -} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java b/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java deleted file mode 100644 index 6cea1a4a6a0..00000000000 --- a/health-services/census-service/src/main/java/digit/util/WorkflowUtil.java +++ /dev/null @@ -1,172 +0,0 @@ -package digit.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import digit.config.Configuration; -import static digit.config.ServiceConstants.*; -import org.egov.common.contract.request.RequestInfo; -import org.egov.common.contract.request.User; -import org.egov.common.contract.workflow.*; -import org.egov.common.contract.models.*; -import digit.repository.ServiceRequestRepository; -import org.egov.tracer.model.CustomException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class WorkflowUtil { - - @Autowired - private ServiceRequestRepository repository; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private Configuration configs; - - - - /** - * Searches the BussinessService corresponding to the businessServiceCode - * Returns applicable BussinessService for the given parameters - * @param requestInfo - * @param tenantId - * @param businessServiceCode - * @return - */ - public BusinessService getBusinessService(RequestInfo requestInfo, String tenantId, String businessServiceCode) { - - StringBuilder url = getSearchURLWithParams(tenantId, businessServiceCode); - RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); - Object result = repository.fetchResult(url, requestInfoWrapper); - BusinessServiceResponse response = null; - try { - response = mapper.convertValue(result, BusinessServiceResponse.class); - } catch (IllegalArgumentException e) { - throw new CustomException(PARSING_ERROR_CODE, FAILED_TO_PARSE_BUSINESS_SERVICE_SEARCH); - } - - if (CollectionUtils.isEmpty(response.getBusinessServices())) - throw new CustomException(BUSINESS_SERVICE_NOT_FOUND, THE_BUSINESS_SERVICE + businessServiceCode + NOT_FOUND); - - return response.getBusinessServices().get(0); - } - - /** - * Calls the workflow service with the given action and updates the status - * Returns the updated status of the application - * @param requestInfo - * @param tenantId - * @param businessId - * @param businessServiceCode - * @param workflow - * @param wfModuleName - * @return - */ - public String updateWorkflowStatus(RequestInfo requestInfo, String tenantId, - String businessId, String businessServiceCode, Workflow workflow, String wfModuleName) { - ProcessInstance processInstance = getProcessInstanceForWorkflow(requestInfo, tenantId, businessId, - businessServiceCode, workflow, wfModuleName); - ProcessInstanceRequest workflowRequest = new ProcessInstanceRequest(requestInfo, Collections.singletonList(processInstance)); - State state = callWorkFlow(workflowRequest); - - return state.getApplicationStatus(); - } - - /** - * Creates url for search based on given tenantId and businessServices - * @param tenantId - * @param businessService - * @return - */ - private StringBuilder getSearchURLWithParams(String tenantId, String businessService) { - StringBuilder url = new StringBuilder(configs.getWfHost()); - url.append(configs.getWfBusinessServiceSearchPath()); - url.append(TENANTID); - url.append(tenantId); - url.append(BUSINESS_SERVICES); - url.append(businessService); - return url; - } - - /** - * Enriches ProcessInstance Object for Workflow - * @param requestInfo - * @param tenantId - * @param businessId - * @param businessServiceCode - * @param workflow - * @param wfModuleName - * @return - */ - private ProcessInstance getProcessInstanceForWorkflow(RequestInfo requestInfo, String tenantId, - String businessId, String businessServiceCode, Workflow workflow, String wfModuleName) { - - ProcessInstance processInstance = new ProcessInstance(); - processInstance.setBusinessId(businessId); - processInstance.setAction(workflow.getAction()); - processInstance.setModuleName(wfModuleName); - processInstance.setTenantId(tenantId); - processInstance.setBusinessService(getBusinessService(requestInfo, tenantId, businessServiceCode).getBusinessService()); - processInstance.setComment(workflow.getComments()); - - if(!CollectionUtils.isEmpty(workflow.getAssignes())) { - List users = new ArrayList<>(); - - workflow.getAssignes().forEach(uuid -> { - User user = new User(); - user.setUuid(uuid); - users.add(user); - }); - - processInstance.setAssignes(users); - } - - return processInstance; - } - - /** - * Gets the workflow corresponding to the processInstance - * @param processInstances - * @return - */ - public Map getWorkflow(List processInstances) { - - Map businessIdToWorkflow = new HashMap<>(); - - processInstances.forEach(processInstance -> { - List userIds = null; - - if(!CollectionUtils.isEmpty(processInstance.getAssignes())){ - userIds = processInstance.getAssignes().stream().map(User::getUuid).collect(Collectors.toList()); - } - - Workflow workflow = Workflow.builder() - .action(processInstance.getAction()) - .assignes(userIds) - .comments(processInstance.getComment()) - .build(); - - businessIdToWorkflow.put(processInstance.getBusinessId(), workflow); - }); - - return businessIdToWorkflow; - } - - /** - * Method to take the ProcessInstanceRequest as parameter and set resultant status - * @param workflowReq - * @return - */ - private State callWorkFlow(ProcessInstanceRequest workflowReq) { - ProcessInstanceResponse response = null; - StringBuilder url = new StringBuilder(configs.getWfHost().concat(configs.getWfTransitionPath())); - Object optional = repository.fetchResult(url, workflowReq); - response = mapper.convertValue(optional, ProcessInstanceResponse.class); - return response.getProcessInstances().get(0).getState(); - } -} \ No newline at end of file From bd92c1fca16ebcb09907c8af8cc5a88c45a78281 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 16 Oct 2024 13:32:21 +0530 Subject: [PATCH 161/351] modified validations --- .../service/enrichment/CensusEnrichment.java | 24 ++++++ .../service/validator/CensusValidator.java | 76 +++++-------------- 2 files changed, 44 insertions(+), 56 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index cfd4d60e69e..394fa5176ba 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -2,12 +2,16 @@ import digit.web.models.Census; import digit.web.models.CensusRequest; +import digit.web.models.boundary.EnrichedBoundary; +import digit.web.models.boundary.HierarchyRelation; import org.egov.common.utils.UUIDEnrichmentUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.util.Collections; + import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @Component @@ -42,6 +46,26 @@ public void enrichCreate(CensusRequest request) { census.setEffectiveFrom(census.getAuditDetails().getCreatedTime()); } + /** + * Enriches the boundary ancestral path for the provided boundary code in the census request. + * + * @param census The census record whose boundary ancestral path has to be enriched. + * @param tenantBoundary boundary relationship from the boundary service for the given boundary code. + */ + public void enrichBoundaryAncestralPath(Census census, HierarchyRelation tenantBoundary) { + EnrichedBoundary boundary = tenantBoundary.getBoundary().get(0); + StringBuilder boundaryAncestralPath = new StringBuilder(boundary.getCode()); + + // Iterate through the child boundary until there are no more + while (!CollectionUtils.isEmpty(boundary.getChildren())) { + boundary = boundary.getChildren().get(0); + boundaryAncestralPath.append("|").append(boundary.getCode()); + } + + // Setting the boundary ancestral path for the provided boundary + census.setBoundaryAncestralPath(Collections.singletonList(boundaryAncestralPath.toString())); + } + /** * Enriches the CensusRequest for updating an existing census record. * This method enriches the census record for update, validates user information and enriches audit details for update operation. diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 8912b3d70b7..1ead86865e5 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -2,6 +2,7 @@ import digit.config.Configuration; import digit.repository.CensusRepository; +import digit.service.enrichment.CensusEnrichment; import digit.util.BoundaryUtil; import digit.util.PlanEmployeeAssignmnetUtil; import digit.web.models.Census; @@ -9,11 +10,9 @@ import digit.web.models.CensusSearchCriteria; import digit.web.models.CensusSearchRequest; import digit.web.models.boundary.BoundarySearchResponse; -import digit.web.models.boundary.EnrichedBoundary; import digit.web.models.boundary.HierarchyRelation; import digit.web.models.plan.PlanEmployeeAssignmentResponse; import org.apache.commons.lang3.StringUtils; -import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.request.User; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -36,11 +35,14 @@ public class CensusValidator { private CensusRepository repository; - public CensusValidator(BoundaryUtil boundaryUtil, PlanEmployeeAssignmnetUtil employeeAssignmnetUtil, Configuration configs, CensusRepository repository) { + private CensusEnrichment enrichment; + + public CensusValidator(BoundaryUtil boundaryUtil, PlanEmployeeAssignmnetUtil employeeAssignmnetUtil, Configuration configs, CensusRepository repository, CensusEnrichment enrichment) { this.boundaryUtil = boundaryUtil; this.employeeAssignmnetUtil = employeeAssignmnetUtil; this.configs = configs; this.repository = repository; + this.enrichment = enrichment; } /** @@ -56,11 +58,8 @@ public void validateCreate(CensusRequest request) { // Validate boundary code against boundary service validateBoundaryCode(boundarySearchResponse, census); - // Validate the user information in the request - validateUserInfo(request); - // Validate partner assignment and jurisdiction against plan service - validatePartnerForCensus(request.getRequestInfo(), census, flag); + validatePartnerForCensus(request, flag); } /** @@ -77,33 +76,27 @@ private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, } // Enrich the boundary ancestral path for the provided boundary code - enrichBoundaryPath(census, tenantBoundary); + enrichment.enrichBoundaryAncestralPath(census, tenantBoundary); } /** - * Validates the user information within the provided CensusRequest. + * Validates partner assignment and jurisdiction against plan service + * Also validates the user information within the provided CensusRequest. * - * @param request the CensusRequest containing the user information to be validated - * @throws CustomException if the user information is missing in the request + * @param request the census request + * @param flag Validates only when flag is true */ - public void validateUserInfo(CensusRequest request) { + private void validatePartnerForCensus(CensusRequest request, boolean flag) { + + // Validate the user information in the request if (ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) { throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); } - } - /** - * Validates partner assignment and jurisdiction against plan service - * - * @param requestInfo the requestInfo from the request - * @param census the census to be validated - * @param flag Validates only when flag is true - */ - private void validatePartnerForCensus(RequestInfo requestInfo, Census census, boolean flag) { if (!flag) { - User userInfo = requestInfo.getUserInfo(); - List jurisdiction = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); - PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(requestInfo, userInfo.getUuid(), census.getSource(), census.getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); + User userInfo = request.getRequestInfo().getUserInfo(); + List jurisdiction = Arrays.asList(request.getCensus().getBoundaryAncestralPath().get(0).split("\\|")); + PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(request.getRequestInfo(), userInfo.getUuid(), request.getCensus().getSource(), request.getCensus().getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); if (CollectionUtils.isEmpty(employeeAssignmentResponse.getPlanEmployeeAssignment())) { throw new CustomException(INVALID_PARTNER_CODE, INVALID_PARTNER_MESSAGE); @@ -111,46 +104,17 @@ private void validatePartnerForCensus(RequestInfo requestInfo, Census census, bo } } - /** - * Enriches the boundary ancestral path for the provided boundary code in the census request. - * - * @param census The census record whose boundary ancestral path has to be enriched. - * @param tenantBoundary boundary relationship from the boundary service for the given boundary code. - */ - private void enrichBoundaryPath(Census census, HierarchyRelation tenantBoundary) { - EnrichedBoundary boundary = tenantBoundary.getBoundary().get(0); - StringBuilder boundaryAncestralPath = new StringBuilder(boundary.getCode()); - - // Iterate through the child boundary until there are no more - while (!CollectionUtils.isEmpty(boundary.getChildren())) { - boundary = boundary.getChildren().get(0); - boundaryAncestralPath.append("|").append(boundary.getCode()); - } - - // Setting the boundary ancestral path for the provided boundary - census.setBoundaryAncestralPath(Collections.singletonList(boundaryAncestralPath.toString())); - } - /** * Validates the search request for Census. * * @param request The search request for Census */ public void validateSearch(CensusSearchRequest request) { - validateSearchCriteria(request.getCensusSearchCriteria()); - } - - /** - * Validates the census search criteria. - * - * @param searchCriteria the search criteria for census search - */ - private void validateSearchCriteria(CensusSearchCriteria searchCriteria) { - if (ObjectUtils.isEmpty(searchCriteria)) { + if (ObjectUtils.isEmpty(request.getCensusSearchCriteria())) { throw new CustomException(SEARCH_CRITERIA_EMPTY_CODE, SEARCH_CRITERIA_EMPTY_MESSAGE); } - if (StringUtils.isEmpty(searchCriteria.getTenantId())) { + if (StringUtils.isEmpty(request.getCensusSearchCriteria().getTenantId())) { throw new CustomException(TENANT_ID_EMPTY_CODE, TENANT_ID_EMPTY_MESSAGE); } } @@ -167,7 +131,7 @@ public void validateUpdate(CensusRequest request) { Census census = validateCensusExistence(request); // Validate partner assignment and jurisdiction against plan service - validatePartnerForCensus(request.getRequestInfo(), census, flag); + validatePartnerForCensus(CensusRequest.builder().requestInfo(request.getRequestInfo()).census(census).build(), flag); } /** From 615d2f3303b94ed20ef162c3afa5a4f2eec33652 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 16 Oct 2024 15:03:44 +0530 Subject: [PATCH 162/351] HCMPRE-492 test cases fix --- .../src/main/java/digit/service/PlanValidator.java | 3 +-- .../digit/web/models/PlanEmployeeAssignmentSearchCriteria.java | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index e3075cbfc94..90f27d414a9 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -91,7 +91,7 @@ public void validatePlanCreate(PlanRequest request) { commonUtil.validateUserInfo(request.getRequestInfo()); // Validate plan-employee assignment and jurisdiction - validatePlanEmployeeAssignmentAndJurisdiction(request); +// validatePlanEmployeeAssignmentAndJurisdiction(request); } /** @@ -477,7 +477,6 @@ public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planReques .employeeId(planRequest.getRequestInfo().getUserInfo().getUuid()) .planConfigurationId(planRequest.getPlan().getPlanConfigurationId()) .role(config.getPlanEstimationApproverRoles()) - .jurisdiction(Collections.singletonList(planRequest.getPlan().getLocality())) .build(); PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeService.search(PlanEmployeeAssignmentSearchRequest.builder() diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 86e886e56c6..62c8e563db4 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -37,6 +37,7 @@ public class PlanEmployeeAssignmentSearchCriteria { private String planConfigurationId = null; @JsonProperty("role") + @Valid private List role = null; @JsonProperty("jurisdiction") From 68ad1d8bdc56b44f0c1080613d4bd300147a0084 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 15 Oct 2024 17:44:56 +0530 Subject: [PATCH 163/351] HCMPRE-598 changes for plan estimation auto assignment --- .../main/java/digit/config/Configuration.java | 9 + .../java/digit/service/PlanValidator.java | 2 + .../service/workflow/WorkflowService.java | 323 +++++++++++------- .../src/main/java/digit/web/models/Plan.java | 4 + .../src/main/resources/application.properties | 3 + 5 files changed, 225 insertions(+), 116 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index e674f272c56..1576a7c0935 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -81,4 +81,13 @@ public class Configuration { @Value("${egov.workflow.transition.path}") private String wfTransitionPath; + @Value("${workflow.initiate.action}") + private List wfInitiateActions; + + @Value("${workflow.intermediate.action}") + private List wfIntermediateActions; + + @Value("${workflow.send.back.actions}") + private List wfSendBackActions; + } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 90f27d414a9..e45180a4624 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -486,6 +486,8 @@ public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planReques if(CollectionUtils.isEmpty(planEmployeeAssignmentResponse.getPlanEmployeeAssignment())) throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_CODE, PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_MESSAGE + planRequest.getPlan().getLocality()); + //enrich jurisdiction of current assignee + planRequest.getPlan().setAssigneeJurisdiction(planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); } } diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index c6b279898b3..491465b37b7 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -3,11 +3,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import digit.config.Configuration; import digit.repository.ServiceRequestRepository; +import digit.service.PlanEmployeeService; import digit.util.CommonUtil; -import digit.web.models.Plan; -import digit.web.models.PlanConfiguration; -import digit.web.models.PlanConfigurationRequest; -import digit.web.models.PlanRequest; +import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.Workflow; import org.egov.common.contract.request.User; @@ -18,6 +16,7 @@ import org.springframework.util.ObjectUtils; import java.util.*; +import java.util.stream.Collectors; import static digit.config.ServiceConstants.*; @@ -33,29 +32,32 @@ public class WorkflowService { private CommonUtil commonUtil; - public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil) { - this.serviceRequestRepository = serviceRequestRepository; + private PlanEmployeeService planEmployeeService; + + public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil, PlanEmployeeService planEmployeeService) { + this.serviceRequestRepository = serviceRequestRepository; this.config = config; - this.mapper = mapper; + this.mapper = mapper; this.commonUtil = commonUtil; + this.planEmployeeService = planEmployeeService; } - /** - * Integrates with the workflow for the given plan configuration request. - * If the action is null, it does not proceed with integration. - * - * @param planConfigurationRequest The request containing the plan configuration to integrate with the workflow. - */ - public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigurationRequest) { - if (ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow())) - return; + /** + * Integrates with the workflow for the given plan configuration request. + * If the action is null, it does not proceed with integration. + * + * @param planConfigurationRequest The request containing the plan configuration to integrate with the workflow. + */ + public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigurationRequest) { + if (ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow())) + return; - ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planConfigurationRequest); - ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planConfigurationRequest); + ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); - // Setting the status back to the plan configuration object from workflow response - planConfigurationRequest.getPlanConfiguration().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); - } + // Setting the status back to the plan configuration object from workflow response + planConfigurationRequest.getPlanConfiguration().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); + } /** * Integrates with the workflow for the given plan request. @@ -67,107 +69,196 @@ public void invokeWorkflowForStatusUpdate(PlanRequest planRequest) { if (ObjectUtils.isEmpty(planRequest.getPlan().getWorkflow())) return; - ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planRequest); - ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planRequest); + ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); - // Setting the status back to the plan configuration object from workflow response - planRequest.getPlan().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); - } + // Setting the status back to the plan configuration object from workflow response + planRequest.getPlan().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); + } - /** - * Calls the workflow transition service and retrieves the process instance response. - * - * @param processInstanceRequest The request containing process instance details for the workflow transition. - * @return The response containing details of the process instances after the transition. - * @throws CustomException if there is an error during the workflow integration. - */ - public ProcessInstanceResponse callWorkflowTransition(ProcessInstanceRequest processInstanceRequest) { - ProcessInstanceResponse processInstanceResponse; - try { - Object response = serviceRequestRepository.fetchResult(getWorkflowTransitionUri(), processInstanceRequest); - processInstanceResponse = mapper.convertValue(response, ProcessInstanceResponse.class); - } catch (Exception e) { - throw new CustomException(WORKFLOW_INTEGRATION_ERROR_CODE, WORKFLOW_INTEGRATION_ERROR_MESSAGE + e.getMessage()); - } - - return processInstanceResponse; - } + /** + * Calls the workflow transition service and retrieves the process instance response. + * + * @param processInstanceRequest The request containing process instance details for the workflow transition. + * @return The response containing details of the process instances after the transition. + * @throws CustomException if there is an error during the workflow integration. + */ + public ProcessInstanceResponse callWorkflowTransition(ProcessInstanceRequest processInstanceRequest) { + ProcessInstanceResponse processInstanceResponse; + try { + Object response = serviceRequestRepository.fetchResult(getWorkflowTransitionUri(), processInstanceRequest); + processInstanceResponse = mapper.convertValue(response, ProcessInstanceResponse.class); + } catch (Exception e) { + throw new CustomException(WORKFLOW_INTEGRATION_ERROR_CODE, WORKFLOW_INTEGRATION_ERROR_MESSAGE + e.getMessage()); + } - /** - * Creates a workflow request from the given plan configuration request. - * - * @param planConfigurationRequest The request containing the plan configuration to create a workflow request. - * @return The constructed process instance request for the workflow. - */ - public ProcessInstanceRequest createWorkflowRequest(PlanConfigurationRequest planConfigurationRequest) { - PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); - ProcessInstance processInstance = ProcessInstance.builder() - .businessId(planConfig.getId()) - .tenantId(planConfig.getTenantId()) - .businessService(PLAN_CONFIGURATION_BUSINESS_SERVICE) - .moduleName(MODULE_NAME_VALUE) - .action(planConfig.getWorkflow().getAction()) - .comment(planConfig.getWorkflow().getComments()) - .documents(planConfig.getWorkflow().getDocuments()) - .build(); - - enrichAssignesInWorkflow(processInstance, planConfig.getWorkflow()); - - return ProcessInstanceRequest.builder() - .requestInfo(planConfigurationRequest.getRequestInfo()) - .processInstances(Collections.singletonList(processInstance)) - .build(); - } + return processInstanceResponse; + } - /** - * Creates a workflow request from the given plan configuration request. - * - * @param planRequest The request containing the plan to create a workflow request. - * @return The constructed process instance request for the workflow. - */ - public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { - Plan plan = planRequest.getPlan(); - ProcessInstance processInstance = ProcessInstance.builder() - .businessId(plan.getId()) - .tenantId(plan.getTenantId()) - .businessService(PLAN_ESTIMATION_BUSINESS_SERVICE) - .moduleName(MODULE_NAME_VALUE) - .action(plan.getWorkflow().getAction()) - .comment(plan.getWorkflow().getComments()) - .documents(plan.getWorkflow().getDocuments()) - .build(); - - enrichAssignesInWorkflow(processInstance, plan.getWorkflow()); - - return ProcessInstanceRequest.builder() - .requestInfo(planRequest.getRequestInfo()) - .processInstances(Collections.singletonList(processInstance)) - .build(); - } + /** + * Creates a workflow request from the given plan configuration request. + * + * @param planConfigurationRequest The request containing the plan configuration to create a workflow request. + * @return The constructed process instance request for the workflow. + */ + public ProcessInstanceRequest createWorkflowRequest(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + ProcessInstance processInstance = ProcessInstance.builder() + .businessId(planConfig.getId()) + .tenantId(planConfig.getTenantId()) + .businessService(PLAN_CONFIGURATION_BUSINESS_SERVICE) + .moduleName(MODULE_NAME_VALUE) + .action(planConfig.getWorkflow().getAction()) + .comment(planConfig.getWorkflow().getComments()) + .documents(planConfig.getWorkflow().getDocuments()) + .build(); - /** - * Enriches the process instance with assignees from the given workflow. - * - * @param processInstance The process instance to enrich with assignees. - * @param workflow The workflow containing assignees to be added to the process instance. - */ - public void enrichAssignesInWorkflow(ProcessInstance processInstance, Workflow workflow) { - List userList = CollectionUtils.isEmpty(workflow.getAssignes()) - ? new LinkedList<>() - : workflow.getAssignes().stream() - .map(assignee -> User.builder().uuid(assignee).build()) - .toList(); + enrichAssignesInProcessInstance(processInstance, planConfig.getWorkflow()); - processInstance.setAssignes(userList); - } + return ProcessInstanceRequest.builder() + .requestInfo(planConfigurationRequest.getRequestInfo()) + .processInstances(Collections.singletonList(processInstance)) + .build(); + } - /** - * Constructs the URI for the workflow service transition API. - * - * @return The StringBuilder containing the constructed workflow transition URI. - */ - private StringBuilder getWorkflowTransitionUri() { - return new StringBuilder().append(config.getWfHost()).append(config.getWfTransitionPath()); - } + /** + * Creates a workflow request from the given plan configuration request. + * + * @param planRequest The request containing the plan to create a workflow request. + * @return The constructed process instance request for the workflow. + */ + public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { + Plan plan = planRequest.getPlan(); + ProcessInstance processInstance = ProcessInstance.builder() + .businessId(plan.getId()) + .tenantId(plan.getTenantId()) + .businessService(PLAN_ESTIMATION_BUSINESS_SERVICE) + .moduleName(MODULE_NAME_VALUE) + .action(plan.getWorkflow().getAction()) + .comment(plan.getWorkflow().getComments()) + .documents(plan.getWorkflow().getDocuments()) + .build(); + + autoAssignAssignee(plan.getWorkflow(), planRequest); + enrichAssignesInProcessInstance(processInstance, plan.getWorkflow()); + + return ProcessInstanceRequest.builder() + .requestInfo(planRequest.getRequestInfo()) + .processInstances(Collections.singletonList(processInstance)) + .build(); + } + + /** + * Enriches the process instance with assignees from the given workflow. + * + * @param processInstance The process instance to enrich with assignees. + * @param workflow The workflow containing assignees to be added to the process instance. + */ + public void enrichAssignesInProcessInstance(ProcessInstance processInstance, Workflow workflow) { + List userList = CollectionUtils.isEmpty(workflow.getAssignes()) + ? new LinkedList<>() + : workflow.getAssignes().stream() + .map(assignee -> User.builder().uuid(assignee).build()) + .toList(); + + processInstance.setAssignes(userList); + } + + /** + * Constructs the URI for the workflow service transition API. + * + * @return The StringBuilder containing the constructed workflow transition URI. + */ + private StringBuilder getWorkflowTransitionUri() { + return new StringBuilder().append(config.getWfHost()).append(config.getWfTransitionPath()); + } + + /** + * Automatically assigns an assignee based on the workflow action and jurisdiction hierarchy. + * Retrieves jurisdiction boundaries from the plan request and searches for matching employee assignments. + * + * For INITIATE actions, assigns the employee from the lowest boundary. + * For INTERMEDIATE actions (non-ROOT_APPROVER), assigns an employee from a higher-level boundary. + * For SEND_BACK actions, assigns the last modified user. + * + * The assignee is set in both the workflow and the plan request. + * + * @param workflow the workflow object to set the assignee + * @param planRequest the plan request containing workflow and jurisdiction details + */ + private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { + String[] allheirarchysBoundaryCodes = planRequest.getPlan().getBoundaryAncestralPath().split("//|"); + String[] heirarchysBoundaryCodes = Arrays.copyOf(allheirarchysBoundaryCodes, allheirarchysBoundaryCodes.length - 1); + + PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = + PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(planRequest.getPlan().getTenantId()) + .jurisdiction(Arrays.stream(heirarchysBoundaryCodes).toList()) + .planConfigurationId(planRequest.getPlan().getPlanConfigurationId()) + .role(config.getPlanEstimationApproverRoles()) + .build(); + + //search for plan-employee assignments for the ancestral heirarchy codes. + PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeService.search(PlanEmployeeAssignmentSearchRequest.builder() + .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) + .requestInfo(planRequest.getRequestInfo()).build()); + + // Create a map of jurisdiction to employeeId + Map jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() + .filter(assignment -> assignment.getJurisdiction() != null && !assignment.getJurisdiction().isEmpty()) + .flatMap(assignment -> { + String employeeId = assignment.getEmployeeId(); + return assignment.getJurisdiction().stream() + .filter(jurisdiction -> Arrays.asList(heirarchysBoundaryCodes).contains(jurisdiction)) + .map(jurisdiction -> new AbstractMap.SimpleEntry<>(jurisdiction, employeeId)); + }) + .collect(Collectors.toMap( + Map.Entry::getKey, // jurisdiction as the key + Map.Entry::getValue, // employeeId as the value + (existing, replacement) -> existing, // Keep the first employeeId for duplicates + LinkedHashMap::new // Ensure insertion order is preserved + )); + + String assignee = null; //assignee will remain null in case terminate actions are being taken + int length = heirarchysBoundaryCodes.length; + + String action = planRequest.getPlan().getWorkflow().getAction(); + if (config.getWfInitiateActions().contains(action)) { + if (length - 1 >= 0) + assignee = jurisdictionToEmployeeMap.get(heirarchysBoundaryCodes[length - 1]); + } else if (config.getWfIntermediateActions().contains(action)) { + if (!planRequest.getRequestInfo().getUserInfo().getRoles().contains("ROOT_ESTIMATION_APPROVER")) + assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, planRequest, jurisdictionToEmployeeMap); + } else if (config.getWfSendBackActions().contains(action)) { + assignee = planRequest.getPlan().getAuditDetails().getLastModifiedBy(); + } + + workflow.setAssignes(Collections.singletonList(assignee)); + planRequest.getPlan().setAssignee(assignee); + } + + public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, PlanRequest planRequest, Map jurisdictionToEmployeeMap) { + for (int i = heirarchysBoundaryCodes.length - 2; i >= 0; i--) { + String boundaryCode = heirarchysBoundaryCodes[i]; + + // Check if this boundary code is present in assigneeJurisdiction + if (planRequest.getPlan().getAssigneeJurisdiction().contains(boundaryCode)) { + + if (i - 1 >= 0) { + // Check the next higher level in the hierarchy (one index above the match) + String higherBoundaryCode = heirarchysBoundaryCodes[i - 1]; + + // Fetch the employeeId from the map for the higher boundary code + String employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); + + // If an employee is found, set them as the assignee and break the loop + if (employeeId != null) { + return employeeId; + } + } + } + } + return null; + } } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index a97d0c752df..59d3cc2973a 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Plan.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Plan.java @@ -1,5 +1,6 @@ package digit.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; @@ -74,6 +75,9 @@ public class Plan { @NotNull private String boundaryAncestralPath = null; + @JsonIgnore + private List assigneeJurisdiction; + @JsonProperty("workflow") @Valid private Workflow workflow; diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index e029d9dc50e..8988b7e2836 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -68,6 +68,9 @@ egov.user.search.endpoint=/user/_search # Workflow egov.workflow.host=https://unified-dev.digit.org egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition +workflow.initiate.action=INITIATE +workflow.intermediate.action=EDIT_AND_SEND_FOR_APPROVAL,APPROVE +workflow.send.back.actions=SEND_BACK_FOR_CORRECTION # Pagination config plan.default.offset=0 From bf9f2f6594430ca7775983fc8fac876cd9d59439 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 16 Oct 2024 17:03:54 +0530 Subject: [PATCH 164/351] total count enrichment --- .../repository/PlanFacilityRepository.java | 2 ++ .../impl/PlanFacilityRepositoryImpl.java | 15 +++++++++++ .../PlanFacilityQueryBuilder.java | 27 ++++++++++++++++--- .../validator/PlanFacilityValidator.java | 5 +++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java index 875392dab40..ce94f569086 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java @@ -10,4 +10,6 @@ public interface PlanFacilityRepository { public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria); void update(PlanFacilityRequest planFacilityRequest); + + public Integer count(PlanFacilitySearchCriteria planFacilitySearchCriteria); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 08a01b0e513..3608a612010 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -114,6 +114,21 @@ public void update(PlanFacilityRequest planFacilityRequest) { } } + /** + * Counts the number of plan facilities based on the provided search criteria. + * + * @param planFacilitySearchCriteria The search criteria for filtering plan facilities. + * @return The total count of plan facilities matching the search criteria. + */ + @Override + public Integer count(PlanFacilitySearchCriteria planFacilitySearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = planFacilityQueryBuilder.getPlanFacilityCountQuery(planFacilitySearchCriteria, preparedStmtList); + Integer count = jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); + + return count; + } + /** * Helper method to query database for plan facilities based on the provided search criteria. * diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index cc23ad23836..743cb1cc9d2 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -39,14 +39,28 @@ public PlanFacilityQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE = " order by plan_facility_linkage.last_modified_time desc "; + private static final String PLAN_FACILITY_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + public String getPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { - String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); + String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE); query = getPaginatedQuery(query, planFacilitySearchCriteria, preparedStmtList); return query; } - private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { + /** + * Constructs the count query to get the total count of plan facilities based on search criteria. + * + * @param planFacilitySearchCriteria The criteria used for filtering PlanFacility objects. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A SQL query string to get the total count of plan facilities. + */ + public String getPlanFacilityCountQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { + String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList, Boolean.TRUE); + return query; + } + + private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList, boolean isCount) { StringBuilder builder = new StringBuilder(PLAN_FACILITY_QUERY); if (!CollectionUtils.isEmpty(planFacilitySearchCriteria.getIds())) { @@ -75,6 +89,14 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(residingBoundaries)); } + StringBuilder countQuery = new StringBuilder(); + if (isCount) { + countQuery.append(PLAN_FACILITY_SEARCH_QUERY_COUNT_WRAPPER).append(builder); + countQuery.append(") AS subquery"); + + return countQuery.toString(); + } + return builder.toString(); } @@ -91,5 +113,4 @@ private String getPaginatedQuery(String query, PlanFacilitySearchCriteria planFa return paginatedQuery.toString(); } - } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 408905f038c..fcfa8cafdcc 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -15,9 +15,12 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; + import static digit.config.ServiceConstants.*; + import java.util.*; import java.util.stream.Collectors; + import digit.web.models.projectFactory.Boundary; @Component @@ -212,7 +215,7 @@ public List fetchPlanConfigurationById(String planConfigurati .id(planConfigurationId) .tenantId(tenantId) .build()); - log.info("planConfigurations: "+planConfigurations); + log.info("planConfigurations: " + planConfigurations); // Validate planConfiguration exists if (CollectionUtils.isEmpty(planConfigurations)) { From 0d1c97475cadce69e59aa3c68f462fda60cb11dd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 16 Oct 2024 17:46:34 +0530 Subject: [PATCH 165/351] changed role from String to list in planEmployeeSearchCriteria --- .../PlanEmployeeAssignmentQueryBuilder.java | 7 ++++--- .../PlanEmployeeAssignmentValidator.java | 6 +++--- .../src/main/java/digit/util/CommonUtil.java | 2 +- .../src/main/java/digit/util/MdmsUtil.java | 19 ++----------------- .../PlanEmployeeAssignmentSearchCriteria.java | 3 +-- 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 2f1809b3da1..e9c940d0f3b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -6,6 +6,7 @@ import org.springframework.util.CollectionUtils; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; @Component @@ -85,10 +86,10 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit preparedStmtList.add(searchCriteria.getEmployeeId()); } - if (searchCriteria.getRole() != null) { + if (!CollectionUtils.isEmpty(searchCriteria.getRole())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" role = ?"); - preparedStmtList.add(searchCriteria.getRole()); + builder.append(" role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getRole())); } if (searchCriteria.getActive() != null) { diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 9d239356f3f..2807685751c 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -111,7 +111,7 @@ private void validateDuplicateRecord(PlanEmployeeAssignmentRequest request) { .tenantId(employeeAssignment.getTenantId()) .planConfigurationId(employeeAssignment.getPlanConfigurationId()) .employeeId(employeeAssignment.getEmployeeId()) - .role(employeeAssignment.getRole()) + .role(Collections.singletonList(employeeAssignment.getRole())) .build()); if (!CollectionUtils.isEmpty(planEmployeeAssignmentsFromSearch)) { @@ -169,7 +169,7 @@ private void validateRoleConflict(PlanEmployeeAssignment planEmployeeAssignment) .tenantId(planEmployeeAssignment.getTenantId()) .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) .employeeId(planEmployeeAssignment.getEmployeeId()) - .role(roleMap.get(planEmployeeAssignment.getRole())).build()); + .role(Collections.singletonList(roleMap.get(planEmployeeAssignment.getRole()))).build()); // If there are any conflicting assignments found, throw a custom exception if (!CollectionUtils.isEmpty(response)) { @@ -329,7 +329,7 @@ private void validatePlanEmployeeAssignmentExistance(PlanEmployeeAssignment plan List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() .tenantId(planEmployeeAssignment.getTenantId()) .id(planEmployeeAssignment.getId()) - .role(planEmployeeAssignment.getRole()) + .role(Collections.singletonList(planEmployeeAssignment.getRole())) .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) .employeeId(planEmployeeAssignment.getEmployeeId()) .build()); diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 84c8eacbf26..1862b251dcb 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -154,7 +154,7 @@ public List searchPlanConfigId(String planConfigId, String te */ public Map getMicroplanHierarchy(Object mdmsData) { - String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; + String jsonPathForMicroplanHierarchy = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + HIERARCHY_CONFIG_FOR_MICROPLAN; List> hierarchyForMicroplan; diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java index e9b87d3d5df..cdb0486c4f6 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsUtil.java @@ -67,32 +67,15 @@ public Object fetchMdmsData(RequestInfo requestInfo, String tenantId) { public MdmsCriteriaReq getMdmsRequest(RequestInfo requestInfo, String tenantId) { ModuleDetail assumptionModuleDetail = getPlanModuleDetail(); - ModuleDetail adminConsoleModuleDetail = getAdminConsoleModuleDetail(); List moduleDetails = new LinkedList<>(); moduleDetails.add(assumptionModuleDetail); - moduleDetails.add(adminConsoleModuleDetail); MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId).build(); return MdmsCriteriaReq.builder().mdmsCriteria(mdmsCriteria).requestInfo(requestInfo).build(); } - /** - * This method constructs module detail object for 'HCM-ADMIN-CONSOLE' module - * - * @return Returns the module details for 'HCM-ADMIN-CONSOLE' module - */ - private ModuleDetail getAdminConsoleModuleDetail() { - List adminConsoleMasterDetails = new ArrayList<>(); - - MasterDetail hierarchyConfig = MasterDetail.builder().name(MDMS_MASTER_HIERARCHY_CONFIG).build(); - - adminConsoleMasterDetails.add(hierarchyConfig); - - return ModuleDetail.builder().masterDetails(adminConsoleMasterDetails).moduleName(MDMS_ADMIN_CONSOLE_MODULE_NAME).build(); - } - /** * This method constructs module detail object for 'hcm-microplanning' module * @@ -108,6 +91,7 @@ private ModuleDetail getPlanModuleDetail() { MasterDetail metricDetails = MasterDetail.builder().name(MDMS_MASTER_METRIC).build(); MasterDetail unitDetails = MasterDetail.builder().name(MDMS_MASTER_UOM).build(); MasterDetail namingRegexDetails = MasterDetail.builder().name(MDMS_MASTER_NAME_VALIDATION).build(); + MasterDetail hierarchyConfig = MasterDetail.builder().name(MDMS_MASTER_HIERARCHY_CONFIG).build(); assumptionMasterDetails.add(assumptionMasterDetail); assumptionMasterDetails.add(uploadConfigMasterDetail); @@ -116,6 +100,7 @@ private ModuleDetail getPlanModuleDetail() { assumptionMasterDetails.add(metricDetails); assumptionMasterDetails.add(unitDetails); assumptionMasterDetails.add(namingRegexDetails); + assumptionMasterDetails.add(hierarchyConfig); return ModuleDetail.builder().masterDetails(assumptionMasterDetails).moduleName(MDMS_PLAN_MODULE_NAME).build(); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 77aee5eac24..86e886e56c6 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -37,8 +37,7 @@ public class PlanEmployeeAssignmentSearchCriteria { private String planConfigurationId = null; @JsonProperty("role") - @Size(min = 2, max = 64) - private String role = null; + private List role = null; @JsonProperty("jurisdiction") @Valid From 2584675e651d0ff7d6df692aa68ecdfe23d0968d Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 16 Oct 2024 18:17:24 +0530 Subject: [PATCH 166/351] added total count in response pojo --- .../src/main/java/digit/service/PlanFacilityService.java | 1 + .../src/main/java/digit/web/models/PlanFacilityResponse.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index b393a4946a8..681564b40ed 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -76,6 +76,7 @@ else if (planFacilitySearchRequest.getPlanFacilitySearchCriteria().getPlanConfig return PlanFacilityResponse.builder() .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(planFacilitySearchRequest.getRequestInfo(), Boolean.TRUE)) .planFacility(planFacilityList) + .totalCount(planFacilityRepository.count(planFacilitySearchRequest.getPlanFacilitySearchCriteria())) .build(); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java index e2ca983a8a8..1ac3db052c6 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java @@ -26,4 +26,8 @@ public class PlanFacilityResponse { @JsonProperty("PlanFacility") @Valid private List planFacility = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; } From 0fd62e72261d2f793d606d46770cfffbb3fe0f97 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 11:26:51 +0530 Subject: [PATCH 167/351] added partnerAssignmentValidationEnabled in census pojo --- .../digit/service/validator/CensusValidator.java | 14 +++++++------- .../src/main/java/digit/web/models/Census.java | 3 +++ .../src/main/java/digit/web/models/CensusDTO.java | 4 ++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 1ead86865e5..4549516b808 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -53,13 +53,12 @@ public CensusValidator(BoundaryUtil boundaryUtil, PlanEmployeeAssignmnetUtil emp public void validateCreate(CensusRequest request) { Census census = request.getCensus(); BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), census.getBoundaryCode(), census.getTenantId(), census.getHierarchyType(), Boolean.TRUE, Boolean.FALSE); - boolean flag = true; // Validate boundary code against boundary service validateBoundaryCode(boundarySearchResponse, census); // Validate partner assignment and jurisdiction against plan service - validatePartnerForCensus(request, flag); + validatePartnerForCensus(request); } /** @@ -84,16 +83,17 @@ private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, * Also validates the user information within the provided CensusRequest. * * @param request the census request - * @param flag Validates only when flag is true */ - private void validatePartnerForCensus(CensusRequest request, boolean flag) { + private void validatePartnerForCensus(CensusRequest request) { + + Census census = request.getCensus(); // Validate the user information in the request if (ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) { throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); } - if (!flag) { + if (census.isPartnerAssignmentValidationEnabled()) { User userInfo = request.getRequestInfo().getUserInfo(); List jurisdiction = Arrays.asList(request.getCensus().getBoundaryAncestralPath().get(0).split("\\|")); PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(request.getRequestInfo(), userInfo.getUuid(), request.getCensus().getSource(), request.getCensus().getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); @@ -125,13 +125,13 @@ public void validateSearch(CensusSearchRequest request) { * @param request the update request for Census. */ public void validateUpdate(CensusRequest request) { - boolean flag = true; // Validate if Census record to be updated exists Census census = validateCensusExistence(request); + request.setCensus(census); // Validate partner assignment and jurisdiction against plan service - validatePartnerForCensus(CensusRequest.builder().requestInfo(request.getRequestInfo()).census(census).build(), flag); + validatePartnerForCensus(request); } /** diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 7f409efd822..27f2738a346 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -79,6 +79,9 @@ public class Census { @JsonIgnore private List boundaryAncestralPath = null; + @JsonIgnore + private boolean partnerAssignmentValidationEnabled; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 730c5299408..a8f7fc350a1 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -1,5 +1,6 @@ package digit.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; @@ -75,6 +76,9 @@ public class CensusDTO { @JsonProperty("boundaryAncestralPath") private String boundaryAncestralPath = null; + @JsonIgnore + private boolean partnerAssignmentValidationEnabled; + @JsonProperty("additionalDetails") private Object additionalDetails = null; From 500b8b3d2e03d6f8d9f419d900bd3f02943fcc12 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 12:20:41 +0530 Subject: [PATCH 168/351] Adding census-service in build-config --- build/build-config.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build/build-config.yml b/build/build-config.yml index dec24965782..c6deba9aff5 100644 --- a/build/build-config.yml +++ b/build/build-config.yml @@ -259,7 +259,13 @@ config: build: - work-dir: "analytics/auth-proxy" image-name: "auth-proxy" - + - name: "builds/health-campaign-services/health-services/census-service" + build: + - work-dir: "health-services/census-service" + image-name: "census-service" + dockerfile: "build/17/maven/Dockerfile" + - work-dir: "health-services/census-service/src/main/resources/db" + image-name: "census-service-db" # frontend - name: builds/health-campaign-services/frontend/workbench-ui build: From 91b8cf3c0e92008dff37f0ae99c98d0c2e9ddb1b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 12:22:10 +0530 Subject: [PATCH 169/351] Adding census-service in build-config --- build/build-config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/build-config.yml b/build/build-config.yml index c6deba9aff5..cafec0ff43c 100644 --- a/build/build-config.yml +++ b/build/build-config.yml @@ -266,6 +266,7 @@ config: dockerfile: "build/17/maven/Dockerfile" - work-dir: "health-services/census-service/src/main/resources/db" image-name: "census-service-db" + # frontend - name: builds/health-campaign-services/frontend/workbench-ui build: From 89670ff1397d32f7816d554b52a5ec0141adf784 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 14:09:12 +0530 Subject: [PATCH 170/351] added censusControllerTest --- .../web/controllers/CensusControllerTest.java | 69 +++++++++++++++++++ .../controllers/CreateApiControllerTest.java | 53 -------------- .../controllers/SearchApiControllerTest.java | 53 -------------- .../controllers/UpdateApiControllerTest.java | 53 -------------- 4 files changed, 69 insertions(+), 159 deletions(-) create mode 100644 health-services/census-service/src/test/java/digit/web/controllers/CensusControllerTest.java delete mode 100644 health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java delete mode 100644 health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java delete mode 100644 health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java diff --git a/health-services/census-service/src/test/java/digit/web/controllers/CensusControllerTest.java b/health-services/census-service/src/test/java/digit/web/controllers/CensusControllerTest.java new file mode 100644 index 00000000000..df3d8c23267 --- /dev/null +++ b/health-services/census-service/src/test/java/digit/web/controllers/CensusControllerTest.java @@ -0,0 +1,69 @@ +package digit.web.controllers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.service.CensusService; +import digit.web.models.CensusRequest; +import digit.web.models.CensusSearchRequest; +import org.junit.Test; +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.context.annotation.Import; +import org.springframework.http.MediaType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import digit.TestConfiguration; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * API tests for CensusApiController + */ +@Ignore +@RunWith(SpringRunner.class) +@WebMvcTest(CensusController.class) +@Import(TestConfiguration.class) +public class CensusControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private JdbcTemplate jdbcTemplate; + + @MockBean + private CensusService service; + + @Autowired + private ObjectMapper objectMapper; + + + @Test + public void censusCreatePostSuccess() throws Exception { + CensusRequest request = CensusRequest.builder().build(); + mockMvc.perform(post("/_create").contentType(MediaType + .APPLICATION_JSON_UTF8).content(objectMapper.writeValueAsString(request))) + .andExpect(status().isAccepted()); + } + + @Test + public void censusSearchPostSuccess() throws Exception { + CensusSearchRequest request = CensusSearchRequest.builder().build(); + mockMvc.perform(post("/_search").contentType(MediaType + .APPLICATION_JSON_UTF8).content(objectMapper.writeValueAsString(request))) + .andExpect(status().isOk()); + } + + @Test + public void censusUpdatePostSuccess() throws Exception { + CensusRequest request = CensusRequest.builder().build(); + mockMvc.perform(post("/_update").contentType(MediaType + .APPLICATION_JSON_UTF8).content(objectMapper.writeValueAsString(request))) + .andExpect(status().isAccepted()); + } + +} diff --git a/health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java b/health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java deleted file mode 100644 index d65b8f5d44e..00000000000 --- a/health-services/census-service/src/test/java/digit/web/controllers/CreateApiControllerTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package digit.web.controllers; - -import digit.web.models.CensusRequest; -import digit.web.models.CensusResponse; -import digit.web.models.ErrorRes; -import org.junit.Test; -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import digit.TestConfiguration; - - import java.util.ArrayList; - import java.util.HashMap; - import java.util.List; - import java.util.Map; - -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** -* API tests for CreateApiController -*/ -@Ignore -@RunWith(SpringRunner.class) -@WebMvcTest(CreateApiController.class) -@Import(TestConfiguration.class) -public class CreateApiControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Test - public void createPostSuccess() throws Exception { - mockMvc.perform(post("/_create").contentType(MediaType - .APPLICATION_JSON_UTF8)) - .andExpect(status().isOk()); - } - - @Test - public void createPostFailure() throws Exception { - mockMvc.perform(post("/_create").contentType(MediaType - .APPLICATION_JSON_UTF8)) - .andExpect(status().isBadRequest()); - } - -} diff --git a/health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java b/health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java deleted file mode 100644 index 87ec62ea284..00000000000 --- a/health-services/census-service/src/test/java/digit/web/controllers/SearchApiControllerTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package digit.web.controllers; - -import digit.web.models.CensusResponse; -import digit.web.models.CensusSearchRequest; -import digit.web.models.ErrorRes; -import org.junit.Test; -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import digit.TestConfiguration; - - import java.util.ArrayList; - import java.util.HashMap; - import java.util.List; - import java.util.Map; - -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** -* API tests for SearchApiController -*/ -@Ignore -@RunWith(SpringRunner.class) -@WebMvcTest(SearchApiController.class) -@Import(TestConfiguration.class) -public class SearchApiControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Test - public void searchPostSuccess() throws Exception { - mockMvc.perform(post("/_search").contentType(MediaType - .APPLICATION_JSON_UTF8)) - .andExpect(status().isOk()); - } - - @Test - public void searchPostFailure() throws Exception { - mockMvc.perform(post("/_search").contentType(MediaType - .APPLICATION_JSON_UTF8)) - .andExpect(status().isBadRequest()); - } - -} diff --git a/health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java b/health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java deleted file mode 100644 index 811169a1837..00000000000 --- a/health-services/census-service/src/test/java/digit/web/controllers/UpdateApiControllerTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package digit.web.controllers; - -import digit.web.models.CensusRequest; -import digit.web.models.CensusResponse; -import digit.web.models.ErrorRes; -import org.junit.Test; -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import digit.TestConfiguration; - - import java.util.ArrayList; - import java.util.HashMap; - import java.util.List; - import java.util.Map; - -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** -* API tests for UpdateApiController -*/ -@Ignore -@RunWith(SpringRunner.class) -@WebMvcTest(UpdateApiController.class) -@Import(TestConfiguration.class) -public class UpdateApiControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Test - public void updatePostSuccess() throws Exception { - mockMvc.perform(post("/_update").contentType(MediaType - .APPLICATION_JSON_UTF8)) - .andExpect(status().isOk()); - } - - @Test - public void updatePostFailure() throws Exception { - mockMvc.perform(post("/_update").contentType(MediaType - .APPLICATION_JSON_UTF8)) - .andExpect(status().isBadRequest()); - } - -} From d3834cec724dccdad5c78e39372cbbc458c5cd6d Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 14:30:40 +0530 Subject: [PATCH 171/351] changed status from string to list --- .../repository/querybuilder/PlanConfigQueryBuilder.java | 6 +++--- .../digit/web/models/PlanConfigurationSearchCriteria.java | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 608e0257def..6df15346161 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -115,10 +115,10 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter preparedStmtList.add(criteria.getName() + PERCENTAGE_WILDCARD); } - if (criteria.getStatus() != null) { + if (!CollectionUtils.isEmpty(criteria.getStatus())) { addClauseIfRequired(preparedStmtList, builder); - builder.append(" pc.status = ?"); - preparedStmtList.add(criteria.getStatus()); + builder.append(" pc.status IN ( ").append(queryUtil.createQuery(criteria.getStatus().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(criteria.getStatus())); } if (criteria.getUserUuid() != null) { diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java index 2f9f3cd7831..83000157f5f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java @@ -11,6 +11,8 @@ import lombok.Data; import lombok.Builder; +import java.util.List; + /** * PlanConfigurationSearchCriteria */ @@ -36,7 +38,7 @@ public class PlanConfigurationSearchCriteria { private String campaignId = null; @JsonProperty("status") - private String status = null; + private List status = null; @JsonProperty("userUuid") private String userUuid = null; From fc3eb1d329a6aa56e502306cdc88a3f478e475e5 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 15:06:59 +0530 Subject: [PATCH 172/351] added dockerfile --- .../src/main/resources/Dockerfile | 20 ------------------- .../src/main/resources/db/Dockerfile | 9 +++++++++ .../src/main/resources/db/migrate.sh | 3 +++ 3 files changed, 12 insertions(+), 20 deletions(-) delete mode 100644 health-services/census-service/src/main/resources/Dockerfile create mode 100644 health-services/census-service/src/main/resources/db/Dockerfile create mode 100644 health-services/census-service/src/main/resources/db/migrate.sh diff --git a/health-services/census-service/src/main/resources/Dockerfile b/health-services/census-service/src/main/resources/Dockerfile deleted file mode 100644 index 910b6c12e4a..00000000000 --- a/health-services/census-service/src/main/resources/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -#FROM egovio/alpine-maven-builder-jdk-8:1-master-NA-6036091e AS build -FROM egovio/amazoncorretto:17-alpine3.19 AS build -ARG WORK_DIR -WORKDIR /app -# Install Maven -RUN apk add --no-cache maven -# copy the project files -COPY ${WORK_DIR}/pom.xml ./pom.xml -COPY build/maven/start.sh ./start.sh -# not useful for stateless builds -# RUN mvn -B dependency:go-offline -COPY ${WORK_DIR}/src ./src -RUN mvn -B -f /app/pom.xml package -# Create runtime image -#FROM egovio/8-openjdk-alpine -FROM egovio/amazoncorretto:17-alpine3.19 -WORKDIR /opt/egov -COPY --from=build /app/target/*.jar /app/start.sh /opt/egov/ -RUN chmod +x /opt/egov/start.sh -CMD ["/opt/egov/start.sh"] \ No newline at end of file diff --git a/health-services/census-service/src/main/resources/db/Dockerfile b/health-services/census-service/src/main/resources/db/Dockerfile new file mode 100644 index 00000000000..f38638a269f --- /dev/null +++ b/health-services/census-service/src/main/resources/db/Dockerfile @@ -0,0 +1,9 @@ +FROM egovio/flyway:10.7.1 + +COPY ./migration/main /flyway/sql + +COPY migrate.sh /usr/bin/migrate.sh + +RUN chmod +x /usr/bin/migrate.sh + +ENTRYPOINT ["/usr/bin/migrate.sh"] diff --git a/health-services/census-service/src/main/resources/db/migrate.sh b/health-services/census-service/src/main/resources/db/migrate.sh new file mode 100644 index 00000000000..c58d6f91e3f --- /dev/null +++ b/health-services/census-service/src/main/resources/db/migrate.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +flyway -url=$DB_URL -table=$SCHEMA_TABLE -user=$FLYWAY_USER -password=$FLYWAY_PASSWORD -locations=$FLYWAY_LOCATIONS -baselineOnMigrate=true -outOfOrder=true migrate \ No newline at end of file From 0ee6a03b1a824a1f8a2407d9d3c944147dc8af24 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 17 Oct 2024 16:21:26 +0530 Subject: [PATCH 173/351] HCMPRE-492 workflow integration testing fixes --- .../java/digit/config/ServiceConstants.java | 5 ++++ .../repository/ServiceRequestRepository.java | 2 +- .../java/digit/service/PlanValidator.java | 11 ++++++++ .../service/workflow/WorkflowService.java | 26 +++++++++++++------ 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index ec91c9eb97e..7fbf068f4f8 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -105,6 +105,9 @@ public class ServiceConstants { public static final String PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_FOR_BOUNDARY_NOT_FOUND"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_MESSAGE = "No plan-employee assignment found for the provided boundary - "; + public static final String JURISDICTION_NOT_FOUND_CODE = "JURISDICTION_NOT_FOUND"; + public static final String JURISDICTION_NOT_FOUND_MESSAGE = "Employee doesn't have the jurisdiction to take action for the provided locality."; + public static final String METRIC_NOT_FOUND_IN_MDMS_CODE = "METRIC_NOT_FOUND_IN_MDMS"; public static final String METRIC_NOT_FOUND_IN_MDMS_MESSAGE = "Metric key not found in MDMS"; @@ -214,6 +217,8 @@ public class ServiceConstants { public static final String DOT_REGEX = "\\."; + public static final String PIPE_REGEX = "\\|"; + public static final String FILTER_CODE = "$.*.code"; public static final String FILTER_ID = "$.*.id"; diff --git a/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java b/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java index 90256d5a131..5a724b5b219 100644 --- a/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/ServiceRequestRepository.java @@ -35,7 +35,7 @@ public Object fetchResult(StringBuilder uri, Object request) { response = restTemplate.postForObject(uri.toString(), request, Map.class); } catch (HttpClientErrorException e) { log.error(EXTERNAL_SERVICE_EXCEPTION, e); - throw new ServiceCallException(e.getResponseBodyAsString()); + throw new CustomException(EXTERNAL_SERVICE_EXCEPTION, e.getResponseBodyAsString()); } catch (Exception e) { log.error(SEARCHER_SERVICE_EXCEPTION, e); throw new CustomException(EXTERNAL_SERVICE_EXCEPTION, e.getMessage()); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index e45180a4624..9c65d090a38 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -486,8 +486,19 @@ public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planReques if(CollectionUtils.isEmpty(planEmployeeAssignmentResponse.getPlanEmployeeAssignment())) throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_CODE, PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_MESSAGE + planRequest.getPlan().getLocality()); + validateJurisdictionPresent(planRequest, planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); + //enrich jurisdiction of current assignee planRequest.getPlan().setAssigneeJurisdiction(planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); } + public void validateJurisdictionPresent(PlanRequest planRequest, List jurisdictions) { + Set boundarySet = new HashSet<>(Arrays.asList(planRequest.getPlan().getBoundaryAncestralPath().split(PIPE_REGEX))); + + // Check if any jurisdiction is present in the boundary set + if (jurisdictions.stream().noneMatch(boundarySet::contains)) + throw new CustomException(JURISDICTION_NOT_FOUND_CODE, JURISDICTION_NOT_FOUND_MESSAGE); + + } + } diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 491465b37b7..74728ed5519 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -10,6 +10,7 @@ import org.egov.common.contract.models.Workflow; import org.egov.common.contract.request.User; import org.egov.common.contract.workflow.*; +import org.egov.common.utils.AuditDetailsEnrichmentUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -74,6 +75,11 @@ public void invokeWorkflowForStatusUpdate(PlanRequest planRequest) { // Setting the status back to the plan configuration object from workflow response planRequest.getPlan().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); + + // Enrich audit details after auto assignment is complete + planRequest.getPlan().setAuditDetails(AuditDetailsEnrichmentUtil + .prepareAuditDetails( planRequest.getPlan().getAuditDetails(), planRequest.getRequestInfo(), Boolean.FALSE)); + } /** @@ -142,6 +148,7 @@ public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { autoAssignAssignee(plan.getWorkflow(), planRequest); enrichAssignesInProcessInstance(processInstance, plan.getWorkflow()); + log.info("Process Instance assignes - " + processInstance.getAssignes()); return ProcessInstanceRequest.builder() .requestInfo(planRequest.getRequestInfo()) .processInstances(Collections.singletonList(processInstance)) @@ -187,7 +194,7 @@ private StringBuilder getWorkflowTransitionUri() { * @param planRequest the plan request containing workflow and jurisdiction details */ private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { - String[] allheirarchysBoundaryCodes = planRequest.getPlan().getBoundaryAncestralPath().split("//|"); + String[] allheirarchysBoundaryCodes = planRequest.getPlan().getBoundaryAncestralPath().split(PIPE_REGEX); String[] heirarchysBoundaryCodes = Arrays.copyOf(allheirarchysBoundaryCodes, allheirarchysBoundaryCodes.length - 1); PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = @@ -220,25 +227,28 @@ private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { )); String assignee = null; //assignee will remain null in case terminate actions are being taken - int length = heirarchysBoundaryCodes.length; String action = planRequest.getPlan().getWorkflow().getAction(); if (config.getWfInitiateActions().contains(action)) { - if (length - 1 >= 0) - assignee = jurisdictionToEmployeeMap.get(heirarchysBoundaryCodes[length - 1]); + for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { + assignee = jurisdictionToEmployeeMap.get(heirarchysBoundaryCodes[i]); + if (assignee != null) + break; // Stop iterating once an assignee is found + } } else if (config.getWfIntermediateActions().contains(action)) { - if (!planRequest.getRequestInfo().getUserInfo().getRoles().contains("ROOT_ESTIMATION_APPROVER")) - assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, planRequest, jurisdictionToEmployeeMap); + assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, planRequest, jurisdictionToEmployeeMap); } else if (config.getWfSendBackActions().contains(action)) { assignee = planRequest.getPlan().getAuditDetails().getLastModifiedBy(); } - workflow.setAssignes(Collections.singletonList(assignee)); + if(!ObjectUtils.isEmpty(assignee)) + workflow.setAssignes(Collections.singletonList(assignee)); + planRequest.getPlan().setAssignee(assignee); } public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, PlanRequest planRequest, Map jurisdictionToEmployeeMap) { - for (int i = heirarchysBoundaryCodes.length - 2; i >= 0; i--) { + for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { String boundaryCode = heirarchysBoundaryCodes[i]; // Check if this boundary code is present in assigneeJurisdiction From 7f3b8e6691d25cb441df4cee53457bc5faad36b6 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 17 Oct 2024 16:24:44 +0530 Subject: [PATCH 174/351] HCMPRE-492 workflow integration testing fixes --- .../src/main/java/digit/service/PlanValidator.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 9c65d090a38..7602c8eb6d9 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -89,9 +89,6 @@ public void validatePlanCreate(PlanRequest request) { // Validate the user information in the request commonUtil.validateUserInfo(request.getRequestInfo()); - - // Validate plan-employee assignment and jurisdiction -// validatePlanEmployeeAssignmentAndJurisdiction(request); } /** From 88168346128e7ff64b35bb5d003ec523d09c05a7 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 17 Oct 2024 16:29:33 +0530 Subject: [PATCH 175/351] HCMPRE-492 workflow integration testing fixes --- .../java/digit/repository/querybuilder/PlanQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 66ffd274508..bee0c7d3f9a 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -116,7 +116,7 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< if (!CollectionUtils.isEmpty(planSearchCriteria.getJurisdiction())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" ARRAY [ ") - .append(queryUtil.createQuery(planSearchCriteria.getJurisdiction().size())) // Create placeholders (?, ?, ?...) + .append(queryUtil.createQuery(planSearchCriteria.getJurisdiction().size())) .append(" ]::text[] "); builder.append(" && string_to_array(boundary_ancestral_path, '|') "); From c958146a99d24b6897bc854b188dec452f138174 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 17 Oct 2024 17:05:48 +0530 Subject: [PATCH 176/351] HCMPRE-492 adding comments for new methods --- .../main/java/digit/service/PlanValidator.java | 15 +++++++++++++++ .../digit/service/workflow/WorkflowService.java | 12 +++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 7602c8eb6d9..27363cd6111 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -467,6 +467,13 @@ public void validateMetricDetailUnit(PlanRequest request, Object mdmsData) { } + /** + * Validates the plan's employee assignment and ensures the jurisdiction is valid based on tenant, employee, role, and plan configuration. + * If no assignment is found, throws a custom exception. + * + * @param planRequest the request containing the plan and workflow details + * @throws CustomException if no employee assignment is found or jurisdiction is invalid + */ public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planRequest) { PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = PlanEmployeeAssignmentSearchCriteria .builder() @@ -489,6 +496,14 @@ public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planReques planRequest.getPlan().setAssigneeJurisdiction(planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); } + /** + * Validates that at least one jurisdiction exists within the hierarchy's boundary codes. + * If no jurisdiction is found in the boundary set, throws a custom exception. + * + * @param planRequest the request containing the boundary ancestral path + * @param jurisdictions the list of jurisdictions to check against the boundary set + * @throws CustomException if none of the jurisdictions are present in the boundary codes + */ public void validateJurisdictionPresent(PlanRequest planRequest, List jurisdictions) { Set boundarySet = new HashSet<>(Arrays.asList(planRequest.getPlan().getBoundaryAncestralPath().split(PIPE_REGEX))); diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 74728ed5519..8c5ab64d853 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -247,7 +247,17 @@ private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { planRequest.getPlan().setAssignee(assignee); } - public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, PlanRequest planRequest, Map jurisdictionToEmployeeMap) { +/** + * Assigns an employee from a higher-level jurisdiction in the hierarchy. + * Iterates through boundary codes, checking if they match the assignee's jurisdiction. + * If a higher-level boundary has an assigned employee, returns that employee's ID. + * + * @param heirarchysBoundaryCodes boundary codes representing the hierarchy + * @param planRequest the request with plan and jurisdiction details + * @param jurisdictionToEmployeeMap map of jurisdiction codes to employee IDs + * @return the employee ID from the higher boundary, or null if + */ +public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, PlanRequest planRequest, Map jurisdictionToEmployeeMap) { for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { String boundaryCode = heirarchysBoundaryCodes[i]; From 2bdcf9e3c64d3542b9ceef3120b1d525ba78bc90 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 18:11:17 +0530 Subject: [PATCH 177/351] Added hierarchyType in planEmployeeAssignment --- .../java/digit/web/models/PlanConfigurationSearchCriteria.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java index 83000157f5f..0ae2941a63f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java @@ -51,5 +51,4 @@ public class PlanConfigurationSearchCriteria { @Min(1) @Max(50) private Integer limit; - } From 36da6fa47e70d6896535f749c4edd195186cba40 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 17 Oct 2024 19:53:21 +0530 Subject: [PATCH 178/351] HCMPRE-492 changes related to auto enrichment of ancestral materialized path and boundary validation --- .../main/java/digit/config/Configuration.java | 7 ++ .../java/digit/config/ServiceConstants.java | 5 ++ .../repository/impl/PlanRepositoryImpl.java | 44 ++++++++-- .../main/java/digit/service/PlanEnricher.java | 28 +++++- .../java/digit/service/PlanValidator.java | 42 ++++++++- .../main/java/digit/util/BoundaryUtil.java | 82 +++++++++++++++++ .../src/main/java/digit/web/models/Plan.java | 6 +- .../main/java/digit/web/models/PlanDTO.java | 87 +++++++++++++++++++ .../java/digit/web/models/PlanRequestDTO.java | 29 +++++++ .../boundary/BoundarySearchResponse.java | 42 +++++++++ .../web/models/boundary/EnrichedBoundary.java | 42 +++++++++ .../models/boundary/HierarchyRelation.java | 34 ++++++++ .../src/main/resources/application.properties | 4 + 13 files changed, 440 insertions(+), 12 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanRequestDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 1576a7c0935..ce8f09d872b 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -49,6 +49,13 @@ public class Configuration { @Value("${egov.user.search.endpoint}") private String userSearchEndPoint; + // Boundary Service + @Value("${egov.boundary.service.host}") + private String boundaryServiceHost; + + @Value("${egov.boundary.relationship.search.endpoint}") + private String boundaryRelationshipSearchEndpoint; + //Persister Topic @Value("${plan.configuration.create.topic}") private String planConfigCreateTopic; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 7fbf068f4f8..b854374469e 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -16,6 +16,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from project factory: "; + public static final String ERROR_WHILE_FETCHING_BOUNDARY_DETAILS = "Exception occurred while fetching boundary relationship from boundary service: "; + public static final String ERROR_WHILE_FETCHING_DATA_FROM_HRMS = "Exception occurred while fetching employee from hrms: "; public static final String RES_MSG_ID = "uief87324"; @@ -108,6 +110,9 @@ public class ServiceConstants { public static final String JURISDICTION_NOT_FOUND_CODE = "JURISDICTION_NOT_FOUND"; public static final String JURISDICTION_NOT_FOUND_MESSAGE = "Employee doesn't have the jurisdiction to take action for the provided locality."; + public static final String NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_CODE = "NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE"; + public static final String NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_MESSAGE = "Invalid or incorrect boundaryCode. No boundary data found."; + public static final String METRIC_NOT_FOUND_IN_MDMS_CODE = "METRIC_NOT_FOUND_IN_MDMS"; public static final String METRIC_NOT_FOUND_IN_MDMS_MESSAGE = "Metric key not found in MDMS"; diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index c6acbb55221..2908f45589f 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -5,9 +5,7 @@ import digit.repository.PlanRepository; import digit.repository.querybuilder.PlanQueryBuilder; import digit.repository.rowmapper.PlanRowMapper; -import digit.web.models.Plan; -import digit.web.models.PlanRequest; -import digit.web.models.PlanSearchCriteria; +import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SingleColumnRowMapper; @@ -47,7 +45,8 @@ public PlanRepositoryImpl(Producer producer, PlanQueryBuilder planQueryBuilder, @Override public void create(PlanRequest planRequest) { try { - producer.push(config.getPlanCreateTopic(), planRequest); + PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); + producer.push(config.getPlanCreateTopic(), planRequestDTO); } catch (Exception e) { log.info("Pushing message to topic " + config.getPlanCreateTopic() + " failed.", e); } @@ -82,7 +81,8 @@ public List search(PlanSearchCriteria planSearchCriteria) { @Override public void update(PlanRequest planRequest) { try { - producer.push(config.getPlanUpdateTopic(), planRequest); + PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); + producer.push(config.getPlanUpdateTopic(), planRequestDTO); } catch (Exception e) { log.info("Pushing message to topic " + config.getPlanUpdateTopic() + " failed.", e); } @@ -112,4 +112,38 @@ private List searchPlanByIds(List planIds) { return jdbcTemplate.query(query, planRowMapper, preparedStmtList.toArray()); } + /** + * Converts the PlanRequest to a data transfer object (DTO) + * + * @param planRequest The request to be converted to DTO + * @return a DTO for PlanRequest + */ + private PlanRequestDTO convertToPlanReqDTO(PlanRequest planRequest) { + Plan plan = planRequest.getPlan(); + + // Creating a new data transfer object (DTO) for Plan + PlanDTO planDTO = PlanDTO.builder() + .id(plan.getId()) + .tenantId(plan.getTenantId()) + .locality(plan.getLocality()) + .campaignId(plan.getCampaignId()) + .planConfigurationId(plan.getPlanConfigurationId()) + .status(plan.getStatus()) + .assignee(plan.getAssignee()) + .additionalDetails(plan.getAdditionalDetails()) + .activities(plan.getActivities()) + .resources(plan.getResources()) + .targets(plan.getTargets()) + .auditDetails(plan.getAuditDetails()) + .boundaryAncestralPath(plan.getBoundaryAncestralPath()) + .build(); + + // Returning the PlanRequestDTO + return PlanRequestDTO.builder() + .requestInfo(planRequest.getRequestInfo()) + .planDTO(planDTO) + .build(); + } + + } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java index 75d79c840a3..61d1b156d71 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java @@ -1,16 +1,16 @@ package digit.service; +import digit.web.models.Plan; import digit.web.models.PlanRequest; +import digit.web.models.boundary.EnrichedBoundary; +import digit.web.models.boundary.HierarchyRelation; import org.egov.common.utils.AuditDetailsEnrichmentUtil; import org.egov.common.utils.UUIDEnrichmentUtil; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; @Component public class PlanEnricher { @@ -106,4 +106,24 @@ public void enrichPlanUpdate(PlanRequest body) { }); } + + /** + * Enriches the boundary ancestral path for the provided boundary code in the census request. + * + * @param plan The plan record whose boundary ancestral path has to be enriched. + * @param tenantBoundary boundary relationship from the boundary service for the given boundary code. + */ + public void enrichBoundaryAncestralPath(Plan plan, HierarchyRelation tenantBoundary) { + EnrichedBoundary boundary = tenantBoundary.getBoundary().get(0); + StringBuilder boundaryAncestralPath = new StringBuilder(boundary.getCode()); + + // Iterate through the child boundary until there are no more + while (!CollectionUtils.isEmpty(boundary.getChildren())) { + boundary = boundary.getChildren().get(0); + boundaryAncestralPath.append("|").append(boundary.getCode()); + } + + // Setting the boundary ancestral path for the provided boundary + plan.setBoundaryAncestralPath(boundaryAncestralPath.toString()); + } } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 27363cd6111..88ca5a2efaf 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -4,10 +4,13 @@ import digit.config.Configuration; import digit.repository.PlanConfigurationRepository; import digit.repository.PlanRepository; +import digit.util.BoundaryUtil; import digit.util.CampaignUtil; import digit.util.CommonUtil; import digit.util.MdmsUtil; import digit.web.models.*; +import digit.web.models.boundary.BoundarySearchResponse; +import digit.web.models.boundary.HierarchyRelation; import digit.web.models.projectFactory.CampaignResponse; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; @@ -39,7 +42,11 @@ public class PlanValidator { private Configuration config; - public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeService planEmployeeService, Configuration config) { + private PlanEnricher planEnricher; + + private BoundaryUtil boundaryUtil; + + public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil, CommonUtil commonUtil, CampaignUtil campaignUtil, PlanEmployeeService planEmployeeService, Configuration config, PlanEnricher planEnricher, BoundaryUtil boundaryUtil) { this.planRepository = planRepository; this.planConfigurationRepository = planConfigurationRepository; this.mdmsUtil = mdmsUtil; @@ -48,6 +55,8 @@ public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository this.campaignUtil = campaignUtil; this.planEmployeeService = planEmployeeService; this.config = config; + this.planEnricher = planEnricher; + this.boundaryUtil = boundaryUtil; } /** @@ -59,6 +68,10 @@ public void validatePlanCreate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); + BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), request.getPlan().getLocality(), request.getPlan().getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType(), Boolean.TRUE, Boolean.FALSE); + + // Validate locality against boundary service + validateBoundaryCode(boundarySearchResponse, request.getPlan()); // Validate activities validateActivities(request); @@ -89,6 +102,10 @@ public void validatePlanCreate(PlanRequest request) { // Validate the user information in the request commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validate plan-employee assignment and jurisdiction is request is from Resource Estimation Consumer + if(request.getPlan().isRequestFromResourceEstimationConsumer()) + validatePlanEmployeeAssignmentAndJurisdiction(request); } /** @@ -288,6 +305,10 @@ public void validatePlanUpdate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); + BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), request.getPlan().getLocality(), request.getPlan().getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType(), Boolean.TRUE, Boolean.FALSE); + + // Validate locality against boundary service + validateBoundaryCode(boundarySearchResponse, request.getPlan()); // Validate activities validateActivities(request); @@ -513,4 +534,23 @@ public void validateJurisdictionPresent(PlanRequest planRequest, List ju } + /** + * Validates the boundary code provided in census request against boundary service. + * + * @param boundarySearchResponse response from the boundary service. + * @param plan Plan record whose loclality is to be validated. + */ + private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, Plan plan) { + HierarchyRelation tenantBoundary = boundarySearchResponse.getTenantBoundary().get(0); + + if (CollectionUtils.isEmpty(tenantBoundary.getBoundary())) { + throw new CustomException(NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_CODE, NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_MESSAGE); + } + + // Enrich the boundary ancestral path for the provided boundary code + if(plan.isRequestFromResourceEstimationConsumer()) + planEnricher.enrichBoundaryAncestralPath(plan, tenantBoundary); + } + + } diff --git a/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java b/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java new file mode 100644 index 00000000000..e5513928780 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java @@ -0,0 +1,82 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.RequestInfoWrapper; +import digit.web.models.boundary.BoundarySearchResponse; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; +import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_BOUNDARY_DETAILS; + + +@Slf4j +@Component +public class BoundaryUtil { + + private RestTemplate restTemplate; + + private Configuration configs; + + public BoundaryUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.configs = configs; + } + + /** + * This method fetches boundary relationships from Boundary service for the provided boundaryCode and hierarchyType. + * + * @param requestInfo request info from the request. + * @param boundaryCode boundary code from the request. + * @param tenantId tenant id from the request. + * @param hierarchyType hierarchy type from the request. + * @param includeParents is true if you want to include parent boundary. + * @param includeChildren is true if you want to include child boundary. + * @return returns the response from boundary service + */ + public BoundarySearchResponse fetchBoundaryData(RequestInfo requestInfo, String boundaryCode, String tenantId, String hierarchyType, Boolean includeParents, Boolean includeChildren) { + + // Create Boundary Relationship search uri + Map uriParameters = new HashMap<>(); + StringBuilder uri = getBoundaryRelationshipSearchUri(uriParameters, boundaryCode, tenantId, hierarchyType, includeParents, includeChildren); + + // Create request body + RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); + BoundarySearchResponse boundarySearchResponse = new BoundarySearchResponse(); + + try { + boundarySearchResponse = restTemplate.postForObject(uri.toString(), requestInfoWrapper, BoundarySearchResponse.class, uriParameters); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_BOUNDARY_DETAILS, e); + } + + return boundarySearchResponse; + } + + /** + * This method creates Boundary service uri with query parameters + * + * @param uriParameters map that stores values corresponding to the placeholder in uri + * @param boundaryCode boundary code from the request. + * @param tenantId tenant id from the request. + * @param hierarchyType hierarchy type from the request. + * @param includeParents is true if you want to include parent boundary. + * @param includeChildren is true if you want to include child boundary. + * @return a complete boundary service uri + */ + private StringBuilder getBoundaryRelationshipSearchUri(Map uriParameters, String boundaryCode, String tenantId, String hierarchyType, Boolean includeParents, Boolean includeChildren) { + StringBuilder uri = new StringBuilder(); + uri.append(configs.getBoundaryServiceHost()).append(configs.getBoundaryRelationshipSearchEndpoint()).append("?codes={boundaryCode}&includeParents={includeParents}&includeChildren={includeChildren}&tenantId={tenantId}&hierarchyType={hierarchyType}"); + + uriParameters.put("boundaryCode", boundaryCode); + uriParameters.put("tenantId", tenantId); + uriParameters.put("includeParents", includeParents.toString()); + uriParameters.put("includeChildren", includeChildren.toString()); + uriParameters.put("hierarchyType", hierarchyType); + + return uri; + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index 59d3cc2973a..b1c989bf1dc 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Plan.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Plan.java @@ -71,10 +71,12 @@ public class Plan { @JsonProperty("auditDetails") private AuditDetails auditDetails = null; - @JsonProperty("boundaryAncestralPath") - @NotNull + @JsonIgnore private String boundaryAncestralPath = null; + @JsonIgnore + private boolean isRequestFromResourceEstimationConsumer; + @JsonIgnore private List assigneeJurisdiction; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java new file mode 100644 index 00000000000..2cf0aaea4d3 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java @@ -0,0 +1,87 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * Plan + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanDTO { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("locality") + @Size(min = 1, max = 64) + private String locality = null; + + @JsonProperty("campaignId") + @Size(max = 64) + private String campaignId = null; + + @JsonProperty("planConfigurationId") + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("status") + @Size(max = 64) + private String status = null; + + @JsonProperty("assignee") + @Size(max = 64) + private String assignee = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("activities") + @Valid + private List activities; + + @JsonProperty("resources") + @Valid + private List resources; + + @JsonProperty("targets") + @Valid + private List targets; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; + + @JsonProperty("boundaryAncestralPath") + private String boundaryAncestralPath = null; + + @JsonIgnore + private Boolean partnerAssignmentValidationEnabled; + + @JsonIgnore + private List assigneeJurisdiction; + + @JsonProperty("workflow") + @Valid + private Workflow workflow; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanRequestDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanRequestDTO.java new file mode 100644 index 00000000000..1b60fca0696 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanRequestDTO.java @@ -0,0 +1,29 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanCreateRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanRequestDTO { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Plan") + @Valid + private PlanDTO planDTO = null; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java new file mode 100644 index 00000000000..7f92e1f53c8 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java @@ -0,0 +1,42 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + +/** + * BoundarySearchResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundarySearchResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("TenantBoundary") + @Valid + private List tenantBoundary = null; + + + public BoundarySearchResponse addTenantBoundaryItem(HierarchyRelation tenantBoundaryItem) { + if (this.tenantBoundary == null) { + this.tenantBoundary = new ArrayList<>(); + } + this.tenantBoundary.add(tenantBoundaryItem); + return this; + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java new file mode 100644 index 00000000000..c42af3737ce --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java @@ -0,0 +1,42 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonIgnore; +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 javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * EnrichedBoundary + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class EnrichedBoundary { + + @JsonProperty("id") + private String id; + + @JsonProperty("code") + @NotNull + private String code; + + @JsonProperty("boundaryType") + private String boundaryType; + + @JsonProperty("children") + @Valid + private List children = null; + + @JsonIgnore + private String parent = null; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java new file mode 100644 index 00000000000..7a3e26f6595 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java @@ -0,0 +1,34 @@ +package digit.web.models.boundary; + +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 javax.validation.Valid; +import java.util.List; + +/** + * HierarchyRelation + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class HierarchyRelation { + + @JsonProperty("tenantId") + private String tenantId = null; + + @JsonProperty("hierarchyType") + private String hierarchyType = null; + + @JsonProperty("boundary") + @Valid + private List boundary = null; + + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 8988b7e2836..de9d05e0a65 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -65,6 +65,10 @@ egov.project.factory.search.endpoint=/project-factory/v1/project-type/search egov.user.service.host=https://unified-dev.digit.org egov.user.search.endpoint=/user/_search +#Boundary service urls +egov.boundary.service.host=https://unified-dev.digit.org +egov.boundary.relationship.search.endpoint=/boundary-service/boundary-relationships/_search + # Workflow egov.workflow.host=https://unified-dev.digit.org egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition From f482abde92faf3941f19eec91ff239c47f53c914 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 18 Oct 2024 11:29:52 +0530 Subject: [PATCH 179/351] HCMPRE-492 changes related to auto enrichment of ancestral materialized path and boundary validation --- .../src/main/java/digit/service/PlanValidator.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 88ca5a2efaf..1c111576765 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -70,6 +70,9 @@ public void validatePlanCreate(PlanRequest request) { CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), request.getPlan().getLocality(), request.getPlan().getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType(), Boolean.TRUE, Boolean.FALSE); + //TODO: remove after setting the flag in consumer + request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); + // Validate locality against boundary service validateBoundaryCode(boundarySearchResponse, request.getPlan()); @@ -104,7 +107,7 @@ public void validatePlanCreate(PlanRequest request) { commonUtil.validateUserInfo(request.getRequestInfo()); // Validate plan-employee assignment and jurisdiction is request is from Resource Estimation Consumer - if(request.getPlan().isRequestFromResourceEstimationConsumer()) + if(!request.getPlan().isRequestFromResourceEstimationConsumer()) validatePlanEmployeeAssignmentAndJurisdiction(request); } @@ -306,6 +309,10 @@ public void validatePlanUpdate(PlanRequest request) { Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), request.getPlan().getLocality(), request.getPlan().getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType(), Boolean.TRUE, Boolean.FALSE); + request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); + + //TODO: remove after setting the flag in consumer + request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); // Validate locality against boundary service validateBoundaryCode(boundarySearchResponse, request.getPlan()); @@ -547,6 +554,8 @@ private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, throw new CustomException(NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_CODE, NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_MESSAGE); } + //TODO: change to if(!plan.isRequestFromResourceEstimationConsumer()) after triggering from consumer + // Enrich the boundary ancestral path for the provided boundary code if(plan.isRequestFromResourceEstimationConsumer()) planEnricher.enrichBoundaryAncestralPath(plan, tenantBoundary); From 8e0531897e3143c1733c1232284bf01086925575 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 18 Oct 2024 11:34:43 +0530 Subject: [PATCH 180/351] removed health-services-common --- health-services/census-service/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/health-services/census-service/pom.xml b/health-services/census-service/pom.xml index 64ebc35ab54..c999d9f6cab 100644 --- a/health-services/census-service/pom.xml +++ b/health-services/census-service/pom.xml @@ -36,11 +36,6 @@ org.springframework.boot spring-boot-starter-web - - org.egov.common - health-services-common - 1.0.18-SNAPSHOT - org.egov.common health-services-models From e3be802eb5d814473bc999aa670bbe6f3207d4de Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Fri, 18 Oct 2024 13:22:24 +0530 Subject: [PATCH 181/351] Enhanced plan facility: Added name, status and type as search parameters --- .../java/digit/config/ServiceConstants.java | 6 +++ .../impl/PlanFacilityRepositoryImpl.java | 7 ++-- .../PlanFacilityQueryBuilder.java | 7 ++++ .../digit/service/PlanFacilityService.java | 14 ++----- .../enrichment/PlanFacilityEnricher.java | 39 +++++++++++++++++++ .../controllers/PlanFacilityController.java | 23 +++++------ .../models/PlanFacilitySearchCriteria.java | 14 +++++++ .../web/models/PlanFacilitySearchRequest.java | 4 ++ 8 files changed, 88 insertions(+), 26 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 9b678d41ae6..3af287eba5c 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -299,4 +299,10 @@ public class ServiceConstants { public static final String FAILED_MESSAGE = "Failed to push message to topic"; + public static final String FACILITY_NAME_SEARCH_PARAMETER_KEY = "name"; + + public static final String FACILITY_STATUS_SEARCH_PARAMETER_KEY = "status"; + + public static final String FACILITY_TYPE_SEARCH_PARAMETER_KEY = "facilityType"; + } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 08a01b0e513..cfe0c0e32f5 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -94,8 +94,7 @@ private String convertArrayToString(List stringList) { @Override public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria) { // Fetch plan facility from database - List planFacilities = queryDatabaseForPlanFacilities(planFacilitySearchCriteria); - return planFacilities; + return queryDatabaseForPlanFacilities(planFacilitySearchCriteria); } /** @@ -123,8 +122,8 @@ public void update(PlanFacilityRequest planFacilityRequest) { private List queryDatabaseForPlanFacilities(PlanFacilitySearchCriteria planFacilitySearchCriteria) { List preparedStmtList = new ArrayList<>(); String query = planFacilityQueryBuilder.getPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); - log.debug("Plan facility search {}", query); - log.debug(preparedStmtList.toString()); + log.info("Plan facility search {}", query); + log.info(preparedStmtList.toString()); return jdbcTemplate.query(query, planFacilityRowMapper, preparedStmtList.toArray()); } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index cc23ad23836..7f8e6c3135a 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -75,6 +75,13 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(residingBoundaries)); } + if(!CollectionUtils.isEmpty(planFacilitySearchCriteria.getFiltersMap())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" additional_details @> CAST( ? AS jsonb )"); + String partialQueryJsonString = queryUtil.preparePartialJsonStringFromFilterMap(planFacilitySearchCriteria.getFiltersMap()); + preparedStmtList.add(partialQueryJsonString); + } + return builder.toString(); } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index b393a4946a8..442b91ab87b 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -58,18 +58,10 @@ public PlanFacilityResponse createPlanFacility(PlanFacilityRequest planFacilityR * @return PlanFacilityResponse object containing the search results and response information. */ public PlanFacilityResponse searchPlanFacility(PlanFacilitySearchRequest planFacilitySearchRequest) { + // Enrich search request + planFacilityEnricher.enrichSearchRequest(planFacilitySearchRequest); - // search validations - if (planFacilitySearchRequest == null || planFacilitySearchRequest.getPlanFacilitySearchCriteria() == null) { - throw new IllegalArgumentException("Search request or criteria cannot be null"); - } - else if (planFacilitySearchRequest.getPlanFacilitySearchCriteria().getTenantId().isEmpty()) { - throw new IllegalArgumentException("Tenant Id cannot be null"); - } - else if (planFacilitySearchRequest.getPlanFacilitySearchCriteria().getPlanConfigurationId().isEmpty()) { - throw new IllegalArgumentException("Plan Configuration ID cannot be null"); - } - + // Delegate request to repository List planFacilityList = planFacilityRepository.search(planFacilitySearchRequest.getPlanFacilitySearchCriteria()); // Build and return response back to controller diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 42bbc00b85d..3aef5852f76 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -2,11 +2,20 @@ import digit.web.models.PlanFacility; import digit.web.models.PlanFacilityRequest; +import digit.web.models.PlanFacilitySearchCriteria; +import digit.web.models.PlanFacilitySearchRequest; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.AuditDetailsEnrichmentUtil; import org.egov.common.utils.UUIDEnrichmentUtil; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static digit.config.ServiceConstants.*; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @Component @@ -43,4 +52,34 @@ public void enrichPlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { //enrich audit details planFacility.setAuditDetails(prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.FALSE)); } + + /** + * Enriches plan facility search request + * + * @param planFacilitySearchRequest + */ + public void enrichSearchRequest(PlanFacilitySearchRequest planFacilitySearchRequest) { + PlanFacilitySearchCriteria planFacilitySearchCriteria = planFacilitySearchRequest.getPlanFacilitySearchCriteria(); + + // Filter map for filtering facility meta data present in additional details + Map filtersMap = new LinkedHashMap<>(); + + // Add facility name as a filter if present in search criteria + if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityName())) { + filtersMap.put(FACILITY_NAME_SEARCH_PARAMETER_KEY, planFacilitySearchCriteria.getFacilityName()); + } + + // Add facility status as a filter if present in search criteria + if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityStatus())) { + filtersMap.put(FACILITY_STATUS_SEARCH_PARAMETER_KEY, planFacilitySearchCriteria.getFacilityStatus()); + } + + // Add facility type as a filter if present in search criteria + if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityType())) { + filtersMap.put(FACILITY_TYPE_SEARCH_PARAMETER_KEY, planFacilitySearchCriteria.getFacilityType()); + } + + if(!CollectionUtils.isEmpty(filtersMap)) + planFacilitySearchCriteria.setFiltersMap(filtersMap); + } } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java index fdfb713f1b9..bca90f5c544 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -35,26 +35,27 @@ public ResponseEntity createPlanFacility(@Valid @RequestBo } /** - * Request handler for serving plan facility update requests + * Request handler for serving plan facility search requests * * @param planFacilityRequest * @return */ - @RequestMapping(value = "/facility/_update", method = RequestMethod.POST) - public ResponseEntity updatePlanFacility(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { - PlanFacilityResponse planFacilityResponse = planFacilityService.updatePlanFacility(planFacilityRequest); - return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse); + @RequestMapping(value = "/facility/_search", method = RequestMethod.POST) + public ResponseEntity searchPlanFacility(@Valid @RequestBody PlanFacilitySearchRequest planFacilityRequest) { + PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(planFacilityRequest); + return ResponseEntity.status(HttpStatus.OK).body(planFacilityResponse); } /** - * Request handler for serving plan facility search requests + * Request handler for serving plan facility update requests * * @param planFacilityRequest * @return */ - @RequestMapping(value = "/facility/_search", method = RequestMethod.POST) - public ResponseEntity searchPlanFacility(@Valid @RequestBody PlanFacilitySearchRequest planFacilityRequest) { - PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(planFacilityRequest); - return ResponseEntity.status(HttpStatus.OK).body(planFacilityResponse); + @RequestMapping(value = "/facility/_update", method = RequestMethod.POST) + public ResponseEntity updatePlanFacility(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { + PlanFacilityResponse planFacilityResponse = planFacilityService.updatePlanFacility(planFacilityRequest); + return ResponseEntity.status(HttpStatus.ACCEPTED).body(planFacilityResponse); } -} + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java index 464a8bdf19f..2bdb197264f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java @@ -1,5 +1,6 @@ package digit.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; @@ -9,6 +10,7 @@ import org.springframework.validation.annotation.Validated; import java.util.List; +import java.util.Map; import java.util.Set; @Validated @@ -29,6 +31,15 @@ public class PlanFacilitySearchCriteria { @NotNull private String planConfigurationId = null; + @JsonProperty("facilityName") + private String facilityName = null; + + @JsonProperty("facilityStatus") + private String facilityStatus = null; + + @JsonProperty("facilityType") + private String facilityType = null; + @JsonProperty("residingBoundaries") private List residingBoundaries = null; @@ -38,4 +49,7 @@ public class PlanFacilitySearchCriteria { @JsonProperty("limit") private Integer limit = null; + @JsonIgnore + private Map filtersMap = null; + } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java index 85f3a26ba0b..65517af3d18 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java @@ -9,6 +9,8 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; +import javax.validation.constraints.NotNull; + /** * PlanFacilitySearchRequest */ @@ -20,10 +22,12 @@ public class PlanFacilitySearchRequest { @JsonProperty("RequestInfo") + @NotNull @Valid private RequestInfo requestInfo = null; @JsonProperty("PlanFacilitySearchCriteria") + @NotNull @Valid private PlanFacilitySearchCriteria planFacilitySearchCriteria = null; From 138e242f368939f21eceb330843bab5996e7cc51 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 18 Oct 2024 12:08:07 +0530 Subject: [PATCH 182/351] changed role map --- .../plan-service/src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 55c39a25565..a6d753075ed 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -84,4 +84,4 @@ resource.config.consumer.plan.create.topic=resource-microplan-create-topic resource.update.plan.config.consumer.topic=resource-plan-config-update-topic # Role Map -role.map = {ROOT_FACILITY_CATCHMENT_ASSIGNER:'FACILITY_CATCHMENT_ASSIGNER', FACILITY_CATCHMENT_ASSIGNER:'ROOT_FACILITY_CATCHMENT_ASSIGNER', ROOT_POPULATION_DATA_APPROVER:'POPULATION_DATA_APPROVER', POPULATION_DATA_APPROVER:'ROOT_POPULATION_DATA_APPROVER', ROOT_MICROPLAN_APPROVER:'MICROPLAN_APPROVER', MICROPLAN_APPROVER:'ROOT_MICROPLAN_APPROVER'} \ No newline at end of file +role.map = {'ROOT_FACILITY_CATCHMENT_MAPPER':'FACILITY_CATCHMENT_MAPPER', 'FACILITY_CATCHMENT_MAPPER':'ROOT_FACILITY_CATCHMENT_MAPPER', 'ROOT_POPULATION_DATA_APPROVER':'POPULATION_DATA_APPROVER', 'POPULATION_DATA_APPROVER':'ROOT_POPULATION_DATA_APPROVER', 'ROOT_PLAN_ESTIMATION_APPROVER':'PLAN_ESTIMATION_APPROVER', 'PLAN_ESTIMATION_APPROVER':'ROOT_PLAN_ESTIMATION_APPROVER'} \ No newline at end of file From 67db9c0e203ef9d0ac9f50eac50050917929e49c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 18 Oct 2024 10:27:00 +0530 Subject: [PATCH 183/351] Changes employee_id from string to list in planEmployee search criteria --- .../service/validator/PlanEmployeeAssignmentValidator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 2807685751c..735ee8a9ec6 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -110,7 +110,7 @@ private void validateDuplicateRecord(PlanEmployeeAssignmentRequest request) { List planEmployeeAssignmentsFromSearch = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() .tenantId(employeeAssignment.getTenantId()) .planConfigurationId(employeeAssignment.getPlanConfigurationId()) - .employeeId(employeeAssignment.getEmployeeId()) + .employeeId(Collections.singletonList(employeeAssignment.getEmployeeId())) .role(Collections.singletonList(employeeAssignment.getRole())) .build()); @@ -168,7 +168,7 @@ private void validateRoleConflict(PlanEmployeeAssignment planEmployeeAssignment) List response = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() .tenantId(planEmployeeAssignment.getTenantId()) .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) - .employeeId(planEmployeeAssignment.getEmployeeId()) + .employeeId(Collections.singletonList(planEmployeeAssignment.getEmployeeId())) .role(Collections.singletonList(roleMap.get(planEmployeeAssignment.getRole()))).build()); // If there are any conflicting assignments found, throw a custom exception @@ -331,7 +331,7 @@ private void validatePlanEmployeeAssignmentExistance(PlanEmployeeAssignment plan .id(planEmployeeAssignment.getId()) .role(Collections.singletonList(planEmployeeAssignment.getRole())) .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) - .employeeId(planEmployeeAssignment.getEmployeeId()) + .employeeId(Collections.singletonList(planEmployeeAssignment.getEmployeeId())) .build()); if (CollectionUtils.isEmpty(planEmployeeAssignments)) { From 282674a345106894d8bfea46231316b127a0dc09 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 21:15:43 +0530 Subject: [PATCH 184/351] Changes employee_id from string to list in planEmployee search criteria --- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 6 +++--- .../web/models/PlanEmployeeAssignmentSearchCriteria.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index e9c940d0f3b..bc4519725fa 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -80,10 +80,10 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit preparedStmtList.add(searchCriteria.getPlanConfigurationId()); } - if (searchCriteria.getEmployeeId() != null) { + if (!CollectionUtils.isEmpty(searchCriteria.getEmployeeId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" employee_id = ?"); - preparedStmtList.add(searchCriteria.getEmployeeId()); + builder.append(" employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getEmployeeId())); } if (!CollectionUtils.isEmpty(searchCriteria.getRole())) { diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 86e886e56c6..f265107de09 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -30,7 +30,7 @@ public class PlanEmployeeAssignmentSearchCriteria { private String tenantId = null; @JsonProperty("employeeId") - private String employeeId = null; + private List employeeId = null; @JsonProperty("planConfigurationId") @Size(max = 64) From bc3e37c3e033b9eb3b8659065b033295798a6193 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 17:16:00 +0530 Subject: [PATCH 185/351] Added hierarchyType in planEmployeeAssignment --- .../digit/repository/impl/PlanEmployeeAssignmentImpl.java | 1 + .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 8 +++++++- .../rowmapper/PlanEmployeeAssignmentRowMapper.java | 1 + .../java/digit/web/models/PlanEmployeeAssignment.java | 5 +++++ .../java/digit/web/models/PlanEmployeeAssignmentDTO.java | 5 +++++ .../web/models/PlanEmployeeAssignmentSearchCriteria.java | 3 +++ ...0__plan_employee_assignment_add_hierarchy_type_ddl.sql | 2 ++ 7 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index e0b004a9218..48b6bc1b05c 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -103,6 +103,7 @@ public PlanEmployeeAssignmentRequestDTO convertToReqDTO(PlanEmployeeAssignmentRe .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) .employeeId(planEmployeeAssignment.getEmployeeId()) .role(planEmployeeAssignment.getRole()) + .hierarchyType(planEmployeeAssignment.getHierarchyType()) .jurisdiction(String.join(",", planEmployeeAssignment.getJurisdiction())) .additionalDetails(planEmployeeAssignment.getAdditionalDetails()) .active(planEmployeeAssignment.getActive()) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index bc4519725fa..5bd9617aae0 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -18,7 +18,7 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { this.queryUtil = queryUtil; } - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_type, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; @@ -92,6 +92,12 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getRole())); } + if(searchCriteria.getHierarchyType() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" hierarchy_type = ?"); + preparedStmtList.add(searchCriteria.getHierarchyType()); + } + if (searchCriteria.getActive() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" active = ?"); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java index fb7dfee05ba..4ddf99e16cc 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -49,6 +49,7 @@ public List extractData(ResultSet rs) throws SQLExceptio planEmployeeAssignment.setPlanConfigurationId(rs.getString("plan_configuration_id")); planEmployeeAssignment.setEmployeeId(rs.getString("employee_id")); planEmployeeAssignment.setRole(rs.getString("role")); + planEmployeeAssignment.setHierarchyType(rs.getString("hierarchy_type")); planEmployeeAssignment.setJurisdiction(jurisdictionList); planEmployeeAssignment.setActive(rs.getBoolean("active")); planEmployeeAssignment.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("additional_details"))); diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java index 5388ee36648..87507640671 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java @@ -46,6 +46,11 @@ public class PlanEmployeeAssignment { @Size(min = 2, max = 64) private String role = null; + @JsonProperty("hierarchyType") + @NotNull + @Size(min = 2, max = 64) + private String hierarchyType = null; + @JsonProperty("jurisdiction") @Valid @NotEmpty diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java index 346ee066663..7b20968088c 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java @@ -46,6 +46,11 @@ public class PlanEmployeeAssignmentDTO { @Size(min = 2, max = 64) private String role = null; + @JsonProperty("hierarchyType") + @NotNull + @Size(min = 2, max = 64) + private String hierarchyType = null; + @JsonProperty("jurisdiction") @Valid @NotEmpty diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index f265107de09..192c5c11509 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -39,6 +39,9 @@ public class PlanEmployeeAssignmentSearchCriteria { @JsonProperty("role") private List role = null; + @JsonProperty("hierarchyType") + private String hierarchyType = null; + @JsonProperty("jurisdiction") @Valid private List jurisdiction = null; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql new file mode 100644 index 00000000000..e18b9375ff6 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql @@ -0,0 +1,2 @@ +ALTER TABLE plan_employee_assignment ADD hierarchy_type character varying(64); +UPDATE plan_employee_assignment SET hierarchy_type = 'MICROPLAN' WHERE hierarchy_type IS NULL; \ No newline at end of file From d317bcd7047673ace8bad14dac818aa5fd137b5e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 18:55:24 +0530 Subject: [PATCH 186/351] Added hierarchyLevel in planEmployeeAssignment --- .../digit/repository/impl/PlanEmployeeAssignmentImpl.java | 2 +- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 8 ++++---- .../rowmapper/PlanEmployeeAssignmentRowMapper.java | 2 +- .../java/digit/web/models/PlanEmployeeAssignment.java | 5 ++--- .../java/digit/web/models/PlanEmployeeAssignmentDTO.java | 5 ++--- .../web/models/PlanEmployeeAssignmentSearchCriteria.java | 4 ++-- ...0__plan_employee_assignment_add_hierarchy_type_ddl.sql | 3 +-- 7 files changed, 13 insertions(+), 16 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index 48b6bc1b05c..c1e5725c0d2 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -103,7 +103,7 @@ public PlanEmployeeAssignmentRequestDTO convertToReqDTO(PlanEmployeeAssignmentRe .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) .employeeId(planEmployeeAssignment.getEmployeeId()) .role(planEmployeeAssignment.getRole()) - .hierarchyType(planEmployeeAssignment.getHierarchyType()) + .hierarchyLevel(planEmployeeAssignment.getHierarchyLevel()) .jurisdiction(String.join(",", planEmployeeAssignment.getJurisdiction())) .additionalDetails(planEmployeeAssignment.getAdditionalDetails()) .active(planEmployeeAssignment.getActive()) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 5bd9617aae0..e9ab46c1f56 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -18,7 +18,7 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { this.queryUtil = queryUtil; } - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_type, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; @@ -92,10 +92,10 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getRole())); } - if(searchCriteria.getHierarchyType() != null) { + if(searchCriteria.getHierarchyLevel() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" hierarchy_type = ?"); - preparedStmtList.add(searchCriteria.getHierarchyType()); + builder.append(" hierarchy_level = ?"); + preparedStmtList.add(searchCriteria.getHierarchyLevel()); } if (searchCriteria.getActive() != null) { diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java index 4ddf99e16cc..9a0ce4a2037 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -49,7 +49,7 @@ public List extractData(ResultSet rs) throws SQLExceptio planEmployeeAssignment.setPlanConfigurationId(rs.getString("plan_configuration_id")); planEmployeeAssignment.setEmployeeId(rs.getString("employee_id")); planEmployeeAssignment.setRole(rs.getString("role")); - planEmployeeAssignment.setHierarchyType(rs.getString("hierarchy_type")); + planEmployeeAssignment.setHierarchyLevel(rs.getString("hierarchy_level")); planEmployeeAssignment.setJurisdiction(jurisdictionList); planEmployeeAssignment.setActive(rs.getBoolean("active")); planEmployeeAssignment.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("additional_details"))); diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java index 87507640671..750f21fa9e9 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java @@ -46,10 +46,9 @@ public class PlanEmployeeAssignment { @Size(min = 2, max = 64) private String role = null; - @JsonProperty("hierarchyType") - @NotNull + @JsonProperty("hierarchyLevel") @Size(min = 2, max = 64) - private String hierarchyType = null; + private String hierarchyLevel = null; @JsonProperty("jurisdiction") @Valid diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java index 7b20968088c..095d7b54fa6 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java @@ -46,10 +46,9 @@ public class PlanEmployeeAssignmentDTO { @Size(min = 2, max = 64) private String role = null; - @JsonProperty("hierarchyType") - @NotNull + @JsonProperty("hierarchyLevel") @Size(min = 2, max = 64) - private String hierarchyType = null; + private String hierarchyLevel = null; @JsonProperty("jurisdiction") @Valid diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 192c5c11509..c7dad1a28fd 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -39,8 +39,8 @@ public class PlanEmployeeAssignmentSearchCriteria { @JsonProperty("role") private List role = null; - @JsonProperty("hierarchyType") - private String hierarchyType = null; + @JsonProperty("hierarchyLevel") + private String hierarchyLevel = null; @JsonProperty("jurisdiction") @Valid diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql index e18b9375ff6..69bc3d84e7a 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql @@ -1,2 +1 @@ -ALTER TABLE plan_employee_assignment ADD hierarchy_type character varying(64); -UPDATE plan_employee_assignment SET hierarchy_type = 'MICROPLAN' WHERE hierarchy_type IS NULL; \ No newline at end of file +ALTER TABLE plan_employee_assignment ADD hierarchy_level character varying(64); From 81e729d1076f2c3de06150d279ebe64abc545a96 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 17 Oct 2024 20:18:36 +0530 Subject: [PATCH 187/351] Added validation for hierarchy_level --- .../src/main/java/digit/config/ServiceConstants.java | 3 +++ .../service/validator/PlanEmployeeAssignmentValidator.java | 5 +++++ ...00__plan_employee_assignment_add_hierarchy_level_ddl.sql} | 0 3 files changed, 8 insertions(+) rename health-services/plan-service/src/main/resources/db/migration/main/{V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql => V20242810151500__plan_employee_assignment_add_hierarchy_level_ddl.sql} (100%) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 9b678d41ae6..94231c26250 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -84,6 +84,9 @@ public class ServiceConstants { public static final String INVALID_EMPLOYEE_JURISDICTION_CODE = "INVALID_EMPLOYEE_JURISDICTION"; public static final String INVALID_EMPLOYEE_JURISDICTION_MESSAGE = "The employee's jurisdiction provided is invalid"; + public static final String INVALID_HIERARCHY_LEVEL_CODE = "INVALID_HIERARCHY_LEVEL"; + public static final String INVALID_HIERARCHY_LEVEL_MESSAGE = "The hierarchy level provided is invalid"; + public static final String INVALID_EMPLOYEE_ROLE_CODE = "INVALID_EMPLOYEE_ROLE"; public static final String INVALID_EMPLOYEE_ROLE_MESSAGE = "The employee's role provided is invalid"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java index 735ee8a9ec6..b8eb4d68a16 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -243,9 +243,14 @@ private void validateEmployeeAssignmentJurisdiction(CampaignDetail campaignDetai // Collect all boundary code for the campaign Set boundaryCode = campaignDetail.getBoundaries().stream() + .filter(boundary -> planEmployeeAssignment.getHierarchyLevel().equals(boundary.getType())) .map(Boundary::getCode) .collect(Collectors.toSet()); + if(CollectionUtils.isEmpty(boundaryCode)) { + throw new CustomException(INVALID_HIERARCHY_LEVEL_CODE, INVALID_HIERARCHY_LEVEL_MESSAGE); + } + planEmployeeAssignment.getJurisdiction() .forEach(jurisdiction -> { if (!boundaryCode.contains(jurisdiction)) { diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_level_ddl.sql similarity index 100% rename from health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_type_ddl.sql rename to health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_level_ddl.sql From 0bfa8b4c15e2725253fa29eb2c8c5aec2a44de2a Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 18 Oct 2024 14:11:56 +0530 Subject: [PATCH 188/351] Added facilityAssigned field in census and modified the search criteria --- .../repository/impl/CensusRepositoryImpl.java | 1 + .../querybuilder/CensusQueryBuilder.java | 19 +++++++++++++++---- .../repository/rowmapper/CensusRowMapper.java | 1 + .../main/java/digit/web/models/Census.java | 3 +++ .../main/java/digit/web/models/CensusDTO.java | 3 +++ .../web/models/CensusSearchCriteria.java | 6 ++++++ ...2004__census_add_facility_assigned_ddl.sql | 2 ++ 7 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 0cf88bda570..7a07db81bcb 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -128,6 +128,7 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .effectiveTo(census.getEffectiveTo()) .source(census.getSource()) .boundaryAncestralPath(census.getBoundaryAncestralPath().get(0)) + .facilityAssigned(census.isFacilityAssigned()) .additionalDetails(census.getAdditionalDetails()) .auditDetails(census.getAuditDetails()) .build(); diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 7829b2f51bd..3e675760eee 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -18,7 +18,7 @@ public CensusQueryBuilder(QueryUtil queryUtil) { this.queryUtil = queryUtil; } - private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_ancestral_path as census_boundary_ancestral_path, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + + private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_ancestral_path as census_boundary_ancestral_path, cen.facility_assigned as census_facility_assigned, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time \n" + "\t FROM census cen \n" + "\t LEFT JOIN population_by_demographics pbd ON cen.id = pbd.census_id"; @@ -100,7 +100,19 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep preparedStmtList.add(criteria.getAssignee()); } - if (criteria.getEffectiveTo() != null) { + if (!ObjectUtils.isEmpty(criteria.getSource())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.source = ?"); + preparedStmtList.add(criteria.getSource()); + } + + if (!ObjectUtils.isEmpty(criteria.isFacilityAssigned())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.facility_assigned = ?"); + preparedStmtList.add(criteria.isFacilityAssigned()); + } + + if (!ObjectUtils.isEmpty(criteria.getEffectiveTo())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); if (criteria.getEffectiveTo() == 0) { builder.append(" cen.effective_to IS NULL "); @@ -132,8 +144,7 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep } if (isStatusCount) { - String statusCountQuery = CENSUS_STATUS_COUNT_WRAPPER.replace("{INTERNAL_QUERY}", builder); - return statusCountQuery; + return CENSUS_STATUS_COUNT_WRAPPER.replace("{INTERNAL_QUERY}", builder); } return builder.toString(); diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 393a04c6684..126fd3cb3de 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -60,6 +60,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setStatus(Census.StatusEnum.valueOf(rs.getString("census_status").toUpperCase())); censusEntry.setAssignee(rs.getString("census_assignee")); censusEntry.setBoundaryAncestralPath(Collections.singletonList(rs.getString("census_boundary_ancestral_path"))); + censusEntry.setFacilityAssigned(rs.getBoolean("census_facility_assigned")); censusEntry.setAdditionalDetails(queryUtil.parseJson((PGobject) rs.getObject("census_additional_details"))); censusEntry.setAuditDetails(auditDetails); } diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 27f2738a346..572ae9b3af3 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -82,6 +82,9 @@ public class Census { @JsonIgnore private boolean partnerAssignmentValidationEnabled; + @JsonProperty("facilityAssigned") + private boolean facilityAssigned; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index a8f7fc350a1..2bc62d31553 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -79,6 +79,9 @@ public class CensusDTO { @JsonIgnore private boolean partnerAssignmentValidationEnabled; + @JsonProperty("facilityAssigned") + private boolean facilityAssigned; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index 5736b5f553b..66a7658b16b 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -39,6 +39,12 @@ public class CensusSearchCriteria { @JsonProperty("assignee") private String assignee = null; + @JsonProperty("source") + private String source = null; + + @JsonProperty("facilityAssigned") + private boolean facilityAssigned; + @JsonProperty("jurisdiction") private List jurisdiction = null; diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql new file mode 100644 index 00000000000..134e46bc9dd --- /dev/null +++ b/health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql @@ -0,0 +1,2 @@ +ALTER TABLE census ADD facility_assigned boolean; +UPDATE census SET facility_assigned = false WHERE facility_assigned IS NULL; \ No newline at end of file From fe6f32f20c7b701fb17a0b27caaea33e4906adcd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 18 Oct 2024 14:39:12 +0530 Subject: [PATCH 189/351] Added alias in censusQuery --- .../java/digit/repository/querybuilder/CensusQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 3e675760eee..90924804b3f 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -27,7 +27,7 @@ public CensusQueryBuilder(QueryUtil queryUtil) { private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; - private static final String CENSUS_STATUS_COUNT_WRAPPER = "SELECT COUNT(census_id) as census_status_count, census_status FROM ({INTERNAL_QUERY}) GROUP BY census_status"; + private static final String CENSUS_STATUS_COUNT_WRAPPER = "SELECT COUNT(census_id) as census_status_count, census_status FROM ({INTERNAL_QUERY}) as census_status_map GROUP BY census_status"; /** * Constructs a SQL query string for searching Census records based on the provided search criteria. From 590616324ce885bddc04773c62a546e4d41b9006 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 18 Oct 2024 16:54:39 +0530 Subject: [PATCH 190/351] HCMPRE-492 removing try catch block from create and update methods in Plan repository --- .../repository/impl/PlanRepositoryImpl.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 2908f45589f..88737d8213e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -7,6 +7,7 @@ import digit.repository.rowmapper.PlanRowMapper; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.CustomException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.stereotype.Repository; @@ -44,12 +45,8 @@ public PlanRepositoryImpl(Producer producer, PlanQueryBuilder planQueryBuilder, */ @Override public void create(PlanRequest planRequest) { - try { - PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); - producer.push(config.getPlanCreateTopic(), planRequestDTO); - } catch (Exception e) { - log.info("Pushing message to topic " + config.getPlanCreateTopic() + " failed.", e); - } + PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); + producer.push(config.getPlanCreateTopic(), planRequestDTO); } /** @@ -80,12 +77,8 @@ public List search(PlanSearchCriteria planSearchCriteria) { */ @Override public void update(PlanRequest planRequest) { - try { - PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); - producer.push(config.getPlanUpdateTopic(), planRequestDTO); - } catch (Exception e) { - log.info("Pushing message to topic " + config.getPlanUpdateTopic() + " failed.", e); - } + PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); + producer.push(config.getPlanUpdateTopic(), planRequestDTO); } /** From 6f2fcb3e1d9aa4c4b5c409b3177b71288ef7bf13 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 18 Oct 2024 16:58:43 +0530 Subject: [PATCH 191/351] HCMPRE-492 removing validateBoundaryCode from update --- .../src/main/java/digit/service/PlanValidator.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 1c111576765..6d1fb924829 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -307,15 +307,11 @@ public void validatePlanUpdate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); - BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), request.getPlan().getLocality(), request.getPlan().getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType(), Boolean.TRUE, Boolean.FALSE); request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); //TODO: remove after setting the flag in consumer request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); - // Validate locality against boundary service - validateBoundaryCode(boundarySearchResponse, request.getPlan()); // Validate activities validateActivities(request); @@ -350,9 +346,6 @@ public void validatePlanUpdate(PlanRequest request) { // Validate Metric Detail's Unit against MDMS validateMetricDetailUnit(request, mdmsData); - // Validate if campaign id exists against project factory - validateCampaignId(campaignResponse); - // Validate the user information in the request commonUtil.validateUserInfo(request.getRequestInfo()); From 316c17fc08e4806a7596d80ce728515abd2f1fb8 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 18 Oct 2024 16:59:57 +0530 Subject: [PATCH 192/351] HCMPRE-492 removing validateBoundaryCode from update --- .../plan-service/src/main/java/digit/service/PlanValidator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 6d1fb924829..77a9766646f 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -307,7 +307,6 @@ public void validatePlanUpdate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); //TODO: remove after setting the flag in consumer request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); From 45e3547d895c24a4a683f6cb05fdaa2e2400dd2f Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 18 Oct 2024 17:47:08 +0530 Subject: [PATCH 193/351] changed facilityAssigned type --- .../main/java/digit/repository/impl/CensusRepositoryImpl.java | 2 +- .../digit/repository/querybuilder/CensusQueryBuilder.java | 4 ++-- .../census-service/src/main/java/digit/web/models/Census.java | 2 +- .../src/main/java/digit/web/models/CensusDTO.java | 2 +- .../src/main/java/digit/web/models/CensusSearchCriteria.java | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 7a07db81bcb..4c7ae28c94c 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -128,7 +128,7 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .effectiveTo(census.getEffectiveTo()) .source(census.getSource()) .boundaryAncestralPath(census.getBoundaryAncestralPath().get(0)) - .facilityAssigned(census.isFacilityAssigned()) + .facilityAssigned(census.getFacilityAssigned()) .additionalDetails(census.getAdditionalDetails()) .auditDetails(census.getAuditDetails()) .build(); diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 90924804b3f..407f8c2adc4 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -106,10 +106,10 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep preparedStmtList.add(criteria.getSource()); } - if (!ObjectUtils.isEmpty(criteria.isFacilityAssigned())) { + if (!ObjectUtils.isEmpty(criteria.getFacilityAssigned())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.facility_assigned = ?"); - preparedStmtList.add(criteria.isFacilityAssigned()); + preparedStmtList.add(criteria.getFacilityAssigned()); } if (!ObjectUtils.isEmpty(criteria.getEffectiveTo())) { diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 572ae9b3af3..4afc174a757 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -83,7 +83,7 @@ public class Census { private boolean partnerAssignmentValidationEnabled; @JsonProperty("facilityAssigned") - private boolean facilityAssigned; + private Boolean facilityAssigned = null; @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 2bc62d31553..81dcd9eee49 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -80,7 +80,7 @@ public class CensusDTO { private boolean partnerAssignmentValidationEnabled; @JsonProperty("facilityAssigned") - private boolean facilityAssigned; + private Boolean facilityAssigned = null; @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index 66a7658b16b..4a3ab843cd7 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -43,7 +43,7 @@ public class CensusSearchCriteria { private String source = null; @JsonProperty("facilityAssigned") - private boolean facilityAssigned; + private Boolean facilityAssigned = null; @JsonProperty("jurisdiction") private List jurisdiction = null; From b8b4bdf3f70256bd9ad58c060b3ca0f40231a706 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 18 Oct 2024 18:41:29 +0530 Subject: [PATCH 194/351] modified validation --- .../src/main/java/digit/service/validator/CensusValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 4549516b808..32cbef5e1a7 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -128,7 +128,7 @@ public void validateUpdate(CensusRequest request) { // Validate if Census record to be updated exists Census census = validateCensusExistence(request); - request.setCensus(census); + request.getCensus().setBoundaryAncestralPath(census.getBoundaryAncestralPath()); // Validate partner assignment and jurisdiction against plan service validatePartnerForCensus(request); From 9e142694f73322ab2d49c3b41fed52b23c90dd2f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 18 Oct 2024 20:19:55 +0530 Subject: [PATCH 195/351] HCMPRE-492 passing employeeId in PlanEmployeeAssignmentSearchCriteria as a list --- .../plan-service/src/main/java/digit/service/PlanValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 77a9766646f..8042e755b2f 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -498,7 +498,7 @@ public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planReques PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = PlanEmployeeAssignmentSearchCriteria .builder() .tenantId(planRequest.getPlan().getTenantId()) - .employeeId(planRequest.getRequestInfo().getUserInfo().getUuid()) + .employeeId(Collections.singletonList(planRequest.getRequestInfo().getUserInfo().getUuid())) .planConfigurationId(planRequest.getPlan().getPlanConfigurationId()) .role(config.getPlanEstimationApproverRoles()) .build(); From c03c61023e2f0f64e39575e8949e18702229cf58 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Sat, 19 Oct 2024 11:49:52 +0530 Subject: [PATCH 196/351] HCMPRE-492 fixing boundary ancestral migration script --- .../V20240910200000__plan_add_boundaryAncestralPath_ddl.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql index d1c7ba90f83..a92f896c6e1 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql @@ -1,4 +1,4 @@ ALTER TABLE plan -ADD boundary_ancestral_path TEXT NOT NULL, +ADD boundary_ancestral_path TEXT, ADD status character varying(64) NOT NULL, ADD assignee varchar(64); From 8b549e03af52f14d92b4d9653ba6f681f7c3dc03 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Sat, 19 Oct 2024 11:59:07 +0530 Subject: [PATCH 197/351] HCMPRE-492 fixing boundary ancestral migration script --- .../V20240910200000__plan_add_boundaryAncestralPath_ddl.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql index a92f896c6e1..99ddf042da3 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql @@ -1,4 +1,4 @@ ALTER TABLE plan ADD boundary_ancestral_path TEXT, -ADD status character varying(64) NOT NULL, +ADD status character varying(64) NOT NULL DEFAULT 'VALIDATED', ADD assignee varchar(64); From 81088a0e7e42a72a8cab659b177688870f27e241 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 12:42:36 +0530 Subject: [PATCH 198/351] Added workflow for census --- .../main/java/digit/config/Configuration.java | 16 ++ .../java/digit/config/ServiceConstants.java | 8 + .../repository/rowmapper/CensusRowMapper.java | 2 +- .../java/digit/service/CensusService.java | 7 +- .../service/validator/CensusValidator.java | 19 +- .../service/workflow/WorkflowService.java | 241 ++++++++++++++++++ .../util/PlanEmployeeAssignmnetUtil.java | 41 +-- .../main/java/digit/web/models/Census.java | 24 +- .../main/java/digit/web/models/CensusDTO.java | 8 + 9 files changed, 313 insertions(+), 53 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 8607cedb453..8ebea72e920 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -42,6 +42,22 @@ public class Configuration { @Value("${egov.plan.employee.assignment.search.endpoint}") private String planEmployeeAssignmentSearchEndpoint; + //Workflow + @Value("${egov.workflow.host}") + private String wfHost; + + @Value("${egov.workflow.transition.path}") + private String wfTransitionPath; + + @Value("${workflow.initiate.action}") + private List wfInitiateActions; + + @Value("${workflow.intermediate.action}") + private List wfIntermediateActions; + + @Value("${workflow.send.back.actions}") + private List wfSendBackActions; + //SMSNotification @Value("${egov.sms.notification.topic}") private String smsNotificationTopic; diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 6b0ea54ce65..6194aab07d2 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -41,6 +41,7 @@ public class ServiceConstants { public static final String CITIZEN_UPPER = "CITIZEN"; public static final String CITIZEN_LOWER = "Citizen"; public static final String USER = "user"; + public static final String PIPE_REGEX = "\\|"; public static final String PARSING_ERROR_CODE = "PARSING ERROR"; public static final String PARSING_ERROR_MESSAGE = "Failed to parse JSON data from PGobject"; @@ -58,6 +59,9 @@ public class ServiceConstants { public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; + public static final String WORKFLOW_INTEGRATION_ERROR_CODE = "WORKFLOW_INTEGRATION_ERROR"; + public static final String WORKFLOW_INTEGRATION_ERROR_MESSAGE = "Exception occured while integrating with workflow : "; + public static final String INVALID_PARTNER_CODE = "INVALID_PARTNER"; public static final String INVALID_PARTNER_MESSAGE = "Invalid partner assignment or invalid jurisdiction of the assigned partner"; @@ -70,4 +74,8 @@ public class ServiceConstants { public static final String TENANT_ID_EMPTY_CODE = "TENANT_ID_EMPTY"; public static final String TENANT_ID_EMPTY_MESSAGE = "Tenant Id cannot be empty, TenantId should be present"; + //Workflow constants + public static final String MODULE_NAME_VALUE = "census-service"; + + public static final String CENSUS_BUSINESS_SERVICE = "CENSUS"; } diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 126fd3cb3de..c7dc43017e9 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -57,7 +57,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setEffectiveFrom(rs.getLong("census_effective_from")); censusEntry.setEffectiveTo(rs.getLong("census_effective_to")); censusEntry.setSource(rs.getString("census_source")); - censusEntry.setStatus(Census.StatusEnum.valueOf(rs.getString("census_status").toUpperCase())); + censusEntry.setStatus(rs.getString("census_status").toUpperCase()); censusEntry.setAssignee(rs.getString("census_assignee")); censusEntry.setBoundaryAncestralPath(Collections.singletonList(rs.getString("census_boundary_ancestral_path"))); censusEntry.setFacilityAssigned(rs.getBoolean("census_facility_assigned")); diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index d7f5583713d..de66214e7b3 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -4,6 +4,7 @@ import digit.service.enrichment.CensusEnrichment; import digit.service.enrichment.CensusTimeframeEnrichment; import digit.service.validator.CensusValidator; +import digit.service.workflow.WorkflowService; import digit.util.ResponseInfoFactory; import digit.web.models.CensusRequest; import digit.web.models.CensusResponse; @@ -25,12 +26,15 @@ public class CensusService { private CensusTimeframeEnrichment timeframeEnrichment; - public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository repository, CensusValidator validator, CensusEnrichment enrichment, CensusTimeframeEnrichment timeframeEnrichment) { + private WorkflowService workflow; + + public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository repository, CensusValidator validator, CensusEnrichment enrichment, CensusTimeframeEnrichment timeframeEnrichment, WorkflowService workflow) { this.responseInfoFactory = responseInfoFactory; this.repository = repository; this.validator = validator; this.enrichment = enrichment; this.timeframeEnrichment = timeframeEnrichment; + this.workflow = workflow; } /** @@ -75,6 +79,7 @@ public CensusResponse search(CensusSearchRequest request) { public CensusResponse update(CensusRequest request) { validator.validateUpdate(request); // Validate census update request enrichment.enrichUpdate(request); // Enrich census update request + workflow.invokeWorkflowForStatusUpdate(request); // Call workflow transition API for status update repository.update(request); // Delegate update request to repository return CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 4549516b808..0b8a1ccd13d 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -12,6 +12,8 @@ import digit.web.models.boundary.BoundarySearchResponse; import digit.web.models.boundary.HierarchyRelation; import digit.web.models.plan.PlanEmployeeAssignmentResponse; +import digit.web.models.plan.PlanEmployeeAssignmentSearchCriteria; +import digit.web.models.plan.PlanEmployeeAssignmentSearchRequest; import org.apache.commons.lang3.StringUtils; import org.egov.common.contract.request.User; import org.egov.tracer.model.CustomException; @@ -96,11 +98,26 @@ private void validatePartnerForCensus(CensusRequest request) { if (census.isPartnerAssignmentValidationEnabled()) { User userInfo = request.getRequestInfo().getUserInfo(); List jurisdiction = Arrays.asList(request.getCensus().getBoundaryAncestralPath().get(0).split("\\|")); - PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(request.getRequestInfo(), userInfo.getUuid(), request.getCensus().getSource(), request.getCensus().getTenantId(), configs.getAllowedCensusRoles(), jurisdiction); + + PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() + .employeeId(userInfo.getUuid()) + .planConfigurationId(request.getCensus().getSource()) + .tenantId(request.getCensus().getTenantId()) + .role(configs.getAllowedCensusRoles()) + .jurisdiction(jurisdiction) + .build(); + + PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest.builder() + .requestInfo(request.getRequestInfo()) + .planEmployeeAssignmentSearchCriteria(searchCriteria) + .build()); if (CollectionUtils.isEmpty(employeeAssignmentResponse.getPlanEmployeeAssignment())) { throw new CustomException(INVALID_PARTNER_CODE, INVALID_PARTNER_MESSAGE); } + + //enrich jurisdiction of current assignee + request.getCensus().setAssigneeJurisdiction(employeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); } } diff --git a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java new file mode 100644 index 00000000000..4e726cad595 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -0,0 +1,241 @@ +package digit.service.workflow; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.config.Configuration; +import digit.repository.ServiceRequestRepository; +import digit.util.PlanEmployeeAssignmnetUtil; +import digit.web.models.Census; +import digit.web.models.CensusRequest; +import digit.web.models.plan.PlanEmployeeAssignmentResponse; +import digit.web.models.plan.PlanEmployeeAssignmentSearchCriteria; +import digit.web.models.plan.PlanEmployeeAssignmentSearchRequest; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.models.Workflow; +import org.egov.common.contract.request.User; +import org.egov.common.contract.workflow.*; +import org.egov.common.utils.AuditDetailsEnrichmentUtil; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.*; +import java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; + +@Service +@Slf4j +public class WorkflowService { + + private ServiceRequestRepository serviceRequestRepository; + + private Configuration config; + + private ObjectMapper mapper; + + private PlanEmployeeAssignmnetUtil planEmployeeAssignmnetUtil; + + public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, PlanEmployeeAssignmnetUtil planEmployeeAssignmnetUtil) { + this.serviceRequestRepository = serviceRequestRepository; + this.config = config; + this.mapper = mapper; + this.planEmployeeAssignmnetUtil = planEmployeeAssignmnetUtil; + } + + /** + * Integrates with the workflow for the given census request. + * If the action is null, it does not proceed with integration. + * + * @param censusRequest The request containing the census object to integrate with the workflow. + */ + public void invokeWorkflowForStatusUpdate(CensusRequest censusRequest) { + if (ObjectUtils.isEmpty(censusRequest.getCensus().getWorkflow())) + return; + + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(censusRequest); + ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); + + // Setting the status back to the census object from workflow response + censusRequest.getCensus().setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); + + // Enrich audit details after auto assignment is complete + censusRequest.getCensus().setAuditDetails(AuditDetailsEnrichmentUtil + .prepareAuditDetails( censusRequest.getCensus().getAuditDetails(), censusRequest.getRequestInfo(), Boolean.FALSE)); + + } + + /** + * Calls the workflow transition service and retrieves the process instance response. + * + * @param processInstanceRequest The request containing process instance details for the workflow transition. + * @return The response containing details of the process instances after the transition. + * @throws CustomException if there is an error during the workflow integration. + */ + public ProcessInstanceResponse callWorkflowTransition(ProcessInstanceRequest processInstanceRequest) { + ProcessInstanceResponse processInstanceResponse; + try { + Object response = serviceRequestRepository.fetchResult(getWorkflowTransitionUri(), processInstanceRequest); + processInstanceResponse = mapper.convertValue(response, ProcessInstanceResponse.class); + } catch (Exception e) { + throw new CustomException(WORKFLOW_INTEGRATION_ERROR_CODE, WORKFLOW_INTEGRATION_ERROR_MESSAGE + e.getMessage()); + } + + return processInstanceResponse; + } + + /** + * Creates a workflow request from the given census request. + * + * @param censusRequest The request containing the census to create a workflow request. + * @return The constructed process instance request for the workflow. + */ + public ProcessInstanceRequest createWorkflowRequest(CensusRequest censusRequest) { + Census census = censusRequest.getCensus(); + ProcessInstance processInstance = ProcessInstance.builder() + .businessId(census.getId()) + .tenantId(census.getTenantId()) + .businessService(CENSUS_BUSINESS_SERVICE) + .moduleName(MODULE_NAME_VALUE) + .action(census.getWorkflow().getAction()) + .comment(census.getWorkflow().getComments()) + .documents(census.getWorkflow().getDocuments()) + .build(); + + autoAssignAssignee(census.getWorkflow(), censusRequest); + enrichAssignesInProcessInstance(processInstance, census.getWorkflow()); + + log.info("Process Instance assignes - " + processInstance.getAssignes()); + return ProcessInstanceRequest.builder() + .requestInfo(censusRequest.getRequestInfo()) + .processInstances(Collections.singletonList(processInstance)) + .build(); + } + + /** + * Enriches the process instance with assignees from the given workflow. + * + * @param processInstance The process instance to enrich with assignees. + * @param workflow The workflow containing assignees to be added to the process instance. + */ + public void enrichAssignesInProcessInstance(ProcessInstance processInstance, Workflow workflow) { + List userList = CollectionUtils.isEmpty(workflow.getAssignes()) + ? new LinkedList<>() + : workflow.getAssignes().stream() + .map(assignee -> User.builder().uuid(assignee).build()) + .toList(); + + processInstance.setAssignes(userList); + } + + /** + * Constructs the URI for the workflow service transition API. + * + * @return The StringBuilder containing the constructed workflow transition URI. + */ + private StringBuilder getWorkflowTransitionUri() { + return new StringBuilder().append(config.getWfHost()).append(config.getWfTransitionPath()); + } + + /** + * Automatically assigns an assignee based on the workflow action and jurisdiction hierarchy. + * Retrieves jurisdiction boundaries from the census request and searches for matching employee assignments. + * + * For INITIATE actions, assigns the employee from the lowest boundary. + * For INTERMEDIATE actions (non-ROOT_APPROVER), assigns an employee from a higher-level boundary. + * For SEND_BACK actions, assigns the last modified user. + * + * The assignee is set in both the workflow and the census request. + * + * @param workflow the workflow object to set the assignee + * @param censusRequest the census request containing workflow and jurisdiction details + */ + private void autoAssignAssignee(Workflow workflow, CensusRequest censusRequest) { + String[] allheirarchysBoundaryCodes = censusRequest.getCensus().getBoundaryAncestralPath().get(0).split(PIPE_REGEX); + String[] heirarchysBoundaryCodes = Arrays.copyOf(allheirarchysBoundaryCodes, allheirarchysBoundaryCodes.length - 1); + + PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = + PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(censusRequest.getCensus().getTenantId()) + .jurisdiction(Arrays.stream(heirarchysBoundaryCodes).toList()) + .planConfigurationId(censusRequest.getCensus().getSource()) + .role(config.getAllowedCensusRoles()) + .build(); + + //search for plan-employee assignments for the ancestral heirarchy codes. + PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeAssignmnetUtil.fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest.builder() + .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) + .requestInfo(censusRequest.getRequestInfo()).build()); + + // Create a map of jurisdiction to employeeId + Map jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() + .filter(assignment -> assignment.getJurisdiction() != null && !assignment.getJurisdiction().isEmpty()) + .flatMap(assignment -> { + String employeeId = assignment.getEmployeeId(); + return assignment.getJurisdiction().stream() + .filter(jurisdiction -> Arrays.asList(heirarchysBoundaryCodes).contains(jurisdiction)) + .map(jurisdiction -> new AbstractMap.SimpleEntry<>(jurisdiction, employeeId)); + }) + .collect(Collectors.toMap( + Map.Entry::getKey, // jurisdiction as the key + Map.Entry::getValue, // employeeId as the value + (existing, replacement) -> existing, // Keep the first employeeId for duplicates + LinkedHashMap::new // Ensure insertion order is preserved + )); + + String assignee = null; //assignee will remain null in case terminate actions are being taken + + String action = censusRequest.getCensus().getWorkflow().getAction(); + if (config.getWfInitiateActions().contains(action)) { + for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { + assignee = jurisdictionToEmployeeMap.get(heirarchysBoundaryCodes[i]); + if (assignee != null) + break; // Stop iterating once an assignee is found + } + } else if (config.getWfIntermediateActions().contains(action)) { + assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, censusRequest, jurisdictionToEmployeeMap); + } else if (config.getWfSendBackActions().contains(action)) { + assignee = censusRequest.getCensus().getAuditDetails().getLastModifiedBy(); + } + + if(!ObjectUtils.isEmpty(assignee)) + workflow.setAssignes(Collections.singletonList(assignee)); + + censusRequest.getCensus().setAssignee(assignee); + } + + /** + * Assigns an employee from a higher-level jurisdiction in the hierarchy. + * Iterates through boundary codes, checking if they match the assignee's jurisdiction. + * If a higher-level boundary has an assigned employee, returns that employee's ID. + * + * @param heirarchysBoundaryCodes boundary codes representing the hierarchy + * @param censusRequest the request with census and jurisdiction details + * @param jurisdictionToEmployeeMap map of jurisdiction codes to employee IDs + * @return the employee ID from the higher boundary, or null if + */ + public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, CensusRequest censusRequest, Map jurisdictionToEmployeeMap) { + for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { + String boundaryCode = heirarchysBoundaryCodes[i]; + + // Check if this boundary code is present in assigneeJurisdiction + if (censusRequest.getCensus().getAssigneeJurisdiction().contains(boundaryCode)) { + + if (i - 1 >= 0) { + // Check the next higher level in the hierarchy (one index above the match) + String higherBoundaryCode = heirarchysBoundaryCodes[i - 1]; + + // Fetch the employeeId from the map for the higher boundary code + String employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); + + // If an employee is found, set them as the assignee and break the loop + if (employeeId != null) { + return employeeId; + } + } + } + } + return null; + } + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java b/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java index 3da17a87287..f2f091649ba 100644 --- a/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java +++ b/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java @@ -28,25 +28,18 @@ public PlanEmployeeAssignmnetUtil(RestTemplate restTemplate, Configuration confi /** * This method fetches plan employee assignment from plan service for provided employeeID. - * - * @param requestInfo request info from the request. - * @param employeeId employee id from the request. - * @param planConfigId plan configuration id from the request. - * @param tenantId tenant id from the request. - * @param roles allowed roles for census - * @param jurisdiction list of ancestral boundary codes for the given boundary + * @param planEmployeeAssignmentSearchRequest request containint the planEmployeeAssignment search criteria * @return returns planEmployeeAssignment for provided search criteria. */ - public PlanEmployeeAssignmentResponse fetchPlanEmployeeAssignment(RequestInfo requestInfo, String employeeId, String planConfigId, String tenantId, List roles, List jurisdiction) { + public PlanEmployeeAssignmentResponse fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest planEmployeeAssignmentSearchRequest) { + // Get plan employee assignment uri StringBuilder uri = getPlanEmployeeAssignmentUri(); - // Get search request body for plan employee assignment - PlanEmployeeAssignmentSearchRequest searchRequest = getPlanEmployeeAssignmentRequest(requestInfo, employeeId, planConfigId, tenantId, roles, jurisdiction); PlanEmployeeAssignmentResponse response = new PlanEmployeeAssignmentResponse(); try { - response = restTemplate.postForObject(uri.toString(), searchRequest, PlanEmployeeAssignmentResponse.class); + response = restTemplate.postForObject(uri.toString(), planEmployeeAssignmentSearchRequest, PlanEmployeeAssignmentResponse.class); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_EMPLOYEE_ASSIGNMENT_DETAILS, e); } @@ -54,32 +47,6 @@ public PlanEmployeeAssignmentResponse fetchPlanEmployeeAssignment(RequestInfo re return response; } - /** - * This method builds the search request body for plan employee assignment search - * - * @param requestInfo request info from the request. - * @param employeeId employee id from the request. - * @param planConfigId plan configuration id from the request. - * @param tenantId tenant id from the request. - * @param roles allowed roles for census - * @param jurisdiction list of ancestral boundary codes for the given boundary - * @return the search request for pln employee assignment search - */ - private PlanEmployeeAssignmentSearchRequest getPlanEmployeeAssignmentRequest(RequestInfo requestInfo, String employeeId, String planConfigId, String tenantId, List roles, List jurisdiction) { - PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() - .tenantId(tenantId) - .planConfigurationId(planConfigId) - .employeeId(employeeId) - .role(roles) - .jurisdiction(jurisdiction) - .build(); - - return PlanEmployeeAssignmentSearchRequest.builder() - .requestInfo(requestInfo) - .planEmployeeAssignmentSearchCriteria(searchCriteria) - .build(); - } - /** * This method creates the uri for plan employee assignment search * diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 572ae9b3af3..53552421f4e 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -15,6 +15,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; @@ -47,12 +48,12 @@ public class Census { private String boundaryCode = null; @JsonProperty("assignee") - @NotNull + @Size(max = 64) private String assignee = null; @JsonProperty("status") - @NotNull - private StatusEnum status = null; + @Size(max = 64) + private String status = null; @JsonProperty("type") @NotNull @@ -85,22 +86,19 @@ public class Census { @JsonProperty("facilityAssigned") private boolean facilityAssigned; + @JsonProperty("workflow") + @Valid + private Workflow workflow; + + @JsonIgnore + private List assigneeJurisdiction; + @JsonProperty("additionalDetails") private Object additionalDetails = null; @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; - /** - * The status used in the Census - */ - public enum StatusEnum { - VALIDATED, - APPROVED, - PENDING_FOR_APPROVAL, - PENDING_FOR_VALIDATION - } - /** * Gets or Sets type */ diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 2bc62d31553..5b86e5590e2 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -12,6 +12,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; @@ -82,6 +83,13 @@ public class CensusDTO { @JsonProperty("facilityAssigned") private boolean facilityAssigned; + @JsonProperty("workflow") + @Valid + private Workflow workflow; + + @JsonIgnore + private List assigneeJurisdiction; + @JsonProperty("additionalDetails") private Object additionalDetails = null; From 94651851661d0e5856e94fc312f85ed623ff0832 Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Sat, 19 Oct 2024 13:04:37 +0530 Subject: [PATCH 199/351] Added code to ensure that only active employee assignments are returned --- .../src/main/java/digit/service/PlanEmployeeService.java | 7 +++++-- .../web/models/PlanEmployeeAssignmentSearchCriteria.java | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java index 996b0384e30..afa9ee46f38 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Service; import java.util.Collections; +import java.util.List; @Service public class PlanEmployeeService { @@ -60,11 +61,13 @@ public PlanEmployeeAssignmentResponse create(PlanEmployeeAssignmentRequest reque * @return A list of plan employee assignments that matches the search criteria. */ public PlanEmployeeAssignmentResponse search(PlanEmployeeAssignmentSearchRequest request) { - validator.validateSearch(request); + // Delegate search request to repository + List planEmployeeAssignmentList = repository.search(request.getPlanEmployeeAssignmentSearchCriteria()); + // Build and return response back to controller return PlanEmployeeAssignmentResponse.builder() .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) - .planEmployeeAssignment(repository.search(request.getPlanEmployeeAssignmentSearchCriteria())) + .planEmployeeAssignment(planEmployeeAssignmentList) .totalCount(repository.count(request.getPlanEmployeeAssignmentSearchCriteria())) .build(); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index d1ebec757f2..57154c7204f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -48,5 +48,6 @@ public class PlanEmployeeAssignmentSearchCriteria { private List jurisdiction = null; @JsonProperty("active") - private Boolean active = null; + @Builder.Default + private Boolean active = Boolean.TRUE; } From 53eb8fcccde35f8f9eafe361c854e6674d3a1113 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 13:20:53 +0530 Subject: [PATCH 200/351] Added workflow for census --- .../java/digit/service/enrichment/CensusEnrichment.java | 2 -- .../java/digit/service/validator/CensusValidator.java | 2 +- .../models/plan/PlanEmployeeAssignmentSearchCriteria.java | 2 +- .../src/main/resources/application.properties | 8 ++++++++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index 394fa5176ba..7d3c9deaf09 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -84,8 +84,6 @@ public void enrichUpdate(CensusRequest request) { } }); } - - census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); } } diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 4cc68165bee..ce5bafdc467 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -100,7 +100,7 @@ private void validatePartnerForCensus(CensusRequest request) { List jurisdiction = Arrays.asList(request.getCensus().getBoundaryAncestralPath().get(0).split("\\|")); PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() - .employeeId(userInfo.getUuid()) + .employeeId(Collections.singletonList(userInfo.getUuid())) .planConfigurationId(request.getCensus().getSource()) .tenantId(request.getCensus().getTenantId()) .role(configs.getAllowedCensusRoles()) diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java index d7a1d867273..6e38c1dad95 100644 --- a/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java @@ -31,7 +31,7 @@ public class PlanEmployeeAssignmentSearchCriteria { private String tenantId = null; @JsonProperty("employeeId") - private String employeeId = null; + private List employeeId = null; @JsonProperty("planConfigurationId") @Size(max = 64) diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index f047efd2d21..614ae4c8494 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -56,6 +56,14 @@ egov.boundary.relationship.search.endpoint=/boundary-service/boundary-relationsh egov.plan.service.host=https://unified-dev.digit.org egov.plan.employee.assignment.search.endpoint=/plan-service/employee/_search +# Workflow +egov.workflow.host=https://unified-dev.digit.org +egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition +workflow.initiate.action=INITIATE +workflow.intermediate.action=EDIT_AND_SEND_FOR_APPROVAL,APPROVE +workflow.send.back.actions=SEND_BACK_FOR_CORRECTION + + #Pagination config census.default.offset=0 census.default.limit=10 From 828f60b078d2a6b3bd47e792379e3f64ba1eb3fd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 14:40:57 +0530 Subject: [PATCH 201/351] Added status count for plan --- .../java/digit/repository/PlanRepository.java | 2 ++ .../repository/impl/PlanRepositoryImpl.java | 22 +++++++++++++-- .../querybuilder/PlanQueryBuilder.java | 25 ++++++++++++++--- .../rowmapper/PlanStatusCountRowMapper.java | 28 +++++++++++++++++++ .../main/java/digit/service/PlanService.java | 9 ++++++ .../java/digit/web/models/PlanResponse.java | 6 ++++ 6 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java index e63da7ca881..104342bc2e6 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java @@ -5,6 +5,7 @@ import digit.web.models.PlanSearchCriteria; import java.util.List; +import java.util.Map; public interface PlanRepository { public void create(PlanRequest planRequest); @@ -15,4 +16,5 @@ public interface PlanRepository { public Integer count(PlanSearchCriteria planSearchCriteria); + public Map statusCount(PlanSearchCriteria planSearchCriteria); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 0961afd1144..2f0c47f3fee 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -5,9 +5,9 @@ import digit.repository.PlanRepository; import digit.repository.querybuilder.PlanQueryBuilder; import digit.repository.rowmapper.PlanRowMapper; +import digit.repository.rowmapper.PlanStatusCountRowMapper; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; -import org.egov.tracer.model.CustomException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.stereotype.Repository; @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; @Slf4j @Repository @@ -30,13 +31,16 @@ public class PlanRepositoryImpl implements PlanRepository { private Configuration config; + private PlanStatusCountRowMapper statusCountRowMapper; + public PlanRepositoryImpl(Producer producer, PlanQueryBuilder planQueryBuilder, PlanRowMapper planRowMapper, - JdbcTemplate jdbcTemplate, Configuration config) { + JdbcTemplate jdbcTemplate, Configuration config, PlanStatusCountRowMapper statusCountRowMapper) { this.producer = producer; this.planQueryBuilder = planQueryBuilder; this.planRowMapper = planRowMapper; this.jdbcTemplate = jdbcTemplate; this.config = config; + this.statusCountRowMapper = statusCountRowMapper; } /** @@ -71,6 +75,20 @@ public List search(PlanSearchCriteria planSearchCriteria) { return plans; } + /** + * Counts the plan based on their current status for the provided search criteria. + * + * @param planSearchCriteria The search criteria for filtering plans. + * @return The status count of plans for the given search criteria. + */ + @Override + public Map statusCount(PlanSearchCriteria planSearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = planQueryBuilder.getPlanStatusCountQuery(planSearchCriteria, preparedStmtList); + + return jdbcTemplate.query(query, statusCountRowMapper, preparedStmtList.toArray()); + } + /** * This method emits an event to the persister for it to update the plan in the database. * @param planRequest diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index db0e002cd14..4e154062218 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -25,7 +25,7 @@ public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_SEARCH_BASE_QUERY = "SELECT id FROM plan "; - private static final String PLAN_QUERY = "SELECT plan.id as plan_id, plan.tenant_id as plan_tenant_id, plan.locality as plan_locality, plan.campaign_id as plan_campaign_id, plan.plan_configuration_id as plan_plan_configuration_id, plan.boundary_ancestral_path as plan_boundary_ancestral_path, plan.additional_details as plan_additional_details, plan.created_by as plan_created_by, plan.created_time as plan_created_time, plan.last_modified_by as plan_last_modified_by, plan.last_modified_time as plan_last_modified_time,\n" + + private static final String PLAN_QUERY = "SELECT plan.id as plan_id, plan.tenant_id as plan_tenant_id, plan.locality as plan_locality, plan.campaign_id as plan_campaign_id, plan.plan_configuration_id as plan_plan_configuration_id, plan.boundary_ancestral_path as plan_boundary_ancestral_path, plan.status as plan_status, plan.assignee as plan_assignee, plan.additional_details as plan_additional_details, plan.created_by as plan_created_by, plan.created_time as plan_created_time, plan.last_modified_by as plan_last_modified_by, plan.last_modified_time as plan_last_modified_time,\n" + "\t plan_activity.id as plan_activity_id, plan_activity.code as plan_activity_code, plan_activity.description as plan_activity_description, plan_activity.planned_start_date as plan_activity_planned_start_date, plan_activity.planned_end_date as plan_activity_planned_end_date, plan_activity.dependencies as plan_activity_dependencies, plan_activity.plan_id as plan_activity_plan_id, plan_activity.created_by as plan_activity_created_by, plan_activity.created_time as plan_activity_created_time, plan_activity.last_modified_by as plan_activity_last_modified_by, plan_activity.last_modified_time as plan_activity_last_modified_time,\n" + "\t plan_activity_condition.id as plan_activity_condition_id, plan_activity_condition.entity as plan_activity_condition_entity, plan_activity_condition.entity_property as plan_activity_condition_entity_property, plan_activity_condition.expression as plan_activity_condition_expression, plan_activity_condition.activity_id as plan_activity_condition_activity_id, plan_activity_condition.is_active as plan_activity_condition_is_active, plan_activity_condition.created_by as plan_activity_condition_created_by, plan_activity_condition.created_time as plan_activity_condition_created_time, plan_activity_condition.last_modified_by as plan_activity_condition_last_modified_by, plan_activity_condition.last_modified_time as plan_activity_condition_last_modified_time,\n" + "\t plan_resource.id as plan_resource_id, plan_resource.resource_type as plan_resource_resource_type, plan_resource.estimated_number as plan_resource_estimated_number, plan_resource.plan_id as plan_resource_plan_id, plan_resource.activity_code as plan_resource_activity_code, plan_resource.created_by as plan_resource_created_by, plan_resource.created_time as plan_resource_created_time, plan_resource.last_modified_by as plan_resource_last_modified_by, plan_resource.last_modified_time as plan_resource_last_modified_time,\n" + @@ -40,6 +40,8 @@ public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + private static final String PLAN_STATUS_COUNT_WRAPPER = "SELECT COUNT(plan_id) as plan_status_count, plan_status FROM ({INTERNAL_QUERY}) as plan_status_map GROUP BY plan_status"; + public String getPlanQuery(List ids, List preparedStmtList) { return buildPlanQuery(ids, preparedStmtList); } @@ -57,7 +59,7 @@ private String buildPlanQuery(List ids, List preparedStmtList) { } public String getPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList) { - String query = buildPlanSearchQuery(planSearchCriteria, preparedStmtList, Boolean.FALSE); + String query = buildPlanSearchQuery(planSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.FALSE); query = queryUtil.addOrderByClause(query, PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE); query = getPaginatedQuery(query, planSearchCriteria, preparedStmtList); return query; @@ -71,10 +73,21 @@ public String getPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList) { - String query = buildPlanSearchQuery(criteria, preparedStmtList, Boolean.TRUE); + String query = buildPlanSearchQuery(criteria, preparedStmtList, Boolean.TRUE, Boolean.FALSE); return query; } + /** + * Constructs the status count query to get the count of plans based on their current status for the given search criteria + * + * @param searchCriteria The criteria used for filtering Plans. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A SQL query string to get the status count of Plans for a given search criteria. + */ + public String getPlanStatusCountQuery(PlanSearchCriteria searchCriteria, List preparedStmtList) { + return buildPlanSearchQuery(searchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); + } + /** * Method to build query dynamically based on the criteria passed to the method * @@ -82,7 +95,7 @@ public String getPlanCountQuery(PlanSearchCriteria criteria, List prepar * @param preparedStmtList * @return */ - private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList, boolean isCount) { + private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList, boolean isCount, boolean isStatusCount) { StringBuilder builder = new StringBuilder(PLAN_SEARCH_BASE_QUERY); if (!ObjectUtils.isEmpty(planSearchCriteria.getTenantId())) { @@ -147,6 +160,10 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< return countQuery.toString(); } + if (isStatusCount) { + return PLAN_STATUS_COUNT_WRAPPER.replace("{INTERNAL_QUERY}", builder); + } + return builder.toString(); } diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java new file mode 100644 index 00000000000..2cb3ea038ef --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java @@ -0,0 +1,28 @@ +package digit.repository.rowmapper; + +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Component; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +@Component +public class PlanStatusCountRowMapper implements ResultSetExtractor> { + + @Override + public Map extractData(ResultSet rs) throws SQLException, DataAccessException { + + Map statusCountMap = new HashMap<>(); + + while (rs.next()) { + String status = rs.getString("plan_status"); + Integer statusCount = rs.getInt("plan_status_count"); + statusCountMap.put(status, statusCount); + } + + return statusCountMap; + } +} diff --git a/health-services/plan-service/src/main/java/digit/service/PlanService.java b/health-services/plan-service/src/main/java/digit/service/PlanService.java index b425a48e816..1619e52856d 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanService.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; @Service public class PlanService { @@ -65,10 +66,18 @@ public PlanResponse searchPlan(PlanSearchRequest body) { // Delegate search request to repository List planList = planRepository.search(body.getPlanSearchCriteria()); + // Get the total count of plans for given search criteria + Integer count = planRepository.count(body.getPlanSearchCriteria()); + + // Get the status count of plans for given search criteria + Map statusCountMap = planRepository.statusCount(body.getPlanSearchCriteria()); + // Build and return response back to controller return PlanResponse.builder() .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(body.getRequestInfo(), Boolean.TRUE)) .plan(planList) + .totalCount(count) + .statusCount(statusCountMap) .build(); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java index 153464d72a1..51e11ec94a5 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; +import java.util.Map; + import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; @@ -32,4 +34,8 @@ public class PlanResponse { @Valid private Integer totalCount = null; + @JsonProperty("StatusCount") + @Valid + private Map statusCount = null; + } From ab3bd1d43dbc2042401513bf467318f2473e90b1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 16:31:20 +0530 Subject: [PATCH 202/351] Added status count for plan --- .../src/main/java/digit/config/Configuration.java | 2 +- .../querybuilder/PlanConfigQueryBuilder.java | 6 ++++++ .../repository/querybuilder/PlanQueryBuilder.java | 11 ++++++++--- .../rowmapper/PlanStatusCountRowMapper.java | 2 +- .../web/models/PlanConfigurationSearchCriteria.java | 3 +++ 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 48a67dae07c..77296e9c892 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -107,7 +107,7 @@ public class Configuration { @Value("${workflow.intermediate.action}") private List wfIntermediateActions; - @Value("${workflow.send.back.actions}") + @Value("${workflow.send.back.action}") private List wfSendBackActions; } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 6df15346161..3357073e976 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -103,6 +103,12 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter preparedStmtList.add(criteria.getId()); } + if (!CollectionUtils.isEmpty(criteria.getIds())) { + addClauseIfRequired(preparedStmtList, builder); + builder.append(" pc.id IN ( ").append(queryUtil.createQuery(criteria.getIds().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(criteria.getIds())); + } + if (criteria.getCampaignId() != null) { addClauseIfRequired(preparedStmtList, builder); builder.append(" pc.campaign_id = ?"); diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 4e154062218..a711c34b3f7 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -40,7 +40,7 @@ public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; - private static final String PLAN_STATUS_COUNT_WRAPPER = "SELECT COUNT(plan_id) as plan_status_count, plan_status FROM ({INTERNAL_QUERY}) as plan_status_map GROUP BY plan_status"; + private static final String PLAN_STATUS_COUNT_QUERY = "SELECT COUNT(id) as plan_status_count, status FROM (SELECT id, status FROM plan {INTERNAL_QUERY}) as plan_status_map GROUP BY status"; public String getPlanQuery(List ids, List preparedStmtList) { return buildPlanQuery(ids, preparedStmtList); @@ -98,6 +98,10 @@ public String getPlanStatusCountQuery(PlanSearchCriteria searchCriteria, List preparedStmtList, boolean isCount, boolean isStatusCount) { StringBuilder builder = new StringBuilder(PLAN_SEARCH_BASE_QUERY); + if(isStatusCount) { + builder = new StringBuilder(); + } + if (!ObjectUtils.isEmpty(planSearchCriteria.getTenantId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" tenant_id = ? "); @@ -134,12 +138,13 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< preparedStmtList.add(planSearchCriteria.getStatus()); } - if (!ObjectUtils.isEmpty(planSearchCriteria.getAssignee())) { + if (!isStatusCount && !ObjectUtils.isEmpty(planSearchCriteria.getAssignee())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" assignee = ? "); preparedStmtList.add(planSearchCriteria.getAssignee()); } + if (!CollectionUtils.isEmpty(planSearchCriteria.getJurisdiction())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" ARRAY [ ") @@ -161,7 +166,7 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< } if (isStatusCount) { - return PLAN_STATUS_COUNT_WRAPPER.replace("{INTERNAL_QUERY}", builder); + return PLAN_STATUS_COUNT_QUERY.replace("{INTERNAL_QUERY}", builder); } return builder.toString(); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java index 2cb3ea038ef..4e99bffbe7b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java @@ -18,7 +18,7 @@ public Map extractData(ResultSet rs) throws SQLException, DataA Map statusCountMap = new HashMap<>(); while (rs.next()) { - String status = rs.getString("plan_status"); + String status = rs.getString("status"); Integer statusCount = rs.getInt("plan_status_count"); statusCountMap.put(status, statusCount); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java index 83000157f5f..8ff4d9ca704 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java @@ -31,6 +31,9 @@ public class PlanConfigurationSearchCriteria { @JsonProperty("id") private String id = null; + @JsonProperty("ids") + private List ids = null; + @JsonProperty("name") private String name = null; From 434ffb37ee00b42d6ab9b6d5a1de6bc6765074e7 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 16:49:04 +0530 Subject: [PATCH 203/351] removed assignee search in statusCount enrichment --- .../java/digit/repository/querybuilder/CensusQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 3e675760eee..ef94a9f8272 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -94,7 +94,7 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep preparedStmtList.add(criteria.getStatus()); } - if (!ObjectUtils.isEmpty(criteria.getAssignee())) { + if (!isStatusCount && !ObjectUtils.isEmpty(criteria.getAssignee())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.assignee = ?"); preparedStmtList.add(criteria.getAssignee()); From d594a075ec595f521cd7894fd78b4d1f7be23a6e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 17:21:37 +0530 Subject: [PATCH 204/351] removed assignee search in statusCount enrichment --- .../java/digit/repository/impl/CensusRepositoryImpl.java | 2 +- .../digit/repository/querybuilder/CensusQueryBuilder.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 4c7ae28c94c..a1c6e3db0e4 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -120,7 +120,7 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .hierarchyType(census.getHierarchyType()) .boundaryCode(census.getBoundaryCode()) .assignee(census.getAssignee()) - .status(census.getStatus().toString()) + .status(census.getStatus()) .type(census.getType().toString()) .totalPopulation(census.getTotalPopulation()) .populationByDemographics(census.getPopulationByDemographics()) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index af2f4159a05..685a4c62696 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -63,7 +63,8 @@ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { - return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder().tenantId(searchCriteria.getTenantId()).source(searchCriteria.getSource()).jurisdiction(searchCriteria.getJurisdiction()).build(); + return buildCensusQuery(censusSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); } /** @@ -94,7 +95,7 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep preparedStmtList.add(criteria.getStatus()); } - if (!isStatusCount && !ObjectUtils.isEmpty(criteria.getAssignee())) { + if (!ObjectUtils.isEmpty(criteria.getAssignee())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.assignee = ?"); preparedStmtList.add(criteria.getAssignee()); From 0598e3e4d106173ccd2b188bdb013deac5dd0723 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 17:38:43 +0530 Subject: [PATCH 205/351] modified plan status count query builder --- .../repository/querybuilder/PlanQueryBuilder.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index a711c34b3f7..9fda35bf9e6 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -85,7 +85,16 @@ public String getPlanCountQuery(PlanSearchCriteria criteria, List prepar * @return A SQL query string to get the status count of Plans for a given search criteria. */ public String getPlanStatusCountQuery(PlanSearchCriteria searchCriteria, List preparedStmtList) { - return buildPlanSearchQuery(searchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); + PlanSearchCriteria planSearchCriteria = PlanSearchCriteria.builder() + .tenantId(searchCriteria.getTenantId()) + .ids(searchCriteria.getIds()) + .planConfigurationId(searchCriteria.getPlanConfigurationId()) + .locality(searchCriteria.getLocality()) + .campaignId(searchCriteria.getCampaignId()) + .status(searchCriteria.getStatus()) + .jurisdiction(searchCriteria.getJurisdiction()) + .build(); + return buildPlanSearchQuery(planSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); } /** @@ -138,7 +147,7 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< preparedStmtList.add(planSearchCriteria.getStatus()); } - if (!isStatusCount && !ObjectUtils.isEmpty(planSearchCriteria.getAssignee())) { + if (!ObjectUtils.isEmpty(planSearchCriteria.getAssignee())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" assignee = ? "); preparedStmtList.add(planSearchCriteria.getAssignee()); From aefc39c920803e1ed127fc2b79b8b52e79a2e7b4 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 19 Oct 2024 18:23:40 +0530 Subject: [PATCH 206/351] added duplicate record validation for plan facility --- .../main/java/digit/config/Configuration.java | 2 +- .../java/digit/config/ServiceConstants.java | 3 +++ .../PlanFacilityQueryBuilder.java | 6 ++++++ .../validator/PlanFacilityValidator.java | 20 +++++++++++++++++++ .../models/PlanFacilitySearchCriteria.java | 3 +++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 77296e9c892..48a67dae07c 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -107,7 +107,7 @@ public class Configuration { @Value("${workflow.intermediate.action}") private List wfIntermediateActions; - @Value("${workflow.send.back.action}") + @Value("${workflow.send.back.actions}") private List wfSendBackActions; } diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 6fa91e2bd51..429b4d4a6e1 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -104,6 +104,9 @@ public class ServiceConstants { public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_MESSAGE = "Plan employee assignment for the provided details already exists"; + public static final String PLAN_FACILITY_LINKAGE_ALREADY_EXISTS_CODE = "PLAN_FACILITY_LINKAGE_ALREADY_EXISTS"; + public static final String PLAN_FACILITY_LINKAGE_ALREADY_EXISTS_MESSAGE = "Plan facility linkage for the provided facilityId and planConfigId already exists"; + public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_CODE = "PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY"; public static final String PLAN_EMPLOYEE_ASSIGNMENT_ID_EMPTY_MESSAGE = "Plan employee assignment id cannot be empty"; diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index 7f8e6c3135a..6dabdab2bf4 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -68,6 +68,12 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil preparedStmtList.add(planFacilitySearchCriteria.getPlanConfigurationId()); } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityId())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" facility_id = ? "); + preparedStmtList.add(planFacilitySearchCriteria.getFacilityId()); + } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getResidingBoundaries())) { List residingBoundaries = planFacilitySearchCriteria.getResidingBoundaries(); queryUtil.addClauseIfRequired(builder, preparedStmtList); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index e91c0ae2e0f..42109001e25 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -50,6 +50,9 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe // Retrieve the root-level tenant ID (state-level) based on the facility's tenant ID String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); + // Validate duplicate records for plan facility + validateDuplicateRecords(planFacilityRequest); + // Validate PlanConfiguration Existence and fetch the plan configuration details using the PlanConfigurationId List planConfigurations = fetchPlanConfigurationById(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); @@ -60,6 +63,23 @@ public void validatePlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRe validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, planFacilityRequest); } + /** + * Validates if plan facility linkage for the provided planConfiguration id and facility id already exists + * + * @param planFacilityRequest The plan facility linkage create request + */ + private void validateDuplicateRecords(@Valid PlanFacilityRequest planFacilityRequest) { + PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + + PlanFacilitySearchCriteria searchCriteria = PlanFacilitySearchCriteria.builder().planConfigurationId(planFacility.getPlanConfigurationId()).facilityId(planFacility.getFacilityId()).build(); + + List planFacilityList = planFacilityRepository.search(searchCriteria); + + if (!CollectionUtils.isEmpty(planFacilityList)) { + throw new CustomException(PLAN_FACILITY_LINKAGE_ALREADY_EXISTS_CODE, PLAN_FACILITY_LINKAGE_ALREADY_EXISTS_MESSAGE); + } + } + /** * This method validates the Plan Facility Update request. * It performs multiple validations such as plan facility existence diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java index 2bdb197264f..fd3e750bae7 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java @@ -43,6 +43,9 @@ public class PlanFacilitySearchCriteria { @JsonProperty("residingBoundaries") private List residingBoundaries = null; + @JsonProperty("facilityId") + private String facilityId = null; + @JsonProperty("offset") private Integer offset = null; From 7c24d74d9d02e663ea76fcea49bb05a5241fcf91 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 21 Oct 2024 12:17:40 +0530 Subject: [PATCH 207/351] enabled partnerAssignmentValidation for census --- .../src/main/java/digit/service/CensusService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index de66214e7b3..07c301075b2 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -77,6 +77,7 @@ public CensusResponse search(CensusSearchRequest request) { * @return The updated census response. */ public CensusResponse update(CensusRequest request) { + request.getCensus().setPartnerAssignmentValidationEnabled(true); validator.validateUpdate(request); // Validate census update request enrichment.enrichUpdate(request); // Enrich census update request workflow.invokeWorkflowForStatusUpdate(request); // Call workflow transition API for status update From 07b54849f0f6b7b60b524fea68c061c1150218f0 Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Mon, 21 Oct 2024 12:37:28 +0530 Subject: [PATCH 208/351] Added flag to fetch unique assignments --- .../PlanEmployeeAssignmentQueryBuilder.java | 10 ++++++++-- .../models/PlanEmployeeAssignmentSearchCriteria.java | 5 +++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index e9ab46c1f56..4094c6dffa1 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -20,8 +20,12 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (plan_configuration_id) id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; /** @@ -34,7 +38,8 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { */ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList, Boolean.FALSE); - query = queryUtil.addOrderByClause(query, PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = queryUtil.addOrderByClause(query, Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? + UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE : PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); query = queryUtil.getPaginatedQuery(query, preparedStmtList); return query; } @@ -60,7 +65,8 @@ public String getPlanEmployeeAssignmentCountQuery(PlanEmployeeAssignmentSearchCr * @return A SQL query string for searching planEmployeeAssignment */ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList, Boolean isCount) { - StringBuilder builder = new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); + StringBuilder builder = Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? + new StringBuilder(UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY) : new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); if (searchCriteria.getId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 57154c7204f..8039edc86ac 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -50,4 +50,9 @@ public class PlanEmployeeAssignmentSearchCriteria { @JsonProperty("active") @Builder.Default private Boolean active = Boolean.TRUE; + + @JsonProperty("filterUniqueByPlanConfig") + @Builder.Default + private Boolean filterUniqueByPlanConfig = Boolean.FALSE; + } From 8b009378366005917a65206fee89db77cbd2e33e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 21 Oct 2024 15:25:31 +0530 Subject: [PATCH 209/351] Removing validateResources method from PlanValidator --- .../java/digit/service/PlanValidator.java | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 8042e755b2f..99e055019ab 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -82,9 +82,6 @@ public void validatePlanCreate(PlanRequest request) { // Validate plan configuration existence validatePlanConfigurationExistence(request); - // Validate resources - validateResources(request); - // Validate resource-activity linkage validateResourceActivityLinkage(request); @@ -229,32 +226,6 @@ private void validatePlanConfigurationExistence(PlanRequest request) { } } - /** - * This method validates the resources provided in the request - * - * @param request - */ - private void validateResources(PlanRequest request) { - // If plan configuration id is not provided, providing resources is mandatory - if (ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) - && CollectionUtils.isEmpty(request.getPlan().getResources())) { - throw new CustomException(PLAN_RESOURCES_MANDATORY_CODE, PLAN_RESOURCES_MANDATORY_MESSAGE); - } - - // If plan configuration id is provided, providing resources is not allowed - if (!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) - && !CollectionUtils.isEmpty(request.getPlan().getResources())) { - throw new CustomException(PLAN_RESOURCES_NOT_ALLOWED_CODE, PLAN_RESOURCES_NOT_ALLOWED_MESSAGE); - } - - // Validate resource type existence - if (!CollectionUtils.isEmpty(request.getPlan().getResources())) { - request.getPlan().getResources().forEach(resource -> { - // Validate resource type existence - }); - } - } - /** * This method validates the linkage between resources and activities * @@ -321,9 +292,6 @@ public void validatePlanUpdate(PlanRequest request) { // Validate plan configuration existence validatePlanConfigurationExistence(request); - // Validate resources - validateResources(request); - // Validate resource uuid uniqueness validateResourceUuidUniqueness(request); From 554e20d5dd2c1f239b52248435e35f7ae8782f6d Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 21 Oct 2024 15:44:09 +0530 Subject: [PATCH 210/351] // enriching boundary ancestral path for incoming plan request from the database --- .../src/main/java/digit/service/PlanValidator.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 99e055019ab..2ecdba2eaed 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -382,11 +382,14 @@ private void validateActivitiesUuidUniqueness(PlanRequest request) { */ private void validatePlanExistence(PlanRequest request) { // If plan id provided is invalid, throw an exception - if (CollectionUtils.isEmpty(planRepository.search(PlanSearchCriteria.builder() + List planFromDatabase = planRepository.search(PlanSearchCriteria.builder() .ids(Collections.singleton(request.getPlan().getId())) - .build()))) { + .build()); + if (CollectionUtils.isEmpty(planFromDatabase)) { throw new CustomException(INVALID_PLAN_ID_CODE, INVALID_PLAN_ID_MESSAGE); } + // enriching boundary ancestral path for incoming plan request from the database + request.getPlan().setBoundaryAncestralPath(planFromDatabase.get(0).getBoundaryAncestralPath()); } /** From 479a2f67bc25e86af304d86b88892a1517559eed Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 21 Oct 2024 16:19:44 +0530 Subject: [PATCH 211/351] census consumer for enriching facilityId --- .../main/java/digit/config/Configuration.java | 3 + .../java/digit/config/ServiceConstants.java | 4 ++ .../kafka/FacilityCatchmentConsumer.java | 57 +++++++++++++++++ .../src/main/java/digit/util/CommonUtil.java | 58 ++++++++++++++++++ .../web/models/plan/PlanFacilityDTO.java | 61 +++++++++++++++++++ .../models/plan/PlanFacilityRequestDTO.java | 33 ++++++++++ .../src/main/resources/application.properties | 2 + .../main/java/digit/config/Configuration.java | 3 + .../impl/PlanFacilityRepositoryImpl.java | 2 + .../src/main/resources/application.properties | 2 + 10 files changed, 225 insertions(+) create mode 100644 health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java create mode 100644 health-services/census-service/src/main/java/digit/util/CommonUtil.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityRequestDTO.java diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 8ebea72e920..2c1e919354a 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -28,6 +28,9 @@ public class Configuration { @Value("${census.update.topic}") private String censusUpdateTopic; + @Value("${boundary.facility.catchment.update.topic}") + private String facitilyCatchmentUpdateTopic; + // Boundary Service @Value("${egov.boundary.service.host}") private String boundaryServiceHost; diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 6194aab07d2..c7448233194 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -42,6 +42,7 @@ public class ServiceConstants { public static final String CITIZEN_LOWER = "Citizen"; public static final String USER = "user"; public static final String PIPE_REGEX = "\\|"; + public static final String FACILITY_ID_FIELD = "facilityId"; public static final String PARSING_ERROR_CODE = "PARSING ERROR"; public static final String PARSING_ERROR_MESSAGE = "Failed to parse JSON data from PGobject"; @@ -59,6 +60,9 @@ public class ServiceConstants { public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; + public static final String ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE = "ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS"; + public static final String ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE = "Exception occurred while updating additional details : "; + public static final String WORKFLOW_INTEGRATION_ERROR_CODE = "WORKFLOW_INTEGRATION_ERROR"; public static final String WORKFLOW_INTEGRATION_ERROR_MESSAGE = "Exception occured while integrating with workflow : "; diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java new file mode 100644 index 00000000000..e4374cc81d3 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -0,0 +1,57 @@ +package digit.kafka; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.service.CensusService; +import digit.util.CommonUtil; +import digit.web.models.Census; +import digit.web.models.CensusRequest; +import digit.web.models.CensusResponse; +import digit.web.models.plan.PlanFacilityDTO; +import digit.web.models.plan.PlanFacilityRequestDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +import static digit.config.ServiceConstants.FACILITY_ID_FIELD; + +@Component +@Slf4j +public class FacilityCatchmentConsumer { + + private ObjectMapper objectMapper; + + private CensusService service; + + private CommonUtil commonUtil; + + public FacilityCatchmentConsumer(ObjectMapper objectMapper, CensusService service, CommonUtil commonUtil) { + this.objectMapper = objectMapper; + this.service = service; + this.commonUtil = commonUtil; + } + + @KafkaListener(topics = {"${boundary.facility.catchment.update.topic}"}) + public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + PlanFacilityRequestDTO planFacilityRequestDTO = objectMapper.convertValue(consumerRecord, PlanFacilityRequestDTO.class); + PlanFacilityDTO planFacilityDTO = planFacilityRequestDTO.getPlanFacilityDTO(); + + CensusResponse censusResponse = service.search(commonUtil.getCensusSearchRequest(planFacilityDTO.getTenantId(), planFacilityDTO.getPlanConfigurationId(), planFacilityDTO.getServiceBoundaries())); + List censusFromSearch = censusResponse.getCensus(); + + String facilityId = planFacilityRequestDTO.getPlanFacilityDTO().getFacilityId(); + + censusFromSearch.forEach(census -> { + census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); + service.update(CensusRequest.builder().census(census).build()); + }); + } catch (Exception exception) { + log.error("Error in census consumer", exception); + } + } +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java new file mode 100644 index 00000000000..600966f8ab9 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -0,0 +1,58 @@ +package digit.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import digit.web.models.CensusSearchCriteria; +import digit.web.models.CensusSearchRequest; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +import static digit.config.ServiceConstants.ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE; +import static digit.config.ServiceConstants.ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE; + +@Component +public class CommonUtil { + + private ObjectMapper objectMapper; + + public CommonUtil(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + public Map updateFieldInAdditionalDetails(Object additionalDetails, String fieldToUpdate, String updatedValue) { + try { + + String jsonString = objectMapper.writeValueAsString(additionalDetails); + JsonNode rootNode = objectMapper.readTree(jsonString); + + // Cast rootNode to ObjectNode to allow modifications + ObjectNode objectNode = (ObjectNode) rootNode; + + // Update or Add facilityId in additional details object + objectNode.put(fieldToUpdate, updatedValue); + + // Convert updated ObjectNode back to a Map and set it in 'additionalDetails' + Map updatedDetails = objectMapper.convertValue(objectNode, Map.class); + return updatedDetails; + + } catch (JsonProcessingException e) { + throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE); + } + } + + public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary) { + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() + .tenantId(tenantId) + .source(planConfigId) + .areaCodes(List.of(serviceBoundary.split(", "))) + .effectiveTo(0L) + .build(); + + return CensusSearchRequest.builder().censusSearchCriteria(searchCriteria).build(); + } +} diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java new file mode 100644 index 00000000000..1b931ce0b03 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java @@ -0,0 +1,61 @@ +package digit.web.models.plan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +/** + * Plan Facility DTO + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityDTO { + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId = null; + + @JsonProperty("planConfigurationId") + @NotNull + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("facilityId") + @NotNull + @Size(max = 64) + private String facilityId = null; + + @JsonProperty("residingBoundary") + @NotNull + @Size(min = 1, max = 64) + private String residingBoundary = null; + + // Changed List to String to store as JSON + @JsonProperty("serviceBoundaries") + @NotNull + @Size(min = 1) + private String serviceBoundaries = null; // Store as JSON string + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + @NotNull + private Boolean active = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; + +} \ No newline at end of file diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityRequestDTO.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityRequestDTO.java new file mode 100644 index 00000000000..6bae9ac51c2 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityRequestDTO.java @@ -0,0 +1,33 @@ +package digit.web.models.plan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanFacilityRequestDTO + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilityRequestDTO { + + @JsonProperty("RequestInfo") + @Valid + @NotNull + private RequestInfo requestInfo; + + @JsonProperty("PlanFacility") + @Valid + @NotNull + private PlanFacilityDTO planFacilityDTO; + +} diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 614ae4c8494..d6ca280963b 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -71,5 +71,7 @@ census.default.limit=10 resource.config.consumer.census.create.topic=resource-census-create-topic resource.config.consumer.census.update.topic=resource-census-update-topic +boundary.facility.catchment.update.topic=boundary-catchment-update-topic + #Roles for census allowed.census.roles={'POPULATION_DATA_APPROVER','ROOT_POPULATION_DATA_APPROVER'} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 48a67dae07c..7a7656c6a0b 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -94,6 +94,9 @@ public class Configuration { @Value("${egov.facility.search.endpoint}") private String facilitySearchEndPoint; + @Value("${boundary.facility.catchment.update.topic}") + private String boundaryCatchmentUpdateTopic; + //Workflow @Value("${egov.workflow.host}") private String wfHost; diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index cfe0c0e32f5..6bdaca67168 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -107,6 +107,8 @@ public void update(PlanFacilityRequest planFacilityRequest) { try { PlanFacilityRequestDTO requestDTO = convertToDTO(planFacilityRequest); producer.push(config.getPlanFacilityUpdateTopic(), requestDTO); + producer.push(config.getBoundaryCatchmentUpdateTopic(), requestDTO); + log.info("Successfully pushed update for plan facility: {}", planFacilityRequest.getPlanFacility().getId()); } catch (Exception e) { throw new CustomException(FAILED_MESSAGE,config.getPlanFacilityUpdateTopic()); diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 5df37397f8f..14ca0d0c708 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -90,6 +90,8 @@ plan.default.limit=10 resource.config.consumer.plan.create.topic=resource-microplan-create-topic resource.update.plan.config.consumer.topic=resource-plan-config-update-topic +boundary.facility.catchment.update.topic=boundary-catchment-update-topic + # Role Map plan.estimation.approver.roles = ROOT_PLAN_ESTIMATION_APPROVER, PLAN_ESTIMATION_APPROVER role.map = {'ROOT_FACILITY_CATCHMENT_MAPPER':'FACILITY_CATCHMENT_MAPPER', 'FACILITY_CATCHMENT_MAPPER':'ROOT_FACILITY_CATCHMENT_MAPPER', 'ROOT_POPULATION_DATA_APPROVER':'POPULATION_DATA_APPROVER', 'POPULATION_DATA_APPROVER':'ROOT_POPULATION_DATA_APPROVER', 'ROOT_PLAN_ESTIMATION_APPROVER':'PLAN_ESTIMATION_APPROVER', 'PLAN_ESTIMATION_APPROVER':'ROOT_PLAN_ESTIMATION_APPROVER'} From d411f5d9a502594dd4f0c6bfff55c8e35f489f99 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 21 Oct 2024 17:33:35 +0530 Subject: [PATCH 212/351] modified plan count query --- .../java/digit/repository/querybuilder/PlanQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 9fda35bf9e6..5da94640c04 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -38,7 +38,7 @@ public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE = " order by plan.last_modified_time desc "; - private static final String PLAN_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + private static final String PLAN_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; private static final String PLAN_STATUS_COUNT_QUERY = "SELECT COUNT(id) as plan_status_count, status FROM (SELECT id, status FROM plan {INTERNAL_QUERY}) as plan_status_map GROUP BY status"; From ae1be52f131bfdfd28d0738574daa5625149a461 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 21 Oct 2024 17:47:15 +0530 Subject: [PATCH 213/351] Added pagination --- .../querybuilder/CensusQueryBuilder.java | 29 ++++++++++++++++-- .../web/models/CensusSearchCriteria.java | 3 ++ .../java/digit/web/models/Pagination.java | 30 +++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/web/models/Pagination.java diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 685a4c62696..0ac9035baa5 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -1,5 +1,6 @@ package digit.repository.querybuilder; +import digit.config.Configuration; import digit.util.QueryUtil; import digit.web.models.CensusSearchCriteria; import org.springframework.stereotype.Component; @@ -14,7 +15,10 @@ public class CensusQueryBuilder { private QueryUtil queryUtil; - public CensusQueryBuilder(QueryUtil queryUtil) { + private Configuration config; + + public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { + this.config = config; this.queryUtil = queryUtil; } @@ -40,7 +44,7 @@ public CensusQueryBuilder(QueryUtil queryUtil) { public String getCensusQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { String query = buildCensusQuery(searchCriteria, preparedStmtList, Boolean.FALSE, Boolean.FALSE); query = queryUtil.addOrderByClause(query, CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); - query = queryUtil.getPaginatedQuery(query, preparedStmtList); + query = getPaginatedQuery(query, preparedStmtList, searchCriteria); return query; } @@ -151,4 +155,25 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep return builder.toString(); } + /** + * This method appends pagination i.e. limit and offset to the query. + * + * @param query the query to which pagination is to be added. + * @param preparedStmtList prepared statement list to add limit and offset. + * @return a query with pagination + */ + public String getPaginatedQuery(String query, List preparedStmtList, CensusSearchCriteria searchCriteria) { + StringBuilder paginatedQuery = new StringBuilder(query); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getPagination()) && !ObjectUtils.isEmpty(searchCriteria.getPagination().getOffset()) ? searchCriteria.getPagination().getOffset() : config.getDefaultOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getPagination()) && !ObjectUtils.isEmpty(searchCriteria.getPagination().getLimit()) ? searchCriteria.getPagination().getLimit() : config.getDefaultLimit()); + + return paginatedQuery.toString(); + } + } diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index 4a3ab843cd7..3133270200e 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -51,6 +51,9 @@ public class CensusSearchCriteria { @JsonProperty("effectiveTo") private Long effectiveTo = null; + @JsonProperty("pagination") + private Pagination pagination = null; + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { this.areaCodes = new ArrayList<>(); diff --git a/health-services/census-service/src/main/java/digit/web/models/Pagination.java b/health-services/census-service/src/main/java/digit/web/models/Pagination.java new file mode 100644 index 00000000000..18ab979fba3 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/Pagination.java @@ -0,0 +1,30 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Pagination + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Pagination { + + @JsonIgnore + private String sortBy; + + @JsonIgnore + private String sortOrder; + + @JsonProperty("limit") + private Integer limit; + + @JsonProperty("offset") + private Integer offset; +} From 161d40daadc4794f5f95cf51017bb93f5d614034 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 21 Oct 2024 18:00:52 +0530 Subject: [PATCH 214/351] adding validateResources, validating only when plan configuration id is empty --- .../java/digit/service/PlanValidator.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 2ecdba2eaed..d59fdf37831 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -82,6 +82,9 @@ public void validatePlanCreate(PlanRequest request) { // Validate plan configuration existence validatePlanConfigurationExistence(request); + // Validate resources + validateResources(request); + // Validate resource-activity linkage validateResourceActivityLinkage(request); @@ -226,6 +229,19 @@ private void validatePlanConfigurationExistence(PlanRequest request) { } } + /** + * This method validates the resources provided in the request + * + * @param request + */ + private void validateResources(PlanRequest request) { + // If plan configuration id is not provided, providing resources is mandatory + if (ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) + && CollectionUtils.isEmpty(request.getPlan().getResources())) { + throw new CustomException(PLAN_RESOURCES_MANDATORY_CODE, PLAN_RESOURCES_MANDATORY_MESSAGE); + } + } + /** * This method validates the linkage between resources and activities * @@ -292,6 +308,9 @@ public void validatePlanUpdate(PlanRequest request) { // Validate plan configuration existence validatePlanConfigurationExistence(request); + // Validate resources + validateResources(request); + // Validate resource uuid uniqueness validateResourceUuidUniqueness(request); From 465a5d88fa676f6ab8a713a554dc509097032426 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 21 Oct 2024 18:46:27 +0530 Subject: [PATCH 215/351] Added planConfigName enrichment --- .../java/digit/config/ServiceConstants.java | 5 ++ .../PlanEmployeeAssignmentEnricher.java | 74 ++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 6fa91e2bd51..99541b78f8a 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -26,6 +26,8 @@ public class ServiceConstants { public static final String ROOT_PREFIX = "ROOT"; + public static final String PLAN_CONFIG_NAME_FIELD = "planConfigNames"; + public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; @@ -194,6 +196,9 @@ public class ServiceConstants { public static final String PROCESS_INSTANCE_NOT_FOUND_CODE = "PROCESS_INSTANCE_NOT_FOUND"; public static final String PROCESS_INSTANCE_NOT_FOUND_MESSAGE = "No process instance found with businessId: "; + public static final String ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_CODE = "ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS"; + public static final String ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_MESSAGE = "Exception occured while enriching additional details with plan config names: "; + public static final String FILES_NOT_FOUND_CODE = "FILES_NOT_FOUND"; public static final String FILES_NOT_FOUND_MESSAGE = "Files are not present in Plan Configuration."; diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java index 6850d22357b..395ea9ee503 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -1,15 +1,37 @@ package digit.service.enrichment; -import digit.web.models.PlanEmployeeAssignment; -import digit.web.models.PlanEmployeeAssignmentRequest; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import digit.repository.PlanEmployeeAssignmentRepository; +import digit.util.CommonUtil; +import digit.web.models.*; import org.egov.common.utils.UUIDEnrichmentUtil; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static digit.config.ServiceConstants.*; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @Component public class PlanEmployeeAssignmentEnricher { + private ObjectMapper objectMapper; + + private PlanEmployeeAssignmentRepository repository; + + private CommonUtil commonUtil; + + public PlanEmployeeAssignmentEnricher(ObjectMapper objectMapper, CommonUtil commonUtil, PlanEmployeeAssignmentRepository repository) { + this.objectMapper = objectMapper; + this.commonUtil = commonUtil; + this.repository = repository; + } + /** * Enriches the PlanEmployeeAssignmentRequest with id and audit details and sets active as true. * @@ -28,6 +50,9 @@ public void enrichCreate(PlanEmployeeAssignmentRequest request) { planEmployeeAssignment.setAuditDetails(prepareAuditDetails(planEmployeeAssignment.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); + + // Add a list of plan config names to which the employee is mapped + enrichWithPlanConfigName(planEmployeeAssignment); } /** @@ -43,4 +68,49 @@ public void enrichUpdate(PlanEmployeeAssignmentRequest request) { request.getRequestInfo(), Boolean.FALSE)); } + + /** + * This method enriches the additional details of plan employee assignment object with the name of all the plan configs to which the employee is mapped to. + * + * @param planEmployeeAssignment the object whose additional details is to be enriched + */ + private void enrichWithPlanConfigName(PlanEmployeeAssignment planEmployeeAssignment) { + + String tenantId = planEmployeeAssignment.getTenantId(); + List employeeAssignmentListFromSearch = getAllEmployeeAssignment(planEmployeeAssignment.getEmployeeId(), tenantId); + try { + + // Get or create the additionalDetails as an ObjectNode + ObjectNode objectNode = objectMapper.convertValue(planEmployeeAssignment.getAdditionalDetails(), ObjectNode.class); + + // Create an ArrayNode to hold the list of plan configuration names + ArrayNode planConfigNamesNode = objectNode.putArray(PLAN_CONFIG_NAME_FIELD); + + // Populate the ArrayNode with the plan configuration names + employeeAssignmentListFromSearch.stream() + .map(PlanEmployeeAssignment::getPlanConfigurationId) + .map(id -> getPlanConfigNameById(id, tenantId)) + .forEach(planConfigNamesNode::add); + + // Set the updated additionalDetails back into the planEmployeeAssignment + planEmployeeAssignment.setAdditionalDetails(objectMapper.convertValue(objectNode, Map.class)); + + } catch (Exception e) { + throw new CustomException(ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_MESSAGE); + } + } + + private String getPlanConfigNameById(String planConfigId, String tenantId) { + List planConfigurations = commonUtil.searchPlanConfigId(planConfigId, tenantId); + return planConfigurations.get(0).getName(); + } + + private List getAllEmployeeAssignment(String employeeId, String tenantId) { + PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(tenantId) + .employeeId(Collections.singletonList(employeeId)) + .build(); + + return repository.search(searchCriteria); + } } From abf80633bc337feb9ed2d0555cf0249a0cc75d2f Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Mon, 21 Oct 2024 18:47:53 +0530 Subject: [PATCH 216/351] Adding bulk plan update API --- .../java/digit/repository/PlanRepository.java | 2 + .../repository/impl/PlanRepositoryImpl.java | 22 ++- .../querybuilder/PlanQueryBuilder.java | 5 + .../main/java/digit/service/PlanService.java | 27 +++- .../java/digit/service/PlanValidator.java | 147 ++++++++++++++++-- .../service/workflow/WorkflowService.java | 108 ++++++++++--- .../digit/web/controllers/PlanController.java | 17 +- .../digit/web/models/BulkPlanRequest.java | 33 ++++ 8 files changed, 313 insertions(+), 48 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/BulkPlanRequest.java diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java index eb76b357701..085a7ab7ee8 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java @@ -1,5 +1,6 @@ package digit.repository; +import digit.web.models.BulkPlanRequest; import digit.web.models.Plan; import digit.web.models.PlanRequest; import digit.web.models.PlanSearchCriteria; @@ -13,4 +14,5 @@ public interface PlanRepository { public void update(PlanRequest planRequest); + public void bulkUpdate(BulkPlanRequest body); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 88737d8213e..aee367faaa2 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -66,9 +66,7 @@ public List search(PlanSearchCriteria planSearchCriteria) { } // Fetch plans from database based on the acquired ids - List plans = searchPlanByIds(planIds); - - return plans; + return searchPlanByIds(planIds); } /** @@ -81,6 +79,24 @@ public void update(PlanRequest planRequest) { producer.push(config.getPlanUpdateTopic(), planRequestDTO); } + @Override + public void bulkUpdate(BulkPlanRequest body) { + // Get bulk plan update query + String bulkPlanUpdateQuery = planQueryBuilder.getBulkPlanQuery(); + + // Prepare arguments for batch update + List batchArgs = body.getPlans().stream().map(plan -> new Object[] { + plan.getStatus(), + plan.getAssignee(), + plan.getAuditDetails().getLastModifiedBy(), + plan.getAuditDetails().getLastModifiedTime(), + plan.getId() + }).toList(); + + // Perform batch update + jdbcTemplate.batchUpdate(bulkPlanUpdateQuery, batchArgs); + } + /** * Helper method to query database for plan ids based on the provided search criteria. * @param planSearchCriteria diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index bee0c7d3f9a..95268107270 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -36,6 +36,8 @@ public PlanQueryBuilder(Configuration config, QueryUtil queryUtil) { "\t LEFT JOIN plan_resource ON plan.id = plan_resource.plan_id\n" + "\t LEFT JOIN plan_target ON plan.id = plan_target.plan_id"; + private static final String BULK_PLAN_UPDATE_QUERY = "UPDATE plan SET status = ?, assignee = ?, last_modified_by = ?, last_modified_time = ? WHERE id = ?"; + private static final String PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE = " order by plan.last_modified_time desc "; public String getPlanQuery(List ids, List preparedStmtList) { @@ -141,4 +143,7 @@ private String getPaginatedQuery(String query, PlanSearchCriteria planSearchCrit return paginatedQuery.toString(); } + public String getBulkPlanQuery() { + return BULK_PLAN_UPDATE_QUERY; + } } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanService.java b/health-services/plan-service/src/main/java/digit/service/PlanService.java index b425a48e816..effd6e430f2 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanService.java @@ -2,10 +2,8 @@ import digit.repository.PlanRepository; import digit.service.workflow.WorkflowService; -import digit.web.models.Plan; -import digit.web.models.PlanRequest; -import digit.web.models.PlanResponse; -import digit.web.models.PlanSearchRequest; +import digit.web.models.*; +import org.egov.common.contract.response.ResponseInfo; import org.egov.common.utils.ResponseInfoUtil; import org.springframework.stereotype.Service; @@ -96,4 +94,25 @@ public PlanResponse updatePlan(PlanRequest body) { .plan(Collections.singletonList(body.getPlan())) .build(); } + + /** + * This method processes bulk update requests for plan. + * @param bulkPlanRequest + * @return + */ + public PlanResponse bulkUpdate(BulkPlanRequest bulkPlanRequest) { + // Validate bulk plan update request + planValidator.validateBulkPlanUpdate(bulkPlanRequest); + + // Call workflow transition for updating status and assignee + workflowService.invokeWorkflowForStatusUpdate(bulkPlanRequest); + + // Delegate bulk update request to repository + planRepository.bulkUpdate(bulkPlanRequest); + + // Build and return response back to controller + return PlanResponse.builder().responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(bulkPlanRequest.getRequestInfo(), Boolean.TRUE)) + .plan(bulkPlanRequest.getPlans()) + .build(); + } } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 8042e755b2f..2ddb7d2ee3e 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -318,9 +318,6 @@ public void validatePlanUpdate(PlanRequest request) { // Validate activities uuid uniqueness validateActivitiesUuidUniqueness(request); - // Validate plan configuration existence - validatePlanConfigurationExistence(request); - // Validate resources validateResources(request); @@ -413,12 +410,18 @@ private void validateActivitiesUuidUniqueness(PlanRequest request) { * @param request the PlanRequest containing the plan */ private void validatePlanExistence(PlanRequest request) { - // If plan id provided is invalid, throw an exception - if (CollectionUtils.isEmpty(planRepository.search(PlanSearchCriteria.builder() + // Fetch plan from database + List planFromDatabase = planRepository.search(PlanSearchCriteria.builder() .ids(Collections.singleton(request.getPlan().getId())) - .build()))) { + .build()); + + // Throw exception if plan being updated does not exist in the database + if (CollectionUtils.isEmpty(planFromDatabase)) { throw new CustomException(INVALID_PLAN_ID_CODE, INVALID_PLAN_ID_MESSAGE); } + + // Enrich boundary ancestral path for incoming plan update from the database + request.getPlan().setBoundaryAncestralPath(planFromDatabase.get(0).getBoundaryAncestralPath()); } /** @@ -510,27 +513,29 @@ public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planReques if(CollectionUtils.isEmpty(planEmployeeAssignmentResponse.getPlanEmployeeAssignment())) throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_CODE, PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_MESSAGE + planRequest.getPlan().getLocality()); - validateJurisdictionPresent(planRequest, planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); - - //enrich jurisdiction of current assignee - planRequest.getPlan().setAssigneeJurisdiction(planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); + validateJurisdiction(planRequest.getPlan(), + planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction()); } /** * Validates that at least one jurisdiction exists within the hierarchy's boundary codes. * If no jurisdiction is found in the boundary set, throws a custom exception. * - * @param planRequest the request containing the boundary ancestral path + * @param plan the plan containing the boundary ancestral path * @param jurisdictions the list of jurisdictions to check against the boundary set * @throws CustomException if none of the jurisdictions are present in the boundary codes */ - public void validateJurisdictionPresent(PlanRequest planRequest, List jurisdictions) { - Set boundarySet = new HashSet<>(Arrays.asList(planRequest.getPlan().getBoundaryAncestralPath().split(PIPE_REGEX))); + public void validateJurisdiction(Plan plan, List jurisdictions) { + Set boundarySet = new HashSet<>(Arrays.asList(plan.getBoundaryAncestralPath() + .split(PIPE_REGEX))); // Check if any jurisdiction is present in the boundary set if (jurisdictions.stream().noneMatch(boundarySet::contains)) throw new CustomException(JURISDICTION_NOT_FOUND_CODE, JURISDICTION_NOT_FOUND_MESSAGE); + // Enrich jurisdiction of current assignee + plan.setAssigneeJurisdiction(jurisdictions); + } /** @@ -553,5 +558,121 @@ private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, planEnricher.enrichBoundaryAncestralPath(plan, tenantBoundary); } + /** + * TODO - 1. plan existence 2. plan employee assignment 3. uniqueness check across records + * @param bulkPlanRequest + */ + public void validateBulkPlanUpdate(BulkPlanRequest bulkPlanRequest) { + // Validate attributes across each plan in the bulk request + validatePlanAttributes(bulkPlanRequest); + + // Validate if plans provided in the request body exist + validatePlanExistence(bulkPlanRequest); + + // Validate plan employee assignment and jurisdiction + validatePlanEmployeeAssignmentAndJurisdiction(bulkPlanRequest); + } + + /** + * + * @param bulkPlanRequest + */ + private void validatePlanEmployeeAssignmentAndJurisdiction(BulkPlanRequest bulkPlanRequest) { + // Prepare plan employee assignment search criteria + PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = PlanEmployeeAssignmentSearchCriteria + .builder() + .tenantId(bulkPlanRequest.getPlans().get(0).getTenantId()) + .employeeId(Collections.singletonList(bulkPlanRequest.getRequestInfo().getUserInfo().getUuid())) + .planConfigurationId(bulkPlanRequest.getPlans().get(0).getPlanConfigurationId()) + .role(config.getPlanEstimationApproverRoles()) + .build(); + + // Fetch plan employee assignment + PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeService.search(PlanEmployeeAssignmentSearchRequest.builder() + .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) + .requestInfo(bulkPlanRequest.getRequestInfo()) + .build()); + + // Throw exception if the employee taking action is not a part of plan + if(CollectionUtils.isEmpty(planEmployeeAssignmentResponse.getPlanEmployeeAssignment())) { + throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_CODE, + PLAN_EMPLOYEE_ASSIGNMENT_NOT_FOUND_MESSAGE); + } + + // Validate jurisdiction for each plan + bulkPlanRequest.getPlans().forEach(plan -> validateJurisdiction(plan, + planEmployeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction())); + + } + + /** + * + * @param bulkPlanRequest + */ + private void validatePlanAttributes(BulkPlanRequest bulkPlanRequest) { + if(bulkPlanRequest.getPlans().stream().map(Plan :: getId).collect(Collectors.toSet()).size() + != bulkPlanRequest.getPlans().size()) { + throw new CustomException("BULK_UPDATE_ERROR", + "Plans provided in the bulk update request are not unique."); + } + + if(!bulkPlanRequest.getPlans().stream().allMatch(plan -> + plan.getTenantId().equals(bulkPlanRequest.getPlans().get(0).getTenantId()) && + plan.getPlanConfigurationId().equals(bulkPlanRequest.getPlans().get(0).getPlanConfigurationId()))) { + throw new CustomException("BULK_UPDATE_ERROR", + "Tenant id and plan configuration ids should be same across all entries for bulk update."); + } + bulkPlanRequest.getPlans().forEach(plan -> { + if(ObjectUtils.isEmpty(plan.getWorkflow())) { + throw new CustomException("BULK_UPDATE_ERROR", + "Workflow information is mandatory for each entry for bulk update"); + } + }); + + if(!bulkPlanRequest.getPlans().stream().allMatch(plan -> + plan.getStatus().equals(bulkPlanRequest.getPlans().get(0).getStatus()) && + plan.getWorkflow().getAction().equals(bulkPlanRequest.getPlans().get(0).getWorkflow().getAction()))) { + throw new CustomException("BULK_UPDATE_ERROR", + "All entries should be in the same state for bulk transitioning plan records."); + } + + } + + /** + * + * @param bulkPlanRequest + */ + private void validatePlanExistence(BulkPlanRequest bulkPlanRequest) { + // Get all plan ids to validate existence + List planListFromDatabase = planRepository.search(PlanSearchCriteria.builder() + .ids(bulkPlanRequest.getPlans().stream().map(Plan :: getId).collect(Collectors.toSet())) + .offset(0) + .limit(bulkPlanRequest.getPlans().size()) + .build()); + + // If plan id provided is invalid, throw an exception + if (planListFromDatabase.size() != bulkPlanRequest.getPlans().size()) { + throw new CustomException(INVALID_PLAN_ID_CODE, INVALID_PLAN_ID_MESSAGE); + } + + // Enrich ancestral materialized path for each plan object being passed in the request + enrichAncestralMaterializedPath(bulkPlanRequest, planListFromDatabase); + + } + + /** + * + * @param bulkPlanRequest + * @param planListFromDatabase + */ + private void enrichAncestralMaterializedPath(BulkPlanRequest bulkPlanRequest, List planListFromDatabase) { + Map planIdVsAncestralMaterializedPathMap = planListFromDatabase.stream() + .collect(Collectors.toMap(Plan :: getId, Plan :: getBoundaryAncestralPath)); + + bulkPlanRequest.getPlans().forEach(plan -> + plan.setBoundaryAncestralPath(planIdVsAncestralMaterializedPathMap + .get(plan.getId())) + ); + } } diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 8c5ab64d853..d7cd4210b43 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -8,6 +8,7 @@ import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.Workflow; +import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.request.User; import org.egov.common.contract.workflow.*; import org.egov.common.utils.AuditDetailsEnrichmentUtil; @@ -145,7 +146,9 @@ public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { .documents(plan.getWorkflow().getDocuments()) .build(); - autoAssignAssignee(plan.getWorkflow(), planRequest); + String assignee = getAssigneeForAutoAssignment(plan, planRequest.getRequestInfo()); + plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + enrichAssignesInProcessInstance(processInstance, plan.getWorkflow()); log.info("Process Instance assignes - " + processInstance.getAssignes()); @@ -190,25 +193,25 @@ private StringBuilder getWorkflowTransitionUri() { * * The assignee is set in both the workflow and the plan request. * - * @param workflow the workflow object to set the assignee - * @param planRequest the plan request containing workflow and jurisdiction details + * @param requestInfo auth details for making internal calls + * @param plan the plan object containing workflow and jurisdiction details */ - private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { - String[] allheirarchysBoundaryCodes = planRequest.getPlan().getBoundaryAncestralPath().split(PIPE_REGEX); + private String getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) { + String[] allheirarchysBoundaryCodes = plan.getBoundaryAncestralPath().split(PIPE_REGEX); String[] heirarchysBoundaryCodes = Arrays.copyOf(allheirarchysBoundaryCodes, allheirarchysBoundaryCodes.length - 1); PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() - .tenantId(planRequest.getPlan().getTenantId()) + .tenantId(plan.getTenantId()) .jurisdiction(Arrays.stream(heirarchysBoundaryCodes).toList()) - .planConfigurationId(planRequest.getPlan().getPlanConfigurationId()) + .planConfigurationId(plan.getPlanConfigurationId()) .role(config.getPlanEstimationApproverRoles()) .build(); //search for plan-employee assignments for the ancestral heirarchy codes. PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeService.search(PlanEmployeeAssignmentSearchRequest.builder() .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) - .requestInfo(planRequest.getRequestInfo()).build()); + .requestInfo(requestInfo).build()); // Create a map of jurisdiction to employeeId Map jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() @@ -228,7 +231,7 @@ private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { String assignee = null; //assignee will remain null in case terminate actions are being taken - String action = planRequest.getPlan().getWorkflow().getAction(); + String action = plan.getWorkflow().getAction(); if (config.getWfInitiateActions().contains(action)) { for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { assignee = jurisdictionToEmployeeMap.get(heirarchysBoundaryCodes[i]); @@ -236,33 +239,35 @@ private void autoAssignAssignee(Workflow workflow, PlanRequest planRequest) { break; // Stop iterating once an assignee is found } } else if (config.getWfIntermediateActions().contains(action)) { - assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, planRequest, jurisdictionToEmployeeMap); + assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, plan, jurisdictionToEmployeeMap); } else if (config.getWfSendBackActions().contains(action)) { - assignee = planRequest.getPlan().getAuditDetails().getLastModifiedBy(); + assignee = plan.getAuditDetails().getLastModifiedBy(); } if(!ObjectUtils.isEmpty(assignee)) - workflow.setAssignes(Collections.singletonList(assignee)); + plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + + plan.setAssignee(assignee); - planRequest.getPlan().setAssignee(assignee); + return assignee; } -/** - * Assigns an employee from a higher-level jurisdiction in the hierarchy. - * Iterates through boundary codes, checking if they match the assignee's jurisdiction. - * If a higher-level boundary has an assigned employee, returns that employee's ID. - * - * @param heirarchysBoundaryCodes boundary codes representing the hierarchy - * @param planRequest the request with plan and jurisdiction details - * @param jurisdictionToEmployeeMap map of jurisdiction codes to employee IDs - * @return the employee ID from the higher boundary, or null if - */ -public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, PlanRequest planRequest, Map jurisdictionToEmployeeMap) { + /** + * Assigns an employee from a higher-level jurisdiction in the hierarchy. + * Iterates through boundary codes, checking if they match the assignee's jurisdiction. + * If a higher-level boundary has an assigned employee, returns that employee's ID. + * + * @param heirarchysBoundaryCodes boundary codes representing the hierarchy + * @param plan the object with plan and jurisdiction details + * @param jurisdictionToEmployeeMap map of jurisdiction codes to employee IDs + * @return the employee ID from the higher boundary, or null if + */ + public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Plan plan, Map jurisdictionToEmployeeMap) { for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { String boundaryCode = heirarchysBoundaryCodes[i]; // Check if this boundary code is present in assigneeJurisdiction - if (planRequest.getPlan().getAssigneeJurisdiction().contains(boundaryCode)) { + if (plan.getAssigneeJurisdiction().contains(boundaryCode)) { if (i - 1 >= 0) { // Check the next higher level in the hierarchy (one index above the match) @@ -281,4 +286,57 @@ public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Plan return null; } + public void invokeWorkflowForStatusUpdate(BulkPlanRequest bulkPlanRequest) { + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(bulkPlanRequest); + ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); + + enrichPlansPostTransition(processInstanceResponse, bulkPlanRequest); + } + + private void enrichPlansPostTransition(ProcessInstanceResponse processInstanceResponse, BulkPlanRequest bulkPlanRequest) { + // Update status and audit information post transition + bulkPlanRequest.getPlans().forEach(plan -> { + // Update status of plan + plan.setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); + + // Update audit information of plan + plan.setAuditDetails(AuditDetailsEnrichmentUtil + .prepareAuditDetails(plan.getAuditDetails(), bulkPlanRequest.getRequestInfo(), Boolean.FALSE)); + }); + } + + private ProcessInstanceRequest createWorkflowRequest(BulkPlanRequest bulkPlanRequest) { + List processInstanceList = new ArrayList<>(); + + // Perform auto assignment + String assignee = getAssigneeForAutoAssignment(bulkPlanRequest.getPlans().get(0), + bulkPlanRequest.getRequestInfo()); + + bulkPlanRequest.getPlans().forEach(plan -> { + // Set assignee + plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + + // Create process instance object from plan + ProcessInstance processInstance = ProcessInstance.builder() + .businessId(plan.getId()) + .tenantId(plan.getTenantId()) + .businessService(PLAN_ESTIMATION_BUSINESS_SERVICE) + .moduleName(MODULE_NAME_VALUE) + .action(plan.getWorkflow().getAction()) + .comment(plan.getWorkflow().getComments()) + .documents(plan.getWorkflow().getDocuments()) + .build(); + + // Enrich user list for process instance + enrichAssignesInProcessInstance(processInstance, plan.getWorkflow()); + + // Add entry for bulk transition + processInstanceList.add(processInstance); + }); + + return ProcessInstanceRequest.builder() + .requestInfo(bulkPlanRequest.getRequestInfo()) + .processInstances(processInstanceList) + .build(); + } } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/controllers/PlanController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanController.java index 2381b009d40..43f50e6a5af 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanController.java @@ -30,7 +30,7 @@ public PlanController(PlanService planService) { * @return */ @RequestMapping(value = "/_create", method = RequestMethod.POST) - public ResponseEntity createPost(@Valid @RequestBody PlanRequest body) { + public ResponseEntity create(@Valid @RequestBody PlanRequest body) { PlanResponse planResponse = planService.createPlan(body); return ResponseEntity.status(HttpStatus.ACCEPTED).body(planResponse); } @@ -41,7 +41,7 @@ public ResponseEntity createPost(@Valid @RequestBody PlanRequest b * @return */ @RequestMapping(value = "/_search", method = RequestMethod.POST) - public ResponseEntity searchPost(@Valid @RequestBody PlanSearchRequest body) { + public ResponseEntity search(@Valid @RequestBody PlanSearchRequest body) { PlanResponse planResponse = planService.searchPlan(body); return ResponseEntity.status(HttpStatus.OK).body(planResponse); } @@ -52,9 +52,20 @@ public ResponseEntity searchPost(@Valid @RequestBody PlanSearchReq * @return */ @RequestMapping(value = "/_update", method = RequestMethod.POST) - public ResponseEntity updatePost(@Valid @RequestBody PlanRequest body) { + public ResponseEntity update(@Valid @RequestBody PlanRequest body) { PlanResponse planResponse = planService.updatePlan(body); return ResponseEntity.status(HttpStatus.ACCEPTED).body(planResponse); } + /** + * Request handler for serving bulk plan update requests + * @param body + * @return + */ + @RequestMapping(value = "/bulk/_update", method = RequestMethod.POST) + public ResponseEntity bulkUpdate(@Valid @RequestBody BulkPlanRequest body) { + PlanResponse planResponse = planService.bulkUpdate(body); + return ResponseEntity.status(HttpStatus.CREATED).body(planResponse); + } + } diff --git a/health-services/plan-service/src/main/java/digit/web/models/BulkPlanRequest.java b/health-services/plan-service/src/main/java/digit/web/models/BulkPlanRequest.java new file mode 100644 index 00000000000..f12bbc1ee8f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/BulkPlanRequest.java @@ -0,0 +1,33 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +import java.util.List; + +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BulkPlanRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Plans") + @Valid + @NotNull + @NotEmpty + private List plans = null; + +} \ No newline at end of file From db1fa68cc9d5f4da3fa338cfcb9dfce03115f5e6 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 21 Oct 2024 19:46:57 +0530 Subject: [PATCH 217/351] Integrated Census service in plan Service --- .../main/java/digit/config/Configuration.java | 7 + .../java/digit/config/ServiceConstants.java | 6 + .../src/main/java/digit/util/CensusUtil.java | 60 ++++++++ .../java/digit/web/models/census/Census.java | 136 ++++++++++++++++++ .../web/models/census/CensusResponse.java | 42 ++++++ .../models/census/CensusSearchCriteria.java | 62 ++++++++ .../models/census/CensusSearchRequest.java | 31 ++++ .../census/PopulationByDemographic.java | 69 +++++++++ .../src/main/resources/application.properties | 4 + 9 files changed, 417 insertions(+) create mode 100644 health-services/plan-service/src/main/java/digit/util/CensusUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/Census.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 48a67dae07c..53c016efae9 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -87,6 +87,13 @@ public class Configuration { @Value("${plan.default.limit}") private Integer defaultLimit; + //Census + @Value("${egov.census.host}") + private String censusHost; + + @Value("${egov.census.search.endpoint}") + private String censusSearchEndPoint; + //Facility @Value("${egov.facility.host}") private String facilityHost; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 429b4d4a6e1..6678f0f4a91 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -16,6 +16,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from project factory: "; + public static final String ERROR_WHILE_FETCHING_FROM_CENSUS = "Exception occurred while fetching records from census: "; + public static final String ERROR_WHILE_FETCHING_BOUNDARY_DETAILS = "Exception occurred while fetching boundary relationship from boundary service: "; public static final String ERROR_WHILE_FETCHING_DATA_FROM_HRMS = "Exception occurred while fetching employee from hrms: "; @@ -83,6 +85,10 @@ public class ServiceConstants { public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE = "NO_CENSUS_FOUND_FOR_GIVEN_DETAILS"; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE = "Census records does not exists for the given details: "; + + public static final String INVALID_EMPLOYEE_JURISDICTION_CODE = "INVALID_EMPLOYEE_JURISDICTION"; public static final String INVALID_EMPLOYEE_JURISDICTION_MESSAGE = "The employee's jurisdiction provided is invalid"; diff --git a/health-services/plan-service/src/main/java/digit/util/CensusUtil.java b/health-services/plan-service/src/main/java/digit/util/CensusUtil.java new file mode 100644 index 00000000000..adaa4e64113 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/CensusUtil.java @@ -0,0 +1,60 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.census.CensusResponse; +import digit.web.models.census.CensusSearchRequest; +import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.web.client.RestTemplate; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class CensusUtil { + + private RestTemplate restTemplate; + + private Configuration config; + + public CensusUtil(RestTemplate restTemplate, Configuration config) { + this.restTemplate = restTemplate; + this.config = config; + } + + /** + * This method fetches data from Census based on the given census search request. + * + * @param searchRequest The census search request containing the search criteria. + * @return returns the census response. + */ + public CensusResponse fetchCensusRecords(CensusSearchRequest searchRequest) { + + // Get census search uri + String uri = getCensusUri().toString(); + + CensusResponse censusResponse = null; + try { + censusResponse = restTemplate.postForObject(uri.toString(), searchRequest, CensusResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_CENSUS, e); + } + + if (CollectionUtils.isEmpty(censusResponse.getCensus())) { + throw new CustomException(NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE, NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE); + } + + return censusResponse; + } + + /** + * Builds the census search uri. + * + * @return returns the complete uri for census search. + */ + private StringBuilder getCensusUri() { + return new StringBuilder().append(config.getCensusHost()).append(config.getCensusSearchEndPoint()); + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/Census.java b/health-services/plan-service/src/main/java/digit/web/models/census/Census.java new file mode 100644 index 00000000000..11a196dd81b --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/Census.java @@ -0,0 +1,136 @@ +package digit.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.List; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; + + +/** + * Census + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Census { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("hierarchyType") + @NotNull + private String hierarchyType = null; + + @JsonProperty("boundaryCode") + @NotNull + private String boundaryCode = null; + + @JsonProperty("assignee") + @NotNull + private String assignee = null; + + @JsonProperty("status") + @NotNull + private StatusEnum status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("effectiveFrom") + private Long effectiveFrom = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("source") + @NotNull + private String source = null; + + @JsonIgnore + private List boundaryAncestralPath = null; + + @JsonIgnore + private boolean partnerAssignmentValidationEnabled; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; + + /** + * The status used in the Census + */ + public enum StatusEnum { + VALIDATED, + APPROVED, + PENDING_FOR_APPROVAL, + PENDING_FOR_VALIDATION + } + + /** + * Gets or Sets type + */ + public enum TypeEnum { + PEOPLE("people"), + ANIMALS("animals"), + PLANTS("plants"), + OTHER("other"); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String text) { + for (TypeEnum b : TypeEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java b/health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java new file mode 100644 index 00000000000..dabc56422b6 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java @@ -0,0 +1,42 @@ +package digit.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; +import java.util.Map; + +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Census") + @Valid + private List census = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; + + @JsonProperty("StatusCount") + @Valid + private Map statusCount = null; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java new file mode 100644 index 00000000000..f512c04732f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java @@ -0,0 +1,62 @@ +package digit.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchCriteria + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchCriteria { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + private String tenantId = null; + + @JsonProperty("areaCodes") + private List areaCodes = null; + + @JsonProperty("status") + private String status = null; + + @JsonProperty("assignee") + private String assignee = null; + + @JsonProperty("source") + private String source = null; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("jurisdiction") + private List jurisdiction = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { + if (this.areaCodes == null) { + this.areaCodes = new ArrayList<>(); + } + this.areaCodes.add(areaCodesItem); + return this; + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java new file mode 100644 index 00000000000..157cf16870f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java @@ -0,0 +1,31 @@ +package digit.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("CensusSearchCriteria") + @Valid + private CensusSearchCriteria censusSearchCriteria = null; + + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java b/health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java new file mode 100644 index 00000000000..b36d25b21de --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java @@ -0,0 +1,69 @@ +package digit.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * PopulationByDemographic + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PopulationByDemographic { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("demographicVariable") + private DemographicVariableEnum demographicVariable = null; + + @JsonProperty("populationDistribution") + private Object populationDistribution = null; + + /** + * Gets or Sets demographicVariable + */ + public enum DemographicVariableEnum { + AGE("age"), + + GENDER("gender"), + + ETHNICITY("ethnicity"); + + private String value; + + DemographicVariableEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static DemographicVariableEnum fromValue(String text) { + for (DemographicVariableEnum b : DemographicVariableEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 5df37397f8f..9fd5fb384b6 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -55,6 +55,10 @@ plan.facility.create.topic=save-plan-facility plan.employee.assignment.create.topic=plan-employee-assignment-create-topic plan.employee.assignment.update.topic=plan-employee-assignment-update-topic +# Census +egov.census.host=https://unified-dev.digit.org +egov.census.search.endpoint=/census-service/_search + # Facility egov.facility.host=https://unified-dev.digit.org egov.facility.search.endpoint=/facility/v1/_search From c8441f83ab1a1f4044070f2b58c66b9f5a7e72bf Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Tue, 22 Oct 2024 10:13:31 +0530 Subject: [PATCH 218/351] Updated name of arguments in bulk update API --- .../main/java/digit/repository/impl/PlanRepositoryImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index aee367faaa2..618c1ceb70e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -84,8 +84,8 @@ public void bulkUpdate(BulkPlanRequest body) { // Get bulk plan update query String bulkPlanUpdateQuery = planQueryBuilder.getBulkPlanQuery(); - // Prepare arguments for batch update - List batchArgs = body.getPlans().stream().map(plan -> new Object[] { + // Prepare rows for bulk update + List rows = body.getPlans().stream().map(plan -> new Object[] { plan.getStatus(), plan.getAssignee(), plan.getAuditDetails().getLastModifiedBy(), @@ -94,7 +94,7 @@ public void bulkUpdate(BulkPlanRequest body) { }).toList(); // Perform batch update - jdbcTemplate.batchUpdate(bulkPlanUpdateQuery, batchArgs); + jdbcTemplate.batchUpdate(bulkPlanUpdateQuery, rows); } /** From a142ff68038f1a30ae4b701af13bdca43fa37a7a Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Tue, 22 Oct 2024 11:17:25 +0530 Subject: [PATCH 219/351] Updated search parameters --- .../src/main/java/digit/config/ServiceConstants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 429b4d4a6e1..b45f6ece7da 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -320,9 +320,9 @@ public class ServiceConstants { public static final String FAILED_MESSAGE = "Failed to push message to topic"; - public static final String FACILITY_NAME_SEARCH_PARAMETER_KEY = "name"; + public static final String FACILITY_NAME_SEARCH_PARAMETER_KEY = "facilityName"; - public static final String FACILITY_STATUS_SEARCH_PARAMETER_KEY = "status"; + public static final String FACILITY_STATUS_SEARCH_PARAMETER_KEY = "facilityStatus"; public static final String FACILITY_TYPE_SEARCH_PARAMETER_KEY = "facilityType"; From 249a9da881732c10b7f4ee84c871a3a466c70b5f Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 22 Oct 2024 11:50:52 +0530 Subject: [PATCH 220/351] Validation before moving wf status in planConfig --- .../java/digit/config/ServiceConstants.java | 12 ++++ .../validator/PlanConfigurationValidator.java | 71 +++++++++++++++++-- .../service/workflow/WorkflowService.java | 14 +++- .../src/main/java/digit/util/CensusUtil.java | 2 +- 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 6678f0f4a91..47834546bcc 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -305,6 +305,12 @@ public class ServiceConstants { public static final String SETUP_COMPLETED_STATUS = "SETUP_COMPLETED"; + public static final String APPROVE_CENSUS_DATA_ACTION = "APPROVE_CENSUS_DATA"; + + public static final String FINALIZE_CATCHMENT_MAPPING_ACTION = "FINALIZE_CATCHMENT_MAPPING"; + + public static final String VALIDATED_STATUS = "VALIDATED"; + //Query constants public static final String PERCENTAGE_WILDCARD = "%"; @@ -321,6 +327,12 @@ public class ServiceConstants { public static final String INVALID_RESIDING_BOUNDARY_CODE = "INVALID_RESIDING_BOUNDARY"; public static final String INVALID_RESIDING_BOUNDARY_MESSAGE = "The provided residing boundary is invalid"; + public static final String CANNOT_APPROVE_CENSUS_DATA_CODE = "CANNOT_APPROVE_CENSUS_DATA"; + public static final String CANNOT_APPROVE_CENSUS_DATA_MESSAGE = "Census data can't be approved until all the census records are validated"; + + public static final String CANNOT_FINALIZE_CATCHMENT_MAPPING_CODE = "CANNOT_FINALIZE_CATCHMENT_MAPPING"; + public static final String CANNOT_FINALIZE_CATCHMENT_MAPPING_MESSAGE = "Catchment mapping can't be finalized until all boundaries have facility assigned"; + public static final String HIERARCHY_NOT_FOUND_IN_MDMS_CODE = "HIERARCHY_NOT_FOUND_IN_MDMS"; public static final String HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE = "Hierarchy key not found in mdms"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index a0e354430d7..53942bc02a8 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -3,15 +3,15 @@ import com.jayway.jsonpath.JsonPath; import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; -import digit.util.CampaignUtil; -import digit.util.MdmsUtil; -import digit.util.MdmsV2Util; -import digit.util.CommonUtil; +import digit.util.*; import digit.web.models.*; import java.util.*; import java.util.stream.Collectors; +import digit.web.models.census.CensusResponse; +import digit.web.models.census.CensusSearchCriteria; +import digit.web.models.census.CensusSearchRequest; import digit.web.models.mdmsV2.Mdms; import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; @@ -21,7 +21,6 @@ import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; import static digit.config.ServiceConstants.*; @@ -41,13 +40,16 @@ public class PlanConfigurationValidator { private CampaignUtil campaignUtil; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil) { + private CensusUtil censusUtil; + + public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil, CensusUtil censusUtil) { this.mdmsUtil = mdmsUtil; this.mdmsV2Util = mdmsV2Util; this.planConfigRepository = planConfigRepository; this.commonUtil = commonUtil; this.centralInstanceUtil = centralInstanceUtil; this.campaignUtil = campaignUtil; + this.censusUtil = censusUtil; } /** @@ -630,6 +632,51 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration } } + /** + * Validates if all the census records are validated before approving census data for the given planConfigId. + * + * @param planConfigurationRequest request with plan config id. + */ + public void validateCensusData(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches census records for given planConfigId + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + + Map statusCount = censusResponse.getStatusCount(); + + // Throws exception if all census records are not validated + if (statusCount.size() > 1 || !statusCount.containsKey(VALIDATED_STATUS)) { + throw new CustomException(CANNOT_APPROVE_CENSUS_DATA_CODE, CANNOT_APPROVE_CENSUS_DATA_MESSAGE); + } + } + + /** + * Validates if all boundaries have facility assigned before finalizing catchment mapping for a given planConfigID. + * + * @param planConfigurationRequest request with plan config id. + */ + public void validateCatchmentMapping(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches all census records for given planConfigId + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + Integer totalCensusCount = censusResponse.getTotalCount(); + + censusSearchRequest.getCensusSearchCriteria().setFacilityAssigned(Boolean.TRUE); + + // Fetches all census records for given planConfigId where facility is assigned + CensusResponse censusWithFacilityAssigned = censusUtil.fetchCensusRecords(censusSearchRequest); + Integer totalCensusWithFacilityAssigned = censusWithFacilityAssigned.getTotalCount(); + + if (!totalCensusCount.equals(totalCensusWithFacilityAssigned)) { + throw new CustomException(CANNOT_FINALIZE_CATCHMENT_MAPPING_CODE, CANNOT_FINALIZE_CATCHMENT_MAPPING_MESSAGE); + } + } public boolean isSetupCompleted(PlanConfiguration planConfiguration) { return Objects.equals(planConfiguration.getStatus(), SETUP_COMPLETED_STATUS); @@ -664,4 +711,16 @@ private void checkForEmptyResourceMapping(PlanConfiguration planConfiguration) { } } + // Prepares Census search request for given planConfigId + private CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() + .tenantId(tenantId) + .source(planConfigId) + .build(); + + return CensusSearchRequest.builder() + .requestInfo(requestInfo) + .censusSearchCriteria(searchCriteria) + .build(); + } } diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 8c5ab64d853..8ed878278fa 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -4,6 +4,7 @@ import digit.config.Configuration; import digit.repository.ServiceRequestRepository; import digit.service.PlanEmployeeService; +import digit.service.validator.PlanConfigurationValidator; import digit.util.CommonUtil; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; @@ -35,12 +36,15 @@ public class WorkflowService { private PlanEmployeeService planEmployeeService; - public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil, PlanEmployeeService planEmployeeService) { + private PlanConfigurationValidator validator; + + public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil, PlanEmployeeService planEmployeeService, PlanConfigurationValidator validator) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.mapper = mapper; this.commonUtil = commonUtil; this.planEmployeeService = planEmployeeService; + this.validator = validator; } /** @@ -53,6 +57,14 @@ public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigura if (ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow())) return; + String workflowAction = planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction(); + + if(workflowAction.equals(APPROVE_CENSUS_DATA_ACTION)) { + validator.validateCensusData(planConfigurationRequest); + } else if(workflowAction.equals(FINALIZE_CATCHMENT_MAPPING_ACTION)) { + validator.validateCatchmentMapping(planConfigurationRequest); + } + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planConfigurationRequest); ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); diff --git a/health-services/plan-service/src/main/java/digit/util/CensusUtil.java b/health-services/plan-service/src/main/java/digit/util/CensusUtil.java index adaa4e64113..fa45518c44a 100644 --- a/health-services/plan-service/src/main/java/digit/util/CensusUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CensusUtil.java @@ -37,7 +37,7 @@ public CensusResponse fetchCensusRecords(CensusSearchRequest searchRequest) { CensusResponse censusResponse = null; try { - censusResponse = restTemplate.postForObject(uri.toString(), searchRequest, CensusResponse.class); + censusResponse = restTemplate.postForObject(uri, searchRequest, CensusResponse.class); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_FROM_CENSUS, e); } From edf5af788889de564994e50fc448c61927688377 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 22 Oct 2024 14:04:14 +0530 Subject: [PATCH 221/351] pagination --- .../querybuilder/CensusQueryBuilder.java | 4 +-- .../web/models/CensusSearchCriteria.java | 7 +++-- .../java/digit/web/models/Pagination.java | 30 ------------------- 3 files changed, 7 insertions(+), 34 deletions(-) delete mode 100644 health-services/census-service/src/main/java/digit/web/models/Pagination.java diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 0ac9035baa5..3f65f078bb2 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -167,11 +167,11 @@ public String getPaginatedQuery(String query, List preparedStmtList, Cen // Append offset paginatedQuery.append(" OFFSET ? "); - preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getPagination()) && !ObjectUtils.isEmpty(searchCriteria.getPagination().getOffset()) ? searchCriteria.getPagination().getOffset() : config.getDefaultOffset()); + preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getOffset()) ? searchCriteria.getOffset() : config.getDefaultOffset()); // Append limit paginatedQuery.append(" LIMIT ? "); - preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getPagination()) && !ObjectUtils.isEmpty(searchCriteria.getPagination().getLimit()) ? searchCriteria.getPagination().getLimit() : config.getDefaultLimit()); + preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getLimit()) ? searchCriteria.getLimit() : config.getDefaultLimit()); return paginatedQuery.toString(); } diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index 3133270200e..458b1cd7831 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -51,8 +51,11 @@ public class CensusSearchCriteria { @JsonProperty("effectiveTo") private Long effectiveTo = null; - @JsonProperty("pagination") - private Pagination pagination = null; + @JsonProperty("limit") + private Integer limit = null; + + @JsonProperty("offset") + private Integer offset = null; public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { diff --git a/health-services/census-service/src/main/java/digit/web/models/Pagination.java b/health-services/census-service/src/main/java/digit/web/models/Pagination.java deleted file mode 100644 index 18ab979fba3..00000000000 --- a/health-services/census-service/src/main/java/digit/web/models/Pagination.java +++ /dev/null @@ -1,30 +0,0 @@ -package digit.web.models; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Pagination - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class Pagination { - - @JsonIgnore - private String sortBy; - - @JsonIgnore - private String sortOrder; - - @JsonProperty("limit") - private Integer limit; - - @JsonProperty("offset") - private Integer offset; -} From 5061065c228fbf8505bc977d7a62dea9de914afe Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 23 Oct 2024 11:39:38 +0530 Subject: [PATCH 222/351] Increasing output field's size from 64 to 256 --- .../plan-service/src/main/java/digit/web/models/Operation.java | 2 +- .../db/migration/main/V20242310151500__plan_update_size_ddl.sql | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/web/models/Operation.java b/health-services/plan-service/src/main/java/digit/web/models/Operation.java index 20eabc1d8b3..c4b7922da14 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Operation.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Operation.java @@ -45,7 +45,7 @@ public class Operation { @JsonProperty("output") @NotNull - @Size(min = 1, max = 64) + @Size(min = 1, max = 256) private String output = null; @JsonProperty("showOnEstimationDashboard") diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql new file mode 100644 index 00000000000..4083a5a34a9 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE plan_configuration_operations ALTER COLUMN output TYPE character varying(256); From a557cd54de246f83d408b15a019881347ef9509b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 23 Oct 2024 15:00:14 +0530 Subject: [PATCH 223/351] Bulk update api --- .../java/digit/config/ServiceConstants.java | 12 ++ .../digit/repository/CensusRepository.java | 2 + .../repository/impl/CensusRepositoryImpl.java | 23 +++ .../querybuilder/CensusQueryBuilder.java | 13 +- .../java/digit/service/CensusService.java | 54 +++++- .../service/validator/CensusValidator.java | 161 +++++++++++++++--- .../service/workflow/WorkflowService.java | 141 +++++++++++---- .../web/controllers/CensusController.java | 13 ++ .../digit/web/models/BulkCensusRequest.java | 33 ++++ .../web/models/CensusSearchCriteria.java | 10 ++ .../digit/web/models/CensusSearchRequest.java | 2 + 11 files changed, 397 insertions(+), 67 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/web/models/BulkCensusRequest.java diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index c7448233194..2a7fb63022a 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -72,6 +72,18 @@ public class ServiceConstants { public static final String INVALID_CENSUS_CODE = "INVALID_CENSUS"; public static final String INVALID_CENSUS_MESSAGE = "Provided census does not exist"; + public static final String DUPLICATE_CENSUS_ID_IN_BULK_UPDATE_CODE = "DUPLICATE_CENSUS_ID_IN_BULK_UPDATE"; + public static final String DUPLICATE_CENSUS_ID_IN_BULK_UPDATE_MESSAGE = "Census provided in the bulk update request are not unique."; + + public static final String INVALID_SOURCE_OR_TENANT_ID_FOR_BULK_UPDATE_CODE = "INVALID_SOURCE_OR_TENANT_ID_FOR_BULK_UPDATE"; + public static final String INVALID_SOURCE_OR_TENANT_ID_FOR_BULK_UPDATE_MESSAGE = "Tenant id and source should be same across all entries for bulk update."; + + public static final String WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE_CODE = "WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE"; + public static final String WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE_MESSAGE = "Workflow information is mandatory for each entry for bulk update"; + + public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_CODE = "DIFFERENT_WORKFLOW_FOR_BULK_UPDATE"; + public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_MESSAGE = "All entries should be in the same state for bulk transitioning census records."; + public static final String SEARCH_CRITERIA_EMPTY_CODE = "SEARCH_CRITERIA_EMPTY"; public static final String SEARCH_CRITERIA_EMPTY_MESSAGE = "Search criteria cannot be empty"; diff --git a/health-services/census-service/src/main/java/digit/repository/CensusRepository.java b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java index 5693f385939..20aac629751 100644 --- a/health-services/census-service/src/main/java/digit/repository/CensusRepository.java +++ b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java @@ -13,6 +13,8 @@ public interface CensusRepository { public void update(CensusRequest censusRequest); + public void bulkUpdate(BulkCensusRequest request); + public Integer count(CensusSearchCriteria censusSearchCriteria); public Map statusCount(CensusSearchCriteria censusSearchCriteria); diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index a1c6e3db0e4..9920a517024 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -104,6 +104,29 @@ public void update(CensusRequest censusRequest) { producer.push(config.getCensusUpdateTopic(), requestDTO); } + /** + * Updates workflow status of a list of census records. + * + * @param request The bulk request containing the census records. + */ + @Override + public void bulkUpdate(BulkCensusRequest request) { + // Get bulk census update query + String bulkCensusUpdateQuery = queryBuilder.getBulkCensusQuery(); + + // Prepare arguments for batch update + List batchArgs = request.getCensus().stream().map(census -> new Object[] { + census.getStatus(), + census.getAssignee(), + census.getAuditDetails().getLastModifiedBy(), + census.getAuditDetails().getLastModifiedTime(), + census.getId() + }).toList(); + + // Perform batch update + jdbcTemplate.batchUpdate(bulkCensusUpdateQuery, batchArgs); + } + /** * Converts the CensusRequest to a data transfer object (DTO) * diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 685a4c62696..c3341ce087a 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -25,10 +25,12 @@ public CensusQueryBuilder(QueryUtil queryUtil) { private static final String CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY cen.last_modified_time DESC"; - private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(census_id) AS total_count FROM ( "; private static final String CENSUS_STATUS_COUNT_WRAPPER = "SELECT COUNT(census_id) as census_status_count, census_status FROM ({INTERNAL_QUERY}) as census_status_map GROUP BY census_status"; + private static final String BULK_CENSUS_UPDATE_QUERY = "UPDATE census SET status = ?, assignee = ?, last_modified_by = ?, last_modified_time = ? WHERE id = ?"; + /** * Constructs a SQL query string for searching Census records based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. @@ -83,6 +85,12 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep preparedStmtList.add(criteria.getId()); } + if (!CollectionUtils.isEmpty(criteria.getIds())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.id IN ( ").append(queryUtil.createQuery(criteria.getIds().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, criteria.getIds()); + } + if (!ObjectUtils.isEmpty(criteria.getTenantId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" cen.tenant_id = ?"); @@ -151,4 +159,7 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep return builder.toString(); } + public String getBulkCensusQuery() { + return BULK_CENSUS_UPDATE_QUERY; + } } diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index de66214e7b3..8e959831eb5 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -6,6 +6,7 @@ import digit.service.validator.CensusValidator; import digit.service.workflow.WorkflowService; import digit.util.ResponseInfoFactory; +import digit.web.models.BulkCensusRequest; import digit.web.models.CensusRequest; import digit.web.models.CensusResponse; import digit.web.models.CensusSearchRequest; @@ -44,10 +45,19 @@ public CensusService(ResponseInfoFactory responseInfoFactory, CensusRepository r * @return The created census reponse. */ public CensusResponse create(CensusRequest request) { - validator.validateCreate(request); // Validate census create request - enrichment.enrichCreate(request); // Enrich census create request - timeframeEnrichment.enrichPreviousTimeframe(request); // Enrich timeframe for previous census - repository.create(request); // Delegate creation request to repository + + // Validate census create request + validator.validateCreate(request); + + // Enrich census create request + enrichment.enrichCreate(request); + + // Enrich timeframe for previous census + timeframeEnrichment.enrichPreviousTimeframe(request); + + // Delegate creation request to repository + repository.create(request); + return CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) @@ -61,7 +71,7 @@ public CensusResponse create(CensusRequest request) { * @return A list of census record that matches the search criteria. */ public CensusResponse search(CensusSearchRequest request) { - validator.validateSearch(request); // Validate census search request + return CensusResponse.builder() .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .census(repository.search(request.getCensusSearchCriteria())) @@ -77,13 +87,39 @@ public CensusResponse search(CensusSearchRequest request) { * @return The updated census response. */ public CensusResponse update(CensusRequest request) { - validator.validateUpdate(request); // Validate census update request - enrichment.enrichUpdate(request); // Enrich census update request - workflow.invokeWorkflowForStatusUpdate(request); // Call workflow transition API for status update - repository.update(request); // Delegate update request to repository + + // Validate census update request + validator.validateUpdate(request); + + // Enrich census update request + enrichment.enrichUpdate(request); + + // Call workflow transition API for status update + workflow.invokeWorkflowForStatusUpdate(request); + + // Delegate update request to repository + repository.update(request); + return CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .build(); } + + public CensusResponse bulkUpdate(BulkCensusRequest request) { + + // Validate census bulk update request + validator.validateBulkUpdate(request); + + // Call workflow transition for updating status and assignee + workflow.invokeWorkflowForStatusUpdate(request); + + // Delegate bulk update request to repository + repository.bulkUpdate(request); + + return CensusResponse.builder() + .census(request.getCensus()) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .build(); + } } diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index ce5bafdc467..21c88ab9d6a 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -5,16 +5,12 @@ import digit.service.enrichment.CensusEnrichment; import digit.util.BoundaryUtil; import digit.util.PlanEmployeeAssignmnetUtil; -import digit.web.models.Census; -import digit.web.models.CensusRequest; -import digit.web.models.CensusSearchCriteria; -import digit.web.models.CensusSearchRequest; +import digit.web.models.*; import digit.web.models.boundary.BoundarySearchResponse; import digit.web.models.boundary.HierarchyRelation; import digit.web.models.plan.PlanEmployeeAssignmentResponse; import digit.web.models.plan.PlanEmployeeAssignmentSearchCriteria; import digit.web.models.plan.PlanEmployeeAssignmentSearchRequest; -import org.apache.commons.lang3.StringUtils; import org.egov.common.contract.request.User; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -22,9 +18,9 @@ import org.springframework.util.ObjectUtils; import java.util.*; +import java.util.stream.Collectors; import static digit.config.ServiceConstants.*; -import static digit.config.ServiceConstants.USERINFO_MISSING_MESSAGE; @Component public class CensusValidator { @@ -121,21 +117,6 @@ private void validatePartnerForCensus(CensusRequest request) { } } - /** - * Validates the search request for Census. - * - * @param request The search request for Census - */ - public void validateSearch(CensusSearchRequest request) { - if (ObjectUtils.isEmpty(request.getCensusSearchCriteria())) { - throw new CustomException(SEARCH_CRITERIA_EMPTY_CODE, SEARCH_CRITERIA_EMPTY_MESSAGE); - } - - if (StringUtils.isEmpty(request.getCensusSearchCriteria().getTenantId())) { - throw new CustomException(TENANT_ID_EMPTY_CODE, TENANT_ID_EMPTY_MESSAGE); - } - } - /** * Validates partner assignment and jurisdiction for census update request. * @@ -144,8 +125,7 @@ public void validateSearch(CensusSearchRequest request) { public void validateUpdate(CensusRequest request) { // Validate if Census record to be updated exists - Census census = validateCensusExistence(request); - request.getCensus().setBoundaryAncestralPath(census.getBoundaryAncestralPath()); + validateCensusExistence(request); // Validate partner assignment and jurisdiction against plan service validatePartnerForCensus(request); @@ -155,14 +135,11 @@ public void validateUpdate(CensusRequest request) { * Validates the existence of census record in the repository * * @param request The request containing the census to be validated - * @return the census that exist in the repository */ - private Census validateCensusExistence(CensusRequest request) { + private void validateCensusExistence(CensusRequest request) { Census census = request.getCensus(); CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() .id(census.getId()) - .tenantId(census.getTenantId()) - .areaCodes(Collections.singletonList(census.getBoundaryCode())) .build(); List censusList = repository.search(searchCriteria); @@ -171,7 +148,135 @@ private Census validateCensusExistence(CensusRequest request) { throw new CustomException(INVALID_CENSUS_CODE, INVALID_CENSUS_MESSAGE); } - return censusList.get(0); + request.getCensus().setBoundaryAncestralPath(censusList.get(0).getBoundaryAncestralPath()); + } + + /** + * Validates census records for bulk update. + * Validates the census attributes, checks if census records to be validated exist. + * Also validates the partner assignment and jurisdiction for the given census records. + * + * @param request the census bulk update request. + */ + public void validateBulkUpdate(BulkCensusRequest request) { + + // Validate attributes across each census in the bulk update request + validateCensusAttributes(request); + + // Validate if census in request body exists + validateCensusExistence(request); + + // Validate partner assignment and jurisdiction against plan service + validatePartnerForCensus(request); + } + + /** + * Validates partner assignment and jurisdiction against plan service + * Also validates the user information within the provided CensusRequest. + * + * @param request the census bulk update request + */ + private void validatePartnerForCensus(BulkCensusRequest request) { + + // Validate the user information in the request + if (ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) { + throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); + } + + List jurisdiction = Arrays.asList(request.getCensus().get(0).getBoundaryAncestralPath().get(0).split("\\|")); + + PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() + .employeeId(Collections.singletonList(request.getRequestInfo().getUserInfo().getUuid())) + .planConfigurationId(request.getCensus().get(0).getSource()) + .tenantId(request.getCensus().get(0).getTenantId()) + .role(configs.getAllowedCensusRoles()) + .jurisdiction(jurisdiction) + .build(); + + PlanEmployeeAssignmentResponse employeeAssignmentResponse = employeeAssignmnetUtil.fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest.builder() + .requestInfo(request.getRequestInfo()) + .planEmployeeAssignmentSearchCriteria(searchCriteria) + .build()); + + if (CollectionUtils.isEmpty(employeeAssignmentResponse.getPlanEmployeeAssignment())) { + throw new CustomException(INVALID_PARTNER_CODE, INVALID_PARTNER_MESSAGE); + } + + //enrich jurisdiction of current assignee in all census records + request.getCensus().forEach(census -> census.setAssigneeJurisdiction(employeeAssignmentResponse.getPlanEmployeeAssignment().get(0).getJurisdiction())); + } + + /** + * Validates the existence of bulk census records in the repository + * + * @param request The request containing all the census records to be validated + */ + private void validateCensusExistence(BulkCensusRequest request) { + + // Get all census ids to validate existence + List censusListFromDatabase = repository.search(CensusSearchCriteria.builder() + .ids(request.getCensus().stream().map(Census::getId).collect(Collectors.toSet())) + .offset(0) + .limit(request.getCensus().size()) + .build()); + + // If census id provided is invalid, throw an exception + if (censusListFromDatabase.size() != request.getCensus().size()) { + throw new CustomException(INVALID_CENSUS_CODE, INVALID_CENSUS_MESSAGE); + } + + // Enrich boundary ancestral path for each census object being passed in the request + enrichBoundaryAncestralPath(request, censusListFromDatabase); + } + /** + * Enriches the census records with boundary ancestral path from repository. + * + * @param request bulk request with all census records. + * @param censusListFromDatabase existing census records from the repository. + */ + private void enrichBoundaryAncestralPath(BulkCensusRequest request, List censusListFromDatabase) { + Map censusIdVsBoundaryAncestralPathMap = censusListFromDatabase.stream() + .collect(Collectors.toMap(Census::getId, census -> census.getBoundaryAncestralPath().get(0))); + + request.getCensus().forEach(census -> + census.setBoundaryAncestralPath(Collections.singletonList(censusIdVsBoundaryAncestralPathMap + .get(census.getId()))) + ); + } + + /** + * Validates if census records provided in bulk update are unique. + * Checks if all the records have same source and tenant id. + * Also validates if records have same workflow status and action to be taken. + * + * @param request the census bulk update request + */ + private void validateCensusAttributes(BulkCensusRequest request) { + + if (request.getCensus().stream().map(Census::getId).collect(Collectors.toSet()).size() + != request.getCensus().size()) { + throw new CustomException(DUPLICATE_CENSUS_ID_IN_BULK_UPDATE_CODE, DUPLICATE_CENSUS_ID_IN_BULK_UPDATE_MESSAGE); + } + + if (!request.getCensus().stream().allMatch(census -> + census.getTenantId().equals(request.getCensus().get(0).getTenantId()) && + census.getSource().equals(request.getCensus().get(0).getSource()))) { + throw new CustomException(INVALID_SOURCE_OR_TENANT_ID_FOR_BULK_UPDATE_CODE, INVALID_SOURCE_OR_TENANT_ID_FOR_BULK_UPDATE_MESSAGE); + } + + request.getCensus().forEach(census -> { + if (ObjectUtils.isEmpty(census.getWorkflow())) { + throw new CustomException(WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE_CODE, WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE_MESSAGE); + } + }); + + if (!request.getCensus().stream().allMatch(census -> + census.getStatus().equals(request.getCensus().get(0).getStatus()) && + census.getWorkflow().getAction().equals(request.getCensus().get(0).getWorkflow().getAction()))) { + throw new CustomException(DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_CODE, DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_MESSAGE); + } + } } + diff --git a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java index 4e726cad595..d3669bc8e73 100644 --- a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -4,6 +4,7 @@ import digit.config.Configuration; import digit.repository.ServiceRequestRepository; import digit.util.PlanEmployeeAssignmnetUtil; +import digit.web.models.BulkCensusRequest; import digit.web.models.Census; import digit.web.models.CensusRequest; import digit.web.models.plan.PlanEmployeeAssignmentResponse; @@ -11,6 +12,7 @@ import digit.web.models.plan.PlanEmployeeAssignmentSearchRequest; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.Workflow; +import org.egov.common.contract.request.RequestInfo; import org.egov.common.contract.request.User; import org.egov.common.contract.workflow.*; import org.egov.common.utils.AuditDetailsEnrichmentUtil; @@ -61,10 +63,85 @@ public void invokeWorkflowForStatusUpdate(CensusRequest censusRequest) { // Enrich audit details after auto assignment is complete censusRequest.getCensus().setAuditDetails(AuditDetailsEnrichmentUtil - .prepareAuditDetails( censusRequest.getCensus().getAuditDetails(), censusRequest.getRequestInfo(), Boolean.FALSE)); + .prepareAuditDetails(censusRequest.getCensus().getAuditDetails(), censusRequest.getRequestInfo(), Boolean.FALSE)); } + /** + * Integrates with the workflow for the given bulk census request. + * + * @param request The request containing the list of census objects to integrate with the workflow. + */ + public void invokeWorkflowForStatusUpdate(BulkCensusRequest request) { + + ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(request); + ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); + + enrichCensusPostTransition(processInstanceResponse, request); + } + + /** + * Enriches the census records in bulk update with audit details and workflow status. + * + * @param processInstanceResponse process instance response containing the current workflow status + * @param request the bulk census request + */ + private void enrichCensusPostTransition(ProcessInstanceResponse processInstanceResponse, BulkCensusRequest request) { + // Update status and audit information post transition + request.getCensus().forEach(census -> { + // Update status of Census + census.setStatus(processInstanceResponse.getProcessInstances().get(0).getState().getState()); + + // Update audit information of census + census.setAuditDetails(AuditDetailsEnrichmentUtil + .prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); + }); + } + + /** + * Creates a workflow request from the given list of census records in bulk request. + * + * @param request The request containing the list of census to create a workflow request. + * @return The constructed process instance request for the workflow. + */ + private ProcessInstanceRequest createWorkflowRequest(BulkCensusRequest request) { + List processInstanceList = new ArrayList<>(); + + // Perform auto assignment + String assignee = getAssigneeForAutoAssignment(request.getCensus().get(0), request.getRequestInfo()); + + request.getCensus().forEach(census -> { + + // Set assignee + if (!ObjectUtils.isEmpty(assignee)) + census.getWorkflow().setAssignes(Collections.singletonList(assignee)); + + census.setAssignee(assignee); + + // Create process instance object from census + ProcessInstance processInstance = ProcessInstance.builder() + .businessId(census.getId()) + .tenantId(census.getTenantId()) + .businessService(CENSUS_BUSINESS_SERVICE) + .moduleName(MODULE_NAME_VALUE) + .action(census.getWorkflow().getAction()) + .comment(census.getWorkflow().getComments()) + .documents(census.getWorkflow().getDocuments()) + .build(); + + // Enrich user list for process instance + enrichAssignesInProcessInstance(processInstance, census.getWorkflow()); + + // Add entry for bulk transition + processInstanceList.add(processInstance); + }); + + return ProcessInstanceRequest.builder() + .requestInfo(request.getRequestInfo()) + .processInstances(processInstanceList) + .build(); + } + /** * Calls the workflow transition service and retrieves the process instance response. * @@ -92,6 +169,8 @@ public ProcessInstanceResponse callWorkflowTransition(ProcessInstanceRequest pro */ public ProcessInstanceRequest createWorkflowRequest(CensusRequest censusRequest) { Census census = censusRequest.getCensus(); + + // Create process instance object from census ProcessInstance processInstance = ProcessInstance.builder() .businessId(census.getId()) .tenantId(census.getTenantId()) @@ -102,7 +181,16 @@ public ProcessInstanceRequest createWorkflowRequest(CensusRequest censusRequest) .documents(census.getWorkflow().getDocuments()) .build(); - autoAssignAssignee(census.getWorkflow(), censusRequest); + // Perform auto assignment + String assignee = getAssigneeForAutoAssignment(census, censusRequest.getRequestInfo()); + + // Set Assignee + if (!ObjectUtils.isEmpty(assignee)) + census.getWorkflow().setAssignes(Collections.singletonList(assignee)); + + census.setAssignee(assignee); + + // Enrich user for process instance enrichAssignesInProcessInstance(processInstance, census.getWorkflow()); log.info("Process Instance assignes - " + processInstance.getAssignes()); @@ -138,42 +226,40 @@ private StringBuilder getWorkflowTransitionUri() { } /** - * Automatically assigns an assignee based on the workflow action and jurisdiction hierarchy. + * Returns an assignee based on the workflow action and jurisdiction hierarchy. * Retrieves jurisdiction boundaries from the census request and searches for matching employee assignments. * * For INITIATE actions, assigns the employee from the lowest boundary. * For INTERMEDIATE actions (non-ROOT_APPROVER), assigns an employee from a higher-level boundary. * For SEND_BACK actions, assigns the last modified user. * - * The assignee is set in both the workflow and the census request. - * - * @param workflow the workflow object to set the assignee - * @param censusRequest the census request containing workflow and jurisdiction details + * @param census the census object containing workflow and jurisdiction details + * @param requestInfo the requestInfo */ - private void autoAssignAssignee(Workflow workflow, CensusRequest censusRequest) { - String[] allheirarchysBoundaryCodes = censusRequest.getCensus().getBoundaryAncestralPath().get(0).split(PIPE_REGEX); - String[] heirarchysBoundaryCodes = Arrays.copyOf(allheirarchysBoundaryCodes, allheirarchysBoundaryCodes.length - 1); + private String getAssigneeForAutoAssignment(Census census, RequestInfo requestInfo) { + String[] allHierarchiesBoundaryCodes = census.getBoundaryAncestralPath().get(0).split(PIPE_REGEX); + String[] hierarchiesBoundaryCodes = Arrays.copyOf(allHierarchiesBoundaryCodes, allHierarchiesBoundaryCodes.length - 1); PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() - .tenantId(censusRequest.getCensus().getTenantId()) - .jurisdiction(Arrays.stream(heirarchysBoundaryCodes).toList()) - .planConfigurationId(censusRequest.getCensus().getSource()) + .tenantId(census.getTenantId()) + .jurisdiction(Arrays.stream(hierarchiesBoundaryCodes).toList()) + .planConfigurationId(census.getSource()) .role(config.getAllowedCensusRoles()) .build(); //search for plan-employee assignments for the ancestral heirarchy codes. PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeAssignmnetUtil.fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest.builder() .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) - .requestInfo(censusRequest.getRequestInfo()).build()); + .requestInfo(requestInfo).build()); // Create a map of jurisdiction to employeeId Map jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() - .filter(assignment -> assignment.getJurisdiction() != null && !assignment.getJurisdiction().isEmpty()) + .filter(assignment -> !CollectionUtils.isEmpty(assignment.getJurisdiction())) .flatMap(assignment -> { String employeeId = assignment.getEmployeeId(); return assignment.getJurisdiction().stream() - .filter(jurisdiction -> Arrays.asList(heirarchysBoundaryCodes).contains(jurisdiction)) + .filter(jurisdiction -> Arrays.asList(hierarchiesBoundaryCodes).contains(jurisdiction)) .map(jurisdiction -> new AbstractMap.SimpleEntry<>(jurisdiction, employeeId)); }) .collect(Collectors.toMap( @@ -185,23 +271,20 @@ private void autoAssignAssignee(Workflow workflow, CensusRequest censusRequest) String assignee = null; //assignee will remain null in case terminate actions are being taken - String action = censusRequest.getCensus().getWorkflow().getAction(); + String action = census.getWorkflow().getAction(); if (config.getWfInitiateActions().contains(action)) { - for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { - assignee = jurisdictionToEmployeeMap.get(heirarchysBoundaryCodes[i]); + for (int i = hierarchiesBoundaryCodes.length - 1; i >= 0; i--) { + assignee = jurisdictionToEmployeeMap.get(hierarchiesBoundaryCodes[i]); if (assignee != null) break; // Stop iterating once an assignee is found } } else if (config.getWfIntermediateActions().contains(action)) { - assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, censusRequest, jurisdictionToEmployeeMap); + assignee = assignToHigherBoundaryLevel(hierarchiesBoundaryCodes, census, jurisdictionToEmployeeMap); } else if (config.getWfSendBackActions().contains(action)) { - assignee = censusRequest.getCensus().getAuditDetails().getLastModifiedBy(); + assignee = census.getAuditDetails().getLastModifiedBy(); } - if(!ObjectUtils.isEmpty(assignee)) - workflow.setAssignes(Collections.singletonList(assignee)); - - censusRequest.getCensus().setAssignee(assignee); + return assignee; } /** @@ -209,17 +292,17 @@ private void autoAssignAssignee(Workflow workflow, CensusRequest censusRequest) * Iterates through boundary codes, checking if they match the assignee's jurisdiction. * If a higher-level boundary has an assigned employee, returns that employee's ID. * - * @param heirarchysBoundaryCodes boundary codes representing the hierarchy - * @param censusRequest the request with census and jurisdiction details + * @param heirarchysBoundaryCodes boundary codes representing the hierarchy + * @param census the census object with jurisdiction details * @param jurisdictionToEmployeeMap map of jurisdiction codes to employee IDs * @return the employee ID from the higher boundary, or null if */ - public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, CensusRequest censusRequest, Map jurisdictionToEmployeeMap) { + public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Census census, Map jurisdictionToEmployeeMap) { for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { String boundaryCode = heirarchysBoundaryCodes[i]; // Check if this boundary code is present in assigneeJurisdiction - if (censusRequest.getCensus().getAssigneeJurisdiction().contains(boundaryCode)) { + if (census.getAssigneeJurisdiction().contains(boundaryCode)) { if (i - 1 >= 0) { // Check the next higher level in the hierarchy (one index above the match) diff --git a/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java index 17c6a975c08..8feabf4b455 100644 --- a/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java +++ b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java @@ -1,6 +1,7 @@ package digit.web.controllers; import digit.service.CensusService; +import digit.web.models.BulkCensusRequest; import digit.web.models.CensusRequest; import digit.web.models.CensusResponse; import digit.web.models.CensusSearchRequest; @@ -60,4 +61,16 @@ public ResponseEntity update(@Parameter(in = ParameterIn.DEFAULT CensusResponse response = censusService.update(body); return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); } + + /** + * Request handler for serving bulk census update requests + * + * @param body + * @return + */ + @RequestMapping(value = "/bulk/_update", method = RequestMethod.POST) + public ResponseEntity bulkUpdate(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody BulkCensusRequest body) { + CensusResponse response = censusService.bulkUpdate(body); + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } } diff --git a/health-services/census-service/src/main/java/digit/web/models/BulkCensusRequest.java b/health-services/census-service/src/main/java/digit/web/models/BulkCensusRequest.java new file mode 100644 index 00000000000..e88178822bb --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/BulkCensusRequest.java @@ -0,0 +1,33 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * BulkCensusRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BulkCensusRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Census") + @Valid + private List census = null; + + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java index 4a3ab843cd7..363da1907ae 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.springframework.validation.annotation.Validated; import jakarta.validation.constraints.*; @@ -26,6 +27,9 @@ public class CensusSearchCriteria { @JsonProperty("id") private String id = null; + @JsonProperty("ids") + private Set ids = null; + @JsonProperty("tenantId") @Size(min = 1, max = 100) private String tenantId = null; @@ -51,6 +55,12 @@ public class CensusSearchCriteria { @JsonProperty("effectiveTo") private Long effectiveTo = null; + @JsonProperty("limit") + private Integer limit = null; + + @JsonProperty("offset") + private Integer offset = null; + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { this.areaCodes = new ArrayList<>(); diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java b/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java index 222e8989858..ac595972fe7 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java @@ -1,6 +1,7 @@ package digit.web.models; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; @@ -25,6 +26,7 @@ public class CensusSearchRequest { @JsonProperty("CensusSearchCriteria") @Valid + @NotNull private CensusSearchCriteria censusSearchCriteria = null; From 9dbbc92c62a5f3113f42e1c7531ca2965402c592 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 23 Oct 2024 15:54:48 +0530 Subject: [PATCH 224/351] pagination --- .../querybuilder/CensusQueryBuilder.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index c3341ce087a..cb159606266 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -1,5 +1,6 @@ package digit.repository.querybuilder; +import digit.config.Configuration; import digit.util.QueryUtil; import digit.web.models.CensusSearchCriteria; import org.springframework.stereotype.Component; @@ -14,7 +15,10 @@ public class CensusQueryBuilder { private QueryUtil queryUtil; - public CensusQueryBuilder(QueryUtil queryUtil) { + private Configuration config; + + public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { + this.config = config; this.queryUtil = queryUtil; } @@ -42,7 +46,7 @@ public CensusQueryBuilder(QueryUtil queryUtil) { public String getCensusQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { String query = buildCensusQuery(searchCriteria, preparedStmtList, Boolean.FALSE, Boolean.FALSE); query = queryUtil.addOrderByClause(query, CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); - query = queryUtil.getPaginatedQuery(query, preparedStmtList); + query = getPaginatedQuery(query, preparedStmtList, searchCriteria); return query; } @@ -162,4 +166,25 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep public String getBulkCensusQuery() { return BULK_CENSUS_UPDATE_QUERY; } + + /** + * This method appends pagination i.e. limit and offset to the query. + * + * @param query the query to which pagination is to be added. + * @param preparedStmtList prepared statement list to add limit and offset. + * @return a query with pagination + */ + public String getPaginatedQuery(String query, List preparedStmtList, CensusSearchCriteria searchCriteria) { + StringBuilder paginatedQuery = new StringBuilder(query); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getOffset()) ? searchCriteria.getOffset() : config.getDefaultOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(!ObjectUtils.isEmpty(searchCriteria.getLimit()) ? searchCriteria.getLimit() : config.getDefaultLimit()); + + return paginatedQuery.toString(); + } } From c2d10bffefdc69fce9a9bf2fe880950260130852 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 23 Oct 2024 17:26:27 +0530 Subject: [PATCH 225/351] setting assignee for bulk update api --- .../service/workflow/WorkflowService.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index d7cd4210b43..24af898f15e 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -147,7 +147,12 @@ public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { .build(); String assignee = getAssigneeForAutoAssignment(plan, planRequest.getRequestInfo()); - plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + + // Set Assignee + if(!ObjectUtils.isEmpty(assignee)) + plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + + plan.setAssignee(assignee); enrichAssignesInProcessInstance(processInstance, plan.getWorkflow()); @@ -244,11 +249,6 @@ private String getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) assignee = plan.getAuditDetails().getLastModifiedBy(); } - if(!ObjectUtils.isEmpty(assignee)) - plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); - - plan.setAssignee(assignee); - return assignee; } @@ -313,8 +313,12 @@ private ProcessInstanceRequest createWorkflowRequest(BulkPlanRequest bulkPlanReq bulkPlanRequest.getRequestInfo()); bulkPlanRequest.getPlans().forEach(plan -> { + // Set assignee - plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + if(!ObjectUtils.isEmpty(assignee)) + plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + + plan.setAssignee(assignee); // Create process instance object from plan ProcessInstance processInstance = ProcessInstance.builder() From 4b82c970d6d53be4e191942f52621f4f6c249228 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 23 Oct 2024 17:44:50 +0530 Subject: [PATCH 226/351] added migration script to make status nullable --- .../java/digit/repository/impl/CensusRepositoryImpl.java | 8 ++++---- .../main/V202410223151500__census_update_status_ddl.sql | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 9920a517024..9c2f6a0759c 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -114,8 +114,8 @@ public void bulkUpdate(BulkCensusRequest request) { // Get bulk census update query String bulkCensusUpdateQuery = queryBuilder.getBulkCensusQuery(); - // Prepare arguments for batch update - List batchArgs = request.getCensus().stream().map(census -> new Object[] { + // Prepare rows for bulk update + List rows = request.getCensus().stream().map(census -> new Object[] { census.getStatus(), census.getAssignee(), census.getAuditDetails().getLastModifiedBy(), @@ -123,8 +123,8 @@ public void bulkUpdate(BulkCensusRequest request) { census.getId() }).toList(); - // Perform batch update - jdbcTemplate.batchUpdate(bulkCensusUpdateQuery, batchArgs); + // Perform bulk update + jdbcTemplate.batchUpdate(bulkCensusUpdateQuery, rows); } /** diff --git a/health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql new file mode 100644 index 00000000000..4cb1ea833ea --- /dev/null +++ b/health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE census ALTER COLUMN status DROP NOT NULL; \ No newline at end of file From 83294d8bf1a7bdcc3dd66a5e8705c9a67933a252 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 23 Oct 2024 17:56:07 +0530 Subject: [PATCH 227/351] HCMPRE-853 adding consumer for census create from resource generator service. --- .../digit/kafka/ResourceCensusConsumer.java | 36 +++++++++++++++++++ .../java/digit/service/CensusService.java | 1 + 2 files changed, 37 insertions(+) create mode 100644 health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java diff --git a/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java b/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java new file mode 100644 index 00000000000..7978761c933 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java @@ -0,0 +1,36 @@ +package digit.kafka; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.service.CensusService; +import digit.web.models.CensusRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +@Slf4j +public class ResourceCensusConsumer { + + private CensusService censusService; + + private ObjectMapper mapper; + + public ResourceCensusConsumer(CensusService censusService, ObjectMapper mapper) { + this.censusService = censusService; + this.mapper = mapper; + } + + @KafkaListener(topics = {"${resource.config.consumer.census.create.topic}"}) + public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + CensusRequest censusRequest = mapper.convertValue(consumerRecord, CensusRequest.class); + censusService.create(censusRequest); + } catch (Exception exception) { + log.error("Error in resource census consumer", exception); + } + } +} diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index de66214e7b3..c00ab285483 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -47,6 +47,7 @@ public CensusResponse create(CensusRequest request) { validator.validateCreate(request); // Validate census create request enrichment.enrichCreate(request); // Enrich census create request timeframeEnrichment.enrichPreviousTimeframe(request); // Enrich timeframe for previous census + workflow.invokeWorkflowForStatusUpdate(request); // Call workflow transition API for status update repository.create(request); // Delegate creation request to repository return CensusResponse.builder() .census(Collections.singletonList(request.getCensus())) From 61be50f789772235c4675c9f0be2e6725fffcbdd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 23 Oct 2024 18:09:47 +0530 Subject: [PATCH 228/351] removed unused pojos --- .../src/main/java/digit/web/models/Error.java | 54 ------------------- .../main/java/digit/web/models/ErrorRes.java | 47 ---------------- .../src/main/java/digit/web/models/Role1.java | 36 ------------- .../java/digit/web/models/TenantRole.java | 46 ---------------- 4 files changed, 183 deletions(-) delete mode 100644 health-services/census-service/src/main/java/digit/web/models/Error.java delete mode 100644 health-services/census-service/src/main/java/digit/web/models/ErrorRes.java delete mode 100644 health-services/census-service/src/main/java/digit/web/models/Role1.java delete mode 100644 health-services/census-service/src/main/java/digit/web/models/TenantRole.java diff --git a/health-services/census-service/src/main/java/digit/web/models/Error.java b/health-services/census-service/src/main/java/digit/web/models/Error.java deleted file mode 100644 index 5d82d49a046..00000000000 --- a/health-services/census-service/src/main/java/digit/web/models/Error.java +++ /dev/null @@ -1,54 +0,0 @@ -package digit.web.models; - -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import io.swagger.v3.oas.annotations.media.Schema; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; - -/** - * Error object will be returned as a part of reponse body in conjunction with ResponseInfo as part of ErrorResponse whenever the request processing status in the ResponseInfo is FAILED. HTTP return in this scenario will usually be HTTP 400. - */ -@Schema(description = "Error object will be returned as a part of reponse body in conjunction with ResponseInfo as part of ErrorResponse whenever the request processing status in the ResponseInfo is FAILED. HTTP return in this scenario will usually be HTTP 400.") -@Validated -@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2024-09-25T15:46:57.876914059+05:30[Asia/Kolkata]") -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class Error { - @JsonProperty("code") - @NotNull - private String code = null; - - @JsonProperty("message") - @NotNull - private String message = null; - - @JsonProperty("description") - private String description = null; - - @JsonProperty("params") - private List params = null; - - - public Error addParamsItem(String paramsItem) { - if (this.params == null) { - this.params = new ArrayList<>(); - } - this.params.add(paramsItem); - return this; - } - -} diff --git a/health-services/census-service/src/main/java/digit/web/models/ErrorRes.java b/health-services/census-service/src/main/java/digit/web/models/ErrorRes.java deleted file mode 100644 index e864a188e9a..00000000000 --- a/health-services/census-service/src/main/java/digit/web/models/ErrorRes.java +++ /dev/null @@ -1,47 +0,0 @@ -package digit.web.models; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; - -import java.util.ArrayList; -import java.util.List; - -import org.egov.common.contract.response.ResponseInfo; -import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; - -/** - * All APIs will return ErrorRes in case of failure which will carry ResponseInfo as metadata and Error object as actual representation of error. In case of bulk apis, some apis may chose to return the array of Error objects to indicate individual failure. - */ -@Schema(description = "All APIs will return ErrorRes in case of failure which will carry ResponseInfo as metadata and Error object as actual representation of error. In case of bulk apis, some apis may chose to return the array of Error objects to indicate individual failure.") -@Validated -@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2024-09-25T15:46:57.876914059+05:30[Asia/Kolkata]") -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class ErrorRes { - @JsonProperty("ResponseInfo") - @NotNull - @Valid - private ResponseInfo responseInfo = null; - - @JsonProperty("Errors") - @Valid - private List errors = null; - - - public ErrorRes addErrorsItem(Error errorsItem) { - if (this.errors == null) { - this.errors = new ArrayList<>(); - } - this.errors.add(errorsItem); - return this; - } - -} diff --git a/health-services/census-service/src/main/java/digit/web/models/Role1.java b/health-services/census-service/src/main/java/digit/web/models/Role1.java deleted file mode 100644 index cea8fb9ce17..00000000000 --- a/health-services/census-service/src/main/java/digit/web/models/Role1.java +++ /dev/null @@ -1,36 +0,0 @@ -package digit.web.models; - -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import io.swagger.v3.oas.annotations.media.Schema; -import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; - -/** - * minimal representation of the Roles in the system to be carried along in UserInfo with RequestInfo meta data. Actual authorization service to extend this to have more role related attributes - */ -@Schema(description = "minimal representation of the Roles in the system to be carried along in UserInfo with RequestInfo meta data. Actual authorization service to extend this to have more role related attributes ") -@Validated -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class Role1 { - - @JsonProperty("name") - @NotNull - @Size(max = 64) - private String name = null; - - @JsonProperty("description") - private String description = null; - - -} diff --git a/health-services/census-service/src/main/java/digit/web/models/TenantRole.java b/health-services/census-service/src/main/java/digit/web/models/TenantRole.java deleted file mode 100644 index c7e04032adf..00000000000 --- a/health-services/census-service/src/main/java/digit/web/models/TenantRole.java +++ /dev/null @@ -1,46 +0,0 @@ -package digit.web.models; - -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; -import digit.web.models.Role1; -import io.swagger.v3.oas.annotations.media.Schema; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; - -/** - * User role carries the tenant related role information for the user. A user can have multiple roles per tenant based on the need of the tenant. A user may also have multiple roles for multiple tenants. - */ -@Schema(description = "User role carries the tenant related role information for the user. A user can have multiple roles per tenant based on the need of the tenant. A user may also have multiple roles for multiple tenants.") -@Validated -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class TenantRole { - @JsonProperty("tenantId") - @NotNull - private String tenantId = null; - - @JsonProperty("roles") - @NotNull - @Valid - private List roles = new ArrayList<>(); - - - public TenantRole addRolesItem(Role1 rolesItem) { - this.roles.add(rolesItem); - return this; - } - -} From e812defc32fa6cdbc26f5c2d967cd932e9341b58 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 24 Oct 2024 11:44:06 +0530 Subject: [PATCH 229/351] added status in rowMapper --- .../src/main/java/digit/repository/rowmapper/PlanRowMapper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index 522a79e38e1..3692abd35cc 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java @@ -53,6 +53,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep planEntry.setTenantId(rs.getString("plan_tenant_id")); planEntry.setLocality(rs.getString("plan_locality")); planEntry.setCampaignId(rs.getString("plan_campaign_id")); + planEntry.setStatus(rs.getString("plan_status")); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); planEntry.setBoundaryAncestralPath(rs.getString("plan_boundary_ancestral_path")); planEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); From 269a4268101841e40a3b109c0a8b04d73f05f0f3 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 24 Oct 2024 13:02:24 +0530 Subject: [PATCH 230/351] Integrated business service --- .../main/java/digit/config/Configuration.java | 3 + .../java/digit/config/ServiceConstants.java | 5 ++ .../kafka/FacilityCatchmentConsumer.java | 2 + .../digit/repository/CensusRepository.java | 2 +- .../repository/impl/CensusRepositoryImpl.java | 25 ++++-- .../repository/rowmapper/CensusRowMapper.java | 2 +- .../rowmapper/StatusCountRowMapper.java | 5 +- .../java/digit/service/CensusService.java | 2 +- .../java/digit/util/BusinessServiceUtil.java | 81 +++++++++++++++++++ .../src/main/java/digit/util/CommonUtil.java | 59 +++++++++++--- .../util/PlanEmployeeAssignmnetUtil.java | 6 +- .../src/main/resources/application.properties | 1 + 12 files changed, 168 insertions(+), 25 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/util/BusinessServiceUtil.java diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 2c1e919354a..5fee10f1ceb 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -52,6 +52,9 @@ public class Configuration { @Value("${egov.workflow.transition.path}") private String wfTransitionPath; + @Value("${egov.business.service.search.endpoint}") + private String businessServiceSearchEndpoint; + @Value("${workflow.initiate.action}") private List wfInitiateActions; diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 2a7fb63022a..faeda8989ac 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -19,6 +19,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_EMPLOYEE_ASSIGNMENT_DETAILS = "Exception occurred while fetching plan employee assignment details from plan service: "; + public static final String ERROR_WHILE_FETCHING_BUSINESS_SERVICE_DETAILS = "Exception occurred while fetching business service details: "; + public static final String RES_MSG_ID = "uief87324"; public static final String SUCCESSFUL = "successful"; public static final String FAILED = "failed"; @@ -57,6 +59,9 @@ public class ServiceConstants { public static final String NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_CODE = "NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE"; public static final String NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_MESSAGE = "Invalid or incorrect boundaryCode. No boundary data found."; + public static final String NO_BUSINESS_SERVICE_DATA_FOUND_CODE = "NO_BUSINESS_SERVICE_DATA_FOUND"; + public static final String NO_BUSINESS_SERVICE_DATA_FOUND_MESSAGE = "Invalid or incorrect businessService. No business service data found."; + public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index e4374cc81d3..497bb41c5cf 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -48,6 +48,8 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE censusFromSearch.forEach(census -> { census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); + census.setFacilityAssigned(Boolean.TRUE); + service.update(CensusRequest.builder().census(census).build()); }); } catch (Exception exception) { diff --git a/health-services/census-service/src/main/java/digit/repository/CensusRepository.java b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java index 20aac629751..4a9f159e7e9 100644 --- a/health-services/census-service/src/main/java/digit/repository/CensusRepository.java +++ b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java @@ -17,5 +17,5 @@ public interface CensusRepository { public Integer count(CensusSearchCriteria censusSearchCriteria); - public Map statusCount(CensusSearchCriteria censusSearchCriteria); + public Map statusCount(CensusSearchRequest censusSearchRequest); } diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 9c2f6a0759c..a7c997f38c3 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -6,15 +6,19 @@ import digit.repository.querybuilder.CensusQueryBuilder; import digit.repository.rowmapper.CensusRowMapper; import digit.repository.rowmapper.StatusCountRowMapper; +import digit.util.CommonUtil; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; +import org.springframework.util.ObjectUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; +import static digit.config.ServiceConstants.CENSUS_BUSINESS_SERVICE; + @Slf4j @Repository public class CensusRepositoryImpl implements CensusRepository { @@ -31,13 +35,16 @@ public class CensusRepositoryImpl implements CensusRepository { private StatusCountRowMapper statusCountRowMapper; - public CensusRepositoryImpl(Producer producer, Configuration config, CensusQueryBuilder queryBuilder, CensusRowMapper censusRowMapper, JdbcTemplate jdbcTemplate, StatusCountRowMapper statusCountRowMapper) { + private CommonUtil commonUtil; + + public CensusRepositoryImpl(Producer producer, Configuration config, CensusQueryBuilder queryBuilder, CensusRowMapper censusRowMapper, JdbcTemplate jdbcTemplate, StatusCountRowMapper statusCountRowMapper,CommonUtil commonUtil) { this.producer = producer; this.config = config; this.queryBuilder = queryBuilder; this.censusRowMapper = censusRowMapper; this.jdbcTemplate = jdbcTemplate; this.statusCountRowMapper = statusCountRowMapper; + this.commonUtil = commonUtil; } /** @@ -82,15 +89,23 @@ public Integer count(CensusSearchCriteria censusSearchCriteria) { /** * Counts the census record based on their current status for the provided search criteria. * - * @param censusSearchCriteria The search criteria for filtering census records. + * @param censusSearchRequest The request with search criteria for filtering census records. * @return The status count of census records for the given search criteria. */ @Override - public Map statusCount(CensusSearchCriteria censusSearchCriteria) { + public Map statusCount(CensusSearchRequest censusSearchRequest) { List preparedStmtList = new ArrayList<>(); - String query = queryBuilder.getCensusStatusCountQuery(censusSearchCriteria, preparedStmtList); + List statusList = commonUtil.getStatusFromBusinessService(censusSearchRequest.getRequestInfo(), CENSUS_BUSINESS_SERVICE, censusSearchRequest.getCensusSearchCriteria().getTenantId()); + + String query = queryBuilder.getCensusStatusCountQuery(censusSearchRequest.getCensusSearchCriteria(), preparedStmtList); + Map statusCountMap = jdbcTemplate.query(query, statusCountRowMapper, preparedStmtList.toArray()); + + statusList.forEach(status -> { + if(ObjectUtils.isEmpty(statusCountMap.get(status))) + statusCountMap.put(status, 0); + }); - return jdbcTemplate.query(query, statusCountRowMapper, preparedStmtList.toArray()); + return statusCountMap; } /** diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index c7dc43017e9..eae77786dc4 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -57,7 +57,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setEffectiveFrom(rs.getLong("census_effective_from")); censusEntry.setEffectiveTo(rs.getLong("census_effective_to")); censusEntry.setSource(rs.getString("census_source")); - censusEntry.setStatus(rs.getString("census_status").toUpperCase()); + censusEntry.setStatus(rs.getString("census_status")); censusEntry.setAssignee(rs.getString("census_assignee")); censusEntry.setBoundaryAncestralPath(Collections.singletonList(rs.getString("census_boundary_ancestral_path"))); censusEntry.setFacilityAssigned(rs.getBoolean("census_facility_assigned")); diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/StatusCountRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/StatusCountRowMapper.java index c59c6e22025..b997f2f933f 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/StatusCountRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/StatusCountRowMapper.java @@ -3,6 +3,7 @@ import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; import java.sql.ResultSet; import java.sql.SQLException; @@ -19,7 +20,9 @@ public Map extractData(ResultSet rs) throws SQLException, DataA while (rs.next()) { String status = rs.getString("census_status"); Integer statusCount = rs.getInt("census_status_count"); - statusCountMap.put(status, statusCount); + + if(!ObjectUtils.isEmpty(status)) + statusCountMap.put(status, statusCount); } return statusCountMap; diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index 0c62f0a2073..8d2bdfdcccb 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -79,7 +79,7 @@ public CensusResponse search(CensusSearchRequest request) { .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .census(repository.search(request.getCensusSearchCriteria())) .totalCount(repository.count(request.getCensusSearchCriteria())) - .statusCount(repository.statusCount(request.getCensusSearchCriteria())) + .statusCount(repository.statusCount(request)) .build(); } diff --git a/health-services/census-service/src/main/java/digit/util/BusinessServiceUtil.java b/health-services/census-service/src/main/java/digit/util/BusinessServiceUtil.java new file mode 100644 index 00000000000..ce127d4c637 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/BusinessServiceUtil.java @@ -0,0 +1,81 @@ +package digit.util; + +import digit.config.Configuration; +import digit.models.coremodels.RequestInfoWrapper; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.workflow.BusinessService; +import org.egov.common.contract.workflow.BusinessServiceResponse; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class BusinessServiceUtil { + + private RestTemplate restTemplate; + + private Configuration config; + + public BusinessServiceUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.config = configs; + } + + /** + * This method fetches business service details for the given tenant id and business service. + * + * @param requestInfo the request info from request. + * @param businessService businessService whose details are to be searched. + * @param tenantId tenantId from request. + * @return returns the business service response for the given tenant id and business service. + */ + public BusinessService fetchBusinessService(RequestInfo requestInfo, String businessService, String tenantId) { + + // Get business service uri + Map uriParameters = new HashMap<>(); + String uri = getBusinessServiceUri(businessService, tenantId, uriParameters); + + // Create request body + RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); + BusinessServiceResponse businessServiceResponse = new BusinessServiceResponse(); + + try { + businessServiceResponse = restTemplate.postForObject(uri, requestInfoWrapper, BusinessServiceResponse.class, uriParameters); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_BUSINESS_SERVICE_DETAILS, e); + } + + if (CollectionUtils.isEmpty(businessServiceResponse.getBusinessServices())) { + throw new CustomException(NO_BUSINESS_SERVICE_DATA_FOUND_CODE, NO_BUSINESS_SERVICE_DATA_FOUND_MESSAGE); + } + + return businessServiceResponse.getBusinessServices().get(0); + } + + /** + * This method creates business service uri with query parameters + * + * @param businessService businessService whose details are to be searched. + * @param tenantId tenant id from the request. + * @param uriParameters map that stores values corresponding to the placeholder in uri + * @return + */ + private String getBusinessServiceUri(String businessService, String tenantId, Map uriParameters) { + + StringBuilder uri = new StringBuilder(); + uri.append(config.getWfHost()).append(config.getBusinessServiceSearchEndpoint()).append("?tenantId={tenantId}&businessServices={businessService}"); + + uriParameters.put("tenantId", tenantId); + uriParameters.put("businessService", businessService); + + return uri.toString(); + } +} diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index 600966f8ab9..362d299eb42 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -1,58 +1,91 @@ package digit.util; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import digit.web.models.CensusSearchCriteria; import digit.web.models.CensusSearchRequest; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.workflow.BusinessService; +import org.egov.common.contract.workflow.State; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; import java.util.List; import java.util.Map; -import static digit.config.ServiceConstants.ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE; -import static digit.config.ServiceConstants.ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE; +import static digit.config.ServiceConstants.*; +@Slf4j @Component public class CommonUtil { private ObjectMapper objectMapper; - public CommonUtil(ObjectMapper objectMapper) { + private BusinessServiceUtil businessServiceUtil; + + public CommonUtil(ObjectMapper objectMapper, BusinessServiceUtil businessServiceUtil) { this.objectMapper = objectMapper; + this.businessServiceUtil = businessServiceUtil; } + /** + * Adds or updates the value of provided field in the additional details object. + * @param additionalDetails + * @param fieldToUpdate + * @param updatedValue + * @return + */ public Map updateFieldInAdditionalDetails(Object additionalDetails, String fieldToUpdate, String updatedValue) { try { - String jsonString = objectMapper.writeValueAsString(additionalDetails); - JsonNode rootNode = objectMapper.readTree(jsonString); - - // Cast rootNode to ObjectNode to allow modifications - ObjectNode objectNode = (ObjectNode) rootNode; + // Get or create the additionalDetails as an ObjectNode + ObjectNode objectNode = objectMapper.convertValue(additionalDetails, ObjectNode.class); - // Update or Add facilityId in additional details object + // Update or Add the field in additional details object objectNode.put(fieldToUpdate, updatedValue); // Convert updated ObjectNode back to a Map and set it in 'additionalDetails' Map updatedDetails = objectMapper.convertValue(objectNode, Map.class); return updatedDetails; - } catch (JsonProcessingException e) { + } catch (Exception e) { throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE); } } + /** + * Creates the census search request for the provided details. + * @param tenantId + * @param planConfigId + * @param serviceBoundary + * @return + */ public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary) { CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() .tenantId(tenantId) .source(planConfigId) - .areaCodes(List.of(serviceBoundary.split(", "))) + .areaCodes(List.of(serviceBoundary.split(","))) .effectiveTo(0L) .build(); return CensusSearchRequest.builder().censusSearchCriteria(searchCriteria).build(); } + + /** + * Creates a list of all the workflow states for the provided business service. + * @param requestInfo + * @param businessService + * @param tenantId + * @return + */ + public List getStatusFromBusinessService(RequestInfo requestInfo, String businessService, String tenantId) { + BusinessService businessServices = businessServiceUtil.fetchBusinessService(requestInfo, businessService, tenantId); + + return businessServices.getStates().stream() + .map(State::getState) + .filter(state -> !ObjectUtils.isEmpty(state)) + .toList(); + } } diff --git a/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java b/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java index f2f091649ba..0cb18bdb6db 100644 --- a/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java +++ b/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java @@ -19,11 +19,11 @@ public class PlanEmployeeAssignmnetUtil { private RestTemplate restTemplate; - private Configuration configs; + private Configuration config; public PlanEmployeeAssignmnetUtil(RestTemplate restTemplate, Configuration configs) { this.restTemplate = restTemplate; - this.configs = configs; + this.config = configs; } /** @@ -54,6 +54,6 @@ public PlanEmployeeAssignmentResponse fetchPlanEmployeeAssignment(PlanEmployeeAs */ private StringBuilder getPlanEmployeeAssignmentUri() { StringBuilder uri = new StringBuilder(); - return uri.append(configs.getPlanServiceHost()).append(configs.getPlanEmployeeAssignmentSearchEndpoint()); + return uri.append(config.getPlanServiceHost()).append(config.getPlanEmployeeAssignmentSearchEndpoint()); } } diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index d6ca280963b..2ae09a79768 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -59,6 +59,7 @@ egov.plan.employee.assignment.search.endpoint=/plan-service/employee/_search # Workflow egov.workflow.host=https://unified-dev.digit.org egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition +egov.business.service.search.endpoint=/egov-workflow-v2/egov-wf/businessservice/_search workflow.initiate.action=INITIATE workflow.intermediate.action=EDIT_AND_SEND_FOR_APPROVAL,APPROVE workflow.send.back.actions=SEND_BACK_FOR_CORRECTION From ea553b568dce836bf4a078902d08c697ea5e9155 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 24 Oct 2024 15:58:30 +0530 Subject: [PATCH 231/351] changed topic for facility consumer --- .../src/main/java/digit/config/Configuration.java | 4 ++-- .../src/main/java/digit/kafka/FacilityCatchmentConsumer.java | 2 +- .../census-service/src/main/resources/application.properties | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 5fee10f1ceb..4d280ecc3e0 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -28,8 +28,8 @@ public class Configuration { @Value("${census.update.topic}") private String censusUpdateTopic; - @Value("${boundary.facility.catchment.update.topic}") - private String facitilyCatchmentUpdateTopic; + @Value("${plan.facility.update.topic}") + private String planFcailityUpdateTopic; // Boundary Service @Value("${egov.boundary.service.host}") diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index 497bb41c5cf..3e7ac4cbb1b 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -35,7 +35,7 @@ public FacilityCatchmentConsumer(ObjectMapper objectMapper, CensusService servic this.commonUtil = commonUtil; } - @KafkaListener(topics = {"${boundary.facility.catchment.update.topic}"}) + @KafkaListener(topics = {"${plan.facility.update.topic}"}) public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { try { PlanFacilityRequestDTO planFacilityRequestDTO = objectMapper.convertValue(consumerRecord, PlanFacilityRequestDTO.class); diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 2ae09a79768..a293305e516 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -72,7 +72,7 @@ census.default.limit=10 resource.config.consumer.census.create.topic=resource-census-create-topic resource.config.consumer.census.update.topic=resource-census-update-topic -boundary.facility.catchment.update.topic=boundary-catchment-update-topic +plan.facility.update.topic=update-plan-facility #Roles for census allowed.census.roles={'POPULATION_DATA_APPROVER','ROOT_POPULATION_DATA_APPROVER'} \ No newline at end of file From 3ea365e1b2f6cf5ef1db09a0de6d1f4edc7db225 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 24 Oct 2024 16:14:01 +0530 Subject: [PATCH 232/351] setting assignee in rowMapper --- .../src/main/java/digit/repository/rowmapper/PlanRowMapper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index 3692abd35cc..0e59b6bb8ef 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java @@ -54,6 +54,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep planEntry.setLocality(rs.getString("plan_locality")); planEntry.setCampaignId(rs.getString("plan_campaign_id")); planEntry.setStatus(rs.getString("plan_status")); + planEntry.setAssignee(rs.getString("plan_assignee")); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); planEntry.setBoundaryAncestralPath(rs.getString("plan_boundary_ancestral_path")); planEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); From c88e48da7353ed7b1f1cf4a5619e1d30bded9abc Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 24 Oct 2024 16:42:23 +0530 Subject: [PATCH 233/351] modified facilityDTO --- .../java/digit/repository/impl/PlanFacilityRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index cfe0c0e32f5..f0c662c5452 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -80,7 +80,7 @@ public PlanFacilityRequestDTO convertToDTO(PlanFacilityRequest planFacilityReque * @return a string */ private String convertArrayToString(List stringList) { - return String.join(", ", stringList); + return String.join(",", stringList); } From 940fad83eb6183a2b56103491c4807bb64744cb5 Mon Sep 17 00:00:00 2001 From: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com> Date: Fri, 25 Oct 2024 11:21:10 +0530 Subject: [PATCH 234/351] Setting request info in facility catchment consumer --- .../src/main/java/digit/kafka/FacilityCatchmentConsumer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index 3e7ac4cbb1b..50bbdc84315 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -50,10 +50,10 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); census.setFacilityAssigned(Boolean.TRUE); - service.update(CensusRequest.builder().census(census).build()); + service.update(CensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(census).build()); }); } catch (Exception exception) { log.error("Error in census consumer", exception); } } -} \ No newline at end of file +} From df12fe4d71e3a98614df8d4b1424d6ec30bd22db Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Fri, 25 Oct 2024 12:05:54 +0530 Subject: [PATCH 235/351] Fixed census consumer flow --- .../src/main/java/digit/kafka/FacilityCatchmentConsumer.java | 3 ++- .../src/main/java/digit/service/CensusService.java | 1 - .../census-service/src/main/java/digit/web/models/Census.java | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index 50bbdc84315..b4810ec4a75 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -1,6 +1,7 @@ package digit.kafka; import com.fasterxml.jackson.databind.ObjectMapper; +import digit.repository.CensusRepository; import digit.service.CensusService; import digit.util.CommonUtil; import digit.web.models.Census; @@ -49,7 +50,7 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE censusFromSearch.forEach(census -> { census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); census.setFacilityAssigned(Boolean.TRUE); - + census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); service.update(CensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(census).build()); }); } catch (Exception exception) { diff --git a/health-services/census-service/src/main/java/digit/service/CensusService.java b/health-services/census-service/src/main/java/digit/service/CensusService.java index 8d2bdfdcccb..ec37824bfc1 100644 --- a/health-services/census-service/src/main/java/digit/service/CensusService.java +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -90,7 +90,6 @@ public CensusResponse search(CensusSearchRequest request) { * @return The updated census response. */ public CensusResponse update(CensusRequest request) { - request.getCensus().setPartnerAssignmentValidationEnabled(true); // Validate census update request validator.validateUpdate(request); diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 4bba3af4d58..75252101032 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -81,7 +81,8 @@ public class Census { private List boundaryAncestralPath = null; @JsonIgnore - private boolean partnerAssignmentValidationEnabled; + @Builder.Default + private Boolean partnerAssignmentValidationEnabled = Boolean.TRUE; @JsonProperty("facilityAssigned") private Boolean facilityAssigned = null; From 29d0cc8d94ad1cfb6fdfc69f54ab6bbed7cb71a6 Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Fri, 25 Oct 2024 12:14:12 +0530 Subject: [PATCH 236/351] Fixed validation --- .../src/main/java/digit/service/validator/CensusValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 21c88ab9d6a..566a662d87f 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -91,7 +91,7 @@ private void validatePartnerForCensus(CensusRequest request) { throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); } - if (census.isPartnerAssignmentValidationEnabled()) { + if (census.getPartnerAssignmentValidationEnabled()) { User userInfo = request.getRequestInfo().getUserInfo(); List jurisdiction = Arrays.asList(request.getCensus().getBoundaryAncestralPath().get(0).split("\\|")); From 933610678c9e1ac710f9691572107fca3ffb9b60 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 25 Oct 2024 12:41:58 +0530 Subject: [PATCH 237/351] setting partner assignment validation as false when triggered through consumer --- .../src/main/java/digit/kafka/ResourceCensusConsumer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java b/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java index 7978761c933..e161225b23a 100644 --- a/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java @@ -28,6 +28,7 @@ public ResourceCensusConsumer(CensusService censusService, ObjectMapper mapper) public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { try { CensusRequest censusRequest = mapper.convertValue(consumerRecord, CensusRequest.class); + censusRequest.getCensus().setPartnerAssignmentValidationEnabled(Boolean.FALSE); censusService.create(censusRequest); } catch (Exception exception) { log.error("Error in resource census consumer", exception); From dc799bfa220754c05142228d6ad064d0b9954151 Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Fri, 25 Oct 2024 12:42:05 +0530 Subject: [PATCH 238/351] Corrected comma delimiter in POJO conversion --- .../src/main/java/digit/config/ServiceConstants.java | 1 + .../java/digit/repository/impl/PlanFacilityRepositoryImpl.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index b45f6ece7da..17a629f8274 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -326,4 +326,5 @@ public class ServiceConstants { public static final String FACILITY_TYPE_SEARCH_PARAMETER_KEY = "facilityType"; + public static final String COMMA_DELIMITER = ","; } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index cfe0c0e32f5..3042b9561ec 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -80,7 +80,7 @@ public PlanFacilityRequestDTO convertToDTO(PlanFacilityRequest planFacilityReque * @return a string */ private String convertArrayToString(List stringList) { - return String.join(", ", stringList); + return String.join(COMMA_DELIMITER, stringList); } From c144d89fadfeb62ac2184dd140482e6027135dfd Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Fri, 25 Oct 2024 13:49:15 +0530 Subject: [PATCH 239/351] Fixed census assignment --- .../census-service/src/main/java/digit/util/CommonUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index 362d299eb42..b3c2645d300 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -63,11 +63,15 @@ public Map updateFieldInAdditionalDetails(Object additionalDetai * @return */ public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary) { + List areaCodesForSearch = List.of(serviceBoundary.split(",")); + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() .tenantId(tenantId) .source(planConfigId) - .areaCodes(List.of(serviceBoundary.split(","))) + .areaCodes(areaCodesForSearch) .effectiveTo(0L) + .offset(0) + .limit(areaCodesForSearch.size()) .build(); return CensusSearchRequest.builder().censusSearchCriteria(searchCriteria).build(); From cda10bfc108eef064207136df5a115f5cdbd9820 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 25 Oct 2024 14:19:18 +0530 Subject: [PATCH 240/351] updating save as draft condition --- .../main/java/digit/config/ServiceConstants.java | 2 +- .../validator/PlanConfigurationValidator.java | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 17a629f8274..3a839eee3df 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -297,7 +297,7 @@ public class ServiceConstants { public static final String DRAFT_STATUS = "DRAFT"; - public static final String SETUP_COMPLETED_STATUS = "SETUP_COMPLETED"; + public static final String SETUP_COMPLETED_ACTION = "INITIATE"; //Query constants public static final String PERCENTAGE_WILDCARD = "%"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index a0e354430d7..883bc0c6870 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -632,34 +632,37 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration public boolean isSetupCompleted(PlanConfiguration planConfiguration) { - return Objects.equals(planConfiguration.getStatus(), SETUP_COMPLETED_STATUS); + if(!ObjectUtils.isEmpty(planConfiguration.getWorkflow())) + return Objects.equals(planConfiguration.getWorkflow().getAction(), SETUP_COMPLETED_ACTION); + + return false; } // Checks for whether file, assumption, operation or resource mapping is empty or null at a certain status private void checkForEmptyFiles(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getFiles())) { - log.error("Files cannot be empty at status = " + SETUP_COMPLETED_STATUS); + log.error("Files cannot be empty at action = " + SETUP_COMPLETED_ACTION); throw new CustomException(FILES_NOT_FOUND_CODE, FILES_NOT_FOUND_MESSAGE); } } private void checkForEmptyAssumption(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { - log.error("Assumptions cannot be empty at status = " + SETUP_COMPLETED_STATUS); + log.error("Assumptions cannot be empty at action = " + SETUP_COMPLETED_ACTION); throw new CustomException(ASSUMPTIONS_NOT_FOUND_CODE, ASSUMPTIONS_NOT_FOUND_MESSAGE); } } private void checkForEmptyOperation(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getOperations())) { - log.error("Operations cannot be empty at status = " + SETUP_COMPLETED_STATUS); + log.error("Operations cannot be empty at action = " + SETUP_COMPLETED_ACTION); throw new CustomException(OPERATIONS_NOT_FOUND_CODE, OPERATIONS_NOT_FOUND_MESSAGE); } } private void checkForEmptyResourceMapping(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { - log.error("Resource mapping cannot be empty at status = " + SETUP_COMPLETED_STATUS); + log.error("Resource mapping cannot be empty at action = " + SETUP_COMPLETED_ACTION); throw new CustomException(RESOURCE_MAPPING_NOT_FOUND_CODE, RESOURCE_MAPPING_NOT_FOUND_MESSAGE); } } From a20d0d89d22ca99a00e3505df8b42792bb98658b Mon Sep 17 00:00:00 2001 From: Shashwat Mishra Date: Fri, 25 Oct 2024 14:41:53 +0530 Subject: [PATCH 241/351] Fixed census validation logic --- .../census-service/src/main/java/digit/util/CommonUtil.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index b3c2645d300..6dff6e16e2f 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -64,12 +64,11 @@ public Map updateFieldInAdditionalDetails(Object additionalDetai */ public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary) { List areaCodesForSearch = List.of(serviceBoundary.split(",")); - + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() .tenantId(tenantId) .source(planConfigId) .areaCodes(areaCodesForSearch) - .effectiveTo(0L) .offset(0) .limit(areaCodesForSearch.size()) .build(); From 3186e21fbc6aa907109f7b6e1a71035ec4a6299f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 25 Oct 2024 15:22:16 +0530 Subject: [PATCH 242/351] HCMPRE-1078 remove validations against resourcemapping --- .../validator/PlanConfigurationValidator.java | 121 ------------------ 1 file changed, 121 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 883bc0c6870..0fd2b9c6851 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -71,18 +71,12 @@ public void validateCreate(PlanConfigurationRequest request) { // Validate that the assumption values in the plan configuration are correct validateAssumptionValue(planConfiguration); - // Validate the filestore ID in the plan configuration's request mappings - validateFilestoreId(planConfiguration); - // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); // Validate that the inputs for operations in the request match those in the MDMS data validateOperationsInputAgainstMDMS(request, mdmsData); - // Validate that the resource mappings in the request match those in the MDMS data - validateResourceMappingAgainstMDMS(request, mdmsData); - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings validateMappedToUniqueness(planConfiguration.getResourceMapping()); @@ -230,30 +224,6 @@ public void validateAssumptionUniqueness(PlanConfiguration planConfig) { } } - /** - * Validates the file store IDs in the provided PlanConfiguration's Resource Mapping list. - * - * @param planConfiguration The PlanConfiguration to validate. - */ - public void validateFilestoreId(PlanConfiguration planConfiguration) { - if (isSetupCompleted(planConfiguration)) { - checkForEmptyFiles(planConfiguration); - checkForEmptyResourceMapping(planConfiguration); - - Set fileStoreIds = planConfiguration.getFiles().stream() - .map(File::getFilestoreId) - .collect(Collectors.toSet()); - - planConfiguration.getResourceMapping().forEach(mapping -> { - if (!fileStoreIds.contains(mapping.getFilestoreId())) { - log.error("Resource Mapping " + mapping.getMappedTo() + " does not have valid fileStoreId " + mapping.getFilestoreId()); - throw new CustomException(FILESTORE_ID_INVALID_CODE, FILESTORE_ID_INVALID_MESSAGE); - } - }); - - } - } - /** * Validates the template identifiers of files in the PlanConfigurationRequest against the list of template identifiers * obtained from MDMS (Master Data Management System) data. @@ -456,9 +426,6 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validate that the assumption values in the plan configuration are correct validateAssumptionValue(planConfiguration); - // Validate the filestore ID in the plan configuration's request mappings - validateFilestoreId(planConfiguration); - // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); @@ -468,9 +435,6 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validate the dependencies between operations in the plan configuration validateOperationDependencies(planConfiguration); - // Validate that the resource mappings in the request match those in the MDMS data - validateResourceMappingAgainstMDMS(request, mdmsData); - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings validateMappedToUniqueness(planConfiguration.getResourceMapping()); @@ -530,84 +494,6 @@ public static void validateOperationDependencies(PlanConfiguration planConfigura } - /** - * Validate input (BCode) against MDMS data. - * - * @param request plan configauration request. - * @param mdmsData MDMS data object. - */ - public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { - PlanConfiguration planConfiguration = request.getPlanConfiguration(); - - if (isSetupCompleted(planConfiguration)) { - checkForEmptyFiles(planConfiguration); - checkForEmptyResourceMapping(planConfiguration); - - List files = planConfiguration.getFiles(); - List templateIds = files.stream() - .map(File::getTemplateIdentifier) - .toList(); - List inputFileTypes = files.stream() - .map(File::getInputFileType) - .map(File.InputFileTypeEnum::toString) - .toList(); - - final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS; - List ruleInputsListFromMDMS = null; - try { - log.info(jsonPathForRuleInputs); - ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - HashSet ruleInputsSetFromMDMS = new HashSet<>(ruleInputsListFromMDMS); - HashSet requiredColumns = getRequiredColumnsFromSchema(ruleInputsSetFromMDMS, templateIds, inputFileTypes); - List resourceMappings = planConfiguration.getResourceMapping(); - - // Throw a custom exception if no active mappings with BOUNDARY_CODE are found - if (requiredColumns.contains(ServiceConstants.BOUNDARY_CODE)) { - boolean exists = resourceMappings.stream() - .anyMatch(mapping -> mapping.getActive() && mapping.getMappedTo().equals(ServiceConstants.BOUNDARY_CODE)); - - if (!exists) { - throw new CustomException(BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE, BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE); - } - } - } - - } - - /** - * Filters the Schema MDMS data by type and section - * returns the list of columns which have the property 'isRequired' as true - * - * @param schemas List of schemas from MDMS - * @param templateIds The list of template identifiers from request object - * @param inputFileTypes The list of input file type from request object - * @return List of Columns that are required - */ - public static HashSet getRequiredColumnsFromSchema(HashSet schemas, List templateIds, List inputFileTypes) { - if (CollectionUtils.isEmpty(schemas)) { - return new HashSet<>(); - } - HashSet finalData = new HashSet<>(); - for (Object item : schemas) { - LinkedHashMap schemaEntity = (LinkedHashMap) item; - if (!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) - continue; - LinkedHashMap columns = (LinkedHashMap) ((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); - if (columns == null) return new HashSet<>(); - columns.forEach((key, value) -> { - LinkedHashMap data = value; - if (data.get(MDMS_SCHEMA_PROPERTIES_IS_REQUIRED)) { - finalData.add(key); - } - }); - } - return finalData; - } - /** * Validates Vehicle ids from additional details against MDMS V2 * @@ -660,11 +546,4 @@ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { } } - private void checkForEmptyResourceMapping(PlanConfiguration planConfiguration) { - if (CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { - log.error("Resource mapping cannot be empty at action = " + SETUP_COMPLETED_ACTION); - throw new CustomException(RESOURCE_MAPPING_NOT_FOUND_CODE, RESOURCE_MAPPING_NOT_FOUND_MESSAGE); - } - } - } From d44ac6ffadb1706d4c842fe1b7322923a16e39cd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 26 Oct 2024 14:38:17 +0530 Subject: [PATCH 243/351] enriched planConfigName --- .../java/digit/config/ServiceConstants.java | 4 +-- .../PlanEmployeeAssignmentEnricher.java | 27 +++++-------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 7c58f809c45..489fdbed4e8 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -26,7 +26,7 @@ public class ServiceConstants { public static final String ROOT_PREFIX = "ROOT"; - public static final String PLAN_CONFIG_NAME_FIELD = "planConfigNames"; + public static final String PLAN_CONFIG_NAME_FIELD = "planConfigName"; public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; @@ -200,7 +200,7 @@ public class ServiceConstants { public static final String PROCESS_INSTANCE_NOT_FOUND_MESSAGE = "No process instance found with businessId: "; public static final String ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_CODE = "ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS"; - public static final String ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_MESSAGE = "Exception occured while enriching additional details with plan config names: "; + public static final String ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_MESSAGE = "Exception occurred while enriching additional details: "; public static final String FILES_NOT_FOUND_CODE = "FILES_NOT_FOUND"; public static final String FILES_NOT_FOUND_MESSAGE = "Files are not present in Plan Configuration."; diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java index 395ea9ee503..ad4e1a8ae9f 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -51,7 +51,7 @@ public void enrichCreate(PlanEmployeeAssignmentRequest request) { request.getRequestInfo(), Boolean.TRUE)); - // Add a list of plan config names to which the employee is mapped + // Add plan config name to which the employee is mapped enrichWithPlanConfigName(planEmployeeAssignment); } @@ -70,27 +70,21 @@ public void enrichUpdate(PlanEmployeeAssignmentRequest request) { } /** - * This method enriches the additional details of plan employee assignment object with the name of all the plan configs to which the employee is mapped to. + * This method enriches the additional details of plan employee assignment object with the planConfigName to which employee is mapped. * * @param planEmployeeAssignment the object whose additional details is to be enriched */ private void enrichWithPlanConfigName(PlanEmployeeAssignment planEmployeeAssignment) { - String tenantId = planEmployeeAssignment.getTenantId(); - List employeeAssignmentListFromSearch = getAllEmployeeAssignment(planEmployeeAssignment.getEmployeeId(), tenantId); + String planConfigName = getPlanConfigNameById(planEmployeeAssignment.getPlanConfigurationId(), planEmployeeAssignment.getTenantId()); + try { // Get or create the additionalDetails as an ObjectNode ObjectNode objectNode = objectMapper.convertValue(planEmployeeAssignment.getAdditionalDetails(), ObjectNode.class); - // Create an ArrayNode to hold the list of plan configuration names - ArrayNode planConfigNamesNode = objectNode.putArray(PLAN_CONFIG_NAME_FIELD); - - // Populate the ArrayNode with the plan configuration names - employeeAssignmentListFromSearch.stream() - .map(PlanEmployeeAssignment::getPlanConfigurationId) - .map(id -> getPlanConfigNameById(id, tenantId)) - .forEach(planConfigNamesNode::add); + // Update or Add the field in additional details object + objectNode.put(PLAN_CONFIG_NAME_FIELD, planConfigName); // Set the updated additionalDetails back into the planEmployeeAssignment planEmployeeAssignment.setAdditionalDetails(objectMapper.convertValue(objectNode, Map.class)); @@ -104,13 +98,4 @@ private String getPlanConfigNameById(String planConfigId, String tenantId) { List planConfigurations = commonUtil.searchPlanConfigId(planConfigId, tenantId); return planConfigurations.get(0).getName(); } - - private List getAllEmployeeAssignment(String employeeId, String tenantId) { - PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() - .tenantId(tenantId) - .employeeId(Collections.singletonList(employeeId)) - .build(); - - return repository.search(searchCriteria); - } } From 2f87696cf75424e4dcc0ea71838d0981287e3002 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 26 Oct 2024 17:53:48 +0530 Subject: [PATCH 244/351] enriching initially set service boundaries in plan facility update --- .../impl/PlanFacilityRepositoryImpl.java | 2 +- .../service/validator/PlanFacilityValidator.java | 16 +++++++++++++--- .../main/java/digit/web/models/PlanFacility.java | 4 ++++ .../java/digit/web/models/PlanFacilityDTO.java | 5 +++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 3042b9561ec..a28b3989279 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -1,6 +1,5 @@ package digit.repository.impl; -import com.fasterxml.jackson.databind.ObjectMapper; import digit.config.Configuration; import digit.kafka.Producer; import digit.repository.PlanFacilityRepository; @@ -61,6 +60,7 @@ public PlanFacilityRequestDTO convertToDTO(PlanFacilityRequest planFacilityReque .facilityId(planFacility.getFacilityId()) .residingBoundary(planFacility.getResidingBoundary()) .serviceBoundaries(convertArrayToString(planFacility.getServiceBoundaries())) + .initiallySetServiceBoundaries(planFacility.getInitiallySetServiceBoundaries()) .additionalDetails(planFacility.getAdditionalDetails()) .active(planFacility.getActive()) .auditDetails(planFacility.getAuditDetails()) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 42109001e25..7fbea162514 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -212,12 +212,22 @@ private String validateHierarchyType(CampaignResponse campaignResponse, Object m * @param planFacilityRequest */ private void validatePlanFacilityExistence(PlanFacilityRequest planFacilityRequest) { - // If plan facility id provided is invalid, throw an exception - if (CollectionUtils.isEmpty(planFacilityRepository.search(PlanFacilitySearchCriteria.builder() + List planFacilityListFromSearch = planFacilityRepository.search(PlanFacilitySearchCriteria.builder() .ids(Collections.singleton(planFacilityRequest.getPlanFacility().getId())) - .build()))) { + .build()); + + // If plan facility id provided is invalid, throw an exception + if (CollectionUtils.isEmpty(planFacilityListFromSearch)) { throw new CustomException(INVALID_PLAN_FACILITY_ID_CODE, INVALID_PLAN_FACILITY_ID_MESSAGE); } + + enrichInitialServiceBoundaries(planFacilityListFromSearch, planFacilityRequest); + } + + private void enrichInitialServiceBoundaries(List planFacilityListFromSearch, PlanFacilityRequest planFacilityRequest) { + + List initiallySetServiceBoundaries = planFacilityListFromSearch.get(0).getServiceBoundaries(); + planFacilityRequest.getPlanFacility().setInitiallySetServiceBoundaries(initiallySetServiceBoundaries); } /** diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 54aa0fcbcc2..7237d7c8bd6 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -1,5 +1,6 @@ package digit.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -52,6 +53,9 @@ public class PlanFacility { @Valid private List serviceBoundaries; + @JsonIgnore + private List initiallySetServiceBoundaries; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java index 0270be18d5e..3683177792e 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java @@ -1,7 +1,6 @@ package digit.web.models; import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; @@ -11,7 +10,6 @@ import org.egov.common.contract.models.AuditDetails; import org.springframework.validation.annotation.Validated; -import java.util.ArrayList; import java.util.List; /** @@ -52,6 +50,9 @@ public class PlanFacilityDTO { @Size(min = 1) private String serviceBoundaries = null; // Store as JSON string + @JsonProperty("initiallySetServiceBoundaries") + private List initiallySetServiceBoundaries; + @JsonProperty("additionalDetails") private Object additionalDetails = null; From 10b063b7f0665cf48adec7730d11798c8307dab4 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Sat, 26 Oct 2024 17:54:49 +0530 Subject: [PATCH 245/351] modified census facility consumer --- .../kafka/FacilityCatchmentConsumer.java | 33 +++++++++++++++---- .../src/main/java/digit/util/CommonUtil.java | 25 ++++++++++---- .../web/models/plan/PlanFacilityDTO.java | 5 +++ 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index b4810ec4a75..be4be219301 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -15,8 +15,10 @@ import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import static digit.config.ServiceConstants.FACILITY_ID_FIELD; @@ -42,17 +44,34 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE PlanFacilityRequestDTO planFacilityRequestDTO = objectMapper.convertValue(consumerRecord, PlanFacilityRequestDTO.class); PlanFacilityDTO planFacilityDTO = planFacilityRequestDTO.getPlanFacilityDTO(); - CensusResponse censusResponse = service.search(commonUtil.getCensusSearchRequest(planFacilityDTO.getTenantId(), planFacilityDTO.getPlanConfigurationId(), planFacilityDTO.getServiceBoundaries())); + CensusResponse censusResponse = service.search(commonUtil.getCensusSearchRequest(planFacilityDTO.getTenantId(), planFacilityDTO.getPlanConfigurationId(), planFacilityDTO.getServiceBoundaries(), planFacilityDTO.getInitiallySetServiceBoundaries(), planFacilityRequestDTO.getRequestInfo())); List censusFromSearch = censusResponse.getCensus(); String facilityId = planFacilityRequestDTO.getPlanFacilityDTO().getFacilityId(); - censusFromSearch.forEach(census -> { - census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); - census.setFacilityAssigned(Boolean.TRUE); - census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); - service.update(CensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(census).build()); - }); + Set boundariesWithFacility = new HashSet<>(List.of(planFacilityDTO.getServiceBoundaries().split(","))); + Set boundariesWithNoFacility = new HashSet<>(planFacilityDTO.getInitiallySetServiceBoundaries()); + + // Unassigning facilities to the boundaries which were initially assigned that facility + censusFromSearch.stream() + .filter(census -> boundariesWithNoFacility.contains(census.getBoundaryCode())) + .forEach(census -> { + census.setAdditionalDetails(commonUtil.removeFieldFromAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD)); + census.setFacilityAssigned(Boolean.FALSE); + census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); + service.update(CensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(census).build()); + }); + + // Assigning facilities to the boundaries in the update request. + censusFromSearch.stream() + .filter(census -> boundariesWithFacility.contains(census.getBoundaryCode())) + .forEach(census -> { + census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); + census.setFacilityAssigned(Boolean.TRUE); + census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); + service.update(CensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(census).build()); + }); + } catch (Exception exception) { log.error("Error in census consumer", exception); } diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index 6dff6e16e2f..e4fd38216dc 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -12,8 +12,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import java.util.List; -import java.util.Map; +import java.util.*; import static digit.config.ServiceConstants.*; @@ -55,6 +54,19 @@ public Map updateFieldInAdditionalDetails(Object additionalDetai } } + /** + * Removes the field to be removed from the additional details object. + * @param additionalDetails + * @param fieldToBeRemoved + * @return + */ + public Map removeFieldFromAdditionalDetails(Object additionalDetails, String fieldToBeRemoved) { + Map additionalDetailsMap = objectMapper.convertValue(additionalDetails, Map.class); + additionalDetailsMap.remove(fieldToBeRemoved); + + return additionalDetailsMap; + } + /** * Creates the census search request for the provided details. * @param tenantId @@ -62,18 +74,19 @@ public Map updateFieldInAdditionalDetails(Object additionalDetai * @param serviceBoundary * @return */ - public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary) { - List areaCodesForSearch = List.of(serviceBoundary.split(",")); + public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary, List initiallySetServiceBoundaries, RequestInfo requestInfo) { + Set areaCodesForSearch = new HashSet<>(Arrays.asList(serviceBoundary.split(","))); + areaCodesForSearch.addAll(initiallySetServiceBoundaries); CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() .tenantId(tenantId) .source(planConfigId) - .areaCodes(areaCodesForSearch) + .areaCodes(areaCodesForSearch.stream().toList()) .offset(0) .limit(areaCodesForSearch.size()) .build(); - return CensusSearchRequest.builder().censusSearchCriteria(searchCriteria).build(); + return CensusSearchRequest.builder().requestInfo(requestInfo).censusSearchCriteria(searchCriteria).build(); } /** diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java index 1b931ce0b03..832299c296b 100644 --- a/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java @@ -10,6 +10,8 @@ import org.egov.common.contract.models.AuditDetails; import org.springframework.validation.annotation.Validated; +import java.util.List; + /** * Plan Facility DTO */ @@ -48,6 +50,9 @@ public class PlanFacilityDTO { @Size(min = 1) private String serviceBoundaries = null; // Store as JSON string + @JsonProperty("initiallySetServiceBoundaries") + private List initiallySetServiceBoundaries; + @JsonProperty("additionalDetails") private Object additionalDetails = null; From 9da23d406e5ca41ebcca3e2ce3a2e7c4a4b0f13d Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 28 Oct 2024 13:15:47 +0530 Subject: [PATCH 246/351] Adding changes for updating plan's status count --- .../main/java/digit/config/Configuration.java | 3 + .../java/digit/config/ServiceConstants.java | 5 ++ .../java/digit/repository/PlanRepository.java | 7 +- .../repository/impl/PlanRepositoryImpl.java | 25 +++++-- .../rowmapper/PlanStatusCountRowMapper.java | 5 +- .../main/java/digit/service/PlanService.java | 2 +- .../service/workflow/WorkflowService.java | 74 ++++++++++++++++++- 7 files changed, 108 insertions(+), 13 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 48a67dae07c..cb7fce09dbe 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -101,6 +101,9 @@ public class Configuration { @Value("${egov.workflow.transition.path}") private String wfTransitionPath; + @Value("${egov.business.service.search.endpoint}") + private String businessServiceSearchEndpoint; + @Value("${workflow.initiate.action}") private List wfInitiateActions; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 17a629f8274..d2bd3ac5c9b 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -209,6 +209,9 @@ public class ServiceConstants { public static final String OPERATIONS_NOT_FOUND_CODE = "OPERATIONS_NOT_FOUND"; public static final String OPERATIONS_NOT_FOUND_MESSAGE = "Operations are not present in Plan Configuration."; + public static final String NO_BUSINESS_SERVICE_DATA_FOUND_CODE = "NO_BUSINESS_SERVICE_DATA_FOUND"; + public static final String NO_BUSINESS_SERVICE_DATA_FOUND_MESSAGE = "Invalid or incorrect businessService. No business service data found."; + //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; public static final String MDMS_ADMIN_CONSOLE_MODULE_NAME = "HCM-ADMIN-CONSOLE"; @@ -306,6 +309,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_FACILITY = "Exception occurred while fetching facility details from facility service "; + public static final String ERROR_WHILE_FETCHING_BUSINESS_SERVICE_DETAILS = "Exception occurred while fetching business service details: "; + public static final String INVALID_PLAN_FACILITY_ID_CODE = "INVALID_PLAN_FACILITY_ID"; public static final String INVALID_PLAN_FACILITY_ID_MESSAGE = "Plan facility id provided is invalid"; diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java index 28c4d42aeb7..1b8c334ed7c 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java @@ -1,9 +1,6 @@ package digit.repository; -import digit.web.models.BulkPlanRequest; -import digit.web.models.Plan; -import digit.web.models.PlanRequest; -import digit.web.models.PlanSearchCriteria; +import digit.web.models.*; import java.util.List; import java.util.Map; @@ -17,7 +14,7 @@ public interface PlanRepository { public Integer count(PlanSearchCriteria planSearchCriteria); - public Map statusCount(PlanSearchCriteria planSearchCriteria); + public Map statusCount(PlanSearchRequest planSearchRequest); public void bulkUpdate(BulkPlanRequest body); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 0a577f3a13f..5919bf71976 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -6,17 +6,21 @@ import digit.repository.querybuilder.PlanQueryBuilder; import digit.repository.rowmapper.PlanRowMapper; import digit.repository.rowmapper.PlanStatusCountRowMapper; +import digit.service.workflow.WorkflowService; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.stereotype.Repository; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; +import static digit.config.ServiceConstants.PLAN_ESTIMATION_BUSINESS_SERVICE; + @Slf4j @Repository public class PlanRepositoryImpl implements PlanRepository { @@ -33,14 +37,17 @@ public class PlanRepositoryImpl implements PlanRepository { private PlanStatusCountRowMapper statusCountRowMapper; + private WorkflowService workflowService; + public PlanRepositoryImpl(Producer producer, PlanQueryBuilder planQueryBuilder, PlanRowMapper planRowMapper, - JdbcTemplate jdbcTemplate, Configuration config, PlanStatusCountRowMapper statusCountRowMapper) { + JdbcTemplate jdbcTemplate, Configuration config, PlanStatusCountRowMapper statusCountRowMapper, WorkflowService workflowService) { this.producer = producer; this.planQueryBuilder = planQueryBuilder; this.planRowMapper = planRowMapper; this.jdbcTemplate = jdbcTemplate; this.config = config; this.statusCountRowMapper = statusCountRowMapper; + this.workflowService = workflowService; } /** @@ -76,15 +83,23 @@ public List search(PlanSearchCriteria planSearchCriteria) { /** * Counts the plan based on their current status for the provided search criteria. * - * @param planSearchCriteria The search criteria for filtering plans. + * @param planSearchRequest The search criteria for filtering plans. * @return The status count of plans for the given search criteria. */ @Override - public Map statusCount(PlanSearchCriteria planSearchCriteria) { + public Map statusCount(PlanSearchRequest planSearchRequest) { List preparedStmtList = new ArrayList<>(); - String query = planQueryBuilder.getPlanStatusCountQuery(planSearchCriteria, preparedStmtList); + List statusList = workflowService.getStatusFromBusinessService(planSearchRequest.getRequestInfo(), PLAN_ESTIMATION_BUSINESS_SERVICE, planSearchRequest.getPlanSearchCriteria().getTenantId()); + + String query = planQueryBuilder.getPlanStatusCountQuery(planSearchRequest.getPlanSearchCriteria(), preparedStmtList); + Map statusCountMap = jdbcTemplate.query(query, statusCountRowMapper, preparedStmtList.toArray()); + + statusList.forEach(status -> { + if(ObjectUtils.isEmpty(statusCountMap.get(status))) + statusCountMap.put(status, 0); + }); - return jdbcTemplate.query(query, statusCountRowMapper, preparedStmtList.toArray()); + return statusCountMap; } /** diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java index 4e99bffbe7b..11e14d37763 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java @@ -3,6 +3,7 @@ import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; import java.sql.ResultSet; import java.sql.SQLException; @@ -20,7 +21,9 @@ public Map extractData(ResultSet rs) throws SQLException, DataA while (rs.next()) { String status = rs.getString("status"); Integer statusCount = rs.getInt("plan_status_count"); - statusCountMap.put(status, statusCount); + + if(!ObjectUtils.isEmpty(status)) + statusCountMap.put(status, statusCount); } return statusCountMap; diff --git a/health-services/plan-service/src/main/java/digit/service/PlanService.java b/health-services/plan-service/src/main/java/digit/service/PlanService.java index 61b497c881d..4acaf58218b 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanService.java @@ -68,7 +68,7 @@ public PlanResponse searchPlan(PlanSearchRequest body) { Integer count = planRepository.count(body.getPlanSearchCriteria()); // Get the status count of plans for given search criteria - Map statusCountMap = planRepository.statusCount(body.getPlanSearchCriteria()); + Map statusCountMap = planRepository.statusCount(body); // Build and return response back to controller return PlanResponse.builder() diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 24af898f15e..7b8ffd3ad45 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -16,11 +16,13 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import org.springframework.web.client.RestTemplate; import java.util.*; import java.util.stream.Collectors; import static digit.config.ServiceConstants.*; +import static digit.config.ServiceConstants.NO_BUSINESS_SERVICE_DATA_FOUND_MESSAGE; @Service @Slf4j @@ -36,12 +38,15 @@ public class WorkflowService { private PlanEmployeeService planEmployeeService; - public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil, PlanEmployeeService planEmployeeService) { + private RestTemplate restTemplate; + + public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil, PlanEmployeeService planEmployeeService, RestTemplate restTemplate) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.mapper = mapper; this.commonUtil = commonUtil; this.planEmployeeService = planEmployeeService; + this.restTemplate = restTemplate; } /** @@ -343,4 +348,71 @@ private ProcessInstanceRequest createWorkflowRequest(BulkPlanRequest bulkPlanReq .processInstances(processInstanceList) .build(); } + + /** + * Creates a list of all the workflow states for the provided business service. + * @param requestInfo + * @param businessService + * @param tenantId + * @return + */ + public List getStatusFromBusinessService(RequestInfo requestInfo, String businessService, String tenantId) { + BusinessService businessServices = fetchBusinessService(requestInfo, businessService, tenantId); + + return businessServices.getStates().stream() + .map(State::getState) + .filter(state -> !ObjectUtils.isEmpty(state)) + .toList(); + } + + /** + * This method fetches business service details for the given tenant id and business service. + * + * @param requestInfo the request info from request. + * @param businessService businessService whose details are to be searched. + * @param tenantId tenantId from request. + * @return returns the business service response for the given tenant id and business service. + */ + public BusinessService fetchBusinessService(RequestInfo requestInfo, String businessService, String tenantId) { + + // Get business service uri + Map uriParameters = new HashMap<>(); + String uri = getBusinessServiceUri(businessService, tenantId, uriParameters); + + // Create request body + RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build(); + BusinessServiceResponse businessServiceResponse = new BusinessServiceResponse(); + + try { + businessServiceResponse = restTemplate.postForObject(uri, requestInfoWrapper, BusinessServiceResponse.class, uriParameters); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_BUSINESS_SERVICE_DETAILS, e); + } + + if (CollectionUtils.isEmpty(businessServiceResponse.getBusinessServices())) { + throw new CustomException(NO_BUSINESS_SERVICE_DATA_FOUND_CODE, NO_BUSINESS_SERVICE_DATA_FOUND_MESSAGE); + } + + return businessServiceResponse.getBusinessServices().get(0); + } + + /** + * This method creates business service uri with query parameters + * + * @param businessService businessService whose details are to be searched. + * @param tenantId tenant id from the request. + * @param uriParameters map that stores values corresponding to the placeholder in uri + * @return + */ + private String getBusinessServiceUri(String businessService, String tenantId, Map uriParameters) { + + StringBuilder uri = new StringBuilder(); + uri.append(config.getWfHost()).append(config.getBusinessServiceSearchEndpoint()).append("?tenantId={tenantId}&businessServices={businessService}"); + + uriParameters.put("tenantId", tenantId); + uriParameters.put("businessService", businessService); + + return uri.toString(); + } + } \ No newline at end of file From ff9b73642b81ed1c252f11e8379f0d1dcca7f24d Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 28 Oct 2024 13:16:39 +0530 Subject: [PATCH 247/351] Adding changes for updating plan's status count --- .../plan-service/src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 5df37397f8f..b7e96a1bd4b 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -79,6 +79,7 @@ egov.boundary.relationship.search.endpoint=/boundary-service/boundary-relationsh # Workflow egov.workflow.host=https://unified-dev.digit.org egov.workflow.transition.path=/egov-workflow-v2/egov-wf/process/_transition +egov.business.service.search.endpoint=/egov-workflow-v2/egov-wf/businessservice/_search workflow.initiate.action=INITIATE workflow.intermediate.action=EDIT_AND_SEND_FOR_APPROVAL,APPROVE workflow.send.back.actions=SEND_BACK_FOR_CORRECTION From f6c6fe165871ffdefc59c04fc155668ad7cc0de4 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 28 Oct 2024 13:54:52 +0530 Subject: [PATCH 248/351] modifying search criteria for status count query --- .../src/main/java/digit/config/ServiceConstants.java | 6 ++++++ .../digit/repository/querybuilder/PlanQueryBuilder.java | 3 --- .../main/java/digit/service/workflow/WorkflowService.java | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index d2bd3ac5c9b..45193651abb 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -302,6 +302,12 @@ public class ServiceConstants { public static final String SETUP_COMPLETED_STATUS = "SETUP_COMPLETED"; + public static final String URI_TENANT_ID_PARAM = "tenantId"; + + public static final String URI_BUSINESS_SERVICE_PARAM = "businessService"; + + public static final String URI_BUSINESS_SERVICE_QUERY_TEMPLATE = "?tenantId={tenantId}&businessServices={businessService}"; + //Query constants public static final String PERCENTAGE_WILDCARD = "%"; diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index af4a285b06a..353a95bbdc1 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -89,11 +89,8 @@ public String getPlanCountQuery(PlanSearchCriteria criteria, List prepar public String getPlanStatusCountQuery(PlanSearchCriteria searchCriteria, List preparedStmtList) { PlanSearchCriteria planSearchCriteria = PlanSearchCriteria.builder() .tenantId(searchCriteria.getTenantId()) - .ids(searchCriteria.getIds()) .planConfigurationId(searchCriteria.getPlanConfigurationId()) - .locality(searchCriteria.getLocality()) .campaignId(searchCriteria.getCampaignId()) - .status(searchCriteria.getStatus()) .jurisdiction(searchCriteria.getJurisdiction()) .build(); return buildPlanSearchQuery(planSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 7b8ffd3ad45..5a46a0b7e53 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -407,10 +407,10 @@ public BusinessService fetchBusinessService(RequestInfo requestInfo, String busi private String getBusinessServiceUri(String businessService, String tenantId, Map uriParameters) { StringBuilder uri = new StringBuilder(); - uri.append(config.getWfHost()).append(config.getBusinessServiceSearchEndpoint()).append("?tenantId={tenantId}&businessServices={businessService}"); + uri.append(config.getWfHost()).append(config.getBusinessServiceSearchEndpoint()).append(URI_BUSINESS_SERVICE_QUERY_TEMPLATE); - uriParameters.put("tenantId", tenantId); - uriParameters.put("businessService", businessService); + uriParameters.put(URI_TENANT_ID_PARAM, tenantId); + uriParameters.put(URI_BUSINESS_SERVICE_PARAM, businessService); return uri.toString(); } From 9f3b5bd8ec91b7f701af48b2c7e5c7a8a1c67423 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 28 Oct 2024 15:21:03 +0530 Subject: [PATCH 249/351] Validating one active file on setup complete duting plan config validation --- .../validator/PlanConfigurationValidator.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 0fd2b9c6851..7cea8dd0461 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -271,12 +271,14 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque } // Ensure at least one active file for each required template identifier - requiredTemplateIdentifierSetFromMDMS.forEach(requiredTemplate -> { - if (!activeRequiredTemplates.contains(requiredTemplate)) { - log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); - throw new CustomException(REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE, REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE); - } - }); + if(isSetupCompleted(planConfiguration)){ + requiredTemplateIdentifierSetFromMDMS.forEach(requiredTemplate -> { + if (!activeRequiredTemplates.contains(requiredTemplate)) { + log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); + throw new CustomException(REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE, REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE); + } + }); + } } } From 8bfc96251c41d66efe011624d8b02fcbbdb2d3ba Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 17 Oct 2024 17:17:07 +0530 Subject: [PATCH 250/351] HCMPRE-599 updating Plan service models --- .../src/main/java/org/egov/processor/web/models/Resource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java index 5fea454bd5d..129f4dccad0 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java @@ -3,13 +3,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import java.math.BigDecimal; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; + /** * Resource */ From ac767571c76d953bbe947ab976e8329d1b548dc7 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 17 Oct 2024 17:41:08 +0530 Subject: [PATCH 251/351] HCMPRE-599 updating Plan service models --- .../egov/processor/web/models/Activity.java | 3 +- .../egov/processor/web/models/Assumption.java | 15 ++++-- .../org/egov/processor/web/models/File.java | 16 +++---- .../processor/web/models/MetricDetail.java | 47 +++++++++++++++++-- .../egov/processor/web/models/Operation.java | 25 +++++++--- .../org/egov/processor/web/models/Plan.java | 13 ++--- .../org/egov/processor/web/models/Source.java | 5 ++ 7 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Source.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java index fa9e1193e90..fd56d5701b8 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java @@ -4,13 +4,14 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; +import java.util.List; + /** * Activity */ diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java index b8ed98d54e8..0126b2be7f7 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java @@ -33,11 +33,20 @@ public class Assumption { @JsonProperty("value") @NotNull @Valid - @DecimalMin(value = "0.01", inclusive = true, message = "Assumption value must be greater than 0") - @DecimalMax(value = "999.99", inclusive = true, message = "Assumption value must be less than 1000") - @Digits(integer = 3, fraction = 2, message = "Assumption value must have up to 3 digits and up to 2 decimal points") + @DecimalMin(value = "0.01", inclusive = true, message = "The Assumption value must be greater than 0") + @DecimalMax(value = "9999999999.99", inclusive = true, message = "The assumption value must not exceed 10 digits in total, including up to 2 decimal places.") + @Digits(integer = 10, fraction = 2, message = "The Assumption value must have up to 10 digits and up to 2 decimal points") private BigDecimal value = null; + @JsonProperty("source") + @NotNull(message = "Source cannot be null. Please specify a valid source.") + private Source source = null; + + @JsonProperty("category") + @NotNull + @Size(min = 2, max = 64) + private String category = null; + @JsonProperty("active") @NotNull private Boolean active = true; diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java index fe6b6c1abab..84638ec0af8 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java @@ -13,6 +13,8 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; +import java.util.Arrays; + /** * File */ @@ -30,7 +32,7 @@ public class File { @JsonProperty("filestoreId") @NotNull @Size(min = 1, max = 128) - @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Filestore Id must contain alphanumeric characters and may include some special characters") + @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Filestore Id must not contain only special characters") private String filestoreId = null; @JsonProperty("inputFileType") @@ -40,7 +42,7 @@ public class File { @JsonProperty("templateIdentifier") @NotNull @Size(min = 2, max = 128) - @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Name must contain alphanumeric characters and may include some special characters") + @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Name must not contain only special characters") private String templateIdentifier = null; @JsonProperty("active") @@ -71,12 +73,10 @@ public String toString() { @JsonCreator public static InputFileTypeEnum fromValue(String text) { - for (InputFileTypeEnum b : InputFileTypeEnum.values()) { - if (String.valueOf(b.value).equals(text)) { - return b; - } - } - return null; + return Arrays.stream(InputFileTypeEnum.values()) + .filter(b -> String.valueOf(b.value).equals(text)) + .findFirst() + .orElse(null); // Return null if no matching enum value is found } } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java index 32a5c0b4ccc..9aa1c33ebf4 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java @@ -1,15 +1,18 @@ package org.egov.processor.web.models; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.math.BigDecimal; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.constraints.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; +import java.util.Arrays; + @Validated @Data @AllArgsConstructor @@ -19,16 +22,50 @@ public class MetricDetail { @JsonProperty("value") @NotNull + @DecimalMin(value = "0.01", inclusive = true, message = "Metric value must be greater than 0") + @DecimalMax(value = "999.99", inclusive = true, message = "Metric value must be less than 1000") + @Digits(integer = 3, fraction = 2, message = "Metric value must have up to 3 digits and up to 2 decimal points") private BigDecimal metricValue = null; @JsonProperty("comparator") @NotNull - @Size(min = 1, max = 64) - private String metricComparator = null; + private MetricComparatorEnum metricComparator = null; @JsonProperty("unit") @NotNull @Size(min = 1, max = 128) private String metricUnit = null; + public enum MetricComparatorEnum { + GREATER_THAN(">"), + + LESS_THAN("<"), + + GREATER_THAN_OR_EQUAL_TO(">="), + + LESS_THAN_OR_EQUAL_TO("<="), + + EQUAL("="); + + private final String symbol; + + MetricComparatorEnum(String symbol) { + this.symbol = symbol; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(symbol); + } + + @JsonCreator + public static MetricComparatorEnum fromValue(String text) { + return Arrays.stream(MetricComparatorEnum.values()) + .filter(b -> String.valueOf(b.symbol).equals(text)) + .findFirst() + .orElse(null); // Return null if no matching enum value is found + } + } + } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java index 25b5b189fa0..43f34b29139 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java @@ -13,6 +13,8 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; +import java.util.Arrays; + /** * Operation */ @@ -46,6 +48,19 @@ public class Operation { @Size(min = 1, max = 64) private String output = null; + @JsonProperty("showOnEstimationDashboard") + @NotNull + private Boolean showOnEstimationDashboard = true; + + @JsonProperty("source") + @NotNull(message = "Source cannot be null. Please specify a valid source.") + private Source source = null; + + @JsonProperty("category") + @NotNull + @Size(min = 2, max = 64) + private String category = null; + @JsonProperty("active") @NotNull private Boolean active = true; @@ -80,12 +95,10 @@ public String toString() { @JsonCreator public static OperatorEnum fromValue(String text) { - for (OperatorEnum b : OperatorEnum.values()) { - if (String.valueOf(b.value).equals(text)) { - return b; - } - } - return null; + return Arrays.stream(OperatorEnum.values()) + .filter(b -> String.valueOf(b.value).equals(text)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Unexpected value '" + text + "'")); } } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java index a9d4f3139b5..59e7660492d 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java @@ -4,7 +4,6 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,6 +11,8 @@ import org.egov.common.contract.models.AuditDetails; import org.springframework.validation.annotation.Validated; +import java.util.List; + /** * Plan */ @@ -34,9 +35,9 @@ public class Plan { @Size(min = 1, max = 64) private String locality = null; - @JsonProperty("executionPlanId") + @JsonProperty("campaignId") @Size(max = 64) - private String executionPlanId = null; + private String campaignId = null; @JsonProperty("planConfigurationId") @Size(max = 64) @@ -47,15 +48,15 @@ public class Plan { @JsonProperty("activities") @Valid - private List activities = null; + private List activities; @JsonProperty("resources") @Valid - private List resources = null; + private List resources; @JsonProperty("targets") @Valid - private List targets = null; + private List targets; @JsonProperty("auditDetails") private AuditDetails auditDetails = null; diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Source.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Source.java new file mode 100644 index 00000000000..3d726b35f9f --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Source.java @@ -0,0 +1,5 @@ +package org.egov.processor.web.models; + +public enum Source { + MDMS, CUSTOM, VEHICLE; +} From 1ba964926a22c7ee78cc1e465826a182619d4a12 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Sat, 19 Oct 2024 11:47:55 +0530 Subject: [PATCH 252/351] HCMPRE-599 changes --- .../egov/processor/config/Configuration.java | 6 +++ .../egov/processor/kafka/PlanConsumer.java | 2 - .../egov/processor/service/ExcelParser.java | 36 +++++++++--------- .../util/CampaignIntegrationUtil.java | 4 +- .../org/egov/processor/util/ParsingUtil.java | 2 + .../org/egov/processor/util/PlanUtil.java | 2 +- .../egov/processor/web/models/Activity.java | 13 ++++--- .../egov/processor/web/models/Assumption.java | 16 +++++--- .../egov/processor/web/models/Condition.java | 6 +-- .../org/egov/processor/web/models/File.java | 11 +++--- .../processor/web/models/MetricDetail.java | 6 ++- .../egov/processor/web/models/Operation.java | 10 ++--- .../org/egov/processor/web/models/Plan.java | 33 +++++++++++++--- .../web/models/PlanConfiguration.java | 38 +++++++------------ .../egov/processor/web/models/Resource.java | 9 ++--- .../processor/web/models/ResourceMapping.java | 7 ++-- .../org/egov/processor/web/models/Target.java | 6 +-- 17 files changed, 116 insertions(+), 91 deletions(-) diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java index 12ce0667abd..1b892e12fc5 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java @@ -77,4 +77,10 @@ public class Configuration { @Value("${egov.locale.search.endpoint}") private String egovLocaleSearchEndpoint; + //trigger statuses + @Value("${plan.config.trigger.plan.estimates.status}") + private String planConfigTriggerPlanEstimatesStatus; + + @Value("${plan.config.trigger.census.records.status}") + private String planConfigTriggerCensusRecordsStatus; } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java index 2aa31907413..f152d7503d4 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java @@ -31,10 +31,8 @@ public PlanConsumer(ObjectMapper objectMapper, ResourceEstimationService resourc public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { try { PlanConfigurationRequest planConfigurationRequest = objectMapper.convertValue(consumerRecord, PlanConfigurationRequest.class); - if (planConfigurationRequest.getPlanConfiguration().getStatus().equals(PlanConfiguration.StatusEnum.GENERATED)) { resourceEstimationService.estimateResources(planConfigurationRequest); log.info("Successfully estimated resources for plan."); - } } catch (Exception exception) { log.error("Error processing record from topic "+topic+" with exception :"+exception); throw new CustomException(Integer.toString(HttpStatus.INTERNAL_SERVER_ERROR.value()), diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java index ee005cd81c8..c0af67adddb 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java @@ -28,7 +28,6 @@ import org.egov.processor.web.models.LocaleResponse; import org.egov.processor.web.models.Operation; import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.PlanConfiguration.StatusEnum; import org.egov.processor.web.models.PlanConfigurationRequest; import org.egov.processor.web.models.ResourceMapping; import org.egov.processor.web.models.boundary.BoundarySearchResponse; @@ -132,7 +131,7 @@ private String processExcelFile(PlanConfigurationRequest planConfigurationReques List campaignResourcesList = new ArrayList<>(); DataFormatter dataFormatter = new DataFormatter(); processSheets(planConfigurationRequest, fileStoreId, campaignResponse, planConfig, workbook, - campaignBoundaryList, campaignResourcesList, dataFormatter); + campaignBoundaryList, dataFormatter); String uploadedFileStoreId = uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse, planConfig, workbook, campaignBoundaryList, campaignResourcesList); return uploadedFileStoreId; @@ -197,12 +196,12 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi * @param planConfig The configuration details specific to the plan. * @param excelWorkbook The workbook containing sheets to be processed. * @param campaignBoundaryList List of boundary objects related to the campaign. - * @param campaignResourcesList List of campaign resources to be integrated. * @param dataFormatter The data formatter for formatting cell values. */ + //TODO: processsheetforestimate and processsheetforcensus private void processSheets(PlanConfigurationRequest planConfigurationRequest, String fileStoreId, Object campaignResponse, PlanConfiguration planConfig, Workbook excelWorkbook, - List campaignBoundaryList, List campaignResourcesList, + List campaignBoundaryList, DataFormatter dataFormatter) { LocaleResponse localeResponse = localeUtil.searchLocale(planConfigurationRequest); CampaignResponse campaign = parseCampaignResponse(campaignResponse); @@ -211,11 +210,10 @@ private void processSheets(PlanConfigurationRequest planConfigurationRequest, St List boundaryCodeList = getBoundaryCodeList(planConfigurationRequest, campaign, planConfig); excelWorkbook.forEach(excelWorkbookSheet -> { - if (isSheetAlloedToProcess(planConfigurationRequest, excelWorkbookSheet.getSheetName(),localeResponse)) { - Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(excelWorkbookSheet); - List columnNamesList = mapOfColumnNameAndIndex.keySet().stream().toList(); - parsingUtil.validateColumnNames(columnNamesList, planConfig, fileStoreId); - processRows(planConfigurationRequest, excelWorkbookSheet, dataFormatter, fileStoreId, + if (isSheetAllowedToProcess(planConfigurationRequest, excelWorkbookSheet.getSheetName(),localeResponse)) { + //TODO: remove validateColumnNames() + if(planConfig.getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) + processRows(planConfigurationRequest, excelWorkbookSheet, dataFormatter, fileStoreId, campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); } }); @@ -241,8 +239,7 @@ private void processSheets(PlanConfigurationRequest planConfigurationRequest, St */ private void processRows(PlanConfigurationRequest planConfigurationRequest, Sheet sheet, DataFormatter dataFormatter, String fileStoreId, List campaignBoundaryList, Map attributeNameVsDataTypeMap, List boundaryCodeList) { PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); - Row firstRow = null; - performRowLevelCalculations(planConfigurationRequest, sheet, dataFormatter, fileStoreId, campaignBoundaryList, planConfig, attributeNameVsDataTypeMap, boundaryCodeList, firstRow); + performRowLevelCalculations(planConfigurationRequest, sheet, dataFormatter, fileStoreId, campaignBoundaryList, planConfig, attributeNameVsDataTypeMap, boundaryCodeList); } /** @@ -272,6 +269,8 @@ private List getBoundaryCodeList(PlanConfigurationRequest planConfigurat * @param planConfig The configuration details specific to the plan. * @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 = mdmsUtil.fetchMdmsData(planConfigurationRequest.getRequestInfo(), @@ -309,12 +308,11 @@ private CampaignResponse parseCampaignResponse(Object campaignResponse) { * @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. - * @param firstRow The first row of the sheet. */ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurationRequest, Sheet sheet, DataFormatter dataFormatter, String fileStoreId, List campaignBoundaryList, - PlanConfiguration planConfig, Map attributeNameVsDataTypeMap, List boundaryCodeList, - Row firstRow) { + PlanConfiguration planConfig, Map attributeNameVsDataTypeMap, List boundaryCodeList) { + Row firstRow = null; for (Row row : sheet) { if(isRowEmpty(row)) continue; @@ -342,7 +340,7 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat if (config.isIntegrateWithAdminConsole()) campaignIntegrationUtil.updateCampaignBoundary(planConfig, feature, assumptionValueMap, mappedValues, mapOfColumnNameAndIndex, campaignBoundaryList, resultMap); - planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); + planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); // TODO: remove after testing printRow(sheet, row); } @@ -407,7 +405,7 @@ private void performCalculationsOnOperations(Sheet sheet, PlanConfiguration plan * * @param convertedFile The converted XLS file to upload. * @param tenantId The tenant ID for the file upload. - * @return The file store ID of the uploaded file, or null if an error occurred. + * @return The file store ID of the uploaded file, or null if an error occurred. */ private String uploadConvertedFile(File convertedFile, String tenantId) { if (convertedFile != null) { @@ -543,13 +541,13 @@ public void validateRows(Integer indexOfBoundaryCode, Row row, Row columnHeaderR boundaryCodeList); } catch (JsonProcessingException e) { log.info(ServiceConstants.INPUT_IS_NOT_VALID + (row.getRowNum() + 1) + " at sheet - " + sheet); - planConfigurationRequest.getPlanConfiguration().setStatus(StatusEnum.INVALID_DATA); + planConfigurationRequest.getPlanConfiguration().setStatus("INVALID_DATA"); planUtil.update(planConfigurationRequest); throw new CustomException(Integer.toString(HttpStatus.INTERNAL_SERVER_ERROR.value()), ServiceConstants.INPUT_IS_NOT_VALID + row.getRowNum() + " at sheet - " + sheet); } catch (CustomException customException) { log.info(customException.toString()+ "at sheet - " + sheet.getSheetName()); - planConfigurationRequest.getPlanConfiguration().setStatus(StatusEnum.INVALID_DATA); + planConfigurationRequest.getPlanConfiguration().setStatus("INVALID_DATA"); planUtil.update(planConfigurationRequest); throw new CustomException(Integer.toString(HttpStatus.INTERNAL_SERVER_ERROR.value()), customException.getMessage()+ "at sheet - " + sheet.getSheetName()); @@ -718,7 +716,7 @@ public List getAllBoundaryPresentforHierarchyType(List * @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 isSheetAlloedToProcess(PlanConfigurationRequest planConfigurationRequest, String sheetName,LocaleResponse localeResponse) { + private boolean isSheetAllowedToProcess(PlanConfigurationRequest planConfigurationRequest, String sheetName,LocaleResponse localeResponse) { Map mdmsDataConstants = mdmsUtil.fetchMdmsDataForCommonConstants( planConfigurationRequest.getRequestInfo(), planConfigurationRequest.getPlanConfiguration().getTenantId()); diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java index d14b3512aef..5d17a1e0c5f 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java @@ -83,7 +83,7 @@ public void updateCampaignDetails(PlanConfigurationRequest planConfigurationRequ log.info("Campaign Integration successful."); } catch (Exception e) { log.error(ServiceConstants.ERROR_WHILE_SEARCHING_CAMPAIGN - + planConfigurationRequest.getPlanConfiguration().getExecutionPlanId(), e); + + planConfigurationRequest.getPlanConfiguration().getCampaignId(), e); throw new CustomException("Failed to update campaign details in CampaignIntegration class within method updateCampaignDetails.", e.toString()); } } @@ -279,7 +279,7 @@ public CampaignSearchRequest buildCampaignRequestForSearch(PlanConfigurationRequ PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); List id = new ArrayList(); - id.add(planConfig.getExecutionPlanId()); + id.add(planConfig.getCampaignId()); return CampaignSearchRequest.builder().requestInfo(planConfigurationRequest.getRequestInfo()) .campaignDetails(CampaignDetails.builder().ids(id).tenantId(planConfig.getTenantId()).build()).build(); diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java index b1902b49afb..d8f5672241f 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java @@ -63,6 +63,8 @@ public List fetchAttributeNamesFromJson(JsonNode jsonNode) } return columnNames; } + + public void validateColumnNames(List columnNamesList, PlanConfiguration planConfig, String fileStoreId ) { Set mappedFromSet = planConfig.getResourceMapping().stream() .filter(mapping -> Objects.equals(mapping.getFilestoreId(), fileStoreId)) diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java index d44aaa2a59f..49fbe362cd5 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java @@ -80,7 +80,7 @@ private PlanRequest buildPlanRequest(PlanConfigurationRequest planConfigurationR .requestInfo(planConfigurationRequest.getRequestInfo()) .plan(Plan.builder() .tenantId(planConfig.getTenantId()) - .executionPlanId(planConfig.getExecutionPlanId()) + .campaignId(planConfig.getCampaignId()) .locality(getBoundaryCodeValue(ServiceConstants.BOUNDARY_CODE, feature, mappedValues)) .resources(resultMap.entrySet().stream().map(result -> { diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java index fd56d5701b8..6c093ba63a2 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java @@ -1,16 +1,17 @@ package org.egov.processor.web.models; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; + import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; - -import java.util.List; +import lombok.Data; +import lombok.Builder; /** * Activity diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java index 0126b2be7f7..5f1d262fea7 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java @@ -1,15 +1,19 @@ package org.egov.processor.web.models; import com.fasterxml.jackson.annotation.JsonProperty; + import jakarta.validation.Valid; -import jakarta.validation.constraints.*; +import java.math.BigDecimal; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import jakarta.validation.constraints.DecimalMax; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Digits; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; - -import java.math.BigDecimal; +import lombok.Data; +import lombok.Builder; /** * Assumption diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Condition.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Condition.java index 51d3511c068..c63749d5bab 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Condition.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Condition.java @@ -3,11 +3,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; +import lombok.Data; +import lombok.Builder; /** * Condition diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java index 84638ec0af8..25a62e8ac83 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java @@ -1,17 +1,18 @@ package org.egov.processor.web.models; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; +import org.apache.kafka.common.protocol.types.Field; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; +import lombok.Data; +import lombok.Builder; import java.util.Arrays; diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java index 9aa1c33ebf4..b21b1a62560 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java @@ -3,7 +3,11 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; -import jakarta.validation.constraints.*; +import jakarta.validation.constraints.DecimalMax; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Digits; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java index 43f34b29139..6147edb0f02 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java @@ -1,17 +1,17 @@ package org.egov.processor.web.models; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; +import lombok.Data; +import lombok.Builder; import java.util.Arrays; diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java index 59e7660492d..8f43cca25d7 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java @@ -1,17 +1,19 @@ package org.egov.processor.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; - -import java.util.List; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; /** * Plan @@ -43,6 +45,14 @@ public class Plan { @Size(max = 64) private String planConfigurationId = null; + @JsonProperty("status") + @Size(max = 64) + private String status = null; + + @JsonProperty("assignee") + @Size(max = 64) + private String assignee = null; + @JsonProperty("additionalDetails") private Object additionalDetails = null; @@ -61,4 +71,15 @@ public class Plan { @JsonProperty("auditDetails") private AuditDetails auditDetails = null; + @JsonProperty("boundaryAncestralPath") + @NotNull + private String boundaryAncestralPath = null; + + @JsonIgnore + private List assigneeJurisdiction; + + @JsonProperty("workflow") + @Valid + private Workflow workflow; + } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfiguration.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfiguration.java index e02d7e49b70..218dbaecbea 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfiguration.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfiguration.java @@ -1,14 +1,15 @@ package org.egov.processor.web.models; import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotEmpty; import java.util.ArrayList; import java.util.List; + import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Pattern; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @@ -36,54 +37,43 @@ public class PlanConfiguration { @JsonProperty("name") @NotNull - @Size(min = 2, max = 128) - @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Name must not contain only special characters") + @Size(min = 3, max = 128) private String name = null; - @JsonProperty("executionPlanId") + @JsonProperty("campaignId") @NotNull @Size(min = 2, max = 64) - @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Execution Plan Id must not contain only special characters") - private String executionPlanId = null; + @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Campaign Id must not contain only special characters") + private String campaignId = null; @JsonProperty("status") - @NotNull - private StatusEnum status = null; + private String status = null; @JsonProperty("files") - @NotNull - @NotEmpty @Valid private List files = new ArrayList<>(); @JsonProperty("assumptions") - @NotNull - @NotEmpty @Valid private List assumptions = new ArrayList<>(); @JsonProperty("operations") - @NotNull - @NotEmpty @Valid private List operations = new ArrayList<>(); @JsonProperty("resourceMapping") - @NotNull - @NotEmpty @Valid private List resourceMapping = new ArrayList<>(); @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; - /** - * The status used in the Plan Configuration - */ - public enum StatusEnum { - DRAFT , - GENERATED, - INVALID_DATA - } + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("workflow") + @Valid + private Workflow workflow; + } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java index 129f4dccad0..693ba12ef32 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java @@ -1,15 +1,14 @@ package org.egov.processor.web.models; import com.fasterxml.jackson.annotation.JsonProperty; +import java.math.BigDecimal; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; - -import java.math.BigDecimal; +import lombok.Data; +import lombok.Builder; /** * Resource diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/ResourceMapping.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/ResourceMapping.java index c53868d1033..ee9e1869c0c 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/ResourceMapping.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/ResourceMapping.java @@ -1,15 +1,16 @@ package org.egov.processor.web.models; import com.fasterxml.jackson.annotation.JsonProperty; + import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; +import lombok.Data; +import lombok.Builder; /** * ResourceMapping diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Target.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Target.java index 8d7298939f6..6855fccb123 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Target.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Target.java @@ -3,11 +3,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; +import lombok.Data; +import lombok.Builder; /** * Target From 745e5708bb51f7b18653e535ad1c6afd9b21a901 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 21 Oct 2024 13:31:51 +0530 Subject: [PATCH 253/351] HCMPRE-599 adding census POJOs --- .../processor/web/models/census/Census.java | 136 ++++++++++++++++++ .../web/models/census/CensusRequest.java | 31 ++++ .../web/models/census/CensusResponse.java | 42 ++++++ .../models/census/CensusSearchCriteria.java | 62 ++++++++ .../models/census/CensusSearchRequest.java | 31 ++++ .../census/PopulationByDemographic.java | 69 +++++++++ 6 files changed, 371 insertions(+) create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java new file mode 100644 index 00000000000..b15404226ec --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java @@ -0,0 +1,136 @@ +package org.egov.processor.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.List; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; + + +/** + * Census + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Census { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("hierarchyType") + @NotNull + private String hierarchyType = null; + + @JsonProperty("boundaryCode") + @NotNull + private String boundaryCode = null; + + @JsonProperty("assignee") + @NotNull + private String assignee = null; + + @JsonProperty("status") + @NotNull + private StatusEnum status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("effectiveFrom") + private Long effectiveFrom = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("source") + @NotNull + private String source = null; + + @JsonIgnore + private List boundaryAncestralPath = null; + + @JsonIgnore + private boolean partnerAssignmentValidationEnabled; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; + + /** + * The status used in the Census + */ + public enum StatusEnum { + VALIDATED, + APPROVED, + PENDING_FOR_APPROVAL, + PENDING_FOR_VALIDATION + } + + /** + * Gets or Sets type + */ + public enum TypeEnum { + PEOPLE("people"), + ANIMALS("animals"), + PLANTS("plants"), + OTHER("other"); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String text) { + for (TypeEnum b : TypeEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + +} diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java new file mode 100644 index 00000000000..1043028bce7 --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java @@ -0,0 +1,31 @@ +package org.egov.processor.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Census") + @Valid + private Census census = null; + + +} diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java new file mode 100644 index 00000000000..ba67658ad67 --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java @@ -0,0 +1,42 @@ +package org.egov.processor.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; +import java.util.Map; + +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Census") + @Valid + private List census = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; + + @JsonProperty("StatusCount") + @Valid + private Map statusCount = null; + +} diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java new file mode 100644 index 00000000000..5a47fea7322 --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java @@ -0,0 +1,62 @@ +package org.egov.processor.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchCriteria + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchCriteria { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + private String tenantId = null; + + @JsonProperty("areaCodes") + private List areaCodes = null; + + @JsonProperty("status") + private String status = null; + + @JsonProperty("assignee") + private String assignee = null; + + @JsonProperty("source") + private String source = null; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("jurisdiction") + private List jurisdiction = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { + if (this.areaCodes == null) { + this.areaCodes = new ArrayList<>(); + } + this.areaCodes.add(areaCodesItem); + return this; + } + +} diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java new file mode 100644 index 00000000000..9fe2c0b2ef0 --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java @@ -0,0 +1,31 @@ +package org.egov.processor.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("CensusSearchCriteria") + @Valid + private CensusSearchCriteria censusSearchCriteria = null; + + +} diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java new file mode 100644 index 00000000000..52ab230781b --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java @@ -0,0 +1,69 @@ +package org.egov.processor.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +/** + * PopulationByDemographic + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PopulationByDemographic { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("demographicVariable") + private DemographicVariableEnum demographicVariable = null; + + @JsonProperty("populationDistribution") + private Object populationDistribution = null; + + /** + * Gets or Sets demographicVariable + */ + public enum DemographicVariableEnum { + AGE("age"), + + GENDER("gender"), + + ETHNICITY("ethnicity"); + + private String value; + + DemographicVariableEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static DemographicVariableEnum fromValue(String text) { + for (DemographicVariableEnum b : DemographicVariableEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + +} From 45cd90956c5a75a20344d0da81c7dc2bfee567a2 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 23 Oct 2024 19:18:49 +0530 Subject: [PATCH 254/351] HCMPRE-599changes for triggering pland census records on workflow status --- .../egov/processor/config/Configuration.java | 17 ++- .../processor/config/ServiceConstants.java | 16 ++- .../egov/processor/kafka/PlanConsumer.java | 11 +- .../egov/processor/service/ExcelParser.java | 131 ++++++++++++------ .../org/egov/processor/util/CensusUtil.java | 111 +++++++++++++++ .../org/egov/processor/util/ParsingUtil.java | 48 +++++-- .../org/egov/processor/util/PlanUtil.java | 16 +-- .../org/egov/processor/web/models/Plan.java | 18 +-- .../processor/web/models/census/Census.java | 36 +++-- .../web/models/census/CensusRequest.java | 8 +- .../web/models/census/CensusResponse.java | 15 +- .../models/census/CensusSearchCriteria.java | 13 +- .../models/census/CensusSearchRequest.java | 8 +- 13 files changed, 329 insertions(+), 119 deletions(-) create mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CensusUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java index 1b892e12fc5..203d955afb4 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java @@ -56,15 +56,9 @@ public class Configuration { @Value("${egov.project.factory.host}") private String projectFactoryHostEndPoint; - @Value("${resource.microplan.create.topic}") - private String resourceMicroplanCreateTopic; - @Value("${integrate.with.admin.console}") private boolean isIntegrateWithAdminConsole; - @Value("${resource.update.plan.config.consumer.topic}") - private String resourceUpdatePlanConfigConsumerTopic; - @Value("${egov.boundary.service.host}") private String egovBoundaryServiceHost; @@ -83,4 +77,15 @@ public class Configuration { @Value("${plan.config.trigger.census.records.status}") private String planConfigTriggerCensusRecordsStatus; + + //Kafka topics for creating or updating records in dependent microservices + @Value("${resource.microplan.create.topic}") + private String resourceMicroplanCreateTopic; + + @Value("${resource.update.plan.config.consumer.topic}") + private String resourceUpdatePlanConfigConsumerTopic; + + @Value("${resource.census.create.topic}") + private String resourceCensusCreateTopic; + } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java index 797c9a894c3..98a8e79c77d 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java @@ -36,10 +36,13 @@ public class ServiceConstants { public static final String NOT_ABLE_TO_CONVERT_MULTIPARTFILE_TO_BYTESTREAM_CODE = "NOT_ABLE_TO_CONVERT_MULTIPARTFILE_TO_BYTESTREAM"; public static final String NOT_ABLE_TO_CONVERT_MULTIPARTFILE_TO_BYTESTREAM_MESSAGE = "Not able to fetch byte stream from a multipart file"; - public static final String BOUNDARY_CODE = "boundaryCode"; + public static final String BOUNDARY_CODE = "HCM_ADMIN_CONSOLE_BOUNDARY_CODE"; + public static final String TOTAL_POPULATION = "HCM_ADMIN_CONSOLE_TOTAL_POPULATION"; + public static final String ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE_FOR_LOCALITY = "Exception occurred while fetching plan configuration from plan service for Locality "; - + public static final String ERROR_WHILE_PUSHING_TO_PLAN_SERVICE_FOR_LOCALITY = "Exception occurred while fetching plan configuration from plan service for Locality "; public static final String ERROR_WHILE_SEARCHING_CAMPAIGN = "Exception occurred while searching/updating campaign."; + public static final String FILE_NAME = "output.xls"; public static final String FILE_TYPE = "boundaryWithTarget"; public static final String FILE_TEMPLATE_IDENTIFIER = "Population"; @@ -69,4 +72,13 @@ public class ServiceConstants { public static final String ERROR_WHILE_SEARCHING_LOCALE = "Exception occurred while searching locale. "; public static final String MDMS_MASTER_COMMON_CONSTANTS = "CommonConstants"; + //override sheet names + public static final String HCM_ADMIN_CONSOLE_BOUNDARY_DATA = "HCM_ADMIN_CONSOLE_BOUNDARY_DATA"; + public static final String READ_ME_SHEET_NAME = "readMeSheetName"; + + //Workflow constants + public static final String WORKFLOW_ACTION_INITIATE = "INITIATE"; + public static final String WORKFLOW_COMMENTS_INITIATING_CENSUS = "Initiating census record creation"; + public static final String WORKFLOW_COMMENTS_INITIATING_ESTIMATES = "Initiating plan estimation record creation"; + } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java index f152d7503d4..b4fc26faff1 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java @@ -1,11 +1,10 @@ package org.egov.processor.kafka; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Collections; import java.util.Map; import lombok.extern.slf4j.Slf4j; +import org.egov.processor.config.Configuration; import org.egov.processor.service.ResourceEstimationService; -import org.egov.processor.web.models.PlanConfiguration; import org.egov.processor.web.models.PlanConfigurationRequest; import org.egov.tracer.model.CustomException; import org.springframework.http.HttpStatus; @@ -22,17 +21,23 @@ public class PlanConsumer { private ResourceEstimationService resourceEstimationService; - public PlanConsumer(ObjectMapper objectMapper, ResourceEstimationService resourceEstimationService) { + private Configuration config; + + public PlanConsumer(ObjectMapper objectMapper, ResourceEstimationService resourceEstimationService, Configuration config) { this.objectMapper = objectMapper; this.resourceEstimationService = resourceEstimationService; + this.config = config; } @KafkaListener(topics = { "${plan.config.consumer.kafka.save.topic}", "${plan.config.consumer.kafka.update.topic}" }) public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { try { PlanConfigurationRequest planConfigurationRequest = objectMapper.convertValue(consumerRecord, PlanConfigurationRequest.class); + if (planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus()) + || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { resourceEstimationService.estimateResources(planConfigurationRequest); log.info("Successfully estimated resources for plan."); + } } catch (Exception exception) { log.error("Error processing record from topic "+topic+" with exception :"+exception); throw new CustomException(Integer.toString(HttpStatus.INTERNAL_SERVER_ERROR.value()), diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java index c0af67adddb..ff518f2708e 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java @@ -16,14 +16,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; -import org.egov.processor.util.BoundaryUtil; -import org.egov.processor.util.CalculationUtil; -import org.egov.processor.util.CampaignIntegrationUtil; -import org.egov.processor.util.FilestoreUtil; -import org.egov.processor.util.LocaleUtil; -import org.egov.processor.util.MdmsUtil; -import org.egov.processor.util.ParsingUtil; -import org.egov.processor.util.PlanUtil; +import org.egov.processor.util.*; import org.egov.processor.web.models.Locale; import org.egov.processor.web.models.LocaleResponse; import org.egov.processor.web.models.Operation; @@ -47,6 +40,9 @@ import lombok.extern.slf4j.Slf4j; +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 { @@ -71,9 +67,11 @@ public class ExcelParser implements FileParser { private LocaleUtil localeUtil; + private CensusUtil censusUtil; + public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, FilestoreUtil filestoreUtil, - CalculationUtil calculationUtil, PlanUtil planUtil, CampaignIntegrationUtil campaignIntegrationUtil, - Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil,LocaleUtil localeUtil) { + CalculationUtil calculationUtil, PlanUtil planUtil, CampaignIntegrationUtil campaignIntegrationUtil, + Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil) { this.objectMapper = objectMapper; this.parsingUtil = parsingUtil; this.filestoreUtil = filestoreUtil; @@ -84,7 +82,8 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore this.mdmsUtil = mdmsUtil; this.boundaryUtil = boundaryUtil; this.localeUtil = localeUtil; - } + this.censusUtil = censusUtil; + } /** * Parses file data, extracts information from the file, and processes it. @@ -132,9 +131,8 @@ private String processExcelFile(PlanConfigurationRequest planConfigurationReques DataFormatter dataFormatter = new DataFormatter(); processSheets(planConfigurationRequest, fileStoreId, campaignResponse, planConfig, workbook, campaignBoundaryList, dataFormatter); - String uploadedFileStoreId = uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse, - planConfig, workbook, campaignBoundaryList, campaignResourcesList); - return uploadedFileStoreId; + return uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse, + planConfig, workbook, campaignBoundaryList, campaignResourcesList); } catch (FileNotFoundException e) { log.error("File not found: {}", e.getMessage()); throw new CustomException("FileNotFound", "The specified file was not found."); @@ -205,16 +203,21 @@ private void processSheets(PlanConfigurationRequest planConfigurationRequest, St DataFormatter dataFormatter) { LocaleResponse localeResponse = localeUtil.searchLocale(planConfigurationRequest); CampaignResponse campaign = parseCampaignResponse(campaignResponse); + Map attributeNameVsDataTypeMap = prepareAttributeVsIndexMap(planConfigurationRequest, fileStoreId, campaign, planConfig); List boundaryCodeList = getBoundaryCodeList(planConfigurationRequest, campaign, planConfig); excelWorkbook.forEach(excelWorkbookSheet -> { - if (isSheetAllowedToProcess(planConfigurationRequest, excelWorkbookSheet.getSheetName(),localeResponse)) { - //TODO: remove validateColumnNames() - if(planConfig.getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) + if (isSheetAllowedToProcess(planConfigurationRequest, excelWorkbookSheet.getSheetName(), localeResponse)) { + + if (planConfig.getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { processRows(planConfigurationRequest, excelWorkbookSheet, dataFormatter, fileStoreId, - campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); + campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); + } else if (planConfig.getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { + processRowsForCensusRecords(planConfigurationRequest, excelWorkbookSheet, + fileStoreId, attributeNameVsDataTypeMap, boundaryCodeList, campaign.getCampaign().get(0).getHierarchyType()); + } } }); } @@ -242,6 +245,35 @@ private void processRows(PlanConfigurationRequest planConfigurationRequest, Shee performRowLevelCalculations(planConfigurationRequest, sheet, dataFormatter, fileStoreId, campaignBoundaryList, planConfig, attributeNameVsDataTypeMap, boundaryCodeList); } + private void processRowsForCensusRecords(PlanConfigurationRequest planConfigurationRequest, Sheet sheet, String fileStoreId, Map attributeNameVsDataTypeMap, List boundaryCodeList, String hierarchyType) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + + Map mappedValues = planConfig.getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, + campaignIntegrationUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + Row firstRow = null; + + for (Row row : sheet) { + if (isRowEmpty(row)) + continue; + + if (row.getRowNum() == 0) { + firstRow = row; + continue; + } + + validateRows(indexOfBoundaryCode, row, firstRow, attributeNameVsDataTypeMap, mappedValues, mapOfColumnNameAndIndex, + planConfigurationRequest, boundaryCodeList, sheet); + JsonNode currentRow = createFeatureNodeFromRow(row, mapOfColumnNameAndIndex); + + censusUtil.create(planConfigurationRequest, currentRow, mappedValues, hierarchyType); + } + } + /** * Retrieves a list of boundary codes based on the given plan configuration, campaign details, and request information. * @@ -313,6 +345,16 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat DataFormatter dataFormatter, String fileStoreId, List campaignBoundaryList, PlanConfiguration planConfig, Map attributeNameVsDataTypeMap, List boundaryCodeList) { Row firstRow = null; + Map mappedValues = planConfig.getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); + Map assumptionValueMap = calculationUtil + .convertAssumptionsToMap(planConfig.getAssumptions()); + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + + Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, + campaignIntegrationUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + for (Row row : sheet) { if(isRowEmpty(row)) continue; @@ -323,24 +365,15 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat } Map resultMap = new HashMap<>(); - Map mappedValues = planConfig.getResourceMapping().stream() - .filter(f -> f.getFilestoreId().equals(fileStoreId)) - .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); - Map assumptionValueMap = calculationUtil - .convertAssumptionsToMap(planConfig.getAssumptions()); - Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); - - Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, - campaignIntegrationUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); validateRows(indexOfBoundaryCode, row, firstRow, attributeNameVsDataTypeMap, mappedValues, mapOfColumnNameAndIndex, planConfigurationRequest, boundaryCodeList, sheet); - JsonNode feature = createFeatureNodeFromRow(row, dataFormatter, mapOfColumnNameAndIndex); + 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); - planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); + planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); // TODO: remove after testing printRow(sheet, row); } @@ -456,12 +489,10 @@ private File convertWorkbookToXls(Workbook workbook) { * Creates a JSON feature node from a row in the Excel sheet. * * @param row The row in the Excel sheet. - * @param dataFormatter The data formatter for formatting cell values. * @param columnIndexMap The mapping of column names to column indices. * @return The JSON feature node representing the row. */ - private JsonNode createFeatureNodeFromRow(Row row, DataFormatter dataFormatter, - Map columnIndexMap) { + private JsonNode createFeatureNodeFromRow(Row row, Map columnIndexMap) { ObjectNode featureNode = objectMapper.createObjectNode(); ObjectNode propertiesNode = featureNode.putObject("properties"); @@ -472,12 +503,33 @@ private JsonNode createFeatureNodeFromRow(Row row, DataFormatter dataFormatter, // Get the cell value from the row based on the columnIndex Cell cell = row.getCell(columnIndex); - String cellValue = dataFormatter.formatCellValue(cell); + if (cell == null) { + // Handle null cells if needed + propertiesNode.putNull(columnName); + continue; + } - // Add the columnName and cellValue to the propertiesNode - propertiesNode.put(columnName, cellValue); + switch (cell.getCellType()) { + case STRING: + propertiesNode.put(columnName, cell.getStringCellValue()); + break; + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + // Handle date values + propertiesNode.put(columnName, cell.getDateCellValue().toString()); + } else { + propertiesNode.put(columnName, BigDecimal.valueOf(cell.getNumericCellValue())); + } + break; + case BOOLEAN: + propertiesNode.put(columnName, cell.getBooleanCellValue()); + break; + default: + propertiesNode.putNull(columnName); + break; + } } -// System.out.println("Feature Node ---- > " + featureNode); + return featureNode; } @@ -716,13 +768,14 @@ public List getAllBoundaryPresentforHierarchyType(List * @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) { + private boolean isSheetAllowedToProcess(PlanConfigurationRequest planConfigurationRequest, String sheetName, LocaleResponse localeResponse) { Map mdmsDataConstants = mdmsUtil.fetchMdmsDataForCommonConstants( planConfigurationRequest.getRequestInfo(), planConfigurationRequest.getPlanConfiguration().getTenantId()); - String value = (String) mdmsDataConstants.get("readMeSheetName"); + for (Locale locale : localeResponse.getMessages()) { - if ((locale.getCode().equalsIgnoreCase(value))) { + 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; } diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CensusUtil.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CensusUtil.java new file mode 100644 index 00000000000..0f544d7b9dc --- /dev/null +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CensusUtil.java @@ -0,0 +1,111 @@ +package org.egov.processor.util; + +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.models.Workflow; +import org.egov.processor.config.Configuration; +import org.egov.processor.config.ServiceConstants; +import org.egov.processor.kafka.Producer; +import org.egov.processor.repository.ServiceRequestRepository; +import org.egov.processor.web.models.*; +import org.egov.processor.web.models.census.Census; +import org.egov.processor.web.models.census.CensusRequest; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import static org.egov.processor.config.ServiceConstants.*; + +@Component +@Slf4j +public class CensusUtil { + + private ServiceRequestRepository serviceRequestRepository; + + private Configuration config; + + private Producer producer; + + private ParsingUtil parsingUtil; + + public CensusUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, Producer producer, ParsingUtil parsingUtil) { + this.serviceRequestRepository = serviceRequestRepository; + this.config = config; + this.producer = producer; + this.parsingUtil = parsingUtil; + } + + /** + * Creates and pushes a CensusRequest based on the provided plan configuration, feature JSON node, and mapped values. + * + * @param planConfigurationRequest The plan configuration request with the necessary details. + * @param feature The JSON node containing feature data for the census. + * @param mappedValues A map of property names to their values from the feature node. + * @param heirarchyType The type of hierarchy to be used in the census. + */ + public void create(PlanConfigurationRequest planConfigurationRequest, JsonNode feature, Map mappedValues, String heirarchyType) { + CensusRequest censusRequest = buildCensusRequest(planConfigurationRequest, feature, mappedValues, heirarchyType); + try { + log.info("Census request - " + censusRequest.getCensus()); + producer.push(config.getResourceCensusCreateTopic(), censusRequest); + } catch (Exception e) { + log.error(ERROR_WHILE_PUSHING_TO_PLAN_SERVICE_FOR_LOCALITY + censusRequest.getCensus().getBoundaryCode(), e); + } + } + + /** + * Builds and returns a CensusRequest using the provided plan configuration, feature JSON node, and mapped values. + * + * @param planConfigurationRequest The plan configuration request containing configuration details. + * @param feature The feature JSON node containing property values. + * @param mappedValues The mapped values for extracting properties. + * @param heirarchyType The hierarchy type of the census. + * @return A constructed CensusRequest object with populated details. + */ + private CensusRequest buildCensusRequest(PlanConfigurationRequest planConfigurationRequest, JsonNode feature, Map mappedValues, String heirarchyType) { + + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + return CensusRequest.builder() + .census(Census.builder() + .tenantId(planConfig.getTenantId()) + .hierarchyType(heirarchyType) + .boundaryCode((String) parsingUtil.extractMappedValueFromFeatureForAnInput(ServiceConstants.BOUNDARY_CODE, feature, mappedValues)) + .type(Census.TypeEnum.PEOPLE) + .facilityAssigned(Boolean.FALSE) + .partnerAssignmentValidationEnabled(Boolean.TRUE) + .totalPopulation((BigDecimal) parsingUtil.extractMappedValueFromFeatureForAnInput(ServiceConstants.TOTAL_POPULATION, feature, mappedValues)) + .workflow(Workflow.builder().action(WORKFLOW_ACTION_INITIATE).comments(WORKFLOW_COMMENTS_INITIATING_CENSUS).build()) + .source(planConfig.getId()) + .additionalDetails(enrichAdditionalDetails(feature, mappedValues)).build()) + .requestInfo(planConfigurationRequest.getRequestInfo()).build(); + + } + + /** + * Enriches and returns additional details by extracting values from the feature JSON node based on the provided mappings. + * + * @param feature The feature JSON node containing property values. + * @param mappedValues The mapped values for extracting properties. + * @return A map containing enriched additional details based on the extracted values. + */ + public Map enrichAdditionalDetails(JsonNode feature, Map mappedValues) { + // Create additionalDetails object to hold the enriched data + Map additionalDetails = new HashMap<>(); + + // Iterate over mappedValues keys + for (String key : mappedValues.keySet()) { + // Get the corresponding value from the feature JsonNode + Object valueFromRow = parsingUtil.extractMappedValueFromFeatureForAnInput(key, feature, mappedValues); + // Check if the value exists in the JSON and add it to additonalDetails map + if (!ObjectUtils.isEmpty(valueFromRow)) { + additionalDetails.put(key, valueFromRow); + } + } + + return additionalDetails; + } + +} diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java index d8f5672241f..c644e2f6743 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java @@ -7,7 +7,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -19,11 +18,9 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import com.fasterxml.jackson.databind.node.DecimalNode; import org.apache.commons.io.FileUtils; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.*; import org.egov.processor.web.models.PlanConfiguration; import org.egov.processor.web.models.ResourceMapping; import org.egov.tracer.model.CustomException; @@ -33,6 +30,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ObjectUtils; + +import static org.egov.processor.config.ServiceConstants.PROPERTIES; @Slf4j @Component @@ -101,12 +101,40 @@ public Map getAttributeNameIndexFromExcel(Sheet sheet) { String columnHeader = dataFormatter.formatCellValue(cell); columnIndexMap.put(columnHeader, i); } - List> sortedColumnList = new ArrayList<>(columnIndexMap.entrySet()); - Collections.sort(sortedColumnList, (o1, o2) -> (o1.getValue()).compareTo(o2.getValue())); - for (Map.Entry entry : sortedColumnList) { - sortedMap.put(entry.getKey(), entry.getValue()); + return columnIndexMap; + } + + /** + * Retrieves the mapped value from the feature JSON node using the mapped value for the given input, + * returning it as the appropriate data type. + * + * @param input The input value. + * @param feature The feature JSON node. + * @param mappedValues The mapped values. + * @return The value of the corresponding data type (Long, String, Boolean, etc.). + * @throws CustomException if the input value is not found in the feature JSON node or if the value type is unsupported. + */ + public Object extractMappedValueFromFeatureForAnInput(String input, JsonNode feature, Map mappedValues) { + // Get the value as a JsonNode, not a String + JsonNode mappedValueNode = feature.get(PROPERTIES).get(mappedValues.get(input)); + + // Check if the value exists in the JSON + if (!ObjectUtils.isEmpty(mappedValueNode)) { + + // Now return the value based on its actual type in the JsonNode + if (mappedValueNode instanceof DecimalNode) { + return ((DecimalNode) mappedValueNode).decimalValue(); // Returns BigDecimal + } else if (mappedValueNode.isBoolean()) { + return mappedValueNode.asBoolean(); + } else if (mappedValueNode.isTextual()) { + return mappedValueNode.asText(); + } else { + return null; + } + } + else { + return null; } - return sortedMap; } /** diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java index 49fbe362cd5..b5be6c40bc9 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java @@ -1,34 +1,29 @@ package org.egov.processor.util; -import static org.egov.processor.config.ServiceConstants.ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE_FOR_LOCALITY; -import static org.egov.processor.config.ServiceConstants.PROPERTIES; - 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; +import org.egov.common.contract.models.Workflow; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; import org.egov.processor.repository.ServiceRequestRepository; import org.egov.processor.kafka.Producer; -import org.egov.processor.web.models.Activity; import org.egov.processor.web.models.Plan; import org.egov.processor.web.models.PlanConfiguration; import org.egov.processor.web.models.PlanConfigurationRequest; -import org.egov.processor.web.models.PlanConfigurationResponse; import org.egov.processor.web.models.PlanRequest; import org.egov.processor.web.models.Resource; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import static org.egov.processor.config.ServiceConstants.*; + @Component @Slf4j public class PlanUtil { @@ -55,7 +50,7 @@ public PlanUtil(ServiceRequestRepository serviceRequestRepository, Configuration public void create(PlanConfigurationRequest planConfigurationRequest, JsonNode feature, Map resultMap, Map mappedValues) { PlanRequest planRequest = buildPlanRequest(planConfigurationRequest, feature, resultMap, mappedValues); - try { + try { producer.push(config.getResourceMicroplanCreateTopic(), planRequest); } catch (Exception e) { log.error(ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE_FOR_LOCALITY + planRequest.getPlan().getLocality(), e); @@ -80,6 +75,7 @@ private PlanRequest buildPlanRequest(PlanConfigurationRequest planConfigurationR .requestInfo(planConfigurationRequest.getRequestInfo()) .plan(Plan.builder() .tenantId(planConfig.getTenantId()) + .planConfigurationId(planConfig.getId()) .campaignId(planConfig.getCampaignId()) .locality(getBoundaryCodeValue(ServiceConstants.BOUNDARY_CODE, feature, mappedValues)) @@ -91,6 +87,8 @@ private PlanRequest buildPlanRequest(PlanConfigurationRequest planConfigurationR }).collect(Collectors.toList())) .activities(new ArrayList()) .targets(new ArrayList()) + .workflow(Workflow.builder().action(WORKFLOW_ACTION_INITIATE).comments(WORKFLOW_COMMENTS_INITIATING_ESTIMATES).build()) + .isRequestFromResourceEstimationConsumer(true) .build()) .build(); diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java index 8f43cca25d7..8b2f1803f57 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java @@ -2,18 +2,18 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; - import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import org.egov.common.contract.models.AuditDetails; import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; + +import java.util.List; /** * Plan @@ -71,10 +71,12 @@ public class Plan { @JsonProperty("auditDetails") private AuditDetails auditDetails = null; - @JsonProperty("boundaryAncestralPath") - @NotNull + @JsonIgnore private String boundaryAncestralPath = null; + @JsonIgnore + private boolean isRequestFromResourceEstimationConsumer; + @JsonIgnore private List assigneeJurisdiction; diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java index b15404226ec..9b6c76df2a6 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java @@ -1,13 +1,11 @@ package org.egov.processor.web.models.census; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.List; - +import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; @@ -15,8 +13,11 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; + +import java.math.BigDecimal; +import java.util.List; /** @@ -47,12 +48,12 @@ public class Census { private String boundaryCode = null; @JsonProperty("assignee") - @NotNull + @Size(max = 64) private String assignee = null; @JsonProperty("status") - @NotNull - private StatusEnum status = null; + @Size(max = 64) + private String status = null; @JsonProperty("type") @NotNull @@ -60,7 +61,7 @@ public class Census { @JsonProperty("totalPopulation") @NotNull - private Long totalPopulation = null; + private BigDecimal totalPopulation = null; @JsonProperty("populationByDemographics") @Valid @@ -85,22 +86,19 @@ public class Census { @JsonProperty("facilityAssigned") private Boolean facilityAssigned = null; + @JsonProperty("workflow") + @Valid + private Workflow workflow; + + @JsonIgnore + private List assigneeJurisdiction; + @JsonProperty("additionalDetails") private Object additionalDetails = null; @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; - /** - * The status used in the Census - */ - public enum StatusEnum { - VALIDATED, - APPROVED, - PENDING_FOR_APPROVAL, - PENDING_FOR_VALIDATION - } - /** * Gets or Sets type */ diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java index 1043028bce7..08a9c3bdbce 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java @@ -1,13 +1,13 @@ package org.egov.processor.web.models.census; import com.fasterxml.jackson.annotation.JsonProperty; -import org.egov.common.contract.request.RequestInfo; -import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; /** * CensusRequest diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java index ba67658ad67..7e6c0b77440 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java @@ -1,17 +1,16 @@ package org.egov.processor.web.models.census; import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; -import java.util.Map; - -import org.egov.common.contract.response.ResponseInfo; -import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import java.util.List; +import java.util.Map; /** * CensusResponse diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java index 5a47fea7322..78509561418 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java @@ -2,17 +2,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; import java.util.ArrayList; import java.util.List; -import org.springframework.validation.annotation.Validated; -import jakarta.validation.constraints.*; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; -import lombok.Builder; - /** * CensusSearchCriteria */ diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java index 9fe2c0b2ef0..ef7439bc368 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java +++ b/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java @@ -1,13 +1,13 @@ package org.egov.processor.web.models.census; import com.fasterxml.jackson.annotation.JsonProperty; -import org.egov.common.contract.request.RequestInfo; -import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; /** * CensusSearchRequest From 025f8a9ee8a47ec07780480a635fbf9b5603f410 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 23 Oct 2024 19:20:35 +0530 Subject: [PATCH 255/351] HCMPRE-599 app.prop changes for resource generator service --- .../src/main/resources/application.properties | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/health-services/resource-estimation-service/src/main/resources/application.properties b/health-services/resource-estimation-service/src/main/resources/application.properties index 7cdfe225f6d..0966208ba05 100644 --- a/health-services/resource-estimation-service/src/main/resources/application.properties +++ b/health-services/resource-estimation-service/src/main/resources/application.properties @@ -71,13 +71,20 @@ egov.project.factory.search.endpoint=/project-factory/v1/project-type/search egov.project.factory.update.endpoint=/project-factory/v1/project-type/update egov.project.factory.host=https://unified-dev.digit.org #egov.project.factory.host=http://localhost:8090 +integrate.with.admin.console=true + +#Kafka topics for creating or updating records in dependent microservices resource.microplan.create.topic=resource-microplan-create-topic resource.update.plan.config.consumer.topic=resource-plan-config-update-topic -integrate.with.admin.console=true +resource.census.create.topic=resource-census-create-topic egov.boundary.service.host=https://unified-dev.digit.org #egov.boundary.service.host=http://localhost:8091 egov.boundary.relationship.search.endpoint=/boundary-service/boundary-relationships/_search?includeChildren=true&tenantId={tenantId}&hierarchyType={hierarchyType} egov.locale.service.host=https://unified-qa.digit.org -egov.locale.search.endpoint=/localization/messages/v1/_search?module={module}&locale={locale}&tenantId={tenantId} \ No newline at end of file +egov.locale.search.endpoint=/localization/messages/v1/_search?module={module}&locale={locale}&tenantId={tenantId} + +#trigger statuses +plan.config.trigger.plan.estimates.status=RESOURCE_ESTIMATION_IN_PROGRESS +plan.config.trigger.census.records.status=EXECUTION_TO_BE_DONE \ No newline at end of file From 6870fc54ab28a7d5c86ec178596a1dd3609599c0 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Thu, 24 Oct 2024 10:52:02 +0530 Subject: [PATCH 256/351] Renaming resource-estimation-service to resource-generator --- build/build-config.yml | 6 +++--- .../CHANGELOG.md | 2 +- .../LOCALSETUP.md | 0 .../README.md | 0 .../pom.xml | 2 +- .../src/main/java/org/egov/processor/Main.java | 0 .../main/java/org/egov/processor/config/Configuration.java | 0 .../java/org/egov/processor/config/MainConfiguration.java | 0 .../java/org/egov/processor/config/ServiceConstants.java | 0 .../main/java/org/egov/processor/kafka/PlanConsumer.java | 0 .../src/main/java/org/egov/processor/kafka/Producer.java | 0 .../egov/processor/repository/ServiceRequestRepository.java | 0 .../main/java/org/egov/processor/service/ExcelParser.java | 0 .../main/java/org/egov/processor/service/FileParser.java | 0 .../main/java/org/egov/processor/service/GeoJsonParser.java | 0 .../egov/processor/service/ResourceEstimationService.java | 0 .../java/org/egov/processor/service/ShapeFileParser.java | 0 .../src/main/java/org/egov/processor/util/BoundaryUtil.java | 0 .../main/java/org/egov/processor/util/CalculationUtil.java | 0 .../org/egov/processor/util/CampaignIntegrationUtil.java | 0 .../src/main/java/org/egov/processor/util/CensusUtil.java | 0 .../main/java/org/egov/processor/util/FilestoreUtil.java | 0 .../src/main/java/org/egov/processor/util/LocaleUtil.java | 0 .../src/main/java/org/egov/processor/util/MdmsUtil.java | 0 .../src/main/java/org/egov/processor/util/ParsingUtil.java | 0 .../java/org/egov/processor/util/PlanConfigurationUtil.java | 0 .../src/main/java/org/egov/processor/util/PlanUtil.java | 0 .../org/egov/processor/web/controllers/FileController.java | 0 .../main/java/org/egov/processor/web/models/Activity.java | 0 .../main/java/org/egov/processor/web/models/Assumption.java | 0 .../main/java/org/egov/processor/web/models/Condition.java | 0 .../src/main/java/org/egov/processor/web/models/File.java | 0 .../src/main/java/org/egov/processor/web/models/Locale.java | 0 .../java/org/egov/processor/web/models/LocaleResponse.java | 0 .../java/org/egov/processor/web/models/MetricDetail.java | 0 .../main/java/org/egov/processor/web/models/Operation.java | 0 .../src/main/java/org/egov/processor/web/models/Plan.java | 0 .../org/egov/processor/web/models/PlanConfiguration.java | 0 .../egov/processor/web/models/PlanConfigurationRequest.java | 0 .../processor/web/models/PlanConfigurationResponse.java | 0 .../web/models/PlanConfigurationSearchCriteria.java | 0 .../web/models/PlanConfigurationSearchRequest.java | 0 .../java/org/egov/processor/web/models/PlanRequest.java | 0 .../main/java/org/egov/processor/web/models/Resource.java | 0 .../java/org/egov/processor/web/models/ResourceMapping.java | 0 .../src/main/java/org/egov/processor/web/models/Source.java | 0 .../src/main/java/org/egov/processor/web/models/Target.java | 0 .../web/models/boundary/BoundarySearchResponse.java | 0 .../processor/web/models/boundary/EnrichedBoundary.java | 0 .../processor/web/models/boundary/HierarchyRelation.java | 0 .../web/models/campaignManager/AdditionalDetails.java | 0 .../egov/processor/web/models/campaignManager/Boundary.java | 0 .../egov/processor/web/models/campaignManager/Campaign.java | 0 .../web/models/campaignManager/CampaignCondition.java | 0 .../web/models/campaignManager/CampaignDetails.java | 0 .../web/models/campaignManager/CampaignRequest.java | 0 .../web/models/campaignManager/CampaignResources.java | 0 .../web/models/campaignManager/CampaignResponse.java | 0 .../web/models/campaignManager/CampaignSearchRequest.java | 0 .../web/models/campaignManager/CycleConfigureDate.java | 0 .../processor/web/models/campaignManager/CycleData.java | 0 .../processor/web/models/campaignManager/DeliveryRule.java | 0 .../egov/processor/web/models/campaignManager/Product.java | 0 .../java/org/egov/processor/web/models/census/Census.java | 0 .../org/egov/processor/web/models/census/CensusRequest.java | 0 .../egov/processor/web/models/census/CensusResponse.java | 0 .../processor/web/models/census/CensusSearchCriteria.java | 0 .../processor/web/models/census/CensusSearchRequest.java | 0 .../web/models/census/PopulationByDemographic.java | 0 .../src/main/resources/application.properties | 4 ++-- .../src/main/resources/db/Dockerfile | 0 .../src/main/resources/db/migrate.sh | 0 72 files changed, 7 insertions(+), 7 deletions(-) rename health-services/{resource-estimation-service => resource-generator}/CHANGELOG.md (94%) rename health-services/{resource-estimation-service => resource-generator}/LOCALSETUP.md (100%) rename health-services/{resource-estimation-service => resource-generator}/README.md (100%) rename health-services/{resource-estimation-service => resource-generator}/pom.xml (99%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/Main.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/config/Configuration.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/config/MainConfiguration.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/config/ServiceConstants.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/kafka/PlanConsumer.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/kafka/Producer.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/repository/ServiceRequestRepository.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/ExcelParser.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/FileParser.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/GeoJsonParser.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/ResourceEstimationService.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/ShapeFileParser.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/BoundaryUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/CalculationUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/CensusUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/FilestoreUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/LocaleUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/MdmsUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/ParsingUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/PlanUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/controllers/FileController.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Activity.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Assumption.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Condition.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/File.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Locale.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/LocaleResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/MetricDetail.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Operation.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Plan.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfiguration.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchCriteria.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Resource.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/ResourceMapping.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Source.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Target.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/boundary/EnrichedBoundary.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/boundary/HierarchyRelation.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/AdditionalDetails.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/Boundary.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignCondition.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignDetails.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResources.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignSearchRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CycleData.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/DeliveryRule.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/Product.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/census/Census.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/census/CensusRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/census/CensusResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/resources/application.properties (97%) rename health-services/{resource-estimation-service => resource-generator}/src/main/resources/db/Dockerfile (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/resources/db/migrate.sh (100%) diff --git a/build/build-config.yml b/build/build-config.yml index dec24965782..8f8747b5cc5 100644 --- a/build/build-config.yml +++ b/build/build-config.yml @@ -250,10 +250,10 @@ config: dockerfile: "build/17/maven/Dockerfile" - work-dir: "health-services/plan-service/src/main/resources/db" image-name: "plan-service-db" - - name: "builds/health-campaign-services/health-services/resource-estimation-service" + - name: "builds/health-campaign-services/health-services/resource-generator" build: - - work-dir: "health-services/resource-estimation-service" - image-name: "resource-estimation-service" + - work-dir: "health-services/resource-generator" + image-name: "resource-generator" dockerfile: "build/17/maven/Dockerfile" - name: "builds/health-campaign-services/analytics/auth-proxy" build: diff --git a/health-services/resource-estimation-service/CHANGELOG.md b/health-services/resource-generator/CHANGELOG.md similarity index 94% rename from health-services/resource-estimation-service/CHANGELOG.md rename to health-services/resource-generator/CHANGELOG.md index e5ce4491284..34e3f67acf0 100644 --- a/health-services/resource-estimation-service/CHANGELOG.md +++ b/health-services/resource-generator/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog ## 1.0.0 - 2024-06-24 -#### Base Resource Estimation Service +#### Base Resource Generator Service 1. Resource Estimation Service manages file processing: validating data, calculating for files, updating plans, and integrating with campaigns. 2. File Processing: In file processing, it processes files present in plan configuration by calculating resources. 3. Updating Plan: It creates plans based on rows and updates those by putting them on topics that are consumed by the plan service. diff --git a/health-services/resource-estimation-service/LOCALSETUP.md b/health-services/resource-generator/LOCALSETUP.md similarity index 100% rename from health-services/resource-estimation-service/LOCALSETUP.md rename to health-services/resource-generator/LOCALSETUP.md diff --git a/health-services/resource-estimation-service/README.md b/health-services/resource-generator/README.md similarity index 100% rename from health-services/resource-estimation-service/README.md rename to health-services/resource-generator/README.md diff --git a/health-services/resource-estimation-service/pom.xml b/health-services/resource-generator/pom.xml similarity index 99% rename from health-services/resource-estimation-service/pom.xml rename to health-services/resource-generator/pom.xml index c73dd06629d..cef77c92838 100644 --- a/health-services/resource-estimation-service/pom.xml +++ b/health-services/resource-generator/pom.xml @@ -1,7 +1,7 @@ 4.0.0 org.egov - resource-estimation-service + resource-generator jar file-processor-utility 1.0.0 diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/Main.java b/health-services/resource-generator/src/main/java/org/egov/processor/Main.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/Main.java rename to health-services/resource-generator/src/main/java/org/egov/processor/Main.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java b/health-services/resource-generator/src/main/java/org/egov/processor/config/Configuration.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/config/Configuration.java rename to health-services/resource-generator/src/main/java/org/egov/processor/config/Configuration.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/MainConfiguration.java b/health-services/resource-generator/src/main/java/org/egov/processor/config/MainConfiguration.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/config/MainConfiguration.java rename to health-services/resource-generator/src/main/java/org/egov/processor/config/MainConfiguration.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java b/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java rename to health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/PlanConsumer.java rename to health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/Producer.java b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/Producer.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/kafka/Producer.java rename to health-services/resource-generator/src/main/java/org/egov/processor/kafka/Producer.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/repository/ServiceRequestRepository.java b/health-services/resource-generator/src/main/java/org/egov/processor/repository/ServiceRequestRepository.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/repository/ServiceRequestRepository.java rename to health-services/resource-generator/src/main/java/org/egov/processor/repository/ServiceRequestRepository.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ExcelParser.java rename to health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/FileParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/FileParser.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/service/FileParser.java rename to health-services/resource-generator/src/main/java/org/egov/processor/service/FileParser.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/GeoJsonParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/GeoJsonParser.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/service/GeoJsonParser.java rename to health-services/resource-generator/src/main/java/org/egov/processor/service/GeoJsonParser.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ResourceEstimationService.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ResourceEstimationService.java rename to health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ShapeFileParser.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ShapeFileParser.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/service/ShapeFileParser.java rename to health-services/resource-generator/src/main/java/org/egov/processor/service/ShapeFileParser.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/BoundaryUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/BoundaryUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/BoundaryUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/BoundaryUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CalculationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CalculationUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CensusUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CensusUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/FilestoreUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/FilestoreUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/FilestoreUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/FilestoreUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/LocaleUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/LocaleUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/LocaleUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/LocaleUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/MdmsUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/MdmsUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/ParsingUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/util/PlanUtil.java rename to health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/controllers/FileController.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/controllers/FileController.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/controllers/FileController.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/controllers/FileController.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Activity.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Activity.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Activity.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Assumption.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Assumption.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Condition.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Condition.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Condition.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Condition.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/File.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/File.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/File.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Locale.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Locale.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Locale.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Locale.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/LocaleResponse.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/LocaleResponse.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/LocaleResponse.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/LocaleResponse.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/MetricDetail.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/MetricDetail.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Operation.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Plan.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Plan.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Plan.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfiguration.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfiguration.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfiguration.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfiguration.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationRequest.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationRequest.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationRequest.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationResponse.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationResponse.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationResponse.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationResponse.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchCriteria.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchCriteria.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchCriteria.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchCriteria.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchRequest.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchRequest.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchRequest.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanRequest.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/PlanRequest.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/PlanRequest.java diff --git a/health-services/resource-estimation-service/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 similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Resource.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Resource.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/ResourceMapping.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/ResourceMapping.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/ResourceMapping.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/ResourceMapping.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Source.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Source.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Source.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Source.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Target.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Target.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Target.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/Target.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/EnrichedBoundary.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/boundary/EnrichedBoundary.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/EnrichedBoundary.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/boundary/EnrichedBoundary.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/HierarchyRelation.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/boundary/HierarchyRelation.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/HierarchyRelation.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/boundary/HierarchyRelation.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/AdditionalDetails.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/AdditionalDetails.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/AdditionalDetails.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/AdditionalDetails.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/Boundary.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Boundary.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/Boundary.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Boundary.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignCondition.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignCondition.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignCondition.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignCondition.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignDetails.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignDetails.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignDetails.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignDetails.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignRequest.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignRequest.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignRequest.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResources.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResources.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResources.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResources.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResponse.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResponse.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResponse.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResponse.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignSearchRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignSearchRequest.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CampaignSearchRequest.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CampaignSearchRequest.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CycleData.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CycleData.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CycleData.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/CycleData.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/DeliveryRule.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/DeliveryRule.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/DeliveryRule.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/DeliveryRule.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/Product.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Product.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/Product.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Product.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/Census.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusRequest.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusRequest.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusRequest.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusResponse.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusResponse.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusResponse.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java diff --git a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java similarity index 100% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java rename to health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java diff --git a/health-services/resource-estimation-service/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties similarity index 97% rename from health-services/resource-estimation-service/src/main/resources/application.properties rename to health-services/resource-generator/src/main/resources/application.properties index 0966208ba05..e8cfcd28ab0 100644 --- a/health-services/resource-estimation-service/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -1,5 +1,5 @@ -server.contextPath=/resource-estimation-service -server.servlet.context-path=/resource-estimation-service +server.contextPath=/resource-generator +server.servlet.context-path=/resource-generator server.port=8083 app.timezone=UTC diff --git a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile b/health-services/resource-generator/src/main/resources/db/Dockerfile similarity index 100% rename from health-services/resource-estimation-service/src/main/resources/db/Dockerfile rename to health-services/resource-generator/src/main/resources/db/Dockerfile diff --git a/health-services/resource-estimation-service/src/main/resources/db/migrate.sh b/health-services/resource-generator/src/main/resources/db/migrate.sh similarity index 100% rename from health-services/resource-estimation-service/src/main/resources/db/migrate.sh rename to health-services/resource-generator/src/main/resources/db/migrate.sh From e9161120a7e6922fe3eafbc2e1ce78a9fe5f09d3 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 25 Oct 2024 12:13:06 +0530 Subject: [PATCH 257/351] HCMPRE-1078 enrichment of resource mapping --- health-services/resource-generator/pom.xml | 6 ++ .../egov/processor/config/Configuration.java | 10 +++ .../processor/config/ServiceConstants.java | 16 +++- .../egov/processor/service/ExcelParser.java | 49 ++++++------ .../egov/processor/util/EnrichmentUtil.java | 71 +++++++++++++++++ .../org/egov/processor/util/LocaleUtil.java | 18 +++-- .../org/egov/processor/util/MdmsV2Util.java | 79 +++++++++++++++++++ .../org/egov/processor/util/ParsingUtil.java | 37 +++++++++ .../processor/web/models/mdmsV2/Mdms.java | 55 +++++++++++++ .../web/models/mdmsV2/MdmsCriteriaReqV2.java | 26 ++++++ .../web/models/mdmsV2/MdmsCriteriaV2.java | 62 +++++++++++++++ .../web/models/mdmsV2/MdmsResponseV2.java | 28 +++++++ .../src/main/resources/application.properties | 7 +- 13 files changed, 430 insertions(+), 34 deletions(-) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsV2Util.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/Mdms.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaReqV2.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaV2.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsResponseV2.java diff --git a/health-services/resource-generator/pom.xml b/health-services/resource-generator/pom.xml index cef77c92838..33ac3c4c7d6 100644 --- a/health-services/resource-generator/pom.xml +++ b/health-services/resource-generator/pom.xml @@ -98,6 +98,12 @@ tracer 2.9.0-SNAPSHOT + + org.egov.services + services-common + 2.9.0-SNAPSHOT + compile + org.egov mdms-client 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 203d955afb4..d3b104d04e8 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 @@ -27,6 +27,9 @@ public class Configuration { @Value("${egov.mdms.search.endpoint}") private String mdmsEndPoint; + @Value("${egov.mdms.search.v2.endpoint}") + private String mdmsV2EndPoint; + @Value("${egov.plan.config.host}") private String planConfigHost; @@ -88,4 +91,11 @@ public class Configuration { @Value("${resource.census.create.topic}") private String resourceCensusCreateTopic; + //Default + @Value("${resource.default.offset}") + private Integer defaultOffset; + + @Value("${resource.default.limit}") + private Integer defaultLimit; + } 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 98a8e79c77d..748fc8b28fd 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 @@ -26,8 +26,6 @@ public class ServiceConstants { public static final String MICROPLANNING_MODULE = "microplan"; - public static final String PROPERTIES = "properties"; - public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE = "NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT"; public static final String NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE = "Invalid or incorrect TenantId. No mdms data found for provided Tenant."; @@ -53,7 +51,19 @@ public class ServiceConstants { public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; public static final String MDMS_MASTER_SCHEMAS = "Schemas"; public static final String MDMS_CAMPAIGN_TYPE = "campaignType"; - + public static final String MDMS_SCHEMA_ADMIN_SCHEMA = "adminSchema"; + public static final String MDMS_ADMIN_CONSOLE_MODULE_NAME = "HCM-ADMIN-CONSOLE"; + public static final String BOUNDARY = "boundary"; + public static final String DOT_SEPARATOR = "."; + public static final String MICROPLAN_PREFIX = "MP-"; + + //MDMS field Constants + public static final String DATA = "data"; + public static final String PROPERTIES = "properties"; + public static final String NUMBER_PROPERTIES = "numberProperties"; + public static final String STRING_PROPERTIES = "stringProperties"; + public static final String NAME = "name"; + public static final String ERROR_WHILE_UPDATING_PLAN_CONFIG = "Exception occurred while updating plan configuration."; public static final String VALIDATE_STRING_REGX = "^(?!\\d+$).+$"; 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 ff518f2708e..668e3ca4cb5 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 @@ -69,9 +69,11 @@ public class ExcelParser implements FileParser { private CensusUtil censusUtil; + private EnrichmentUtil enrichmentUtil; + public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, FilestoreUtil filestoreUtil, CalculationUtil calculationUtil, PlanUtil planUtil, CampaignIntegrationUtil campaignIntegrationUtil, - Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil) { + Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil, EnrichmentUtil enrichmentUtil) { this.objectMapper = objectMapper; this.parsingUtil = parsingUtil; this.filestoreUtil = filestoreUtil; @@ -83,6 +85,7 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore this.boundaryUtil = boundaryUtil; this.localeUtil = localeUtil; this.censusUtil = censusUtil; + this.enrichmentUtil = enrichmentUtil; } /** @@ -129,7 +132,7 @@ private String processExcelFile(PlanConfigurationRequest planConfigurationReques List campaignBoundaryList = new ArrayList<>(); List campaignResourcesList = new ArrayList<>(); DataFormatter dataFormatter = new DataFormatter(); - processSheets(planConfigurationRequest, fileStoreId, campaignResponse, planConfig, workbook, + processSheets(planConfigurationRequest, fileStoreId, campaignResponse, workbook, campaignBoundaryList, dataFormatter); return uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse, planConfig, workbook, campaignBoundaryList, campaignResourcesList); @@ -188,34 +191,36 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi * Processes each sheet in the workbook for plan configuration data. * Validates column names, processes rows, and integrates campaign details. * - * @param planConfigurationRequest The request containing configuration details including tenant ID. + * @param request The request containing configuration details including tenant ID. * @param fileStoreId The ID of the uploaded file in the file store. * @param campaignResponse The response object containing campaign details. - * @param planConfig The configuration details specific to the plan. * @param excelWorkbook The workbook containing sheets to be processed. * @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 planConfigurationRequest, String fileStoreId, - Object campaignResponse, PlanConfiguration planConfig, Workbook excelWorkbook, + private void processSheets(PlanConfigurationRequest request, String fileStoreId, + Object campaignResponse, Workbook excelWorkbook, List campaignBoundaryList, DataFormatter dataFormatter) { - LocaleResponse localeResponse = localeUtil.searchLocale(planConfigurationRequest); CampaignResponse campaign = parseCampaignResponse(campaignResponse); + LocaleResponse localeResponse = localeUtil.searchLocale(request); + Object mdmsData = mdmsUtil. fetchMdmsData(request.getRequestInfo(), + request.getPlanConfiguration().getTenantId()); + enrichmentUtil.enrichResourceMapping(request, localeResponse, campaign.getCampaign().get(0).getProjectType(), fileStoreId); + Map attributeNameVsDataTypeMap = prepareAttributeVsIndexMap(request, + fileStoreId, campaign, request.getPlanConfiguration(), mdmsData); - Map attributeNameVsDataTypeMap = prepareAttributeVsIndexMap(planConfigurationRequest, - fileStoreId, campaign, planConfig); - List boundaryCodeList = getBoundaryCodeList(planConfigurationRequest, campaign, planConfig); + List boundaryCodeList = getBoundaryCodeList(request, campaign); excelWorkbook.forEach(excelWorkbookSheet -> { - if (isSheetAllowedToProcess(planConfigurationRequest, excelWorkbookSheet.getSheetName(), localeResponse)) { + if (isSheetAllowedToProcess(request, excelWorkbookSheet.getSheetName(), localeResponse)) { - if (planConfig.getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { - processRows(planConfigurationRequest, excelWorkbookSheet, dataFormatter, fileStoreId, + if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { + processRows(request, excelWorkbookSheet, dataFormatter, fileStoreId, campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); - } else if (planConfig.getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { - processRowsForCensusRecords(planConfigurationRequest, excelWorkbookSheet, + } else if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { + processRowsForCensusRecords(request, excelWorkbookSheet, fileStoreId, attributeNameVsDataTypeMap, boundaryCodeList, campaign.getCampaign().get(0).getHierarchyType()); } } @@ -279,12 +284,11 @@ private void processRowsForCensusRecords(PlanConfigurationRequest planConfigurat * * @param planConfigurationRequest The request containing configuration details including tenant ID. * @param campaign The campaign response object containing campaign details. - * @param planConfig The configuration details specific to the plan. * @return A list of boundary codes corresponding to the specified hierarchy type and tenant ID. */ private List getBoundaryCodeList(PlanConfigurationRequest planConfigurationRequest, - CampaignResponse campaign, PlanConfiguration planConfig) { - BoundarySearchResponse boundarySearchResponse = boundaryUtil.search(planConfig.getTenantId(), + CampaignResponse campaign) { + BoundarySearchResponse boundarySearchResponse = boundaryUtil.search(planConfigurationRequest.getPlanConfiguration().getTenantId(), campaign.getCampaign().get(0).getHierarchyType(), planConfigurationRequest); List boundaryList = new ArrayList<>(); List boundaryCodeList = getAllBoundaryPresentforHierarchyType( @@ -304,14 +308,11 @@ private List getBoundaryCodeList(PlanConfigurationRequest planConfigurat //TODO: fetch from adminSchema master private Map prepareAttributeVsIndexMap(PlanConfigurationRequest planConfigurationRequest, - String fileStoreId, CampaignResponse campaign, PlanConfiguration planConfig) { - Object mdmsData = mdmsUtil.fetchMdmsData(planConfigurationRequest.getRequestInfo(), - planConfigurationRequest.getPlanConfiguration().getTenantId()); + String fileStoreId, CampaignResponse campaign, PlanConfiguration planConfig, Object mdmsData) { org.egov.processor.web.models.File file = planConfig.getFiles().stream() .filter(f -> f.getFilestoreId().equalsIgnoreCase(fileStoreId)).findFirst().get(); - Map attributeNameVsDataTypeMap = mdmsUtil.filterMasterData(mdmsData.toString(), file.getInputFileType(), - file.getTemplateIdentifier(), campaign.getCampaign().get(0).getProjectType()); - return attributeNameVsDataTypeMap; + return mdmsUtil.filterMasterData(mdmsData.toString(), file.getInputFileType(), + file.getTemplateIdentifier(), campaign.getCampaign().get(0).getProjectType()); } 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 new file mode 100644 index 00000000000..5ae922fbe01 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java @@ -0,0 +1,71 @@ +package org.egov.processor.util; + +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.utils.MultiStateInstanceUtil; +import org.egov.common.utils.UUIDEnrichmentUtil; +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.mdmsV2.Mdms; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +import static org.egov.processor.config.ServiceConstants.*; + +@Component +@Slf4j +public class EnrichmentUtil { + + private MdmsV2Util mdmsV2Util; + + private LocaleUtil localeUtil; + + private ParsingUtil parsingUtil; + +// private MultiStateInstanceUtil centralInstanceUtil; + + public EnrichmentUtil(MdmsV2Util mdmsV2Util, LocaleUtil localeUtil, ParsingUtil parsingUtil) { + this.mdmsV2Util = mdmsV2Util; + this.localeUtil = localeUtil; +// this.centralInstanceUtil = centralInstanceUtil; + this.parsingUtil = parsingUtil; + } + + /** + * Enriches the `PlanConfiguration` with resource mappings based on MDMS data and locale messages. + * + * @param request The request containing the configuration to enrich. + * @param localeResponse The response containing locale messages. + * @param campaignType The campaign type identifier. + * @param fileStoreId The associated file store ID. + */ + public void enrichResourceMapping(PlanConfigurationRequest request, LocaleResponse localeResponse, String campaignType, String fileStoreId) + { +// String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanConfiguration().getTenantId()); + String rootTenantId = request.getPlanConfiguration().getTenantId().split("\\.")[0]; + String uniqueIndentifier = BOUNDARY + DOT_SEPARATOR + MICROPLAN_PREFIX + campaignType; + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_ADMIN_SCHEMA, uniqueIndentifier); + List columnNameList = parsingUtil.extractPropertyNamesFromAdminSchema(mdmsV2Data.get(0).getData()); + + List resourceMappingList = new ArrayList<>(); + for(String columnName : columnNameList) { + ResourceMapping resourceMapping = ResourceMapping + .builder() + .filestoreId(fileStoreId) + .mappedTo(columnName) + .active(Boolean.TRUE) + .mappedFrom(localeUtil.localeSearch(localeResponse.getMessages(), columnName)) + .build(); + UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); + resourceMappingList.add(resourceMapping); + } + + //enrich plan configuration with enriched resource mapping list + request.getPlanConfiguration().setResourceMapping(resourceMappingList); + + } + +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/LocaleUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/LocaleUtil.java index 1ecb725308f..12fefec0405 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/LocaleUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/LocaleUtil.java @@ -5,12 +5,9 @@ import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; import org.egov.processor.repository.ServiceRequestRepository; +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.boundary.BoundarySearchResponse; -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.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -71,10 +68,19 @@ public LocaleResponse searchLocale(PlanConfigurationRequest planConfigurationReq log.info("Locale Search successful."); return localeResponse; } catch (Exception e) { - log.error(ServiceConstants.ERROR_WHILE_SEARCHING_LOCALE + localeToUse + " and tenantId" + tenantId, e); + log.error(ServiceConstants.ERROR_WHILE_SEARCHING_LOCALE + localeToUse + " and tenantId " + tenantId, e); throw new CustomException( - ServiceConstants.ERROR_WHILE_SEARCHING_LOCALE + localeToUse + " and tenantId" + tenantId, + ServiceConstants.ERROR_WHILE_SEARCHING_LOCALE + localeToUse + " and tenantId " + tenantId, e.toString()); } } + + public String localeSearch(List localeMessages, String code) { + for (Locale locale : localeMessages) { + if (locale.getCode().equalsIgnoreCase(code)) { + return locale.getMessage(); // Return the message if code matches + } + } + return null; + } } 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 new file mode 100644 index 00000000000..85b87872658 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsV2Util.java @@ -0,0 +1,79 @@ +package org.egov.processor.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.processor.config.Configuration; +import org.egov.processor.web.models.mdmsV2.Mdms; +import org.egov.processor.web.models.mdmsV2.MdmsCriteriaReqV2; +import org.egov.processor.web.models.mdmsV2.MdmsCriteriaV2; +import org.egov.processor.web.models.mdmsV2.MdmsResponseV2; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; +import java.util.List; + +import static org.egov.processor.config.ServiceConstants.*; + +@Slf4j +@Component +public class MdmsV2Util { + + private RestTemplate restTemplate; + + private ObjectMapper objectMapper; + + private Configuration config; + + public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configuration config) + { + this.restTemplate = restTemplate; + this.objectMapper = objectMapper; + this.config = config; + } + + public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode, String uniqueIdentifier) + { + StringBuilder uri = getMdmsV2Uri(); + MdmsCriteriaReqV2 mdmsCriteriaReqV2 = getMdmsV2Request(requestInfo, tenantId, schemaCode, uniqueIdentifier); + MdmsResponseV2 mdmsResponseV2 = null; + try { + mdmsResponseV2 = restTemplate.postForObject(uri.toString(), mdmsCriteriaReqV2, MdmsResponseV2.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_MDMS, e); + } + + if(ObjectUtils.isEmpty(mdmsResponseV2.getMdms())) + { + log.error(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE + " - " + tenantId); + throw new CustomException(NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_CODE, NO_MDMS_DATA_FOUND_FOR_GIVEN_TENANT_MESSAGE); + } + + return mdmsResponseV2.getMdms(); + } + + private StringBuilder getMdmsV2Uri() + { + StringBuilder uri = new StringBuilder(); + return uri.append(config.getMdmsHost()).append(config.getMdmsV2EndPoint()); + } + + private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode, String uniqueIdentifier) + { + MdmsCriteriaV2 mdmsCriteriaV2 = MdmsCriteriaV2.builder() + .tenantId(tenantId) + .schemaCode(schemaCode) + .uniqueIdentifiers(Collections.singletonList(uniqueIdentifier)) + .limit(config.getDefaultLimit()) + .offset(config.getDefaultOffset()).build(); + + return MdmsCriteriaReqV2.builder() + .requestInfo(requestInfo) + .mdmsCriteriaV2(mdmsCriteriaV2).build(); + } + +} 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 c644e2f6743..96eed325956 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 @@ -276,4 +276,41 @@ public File extractShapeFilesFromZip(PlanConfiguration planConfig, String fileSt return shpFile; } + /** + * Extracts the names of properties defined within the "numberProperties" and "stringProperties" arrays from admin schema + * + * @param rootNode The root JSON node from which to extract property names. + * @return A list of property names found in "numberProperties" and "stringProperties". + */ + public List extractPropertyNamesFromAdminSchema(JsonNode rootNode) { + List names = new ArrayList<>(); + + // Access the "properties" node directly from the root node + JsonNode propertiesNode = rootNode.path("properties"); + + // Extract names from "numberProperties" + JsonNode numberProperties = propertiesNode.path("numberProperties"); + if (numberProperties.isArray()) { + for (JsonNode property : numberProperties) { + String name = property.path("name").asText(null); + if (name != null) { + names.add(name); + } + } + } + + // Extract names from "stringProperties" + JsonNode stringProperties = propertiesNode.path("stringProperties"); + if (stringProperties.isArray()) { + for (JsonNode property : stringProperties) { + String name = property.path("name").asText(null); + if (name != null) { + names.add(name); + } + } + } + + return names; + } + } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/Mdms.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/Mdms.java new file mode 100644 index 00000000000..b591caf0929 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/Mdms.java @@ -0,0 +1,55 @@ +package org.egov.processor.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * Mdms + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Mdms { + + @JsonProperty("id") + @Size(min = 2, max = 64) + private String id; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 128) + private String tenantId = null; + + @JsonProperty("schemaCode") + @NotNull + @Size(min = 2, max = 128) + private String schemaCode = null; + + @JsonProperty("uniqueIdentifier") + @Size(min = 2, max = 128) + private String uniqueIdentifier = null; + + @JsonProperty("data") + @NotNull + private JsonNode data = null; + + @JsonProperty("isActive") + private Boolean isActive = true; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails = null; + +} \ No newline at end of file diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaReqV2.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaReqV2.java new file mode 100644 index 00000000000..65c7123d5ca --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaReqV2.java @@ -0,0 +1,26 @@ +package org.egov.processor.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; + +import javax.validation.Valid; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class MdmsCriteriaReqV2 { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo; + + @JsonProperty("MdmsCriteria") + @Valid + private MdmsCriteriaV2 mdmsCriteriaV2; +} \ No newline at end of file diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaV2.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaV2.java new file mode 100644 index 00000000000..c7832894ebc --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaV2.java @@ -0,0 +1,62 @@ +package org.egov.processor.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +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 javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Data +@Validated +@AllArgsConstructor +@NoArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class MdmsCriteriaV2 { + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + @NotNull + private String tenantId; + + @JsonProperty("ids") + private Set ids; + + @JsonProperty("uniqueIdentifier") + @Size(min = 1, max = 64) + private String uniqueIdentifier; + + @JsonProperty("uniqueIdentifiers") + private List uniqueIdentifiers; + + @JsonProperty("schemaCode") + private String schemaCode; + + @JsonProperty("filters") + private Map filterMap; + + @JsonProperty("isActive") + private Boolean isActive; + + @JsonIgnore + private Map schemaCodeFilterMap; + + @JsonIgnore + private Set uniqueIdentifiersForRefVerification; + + @JsonProperty("offset") + private Integer offset; + + @JsonProperty("limit") + private Integer limit; + +} \ No newline at end of file diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsResponseV2.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsResponseV2.java new file mode 100644 index 00000000000..2b570e66f08 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsResponseV2.java @@ -0,0 +1,28 @@ +package org.egov.processor.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; + +import javax.validation.Valid; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) + +public class MdmsResponseV2 { + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("mdms") + @Valid + private List mdms = null; +} \ No newline at end of file diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index e8cfcd28ab0..7211b3c8bf3 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -47,6 +47,7 @@ kafka.producer.config.buffer_memory_config=33554432 #mdms urls egov.mdms.host=https://unified-dev.digit.org egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +egov.mdms.search.v2.endpoint=/mdms-v2/v2/_search #plan config egov.plan.config.host=https://unified-dev.digit.org @@ -87,4 +88,8 @@ egov.locale.search.endpoint=/localization/messages/v1/_search?module={module}&lo #trigger statuses plan.config.trigger.plan.estimates.status=RESOURCE_ESTIMATION_IN_PROGRESS -plan.config.trigger.census.records.status=EXECUTION_TO_BE_DONE \ No newline at end of file +plan.config.trigger.census.records.status=EXECUTION_TO_BE_DONE + +# Pagination config +resource.default.offset=0 +resource.default.limit=10 \ No newline at end of file From d87cf048200e7ebd312c8994d2d12189bcce0144 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 30 Oct 2024 12:25:51 +0530 Subject: [PATCH 258/351] HCMPRE-1122 changing processing logic --- .../egov/processor/util/CalculationUtil.java | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java index d6b53891a8b..67e5e190fb7 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java @@ -92,7 +92,7 @@ public void calculateResources(JsonNode jsonNode, PlanConfigurationRequest planC * @param columnName The input from mapping. * @return The input value. */ - public BigDecimal getInputValueFromJsonFeature(Map resultMap, JsonNode feature, String input, String columnName) { + public BigDecimal getInputValueFromJsonFeature(JsonNode feature, Map resultMap, String input, String columnName) { if (resultMap.containsKey(input)) { return resultMap.get(input); } else { @@ -117,6 +117,33 @@ public BigDecimal getInputValueFromJsonFeature(Map resultMap } } + private BigDecimal getInputValueFromFeatureOrMap(JsonNode feature, Map resultMap, Map assumptionValueMap, String key, String columnName) { + // Try to fetch the value from resultMap + if (resultMap.containsKey(key)) { + return resultMap.get(key); + } + // Try to fetch the value from the feature (if it exists) + if (feature.has(PROPERTIES) && feature.get(PROPERTIES).has(columnName)) { + try { + String cellValue = String.valueOf(feature.get(PROPERTIES).get(columnName)); + BigDecimal value; + if (cellValue.contains(ServiceConstants.SCIENTIFIC_NOTATION_INDICATOR)) { + value = new BigDecimal(cellValue); + } else { + String cleanedValue = cellValue.replaceAll("[^\\d.\\-E]", ""); + value = new BigDecimal(cleanedValue); + } + return value; + } catch (NumberFormatException | NullPointerException e) { + // Handle potential parsing issues + return BigDecimal.ZERO; + } + } + + // If not found in the resultMap, use the assumptionValueMap as a fallback + return assumptionValueMap.getOrDefault(key, BigDecimal.ZERO); + } + /** * Calculates a result based on the provided operation and inputs. * @@ -127,12 +154,18 @@ public BigDecimal getInputValueFromJsonFeature(Map resultMap * @param resultMap A map to store and update the calculated results. * @return The calculated result as a BigDecimal. */ - public BigDecimal calculateResult(Operation operation, JsonNode feature, Map mappedValues, Map assumptionValueMap, Map resultMap) - { + public BigDecimal calculateResult(Operation operation, JsonNode feature, Map mappedValues, Map assumptionValueMap, Map resultMap) { + // Fetch the input value String input = operation.getInput(); String inputFromMapping = mappedValues.get(input); - BigDecimal inputValue = getInputValueFromJsonFeature(resultMap, feature, operation.getInput(), inputFromMapping); - BigDecimal assumptionValue = assumptionValueMap.get(operation.getAssumptionValue()); + BigDecimal inputValue = getInputValueFromJsonFeature(feature, resultMap, input, inputFromMapping); + + // Fetch the assumption value with priority: feature -> resultMap -> assumptionValueMap + String assumptionKey = operation.getAssumptionValue(); + String assumptionFromMapping = mappedValues.get(assumptionKey); + BigDecimal assumptionValue = getInputValueFromFeatureOrMap(feature, resultMap, assumptionValueMap, assumptionKey, assumptionFromMapping); + + // Calculate and return the output return calculateOutputValue(inputValue, operation.getOperator(), assumptionValue); } From bc9c88cc6dbd8ad567a818d519868d246f64ce5b Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 30 Oct 2024 13:38:02 +0530 Subject: [PATCH 259/351] HCMPRE-1122 changing processing logic --- .../egov/processor/util/CalculationUtil.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java index 67e5e190fb7..95c504445fa 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java @@ -16,6 +16,7 @@ import org.egov.processor.web.models.PlanConfigurationRequest; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; import static org.egov.processor.config.ServiceConstants.PROPERTIES; @@ -117,31 +118,30 @@ public BigDecimal getInputValueFromJsonFeature(JsonNode feature, Map resultMap, Map assumptionValueMap, String key, String columnName) { - // Try to fetch the value from resultMap - if (resultMap.containsKey(key)) { - return resultMap.get(key); - } + private BigDecimal getInputValueFromFeatureOrMap(JsonNode feature, Map resultMap, Map assumptionValueMap, String assumptionKey, String columnName) { + // Try to fetch the value from resultMap, If not found in the resultMap, use the assumptionValueMap as a fallback + BigDecimal assumptionValue = resultMap.getOrDefault(assumptionKey, assumptionValueMap.get(assumptionKey)); + // Try to fetch the value from the feature (if it exists) - if (feature.has(PROPERTIES) && feature.get(PROPERTIES).has(columnName)) { - try { - String cellValue = String.valueOf(feature.get(PROPERTIES).get(columnName)); - BigDecimal value; - if (cellValue.contains(ServiceConstants.SCIENTIFIC_NOTATION_INDICATOR)) { - value = new BigDecimal(cellValue); - } else { - String cleanedValue = cellValue.replaceAll("[^\\d.\\-E]", ""); - value = new BigDecimal(cleanedValue); - } - return value; - } catch (NumberFormatException | NullPointerException e) { - // Handle potential parsing issues - return BigDecimal.ZERO; + if(ObjectUtils.isEmpty(assumptionValue)) { + if (feature.has(PROPERTIES) && feature.get(PROPERTIES).has(columnName)) { + try { + String cellValue = String.valueOf(feature.get(PROPERTIES).get(columnName)); + BigDecimal value; + if (cellValue.contains(ServiceConstants.SCIENTIFIC_NOTATION_INDICATOR)) { + value = new BigDecimal(cellValue); + } else { + String cleanedValue = cellValue.replaceAll("[^\\d.\\-E]", ""); + value = new BigDecimal(cleanedValue); + } + return value; + } catch (NumberFormatException | NullPointerException e) { + // Handle potential parsing issues + throw new CustomException("INPUT_VALUE_NOT_FOUND", "Input value not found: " + assumptionKey); } } } - // If not found in the resultMap, use the assumptionValueMap as a fallback - return assumptionValueMap.getOrDefault(key, BigDecimal.ZERO); + return assumptionValue; } /** From b175339f239a66e19c24876a6ff930c151efa77f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 30 Oct 2024 16:28:17 +0530 Subject: [PATCH 260/351] HCMPRE-1122 updating operation related validations --- .../java/digit/config/ServiceConstants.java | 36 +-- .../validator/PlanConfigurationValidator.java | 277 ++++++++---------- .../src/main/java/digit/util/MdmsV2Util.java | 9 +- 3 files changed, 145 insertions(+), 177 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 466cdd23bbb..ff1a26eba2d 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -30,10 +30,7 @@ public class ServiceConstants { public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; public static final String ASSUMPTION_VALUE_NOT_FOUND_CODE = "ASSUMPTION_VALUE_NOT_FOUND"; - public static final String ASSUMPTION_VALUE_NOT_FOUND_MESSAGE = "Operation's Assumption value not found in active assumptions list "; - - public static final String FILESTORE_ID_INVALID_CODE = "FILESTORE_ID_INVALID"; - public static final String FILESTORE_ID_INVALID_MESSAGE = " Resource mapping does not have a Valid File Store Id "; + public static final String ASSUMPTION_VALUE_NOT_FOUND_MESSAGE = "Operation's Assumption value is not present in allowed columns, previous outputs, or active Assumption Keys "; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE = "ASSUMPTION_KEY_NOT_FOUND_IN_MDMS"; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS - "; @@ -57,16 +54,7 @@ public class ServiceConstants { public static final String ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE = "Only one file of the required template identifier should be present "; public static final String INPUT_KEY_NOT_FOUND_CODE = "INPUT_KEY_NOT_FOUND"; - public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key not present in MDMS "; - - public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_CODE = "LOCALITY_NOT_PRESENT_IN_MAPPED_TO"; - public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_MESSAGE = "Resource Mapping's MappedTo must contain 'Locality' "; - - public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE = "DUPLICATE_MAPPED_TO_VALIDATION_ERROR"; - public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE = "Duplicate MappedTo found in Resource Mapping"; - - public static final String TENANT_NOT_FOUND_IN_MDMS_CODE = "TENANT_ID_NOT_FOUND_IN_MDMS"; - public static final String TENANT_NOT_FOUND_IN_MDMS_MESSAGE = "Tenant Id is not present in MDMS"; + public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key is not present in allowed columns or previous outputs - "; public static final String TENANT_ID_EMPTY_CODE = "TENANT_ID_EMPTY"; public static final String TENANT_ID_EMPTY_MESSAGE = "Tenant Id cannot be empty, TenantId should be present"; @@ -131,9 +119,6 @@ public class ServiceConstants { public static final String JSONPATH_ERROR_CODE = "JSONPATH_ERROR"; public static final String JSONPATH_ERROR_MESSAGE = "Failed to parse mdms response with given Jsonpath" ; - public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE = "BOUNDARY_CODE_MAPPING_NOT_FOUND"; - public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE = "Boundary Code Mapping is required column is not found."; - public static final String NAME_VALIDATION_LIST_EMPTY_CODE = "NAME_VALIDATION_LIST_EMPTY"; public static final String NAME_VALIDATION_LIST_EMPTY_MESSAGE = "Name Validation list from MDMS is empty"; @@ -167,9 +152,6 @@ public class ServiceConstants { public static final String PLAN_RESOURCES_MANDATORY_CODE = "PLAN_RESOURCES_MANDATORY"; public static final String PLAN_RESOURCES_MANDATORY_MESSAGE = "Resources are mandatory if plan configuration id is not provided"; - public static final String PLAN_RESOURCES_NOT_ALLOWED_CODE = "PLAN_RESOURCES_NOT_ALLOWED"; - public static final String PLAN_RESOURCES_NOT_ALLOWED_MESSAGE = "Resources are not allowed if plan configuration id is provided"; - public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE = "INVALID_RESOURCE_ACTIVITY_LINKAGE"; public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE = "Resource-Activity linkage is invalid"; @@ -200,9 +182,6 @@ public class ServiceConstants { public static final String FILES_NOT_FOUND_CODE = "FILES_NOT_FOUND"; public static final String FILES_NOT_FOUND_MESSAGE = "Files are not present in Plan Configuration."; - public static final String RESOURCE_MAPPING_NOT_FOUND_CODE = "RESOURCE_MAPPING_NOT_FOUND"; - public static final String RESOURCE_MAPPING_NOT_FOUND_MESSAGE = "Resource mapping is not present in Plan Configuration."; - public static final String ASSUMPTIONS_NOT_FOUND_CODE = "ASSUMPTIONS_NOT_FOUND"; public static final String ASSUMPTIONS_NOT_FOUND_MESSAGE = "Assumptions are not present in Plan Configuration."; @@ -222,8 +201,17 @@ public class ServiceConstants { public static final String MDMS_MASTER_SCHEMAS = "Schemas"; public static final String MDMS_MASTER_METRIC = "Metric"; public static final String MDMS_MASTER_UOM = "Uom"; - public static final String MDMS_CODE = "mdms"; public static final String MDMS_MASTER_NAME_VALIDATION= "MicroplanNamingRegex"; + public static final String MDMS_SCHEMA_ADMIN_SCHEMA = "adminSchema"; + public static final String BOUNDARY = "boundary"; + + //MDMS field Constants + public static final String PROPERTIES = "properties"; + public static final String NUMBER_PROPERTIES = "numberProperties"; + public static final String STRING_PROPERTIES = "stringProperties"; + public static final String NAME = "name"; + + public static final String MICROPLAN_PREFIX = "MP-"; public static final String JSON_ROOT_PATH = "$."; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 7cea8dd0461..2da7ca16670 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -1,7 +1,7 @@ package digit.service.validator; +import com.fasterxml.jackson.databind.JsonNode; import com.jayway.jsonpath.JsonPath; -import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; import digit.util.CampaignUtil; import digit.util.MdmsUtil; @@ -16,7 +16,6 @@ import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.egov.common.contract.request.RequestInfo; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -59,26 +58,23 @@ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS, null); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); // Validate that the assumption keys in the request are unique validateAssumptionUniqueness(planConfiguration); - // Validate that the assumption values in the plan configuration are correct - validateAssumptionValue(planConfiguration); - // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); - // Validate that the inputs for operations in the request match those in the MDMS data - validateOperationsInputAgainstMDMS(request, mdmsData); - - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings - validateMappedToUniqueness(planConfiguration.getResourceMapping()); + //Validating operation's input and assumptionValue fields + validateOperations(request, campaignResponse); //Validating plan config name against MDMS data validatePlanConfigName(request, mdmsData); @@ -89,8 +85,6 @@ public void validateCreate(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); - // Validate if campaign id exists against project factory - validateCampaignId(campaignResponse); } /** @@ -141,28 +135,6 @@ public void validatePlanConfigName(PlanConfigurationRequest request, Object mdms * * @param planConfiguration The plan configuration to validate. */ - public void validateAssumptionValue(PlanConfiguration planConfiguration) { - if (isSetupCompleted(planConfiguration)) { - checkForEmptyAssumption(planConfiguration); - checkForEmptyOperation(planConfiguration); - - // Collect all active assumption keys - Set activeAssumptionKeys = planConfiguration.getAssumptions().stream() - .filter(Assumption::getActive) - .map(Assumption::getKey) - .collect(Collectors.toSet()); - - planConfiguration.getOperations().stream() - .filter(Operation::getActive) - .forEach(operation -> { - if (!activeAssumptionKeys.contains(operation.getAssumptionValue())) { - log.error("Assumption Value " + operation.getAssumptionValue() + " is not present in the list of active Assumption Keys"); - throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + operation.getAssumptionValue()); - } - }); - - } - } /** @@ -283,107 +255,6 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque } } - - /** - * Validates the operations input against the Master Data Management System (MDMS) data. - * - * @param request The PlanConfigurationRequest containing the plan configuration and other details. - * @param mdmsData The MDMS data containing the master rule configure inputs. - */ - public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { - PlanConfiguration planConfiguration = request.getPlanConfiguration(); - - if (isSetupCompleted(planConfiguration)) { - checkForEmptyFiles(planConfiguration); - checkForEmptyOperation(planConfiguration); - - List files = planConfiguration.getFiles(); - List templateIds = files.stream() - .map(File::getTemplateIdentifier) - .collect(Collectors.toList()); - List inputFileTypes = files.stream() - .map(File::getInputFileType) - .map(File.InputFileTypeEnum::toString) - .collect(Collectors.toList()); - - final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS; - List ruleInputsListFromMDMS = null; - try { - log.info(jsonPathForRuleInputs); - ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - HashSet ruleInputsSetFromMDMS = new HashSet<>(ruleInputsListFromMDMS); - - HashSet allowedColumns = getColumnsFromSchemaThatAreRuleInputs(ruleInputsSetFromMDMS, templateIds, inputFileTypes); - planConfiguration.getOperations().stream() - .map(Operation::getOutput) - .forEach(allowedColumns::add); - - planConfiguration.getOperations().forEach(operation -> { - if (!allowedColumns.contains(operation.getInput())) { - log.error("Input Value " + operation.getInput() + " is not present in MDMS Input List"); - throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE); - } - }); - - } - } - - /** - * Filters the Schema MDMS data by type and section - * returns the list of columns which have the property 'isRuleConfigureInputs' as true - * - * @param schemas List of schemas from MDMS - * @param templateIds The list of template identifiers from request object - * @param inputFileTypes The list of input file type from request object - */ - public static HashSet getColumnsFromSchemaThatAreRuleInputs(HashSet schemas, List templateIds, List inputFileTypes) { - if (schemas == null) { - return new HashSet<>(); - } - HashSet finalData = new HashSet<>(); - for (Object item : schemas) { - LinkedHashMap schemaEntity = (LinkedHashMap) item; - if (!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) - continue; - LinkedHashMap columns = (LinkedHashMap) ((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); - if (columns == null) return new HashSet<>(); - columns.forEach((key, value) -> { - LinkedHashMap data = value; - if (data.get(MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT)) { - finalData.add(key); - } - }); // Add the keys to finalData - } - return finalData; - } - - - /** - * Validates that the 'mappedTo' values in the list of 'resourceMappings' are unique. - * If a duplicate 'mappedTo' value is found, it logs an error and throws a CustomException. - * - * @param resourceMappings The list of 'ResourceMapping' objects to validate. - * @throws CustomException If a duplicate 'mappedTo' value is found. - */ - public static void validateMappedToUniqueness(List resourceMappings) { - if (!CollectionUtils.isEmpty(resourceMappings)) { - Set uniqueMappedToSet = new HashSet<>(); - resourceMappings.forEach(mapping -> { - String uniqueKey = mapping.getFilestoreId() + "-" + mapping.getMappedTo(); - if (!uniqueMappedToSet.add(uniqueKey)) { - log.error("Duplicate MappedTo " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - throw new CustomException(DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE, DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE + " - " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - } - }); - } - } - - /** * Validates the search request for plan configurations. * @@ -413,33 +284,27 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS, null); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); // Validate the existence of the plan configuration in the request validatePlanConfigExistence(request); + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); // Validate that the assumption keys in the request are unique validateAssumptionUniqueness(planConfiguration); - // Validate that the assumption values in the plan configuration are correct - validateAssumptionValue(planConfiguration); + //Validating operation's input and assumptionValue fields + validateOperations(request, campaignResponse); // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); - // Validate that the inputs for operations in the request match those in the MDMS data - validateOperationsInputAgainstMDMS(request, mdmsData); - - // Validate the dependencies between operations in the plan configuration - validateOperationDependencies(planConfiguration); - - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings - validateMappedToUniqueness(planConfiguration.getResourceMapping()); - //Validating plan config name against MDMS data validatePlanConfigName(request, mdmsData); @@ -449,8 +314,6 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); - // Validate if campaign id exists against project factory - validateCampaignId(campaignResponse); } /** @@ -548,4 +411,118 @@ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { } } + + public void validateOperations(PlanConfigurationRequest request, CampaignResponse campaignResponse) { + PlanConfiguration planConfiguration = request.getPlanConfiguration(); + + if (isSetupCompleted(planConfiguration)) { + performEmptyChecks(planConfiguration); + + HashSet allowedColumns = getAllowedColumnsFromMDMS(request, campaignResponse.getCampaignDetails().get(0).getProjectType()); + Set activeAssumptionKeys = getActiveAssumptionKeys(planConfiguration); + + validateOperationInputs(planConfiguration, allowedColumns); + validateOperationAssumptionValues(planConfiguration, allowedColumns, activeAssumptionKeys); + } + } + + private void performEmptyChecks(PlanConfiguration planConfiguration) { + checkForEmptyFiles(planConfiguration); + checkForEmptyOperation(planConfiguration); + checkForEmptyAssumption(planConfiguration); + } + + private HashSet getAllowedColumnsFromMDMS(PlanConfigurationRequest request, String campaignType) { + String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanConfiguration().getTenantId()); + String uniqueIndentifier = BOUNDARY + DOT_SEPARATOR + MICROPLAN_PREFIX + campaignType; + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_ADMIN_SCHEMA, uniqueIndentifier); + List columnNameList = extractPropertyNamesFromAdminSchema(mdmsV2Data.get(0).getData()); + return new HashSet<>(columnNameList); + } + + /** + * Extracts the names of properties defined within the "numberProperties" and "stringProperties" arrays from admin schema + * + * @param rootNode The root JSON node from which to extract property names. + * @return A list of property names found in "numberProperties" and "stringProperties". + */ + public List extractPropertyNamesFromAdminSchema(JsonNode rootNode) { + List names = new ArrayList<>(); + + // Access the "properties" node directly from the root node + JsonNode propertiesNode = rootNode.path(PROPERTIES); + + // Extract names from "numberProperties" + JsonNode numberProperties = propertiesNode.path(NUMBER_PROPERTIES); + if (numberProperties.isArray()) { + for (JsonNode property : numberProperties) { + String name = property.path(NAME).asText(null); + if (name != null) { + names.add(name); + } + } + } + + // Extract names from "stringProperties" + JsonNode stringProperties = propertiesNode.path(STRING_PROPERTIES); + if (stringProperties.isArray()) { + for (JsonNode property : stringProperties) { + String name = property.path(NAME).asText(null); + if (name != null) { + names.add(name); + } + } + } + + return names; + } + + + private Set getActiveAssumptionKeys(PlanConfiguration planConfiguration) { + return planConfiguration.getAssumptions().stream() + .filter(Assumption::getActive) + .map(Assumption::getKey) + .collect(Collectors.toSet()); + } + + private void validateOperationInputs(PlanConfiguration planConfiguration, HashSet allowedColumns) { + // Set to keep track of previous outputs + Set previousOutputs = new HashSet<>(); + + for (Operation operation : planConfiguration.getOperations()) { + // Validate input + if (!allowedColumns.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput())) { + log.error("Input Value " + operation.getInput() + " is not present in allowed columns or previous outputs"); + throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE + operation.getInput()); + } + + // Add current operation's output to previousOutputs if it's active + if (operation.getActive()) { + previousOutputs.add(operation.getOutput()); + } + } + } + + private void validateOperationAssumptionValues(PlanConfiguration planConfiguration, HashSet allowedColumns, Set activeAssumptionKeys) { + // Set to keep track of previous outputs + Set previousOutputs = new HashSet<>(); + + for (Operation operation : planConfiguration.getOperations()) { + String assumptionValue = operation.getAssumptionValue(); + + // Validate assumption value + if (!allowedColumns.contains(assumptionValue) && !activeAssumptionKeys.contains(assumptionValue) && !previousOutputs.contains(assumptionValue)) { + log.error("Assumption Value " + assumptionValue + " is not present in allowed columns, previous outputs, or active Assumption Keys"); + throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + assumptionValue); + } + + // Add current operation's output to previousOutputs if it's active + if (operation.getActive()) { + previousOutputs.add(operation.getOutput()); + } + } + } + + + } diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index 8a3601b9c86..dad22d39d35 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -31,10 +31,10 @@ public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configur this.configs = configs; } - public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode) + public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode, String uniqueIdentifier) { StringBuilder uri = getMdmsV2Uri(); - MdmsCriteriaReqV2 mdmsCriteriaReqV2 = getMdmsV2Request(requestInfo, tenantId, schemaCode); + MdmsCriteriaReqV2 mdmsCriteriaReqV2 = getMdmsV2Request(requestInfo, tenantId, schemaCode, uniqueIdentifier); MdmsResponseV2 mdmsResponseV2 = null; try { mdmsResponseV2 = restTemplate.postForObject(uri.toString(), mdmsCriteriaReqV2, MdmsResponseV2.class); @@ -57,7 +57,7 @@ private StringBuilder getMdmsV2Uri() return uri.append(configs.getMdmsHost()).append(configs.getMdmsV2EndPoint()); } - private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode) + private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode, String uniqueIdentifier) { MdmsCriteriaV2 mdmsCriteriaV2 = MdmsCriteriaV2.builder() .tenantId(tenantId) @@ -65,6 +65,9 @@ private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenan .limit(configs.getDefaultLimit()) .offset(configs.getDefaultOffset()).build(); + if(!ObjectUtils.isEmpty(uniqueIdentifier)) + mdmsCriteriaV2.setUniqueIdentifiers(Collections.singletonList(uniqueIdentifier)); + return MdmsCriteriaReqV2.builder() .requestInfo(requestInfo) .mdmsCriteriaV2(mdmsCriteriaV2).build(); From fcfa8647a36b3edb408edb499dd5e2f137fda44d Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 30 Oct 2024 16:43:58 +0530 Subject: [PATCH 261/351] HCMPRE-1122 adding method comments --- .../validator/PlanConfigurationValidator.java | 66 +++++++++++++++++-- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 2da7ca16670..6759695bde3 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -381,7 +381,12 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration } } - + /** + * Checks if the setup process is completed based on the workflow action in the plan configuration. + * + * @param planConfiguration The plan configuration to check. + * @return true if the setup is completed, otherwise false. + */ public boolean isSetupCompleted(PlanConfiguration planConfiguration) { if(!ObjectUtils.isEmpty(planConfiguration.getWorkflow())) return Objects.equals(planConfiguration.getWorkflow().getAction(), SETUP_COMPLETED_ACTION); @@ -389,7 +394,11 @@ public boolean isSetupCompleted(PlanConfiguration planConfiguration) { return false; } - // Checks for whether file, assumption, operation or resource mapping is empty or null at a certain status + /** + * Checks if files are empty or null when the setup action is marked as completed. + * + * @param planConfiguration The plan configuration to check. + */ private void checkForEmptyFiles(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getFiles())) { log.error("Files cannot be empty at action = " + SETUP_COMPLETED_ACTION); @@ -397,6 +406,11 @@ private void checkForEmptyFiles(PlanConfiguration planConfiguration) { } } + /** + * Checks if assumptions are empty or null when the setup action is marked as completed. + * + * @param planConfiguration The plan configuration to check. + */ private void checkForEmptyAssumption(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { log.error("Assumptions cannot be empty at action = " + SETUP_COMPLETED_ACTION); @@ -404,6 +418,11 @@ private void checkForEmptyAssumption(PlanConfiguration planConfiguration) { } } + /** + * Checks if operations are empty or null when the setup action is marked as completed. + * + * @param planConfiguration The plan configuration to check. + */ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getOperations())) { log.error("Operations cannot be empty at action = " + SETUP_COMPLETED_ACTION); @@ -411,7 +430,12 @@ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { } } - + /** + * Validates the inputs and assumption values in the plan configuration after verifying the setup action is completed. + * + * @param request The plan configuration request to validate. + * @param campaignResponse The campaign response containing details for validation. + */ public void validateOperations(PlanConfigurationRequest request, CampaignResponse campaignResponse) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); @@ -426,12 +450,24 @@ public void validateOperations(PlanConfigurationRequest request, CampaignRespons } } + /** + * Performs checks for empty files, assumptions, and operations in the plan configuration. + * + * @param planConfiguration The plan configuration to check. + */ private void performEmptyChecks(PlanConfiguration planConfiguration) { checkForEmptyFiles(planConfiguration); checkForEmptyOperation(planConfiguration); checkForEmptyAssumption(planConfiguration); } + /** + * Retrieves allowed columns based on MDMS data and campaign type. + * + * @param request The plan configuration request containing tenant information. + * @param campaignType The type of campaign for which allowed columns are fetched. + * @return A set of allowed column names. + */ private HashSet getAllowedColumnsFromMDMS(PlanConfigurationRequest request, String campaignType) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanConfiguration().getTenantId()); String uniqueIndentifier = BOUNDARY + DOT_SEPARATOR + MICROPLAN_PREFIX + campaignType; @@ -441,7 +477,7 @@ private HashSet getAllowedColumnsFromMDMS(PlanConfigurationRequest reque } /** - * Extracts the names of properties defined within the "numberProperties" and "stringProperties" arrays from admin schema + * Extracts the names of properties defined within the "numberProperties" and "stringProperties" arrays from admin schema. * * @param rootNode The root JSON node from which to extract property names. * @return A list of property names found in "numberProperties" and "stringProperties". @@ -477,7 +513,12 @@ public List extractPropertyNamesFromAdminSchema(JsonNode rootNode) { return names; } - + /** + * Gets keys of active assumptions in the plan configuration. + * + * @param planConfiguration The plan configuration containing assumptions. + * @return A set of keys of active assumptions. + */ private Set getActiveAssumptionKeys(PlanConfiguration planConfiguration) { return planConfiguration.getAssumptions().stream() .filter(Assumption::getActive) @@ -485,6 +526,12 @@ private Set getActiveAssumptionKeys(PlanConfiguration planConfiguration) .collect(Collectors.toSet()); } + /** + * Validates the input values of operations against allowed columns and previous outputs. + * + * @param planConfiguration The plan configuration containing operations. + * @param allowedColumns The allowed column names for input validation. + */ private void validateOperationInputs(PlanConfiguration planConfiguration, HashSet allowedColumns) { // Set to keep track of previous outputs Set previousOutputs = new HashSet<>(); @@ -503,6 +550,13 @@ private void validateOperationInputs(PlanConfiguration planConfiguration, HashSe } } + /** + * Validates the assumption values of operations against allowed columns, active keys, and previous outputs. + * + * @param planConfiguration The plan configuration containing operations. + * @param allowedColumns The allowed column names for assumption validation. + * @param activeAssumptionKeys The set of active assumption keys. + */ private void validateOperationAssumptionValues(PlanConfiguration planConfiguration, HashSet allowedColumns, Set activeAssumptionKeys) { // Set to keep track of previous outputs Set previousOutputs = new HashSet<>(); @@ -523,6 +577,4 @@ private void validateOperationAssumptionValues(PlanConfiguration planConfigurati } } - - } From f39cc994022fdc163f0d777e55eb84826451e052 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 11:48:09 +0530 Subject: [PATCH 262/351] enhancement in facilityCatchmentConsumer --- .../kafka/FacilityCatchmentConsumer.java | 46 ++++++++++--------- .../repository/impl/CensusRepositoryImpl.java | 2 + .../querybuilder/CensusQueryBuilder.java | 2 +- .../src/main/java/digit/util/CommonUtil.java | 4 +- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index be4be219301..caa67560f67 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -4,8 +4,8 @@ import digit.repository.CensusRepository; import digit.service.CensusService; import digit.util.CommonUtil; +import digit.web.models.BulkCensusRequest; import digit.web.models.Census; -import digit.web.models.CensusRequest; import digit.web.models.CensusResponse; import digit.web.models.plan.PlanFacilityDTO; import digit.web.models.plan.PlanFacilityRequestDTO; @@ -30,12 +30,15 @@ public class FacilityCatchmentConsumer { private CensusService service; + private CensusRepository repository; + private CommonUtil commonUtil; - public FacilityCatchmentConsumer(ObjectMapper objectMapper, CensusService service, CommonUtil commonUtil) { + public FacilityCatchmentConsumer(ObjectMapper objectMapper, CensusService service, CommonUtil commonUtil, CensusRepository repository) { this.objectMapper = objectMapper; this.service = service; this.commonUtil = commonUtil; + this.repository = repository; } @KafkaListener(topics = {"${plan.facility.update.topic}"}) @@ -52,25 +55,26 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE Set boundariesWithFacility = new HashSet<>(List.of(planFacilityDTO.getServiceBoundaries().split(","))); Set boundariesWithNoFacility = new HashSet<>(planFacilityDTO.getInitiallySetServiceBoundaries()); - // Unassigning facilities to the boundaries which were initially assigned that facility - censusFromSearch.stream() - .filter(census -> boundariesWithNoFacility.contains(census.getBoundaryCode())) - .forEach(census -> { - census.setAdditionalDetails(commonUtil.removeFieldFromAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD)); - census.setFacilityAssigned(Boolean.FALSE); - census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); - service.update(CensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(census).build()); - }); - - // Assigning facilities to the boundaries in the update request. - censusFromSearch.stream() - .filter(census -> boundariesWithFacility.contains(census.getBoundaryCode())) - .forEach(census -> { - census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); - census.setFacilityAssigned(Boolean.TRUE); - census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); - service.update(CensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(census).build()); - }); + censusFromSearch.forEach(census -> { + String boundaryCode = census.getBoundaryCode(); + + if (!boundariesWithFacility.contains(boundaryCode)) { + + // Unassigning facilities to the boundaries which were initially assigned that facility + census.setAdditionalDetails(commonUtil.removeFieldFromAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD)); + census.setFacilityAssigned(Boolean.FALSE); + census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); + + } else if (!boundariesWithNoFacility.contains(boundaryCode)) { + + // Assigning facilities to the newly added boundaries in the update request. + census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); + census.setFacilityAssigned(Boolean.TRUE); + census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); + } + }); + + repository.bulkUpdate(BulkCensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(censusFromSearch).build()); } catch (Exception exception) { log.error("Error in census consumer", exception); diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index a7c997f38c3..ae0ff83516a 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -135,6 +135,8 @@ public void bulkUpdate(BulkCensusRequest request) { census.getAssignee(), census.getAuditDetails().getLastModifiedBy(), census.getAuditDetails().getLastModifiedTime(), + census.getAdditionalDetails(), + census.getFacilityAssigned(), census.getId() }).toList(); diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index cb159606266..6124d568f3e 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -33,7 +33,7 @@ public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { private static final String CENSUS_STATUS_COUNT_WRAPPER = "SELECT COUNT(census_id) as census_status_count, census_status FROM ({INTERNAL_QUERY}) as census_status_map GROUP BY census_status"; - private static final String BULK_CENSUS_UPDATE_QUERY = "UPDATE census SET status = ?, assignee = ?, last_modified_by = ?, last_modified_time = ? WHERE id = ?"; + private static final String BULK_CENSUS_UPDATE_QUERY = "UPDATE census SET status = ?, assignee = ?, last_modified_by = ?, last_modified_time = ?, additional_details = ?, facility_assigned = ? WHERE id = ?"; /** * Constructs a SQL query string for searching Census records based on the provided search criteria. diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index e4fd38216dc..a0db311f9cd 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -75,7 +75,9 @@ public Map removeFieldFromAdditionalDetails(Object additionalDet * @return */ public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary, List initiallySetServiceBoundaries, RequestInfo requestInfo) { - Set areaCodesForSearch = new HashSet<>(Arrays.asList(serviceBoundary.split(","))); + Set areaCodesForSearch = new HashSet<>(); + + areaCodesForSearch.addAll(Arrays.asList(serviceBoundary.split(","))); areaCodesForSearch.addAll(initiallySetServiceBoundaries); CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() From 436988b5bcde75ef46889a1012807f319c56211b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 11:56:07 +0530 Subject: [PATCH 263/351] enhancement in facilityCatchmentConsumer --- .../java/digit/config/ServiceConstants.java | 36 +- .../validator/PlanConfigurationValidator.java | 333 ++++++++++-------- .../src/main/java/digit/util/MdmsV2Util.java | 9 +- 3 files changed, 199 insertions(+), 179 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 466cdd23bbb..ff1a26eba2d 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -30,10 +30,7 @@ public class ServiceConstants { public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; public static final String ASSUMPTION_VALUE_NOT_FOUND_CODE = "ASSUMPTION_VALUE_NOT_FOUND"; - public static final String ASSUMPTION_VALUE_NOT_FOUND_MESSAGE = "Operation's Assumption value not found in active assumptions list "; - - public static final String FILESTORE_ID_INVALID_CODE = "FILESTORE_ID_INVALID"; - public static final String FILESTORE_ID_INVALID_MESSAGE = " Resource mapping does not have a Valid File Store Id "; + public static final String ASSUMPTION_VALUE_NOT_FOUND_MESSAGE = "Operation's Assumption value is not present in allowed columns, previous outputs, or active Assumption Keys "; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE = "ASSUMPTION_KEY_NOT_FOUND_IN_MDMS"; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS - "; @@ -57,16 +54,7 @@ public class ServiceConstants { public static final String ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE = "Only one file of the required template identifier should be present "; public static final String INPUT_KEY_NOT_FOUND_CODE = "INPUT_KEY_NOT_FOUND"; - public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key not present in MDMS "; - - public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_CODE = "LOCALITY_NOT_PRESENT_IN_MAPPED_TO"; - public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_MESSAGE = "Resource Mapping's MappedTo must contain 'Locality' "; - - public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE = "DUPLICATE_MAPPED_TO_VALIDATION_ERROR"; - public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE = "Duplicate MappedTo found in Resource Mapping"; - - public static final String TENANT_NOT_FOUND_IN_MDMS_CODE = "TENANT_ID_NOT_FOUND_IN_MDMS"; - public static final String TENANT_NOT_FOUND_IN_MDMS_MESSAGE = "Tenant Id is not present in MDMS"; + public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key is not present in allowed columns or previous outputs - "; public static final String TENANT_ID_EMPTY_CODE = "TENANT_ID_EMPTY"; public static final String TENANT_ID_EMPTY_MESSAGE = "Tenant Id cannot be empty, TenantId should be present"; @@ -131,9 +119,6 @@ public class ServiceConstants { public static final String JSONPATH_ERROR_CODE = "JSONPATH_ERROR"; public static final String JSONPATH_ERROR_MESSAGE = "Failed to parse mdms response with given Jsonpath" ; - public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE = "BOUNDARY_CODE_MAPPING_NOT_FOUND"; - public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE = "Boundary Code Mapping is required column is not found."; - public static final String NAME_VALIDATION_LIST_EMPTY_CODE = "NAME_VALIDATION_LIST_EMPTY"; public static final String NAME_VALIDATION_LIST_EMPTY_MESSAGE = "Name Validation list from MDMS is empty"; @@ -167,9 +152,6 @@ public class ServiceConstants { public static final String PLAN_RESOURCES_MANDATORY_CODE = "PLAN_RESOURCES_MANDATORY"; public static final String PLAN_RESOURCES_MANDATORY_MESSAGE = "Resources are mandatory if plan configuration id is not provided"; - public static final String PLAN_RESOURCES_NOT_ALLOWED_CODE = "PLAN_RESOURCES_NOT_ALLOWED"; - public static final String PLAN_RESOURCES_NOT_ALLOWED_MESSAGE = "Resources are not allowed if plan configuration id is provided"; - public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE = "INVALID_RESOURCE_ACTIVITY_LINKAGE"; public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE = "Resource-Activity linkage is invalid"; @@ -200,9 +182,6 @@ public class ServiceConstants { public static final String FILES_NOT_FOUND_CODE = "FILES_NOT_FOUND"; public static final String FILES_NOT_FOUND_MESSAGE = "Files are not present in Plan Configuration."; - public static final String RESOURCE_MAPPING_NOT_FOUND_CODE = "RESOURCE_MAPPING_NOT_FOUND"; - public static final String RESOURCE_MAPPING_NOT_FOUND_MESSAGE = "Resource mapping is not present in Plan Configuration."; - public static final String ASSUMPTIONS_NOT_FOUND_CODE = "ASSUMPTIONS_NOT_FOUND"; public static final String ASSUMPTIONS_NOT_FOUND_MESSAGE = "Assumptions are not present in Plan Configuration."; @@ -222,8 +201,17 @@ public class ServiceConstants { public static final String MDMS_MASTER_SCHEMAS = "Schemas"; public static final String MDMS_MASTER_METRIC = "Metric"; public static final String MDMS_MASTER_UOM = "Uom"; - public static final String MDMS_CODE = "mdms"; public static final String MDMS_MASTER_NAME_VALIDATION= "MicroplanNamingRegex"; + public static final String MDMS_SCHEMA_ADMIN_SCHEMA = "adminSchema"; + public static final String BOUNDARY = "boundary"; + + //MDMS field Constants + public static final String PROPERTIES = "properties"; + public static final String NUMBER_PROPERTIES = "numberProperties"; + public static final String STRING_PROPERTIES = "stringProperties"; + public static final String NAME = "name"; + + public static final String MICROPLAN_PREFIX = "MP-"; public static final String JSON_ROOT_PATH = "$."; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 7cea8dd0461..6759695bde3 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -1,7 +1,7 @@ package digit.service.validator; +import com.fasterxml.jackson.databind.JsonNode; import com.jayway.jsonpath.JsonPath; -import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; import digit.util.CampaignUtil; import digit.util.MdmsUtil; @@ -16,7 +16,6 @@ import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.egov.common.contract.request.RequestInfo; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -59,26 +58,23 @@ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS, null); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); // Validate that the assumption keys in the request are unique validateAssumptionUniqueness(planConfiguration); - // Validate that the assumption values in the plan configuration are correct - validateAssumptionValue(planConfiguration); - // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); - // Validate that the inputs for operations in the request match those in the MDMS data - validateOperationsInputAgainstMDMS(request, mdmsData); - - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings - validateMappedToUniqueness(planConfiguration.getResourceMapping()); + //Validating operation's input and assumptionValue fields + validateOperations(request, campaignResponse); //Validating plan config name against MDMS data validatePlanConfigName(request, mdmsData); @@ -89,8 +85,6 @@ public void validateCreate(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); - // Validate if campaign id exists against project factory - validateCampaignId(campaignResponse); } /** @@ -141,28 +135,6 @@ public void validatePlanConfigName(PlanConfigurationRequest request, Object mdms * * @param planConfiguration The plan configuration to validate. */ - public void validateAssumptionValue(PlanConfiguration planConfiguration) { - if (isSetupCompleted(planConfiguration)) { - checkForEmptyAssumption(planConfiguration); - checkForEmptyOperation(planConfiguration); - - // Collect all active assumption keys - Set activeAssumptionKeys = planConfiguration.getAssumptions().stream() - .filter(Assumption::getActive) - .map(Assumption::getKey) - .collect(Collectors.toSet()); - - planConfiguration.getOperations().stream() - .filter(Operation::getActive) - .forEach(operation -> { - if (!activeAssumptionKeys.contains(operation.getAssumptionValue())) { - log.error("Assumption Value " + operation.getAssumptionValue() + " is not present in the list of active Assumption Keys"); - throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + operation.getAssumptionValue()); - } - }); - - } - } /** @@ -283,107 +255,6 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque } } - - /** - * Validates the operations input against the Master Data Management System (MDMS) data. - * - * @param request The PlanConfigurationRequest containing the plan configuration and other details. - * @param mdmsData The MDMS data containing the master rule configure inputs. - */ - public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { - PlanConfiguration planConfiguration = request.getPlanConfiguration(); - - if (isSetupCompleted(planConfiguration)) { - checkForEmptyFiles(planConfiguration); - checkForEmptyOperation(planConfiguration); - - List files = planConfiguration.getFiles(); - List templateIds = files.stream() - .map(File::getTemplateIdentifier) - .collect(Collectors.toList()); - List inputFileTypes = files.stream() - .map(File::getInputFileType) - .map(File.InputFileTypeEnum::toString) - .collect(Collectors.toList()); - - final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS; - List ruleInputsListFromMDMS = null; - try { - log.info(jsonPathForRuleInputs); - ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - HashSet ruleInputsSetFromMDMS = new HashSet<>(ruleInputsListFromMDMS); - - HashSet allowedColumns = getColumnsFromSchemaThatAreRuleInputs(ruleInputsSetFromMDMS, templateIds, inputFileTypes); - planConfiguration.getOperations().stream() - .map(Operation::getOutput) - .forEach(allowedColumns::add); - - planConfiguration.getOperations().forEach(operation -> { - if (!allowedColumns.contains(operation.getInput())) { - log.error("Input Value " + operation.getInput() + " is not present in MDMS Input List"); - throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE); - } - }); - - } - } - - /** - * Filters the Schema MDMS data by type and section - * returns the list of columns which have the property 'isRuleConfigureInputs' as true - * - * @param schemas List of schemas from MDMS - * @param templateIds The list of template identifiers from request object - * @param inputFileTypes The list of input file type from request object - */ - public static HashSet getColumnsFromSchemaThatAreRuleInputs(HashSet schemas, List templateIds, List inputFileTypes) { - if (schemas == null) { - return new HashSet<>(); - } - HashSet finalData = new HashSet<>(); - for (Object item : schemas) { - LinkedHashMap schemaEntity = (LinkedHashMap) item; - if (!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) - continue; - LinkedHashMap columns = (LinkedHashMap) ((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); - if (columns == null) return new HashSet<>(); - columns.forEach((key, value) -> { - LinkedHashMap data = value; - if (data.get(MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT)) { - finalData.add(key); - } - }); // Add the keys to finalData - } - return finalData; - } - - - /** - * Validates that the 'mappedTo' values in the list of 'resourceMappings' are unique. - * If a duplicate 'mappedTo' value is found, it logs an error and throws a CustomException. - * - * @param resourceMappings The list of 'ResourceMapping' objects to validate. - * @throws CustomException If a duplicate 'mappedTo' value is found. - */ - public static void validateMappedToUniqueness(List resourceMappings) { - if (!CollectionUtils.isEmpty(resourceMappings)) { - Set uniqueMappedToSet = new HashSet<>(); - resourceMappings.forEach(mapping -> { - String uniqueKey = mapping.getFilestoreId() + "-" + mapping.getMappedTo(); - if (!uniqueMappedToSet.add(uniqueKey)) { - log.error("Duplicate MappedTo " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - throw new CustomException(DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE, DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE + " - " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - } - }); - } - } - - /** * Validates the search request for plan configurations. * @@ -413,33 +284,27 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); String rootTenantId = centralInstanceUtil.getStateLevelTenant(planConfiguration.getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS); + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_VEHICLE_DETAILS, null); CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); // Validate the existence of the plan configuration in the request validatePlanConfigExistence(request); + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); // Validate that the assumption keys in the request are unique validateAssumptionUniqueness(planConfiguration); - // Validate that the assumption values in the plan configuration are correct - validateAssumptionValue(planConfiguration); + //Validating operation's input and assumptionValue fields + validateOperations(request, campaignResponse); // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); - // Validate that the inputs for operations in the request match those in the MDMS data - validateOperationsInputAgainstMDMS(request, mdmsData); - - // Validate the dependencies between operations in the plan configuration - validateOperationDependencies(planConfiguration); - - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings - validateMappedToUniqueness(planConfiguration.getResourceMapping()); - //Validating plan config name against MDMS data validatePlanConfigName(request, mdmsData); @@ -449,8 +314,6 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validates the vehicle id from additional details object against the data from mdms v2 validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); - // Validate if campaign id exists against project factory - validateCampaignId(campaignResponse); } /** @@ -518,7 +381,12 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration } } - + /** + * Checks if the setup process is completed based on the workflow action in the plan configuration. + * + * @param planConfiguration The plan configuration to check. + * @return true if the setup is completed, otherwise false. + */ public boolean isSetupCompleted(PlanConfiguration planConfiguration) { if(!ObjectUtils.isEmpty(planConfiguration.getWorkflow())) return Objects.equals(planConfiguration.getWorkflow().getAction(), SETUP_COMPLETED_ACTION); @@ -526,7 +394,11 @@ public boolean isSetupCompleted(PlanConfiguration planConfiguration) { return false; } - // Checks for whether file, assumption, operation or resource mapping is empty or null at a certain status + /** + * Checks if files are empty or null when the setup action is marked as completed. + * + * @param planConfiguration The plan configuration to check. + */ private void checkForEmptyFiles(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getFiles())) { log.error("Files cannot be empty at action = " + SETUP_COMPLETED_ACTION); @@ -534,6 +406,11 @@ private void checkForEmptyFiles(PlanConfiguration planConfiguration) { } } + /** + * Checks if assumptions are empty or null when the setup action is marked as completed. + * + * @param planConfiguration The plan configuration to check. + */ private void checkForEmptyAssumption(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { log.error("Assumptions cannot be empty at action = " + SETUP_COMPLETED_ACTION); @@ -541,6 +418,11 @@ private void checkForEmptyAssumption(PlanConfiguration planConfiguration) { } } + /** + * Checks if operations are empty or null when the setup action is marked as completed. + * + * @param planConfiguration The plan configuration to check. + */ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { if (CollectionUtils.isEmpty(planConfiguration.getOperations())) { log.error("Operations cannot be empty at action = " + SETUP_COMPLETED_ACTION); @@ -548,4 +430,151 @@ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { } } + /** + * Validates the inputs and assumption values in the plan configuration after verifying the setup action is completed. + * + * @param request The plan configuration request to validate. + * @param campaignResponse The campaign response containing details for validation. + */ + public void validateOperations(PlanConfigurationRequest request, CampaignResponse campaignResponse) { + PlanConfiguration planConfiguration = request.getPlanConfiguration(); + + if (isSetupCompleted(planConfiguration)) { + performEmptyChecks(planConfiguration); + + HashSet allowedColumns = getAllowedColumnsFromMDMS(request, campaignResponse.getCampaignDetails().get(0).getProjectType()); + Set activeAssumptionKeys = getActiveAssumptionKeys(planConfiguration); + + validateOperationInputs(planConfiguration, allowedColumns); + validateOperationAssumptionValues(planConfiguration, allowedColumns, activeAssumptionKeys); + } + } + + /** + * Performs checks for empty files, assumptions, and operations in the plan configuration. + * + * @param planConfiguration The plan configuration to check. + */ + private void performEmptyChecks(PlanConfiguration planConfiguration) { + checkForEmptyFiles(planConfiguration); + checkForEmptyOperation(planConfiguration); + checkForEmptyAssumption(planConfiguration); + } + + /** + * Retrieves allowed columns based on MDMS data and campaign type. + * + * @param request The plan configuration request containing tenant information. + * @param campaignType The type of campaign for which allowed columns are fetched. + * @return A set of allowed column names. + */ + private HashSet getAllowedColumnsFromMDMS(PlanConfigurationRequest request, String campaignType) { + String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlanConfiguration().getTenantId()); + String uniqueIndentifier = BOUNDARY + DOT_SEPARATOR + MICROPLAN_PREFIX + campaignType; + List mdmsV2Data = mdmsV2Util.fetchMdmsV2Data(request.getRequestInfo(), rootTenantId, MDMS_ADMIN_CONSOLE_MODULE_NAME + DOT_SEPARATOR + MDMS_SCHEMA_ADMIN_SCHEMA, uniqueIndentifier); + List columnNameList = extractPropertyNamesFromAdminSchema(mdmsV2Data.get(0).getData()); + return new HashSet<>(columnNameList); + } + + /** + * Extracts the names of properties defined within the "numberProperties" and "stringProperties" arrays from admin schema. + * + * @param rootNode The root JSON node from which to extract property names. + * @return A list of property names found in "numberProperties" and "stringProperties". + */ + public List extractPropertyNamesFromAdminSchema(JsonNode rootNode) { + List names = new ArrayList<>(); + + // Access the "properties" node directly from the root node + JsonNode propertiesNode = rootNode.path(PROPERTIES); + + // Extract names from "numberProperties" + JsonNode numberProperties = propertiesNode.path(NUMBER_PROPERTIES); + if (numberProperties.isArray()) { + for (JsonNode property : numberProperties) { + String name = property.path(NAME).asText(null); + if (name != null) { + names.add(name); + } + } + } + + // Extract names from "stringProperties" + JsonNode stringProperties = propertiesNode.path(STRING_PROPERTIES); + if (stringProperties.isArray()) { + for (JsonNode property : stringProperties) { + String name = property.path(NAME).asText(null); + if (name != null) { + names.add(name); + } + } + } + + return names; + } + + /** + * Gets keys of active assumptions in the plan configuration. + * + * @param planConfiguration The plan configuration containing assumptions. + * @return A set of keys of active assumptions. + */ + private Set getActiveAssumptionKeys(PlanConfiguration planConfiguration) { + return planConfiguration.getAssumptions().stream() + .filter(Assumption::getActive) + .map(Assumption::getKey) + .collect(Collectors.toSet()); + } + + /** + * Validates the input values of operations against allowed columns and previous outputs. + * + * @param planConfiguration The plan configuration containing operations. + * @param allowedColumns The allowed column names for input validation. + */ + private void validateOperationInputs(PlanConfiguration planConfiguration, HashSet allowedColumns) { + // Set to keep track of previous outputs + Set previousOutputs = new HashSet<>(); + + for (Operation operation : planConfiguration.getOperations()) { + // Validate input + if (!allowedColumns.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput())) { + log.error("Input Value " + operation.getInput() + " is not present in allowed columns or previous outputs"); + throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE + operation.getInput()); + } + + // Add current operation's output to previousOutputs if it's active + if (operation.getActive()) { + previousOutputs.add(operation.getOutput()); + } + } + } + + /** + * Validates the assumption values of operations against allowed columns, active keys, and previous outputs. + * + * @param planConfiguration The plan configuration containing operations. + * @param allowedColumns The allowed column names for assumption validation. + * @param activeAssumptionKeys The set of active assumption keys. + */ + private void validateOperationAssumptionValues(PlanConfiguration planConfiguration, HashSet allowedColumns, Set activeAssumptionKeys) { + // Set to keep track of previous outputs + Set previousOutputs = new HashSet<>(); + + for (Operation operation : planConfiguration.getOperations()) { + String assumptionValue = operation.getAssumptionValue(); + + // Validate assumption value + if (!allowedColumns.contains(assumptionValue) && !activeAssumptionKeys.contains(assumptionValue) && !previousOutputs.contains(assumptionValue)) { + log.error("Assumption Value " + assumptionValue + " is not present in allowed columns, previous outputs, or active Assumption Keys"); + throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + assumptionValue); + } + + // Add current operation's output to previousOutputs if it's active + if (operation.getActive()) { + previousOutputs.add(operation.getOutput()); + } + } + } + } diff --git a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java index 8a3601b9c86..dad22d39d35 100644 --- a/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java +++ b/health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java @@ -31,10 +31,10 @@ public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configur this.configs = configs; } - public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode) + public List fetchMdmsV2Data(RequestInfo requestInfo, String tenantId, String schemaCode, String uniqueIdentifier) { StringBuilder uri = getMdmsV2Uri(); - MdmsCriteriaReqV2 mdmsCriteriaReqV2 = getMdmsV2Request(requestInfo, tenantId, schemaCode); + MdmsCriteriaReqV2 mdmsCriteriaReqV2 = getMdmsV2Request(requestInfo, tenantId, schemaCode, uniqueIdentifier); MdmsResponseV2 mdmsResponseV2 = null; try { mdmsResponseV2 = restTemplate.postForObject(uri.toString(), mdmsCriteriaReqV2, MdmsResponseV2.class); @@ -57,7 +57,7 @@ private StringBuilder getMdmsV2Uri() return uri.append(configs.getMdmsHost()).append(configs.getMdmsV2EndPoint()); } - private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode) + private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode, String uniqueIdentifier) { MdmsCriteriaV2 mdmsCriteriaV2 = MdmsCriteriaV2.builder() .tenantId(tenantId) @@ -65,6 +65,9 @@ private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenan .limit(configs.getDefaultLimit()) .offset(configs.getDefaultOffset()).build(); + if(!ObjectUtils.isEmpty(uniqueIdentifier)) + mdmsCriteriaV2.setUniqueIdentifiers(Collections.singletonList(uniqueIdentifier)); + return MdmsCriteriaReqV2.builder() .requestInfo(requestInfo) .mdmsCriteriaV2(mdmsCriteriaV2).build(); From 1bb24669589a3bf9710f4cad8bb35e452fafec19 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 12:07:35 +0530 Subject: [PATCH 264/351] removing catchement topic that was added before --- .../plan-service/src/main/java/digit/config/Configuration.java | 3 --- .../java/digit/repository/impl/PlanFacilityRepositoryImpl.java | 2 -- .../plan-service/src/main/resources/application.properties | 2 -- 3 files changed, 7 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 6cb2109b19e..cb7fce09dbe 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -94,9 +94,6 @@ public class Configuration { @Value("${egov.facility.search.endpoint}") private String facilitySearchEndPoint; - @Value("${boundary.facility.catchment.update.topic}") - private String boundaryCatchmentUpdateTopic; - //Workflow @Value("${egov.workflow.host}") private String wfHost; diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 68acae10832..3042b9561ec 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -107,8 +107,6 @@ public void update(PlanFacilityRequest planFacilityRequest) { try { PlanFacilityRequestDTO requestDTO = convertToDTO(planFacilityRequest); producer.push(config.getPlanFacilityUpdateTopic(), requestDTO); - producer.push(config.getBoundaryCatchmentUpdateTopic(), requestDTO); - log.info("Successfully pushed update for plan facility: {}", planFacilityRequest.getPlanFacility().getId()); } catch (Exception e) { throw new CustomException(FAILED_MESSAGE,config.getPlanFacilityUpdateTopic()); diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 256ecda9e03..b7e96a1bd4b 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -91,8 +91,6 @@ plan.default.limit=10 resource.config.consumer.plan.create.topic=resource-microplan-create-topic resource.update.plan.config.consumer.topic=resource-plan-config-update-topic -boundary.facility.catchment.update.topic=boundary-catchment-update-topic - # Role Map plan.estimation.approver.roles = ROOT_PLAN_ESTIMATION_APPROVER, PLAN_ESTIMATION_APPROVER role.map = {'ROOT_FACILITY_CATCHMENT_MAPPER':'FACILITY_CATCHMENT_MAPPER', 'FACILITY_CATCHMENT_MAPPER':'ROOT_FACILITY_CATCHMENT_MAPPER', 'ROOT_POPULATION_DATA_APPROVER':'POPULATION_DATA_APPROVER', 'POPULATION_DATA_APPROVER':'ROOT_POPULATION_DATA_APPROVER', 'ROOT_PLAN_ESTIMATION_APPROVER':'PLAN_ESTIMATION_APPROVER', 'PLAN_ESTIMATION_APPROVER':'ROOT_PLAN_ESTIMATION_APPROVER'} From f124fa4fe34a95a75828578b6f8046a8ef24b3ac Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 12:53:53 +0530 Subject: [PATCH 265/351] added wf validation for approving estimations --- .../java/digit/config/ServiceConstants.java | 5 +++ .../validator/PlanConfigurationValidator.java | 44 ++++++++++++++++++- .../service/workflow/WorkflowService.java | 2 + 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 47834546bcc..da59ab657ca 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -309,6 +309,8 @@ public class ServiceConstants { public static final String FINALIZE_CATCHMENT_MAPPING_ACTION = "FINALIZE_CATCHMENT_MAPPING"; + public static final String APPROVE_ESTIMATIONS_ACTION = "APPROVE_ESTIMATIONS"; + public static final String VALIDATED_STATUS = "VALIDATED"; //Query constants @@ -330,6 +332,9 @@ public class ServiceConstants { public static final String CANNOT_APPROVE_CENSUS_DATA_CODE = "CANNOT_APPROVE_CENSUS_DATA"; public static final String CANNOT_APPROVE_CENSUS_DATA_MESSAGE = "Census data can't be approved until all the census records are validated"; + public static final String CANNOT_APPROVE_ESTIMATIONS_CODE = "CANNOT_APPROVE_ESTIMATIONS"; + public static final String CANNOT_APPROVE_ESTIMATIONS_MESSAGE = "Estimations can't be approved until all the estimations are validated"; + public static final String CANNOT_FINALIZE_CATCHMENT_MAPPING_CODE = "CANNOT_FINALIZE_CATCHMENT_MAPPING"; public static final String CANNOT_FINALIZE_CATCHMENT_MAPPING_MESSAGE = "Catchment mapping can't be finalized until all boundaries have facility assigned"; diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 53942bc02a8..ffce33e1447 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -3,6 +3,7 @@ import com.jayway.jsonpath.JsonPath; import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; +import digit.service.PlanService; import digit.util.*; import digit.web.models.*; @@ -42,7 +43,9 @@ public class PlanConfigurationValidator { private CensusUtil censusUtil; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil, CensusUtil censusUtil) { + private PlanService planService; + + public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil, CensusUtil censusUtil, PlanService planService) { this.mdmsUtil = mdmsUtil; this.mdmsV2Util = mdmsV2Util; this.planConfigRepository = planConfigRepository; @@ -50,6 +53,7 @@ public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, Plan this.centralInstanceUtil = centralInstanceUtil; this.campaignUtil = campaignUtil; this.censusUtil = censusUtil; + this.planService = planService; } /** @@ -646,9 +650,10 @@ public void validateCensusData(PlanConfigurationRequest planConfigurationRequest CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); Map statusCount = censusResponse.getStatusCount(); + Integer totalCount = censusResponse.getTotalCount(); // Throws exception if all census records are not validated - if (statusCount.size() > 1 || !statusCount.containsKey(VALIDATED_STATUS)) { + if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { throw new CustomException(CANNOT_APPROVE_CENSUS_DATA_CODE, CANNOT_APPROVE_CENSUS_DATA_MESSAGE); } } @@ -678,6 +683,28 @@ public void validateCatchmentMapping(PlanConfigurationRequest planConfigurationR } } + /** + * Validates if all the plan estimations are validated before approving estimations for the given planConfigId. + * + * @param planConfigurationRequest request with plan config id. + */ + public void validateResourceEstimations(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + PlanSearchRequest searchRequest = getPlanSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches plans for given planConfigId + PlanResponse planResponse = planService.searchPlan(searchRequest); + + Map statusCount = planResponse.getStatusCount(); + Integer totalCount = planResponse.getTotalCount(); + + // Throws exception if all plans are not validated + if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { + throw new CustomException(CANNOT_APPROVE_ESTIMATIONS_CODE, CANNOT_APPROVE_ESTIMATIONS_MESSAGE); + } + } + public boolean isSetupCompleted(PlanConfiguration planConfiguration) { return Objects.equals(planConfiguration.getStatus(), SETUP_COMPLETED_STATUS); } @@ -723,4 +750,17 @@ private CensusSearchRequest getCensusSearchRequest(String tenantId, String planC .censusSearchCriteria(searchCriteria) .build(); } + + // Prepares Plan search request for given planConfigId + private PlanSearchRequest getPlanSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { + PlanSearchCriteria searchCriteria = PlanSearchCriteria.builder() + .tenantId(tenantId) + .planConfigurationId(planConfigId) + .build(); + + return PlanSearchRequest.builder() + .requestInfo(requestInfo) + .planSearchCriteria(searchCriteria) + .build(); + } } diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 8ed878278fa..d7a7b39a3d6 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -63,6 +63,8 @@ public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigura validator.validateCensusData(planConfigurationRequest); } else if(workflowAction.equals(FINALIZE_CATCHMENT_MAPPING_ACTION)) { validator.validateCatchmentMapping(planConfigurationRequest); + } else if(workflowAction.equals(APPROVE_ESTIMATIONS_ACTION)) { + validator.validateResourceEstimations(planConfigurationRequest); } ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planConfigurationRequest); From 0900576cef9be6a76aae0f9365521966d8aa495b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 14:07:24 +0530 Subject: [PATCH 266/351] adding additionalDetails as string while preparing rows for batchUpdate --- .../main/java/digit/repository/impl/CensusRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index ae0ff83516a..ca85086665a 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -135,7 +135,7 @@ public void bulkUpdate(BulkCensusRequest request) { census.getAssignee(), census.getAuditDetails().getLastModifiedBy(), census.getAuditDetails().getLastModifiedTime(), - census.getAdditionalDetails(), + census.getAdditionalDetails().toString(), census.getFacilityAssigned(), census.getId() }).toList(); From 2728fa836389eb1989daeacea80fe9501cfb9685 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 14:59:55 +0530 Subject: [PATCH 267/351] adding additionalDetails as string while preparing rows for batchUpdate --- .../repository/impl/CensusRepositoryImpl.java | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index ca85086665a..9f5cbb80fa1 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -9,10 +9,12 @@ import digit.util.CommonUtil; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; +import org.postgresql.util.PGobject; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import org.springframework.util.ObjectUtils; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -130,14 +132,25 @@ public void bulkUpdate(BulkCensusRequest request) { String bulkCensusUpdateQuery = queryBuilder.getBulkCensusQuery(); // Prepare rows for bulk update - List rows = request.getCensus().stream().map(census -> new Object[] { - census.getStatus(), - census.getAssignee(), - census.getAuditDetails().getLastModifiedBy(), - census.getAuditDetails().getLastModifiedTime(), - census.getAdditionalDetails().toString(), - census.getFacilityAssigned(), - census.getId() + List rows = request.getCensus().stream().map(census -> { + + PGobject jsonObject = new PGobject(); + jsonObject.setType("jsonb"); + try { + jsonObject.setValue(census.getAdditionalDetails().toString()); // Convert ObjectNode to JSON string + } catch (SQLException e) { + throw new RuntimeException(e); + } + + return new Object[] { + census.getStatus(), + census.getAssignee(), + census.getAuditDetails().getLastModifiedBy(), + census.getAuditDetails().getLastModifiedTime(), + jsonObject, // Pass PGobject instead of plain string + census.getFacilityAssigned(), + census.getId() + }; }).toList(); // Perform bulk update From 799abba5ccf4aa94b028025e89fff8e4285f843d Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 4 Nov 2024 16:47:10 +0530 Subject: [PATCH 268/351] HCMPRE-1094 changes for facility mapping create trigger on workflow --- .../processor/config/ServiceConstants.java | 17 ++++- .../egov/processor/kafka/PlanConsumer.java | 3 +- .../egov/processor/service/ExcelParser.java | 55 +++++---------- .../service/ResourceEstimationService.java | 35 ++++++++-- .../util/CampaignIntegrationUtil.java | 67 ++++++++++--------- .../org/egov/processor/util/MdmsUtil.java | 2 +- .../campaignManager/ResourceDetails.java | 55 +++++++++++++++ .../ResourceDetailsRequest.java | 30 +++++++++ 8 files changed, 187 insertions(+), 77 deletions(-) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetailsRequest.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 748fc8b28fd..e418600d0c8 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 @@ -33,7 +33,13 @@ public class ServiceConstants { public static final String NOT_ABLE_TO_CONVERT_MULTIPARTFILE_TO_BYTESTREAM_CODE = "NOT_ABLE_TO_CONVERT_MULTIPARTFILE_TO_BYTESTREAM"; public static final String NOT_ABLE_TO_CONVERT_MULTIPARTFILE_TO_BYTESTREAM_MESSAGE = "Not able to fetch byte stream from a multipart file"; - + + 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 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."; + public static final String BOUNDARY_CODE = "HCM_ADMIN_CONSOLE_BOUNDARY_CODE"; public static final String TOTAL_POPULATION = "HCM_ADMIN_CONSOLE_TOTAL_POPULATION"; @@ -43,7 +49,8 @@ public class ServiceConstants { public static final String FILE_NAME = "output.xls"; public static final String FILE_TYPE = "boundaryWithTarget"; - public static final String FILE_TEMPLATE_IDENTIFIER = "Population"; + public static final String FILE_TEMPLATE_IDENTIFIER_POPULATION = "Population"; + public static final String FILE_TEMPLATE_IDENTIFIER_FACILITY = "Facilities"; public static final String INPUT_IS_NOT_VALID = "File does not contain valid input for row "; public static final String MDMS_SCHEMA_TYPE = "type"; @@ -91,4 +98,10 @@ public class ServiceConstants { public static final String WORKFLOW_COMMENTS_INITIATING_CENSUS = "Initiating census record creation"; public static final String WORKFLOW_COMMENTS_INITIATING_ESTIMATES = "Initiating plan estimation record creation"; + //Facility Create constants + public static final String TYPE_FACILITY = "facility"; + public static final String ACTION_CREATE = "create"; + public static final String SOURCE_KEY = "source"; + public static final String MICROPLAN_SOURCE_KEY = "microplan"; + public static final String MICROPLAN_ID_KEY = "microplanId"; } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java index b4fc26faff1..f4bdbda2c5d 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java @@ -1,7 +1,6 @@ package org.egov.processor.kafka; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.egov.processor.config.Configuration; import org.egov.processor.service.ResourceEstimationService; @@ -13,6 +12,8 @@ import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; +import java.util.Map; + @Component @Slf4j public class PlanConsumer { 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 668e3ca4cb5..3aa7ebde5de 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 @@ -1,28 +1,18 @@ package org.egov.processor.service; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -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; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; import org.egov.processor.util.*; -import org.egov.processor.web.models.Locale; -import org.egov.processor.web.models.LocaleResponse; -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.ResourceMapping; +import org.egov.processor.web.models.*; import org.egov.processor.web.models.boundary.BoundarySearchResponse; import org.egov.processor.web.models.boundary.EnrichedBoundary; import org.egov.processor.web.models.campaignManager.Boundary; @@ -32,13 +22,16 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import lombok.extern.slf4j.Slf4j; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +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; import static org.egov.processor.config.ServiceConstants.HCM_ADMIN_CONSOLE_BOUNDARY_DATA; import static org.egov.processor.config.ServiceConstants.READ_ME_SHEET_NAME; @@ -203,7 +196,7 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, Object campaignResponse, Workbook excelWorkbook, List campaignBoundaryList, DataFormatter dataFormatter) { - CampaignResponse campaign = parseCampaignResponse(campaignResponse); + CampaignResponse campaign = campaignIntegrationUtil.parseCampaignResponse(campaignResponse); LocaleResponse localeResponse = localeUtil.searchLocale(request); Object mdmsData = mdmsUtil. fetchMdmsData(request.getRequestInfo(), request.getPlanConfiguration().getTenantId()); @@ -315,18 +308,6 @@ private Map prepareAttributeVsIndexMap(PlanConfigurationRequest file.getTemplateIdentifier(), campaign.getCampaign().get(0).getProjectType()); } - - /** - * Parses an object representing campaign response into a CampaignResponse object. - * - * @param campaignResponse The object representing campaign response to be parsed. - * @return CampaignResponse object parsed from the campaignResponse. - */ - private CampaignResponse parseCampaignResponse(Object campaignResponse) { - CampaignResponse campaign = null; - campaign = objectMapper.convertValue(campaignResponse, CampaignResponse.class); - return campaign; - } /** * Performs row-level calculations and processing on each row in the sheet. diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java index c1b1ab07b7a..263fa75433a 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java @@ -1,9 +1,7 @@ package org.egov.processor.service; -import java.util.HashMap; -import java.util.Map; - +import lombok.extern.slf4j.Slf4j; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; import org.egov.processor.repository.ServiceRequestRepository; @@ -11,10 +9,16 @@ import org.egov.processor.web.models.File; import org.egov.processor.web.models.PlanConfiguration; import org.egov.processor.web.models.PlanConfigurationRequest; +import org.egov.processor.web.models.campaignManager.CampaignResponse; import org.egov.processor.web.models.campaignManager.CampaignSearchRequest; +import org.egov.processor.web.models.campaignManager.ResourceDetails; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Service; -import lombok.extern.slf4j.Slf4j; +import java.util.HashMap; +import java.util.Map; + +import static org.egov.processor.config.ServiceConstants.*; @Service @Slf4j @@ -49,6 +53,7 @@ public void estimateResources(PlanConfigurationRequest planConfigurationRequest) Map parserMap = getInputFileTypeMap(); Object campaignSearchResponse = performCampaignSearch(planConfigurationRequest); processFiles(planConfigurationRequest, planConfiguration, parserMap, campaignSearchResponse); + processFacilityFile(planConfigurationRequest, campaignSearchResponse); } /** @@ -108,5 +113,27 @@ public Map getInputFileTypeMap() return parserMap; } + + public void processFacilityFile(PlanConfigurationRequest planConfigurationRequest, Object campaignResponseObject) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + CampaignResponse campaignResponse = campaignIntegrationUtil.parseCampaignResponse(campaignResponseObject); + String facilityFilestoreId = String.valueOf(planConfig.getFiles().stream() + .filter(file -> FILE_TEMPLATE_IDENTIFIER_FACILITY.equals(file.getTemplateIdentifier())) + .map(File::getFilestoreId) + .findFirst() + .orElseThrow(() -> new CustomException(FILE_NOT_FOUND_CODE, FILE_NOT_FOUND_MESSAGE + FILE_TEMPLATE_IDENTIFIER_FACILITY))); + + ResourceDetails.builder() + .type(TYPE_FACILITY) + .hierarchyType(campaignResponse.getCampaign().get(0).getHierarchyType()) + .tenantId(planConfig.getTenantId()) + .fileStoreId(facilityFilestoreId) + .action(ACTION_CREATE) + .campaignId(planConfig.getCampaignId()) + .additionalDetails(campaignIntegrationUtil.createAdditionalDetailsforFacilityCreate(MICROPLAN_SOURCE_KEY, planConfig.getId())) + .build(); + + } + } 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 5d17a1e0c5f..71116ab7cbe 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 @@ -1,48 +1,25 @@ package org.egov.processor.util; -import static org.egov.processor.config.ServiceConstants.PROPERTIES; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Collectors; - +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.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.ss.usermodel.DataFormatter; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; import org.egov.processor.repository.ServiceRequestRepository; -import org.egov.processor.service.ExcelParser; import org.egov.processor.web.models.File; -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.ResourceMapping; -import org.egov.processor.web.models.campaignManager.Boundary; -import org.egov.processor.web.models.campaignManager.CampaignDetails; -import org.egov.processor.web.models.campaignManager.CampaignRequest; -import org.egov.processor.web.models.campaignManager.CampaignResources; -import org.egov.processor.web.models.campaignManager.CampaignResponse; -import org.egov.processor.web.models.campaignManager.CampaignSearchRequest; +import org.egov.processor.web.models.campaignManager.*; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.*; +import java.util.Map.Entry; -import lombok.extern.slf4j.Slf4j; +import static org.egov.processor.config.ServiceConstants.*; @Component @Slf4j @@ -284,4 +261,30 @@ public CampaignSearchRequest buildCampaignRequestForSearch(PlanConfigurationRequ .campaignDetails(CampaignDetails.builder().ids(id).tenantId(planConfig.getTenantId()).build()).build(); } + + /** + * Parses an object representing campaign response into a CampaignResponse object. + * + * @param campaignResponse The object representing campaign response to be parsed. + * @return CampaignResponse object parsed from the campaignResponse. + */ + public CampaignResponse parseCampaignResponse(Object campaignResponse) { + CampaignResponse campaign = null; + campaign = mapper.convertValue(campaignResponse, CampaignResponse.class); + return campaign; + } + + public JsonNode createAdditionalDetailsforFacilityCreate(String source, String microplanId) { + try { + // Create a map to hold the additional details + Map additionalDetailsMap = new HashMap<>(); + additionalDetailsMap.put(SOURCE_KEY, source); + additionalDetailsMap.put(MICROPLAN_ID_KEY, microplanId); + + // Convert the map to a JsonNode + return mapper.valueToTree(additionalDetailsMap); + } catch (Exception e) { + throw new CustomException(UNABLE_TO_CREATE_ADDITIONAL_DETAILS_CODE, UNABLE_TO_CREATE_ADDITIONAL_DETAILS_MESSAGE);// Or throw a custom exception + } + } } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsUtil.java index 229dbf57f45..e3019ded61b 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsUtil.java @@ -132,7 +132,7 @@ public Map filterMasterData(String masterDataJson, File.InputFil String type = (String) schema.get(ServiceConstants.MDMS_SCHEMA_TYPE); String campaign = (String) schema.get(ServiceConstants.MDMS_CAMPAIGN_TYPE); // String fileT = InputFileTypeEnum.valueOf(type); - if (schema.get(ServiceConstants.MDMS_SCHEMA_SECTION).equals(ServiceConstants.FILE_TEMPLATE_IDENTIFIER) + if (schema.get(ServiceConstants.MDMS_SCHEMA_SECTION).equals(ServiceConstants.FILE_TEMPLATE_IDENTIFIER_POPULATION) && campaign.equals(campaignType) && type.equals(fileType.toString())) { Map schemaProperties = (Map) schema.get("schema"); properties = (Map) schemaProperties.get("Properties"); diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java new file mode 100644 index 00000000000..6fdfda8a5a5 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java @@ -0,0 +1,55 @@ +package org.egov.processor.web.models.campaignManager; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ResourceDetails { + + @JsonProperty("type") + @NotNull + @Size(min = 1, max = 64) + private String type; + + @JsonProperty("hierarchyType") + @NotNull + @Size(min = 1, max = 64) + private String hierarchyType; + + @JsonProperty("tenantId") + @NotNull + @Size(min = 2, max = 64) + private String tenantId; + + @JsonProperty("fileStoreId") + @NotNull + private String fileStoreId; + + @JsonProperty("action") + @Size(min = 1, max = 64) + private String action; + + @JsonProperty("campaignId") + private String campaignId; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetailsRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetailsRequest.java new file mode 100644 index 00000000000..265d4fcdc0e --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetailsRequest.java @@ -0,0 +1,30 @@ +package org.egov.processor.web.models.campaignManager; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * CensusRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ResourceDetailsRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("ResourceDetails") + @Valid + private ResourceDetails resourceDetails = null; + +} From 67f438e57e5a272a0c05a0c5d05d25453ff820d4 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 16:51:39 +0530 Subject: [PATCH 269/351] reverting the change in census-bulk-api --- .../repository/impl/CensusRepositoryImpl.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 9f5cbb80fa1..fa279b4493e 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -132,25 +132,12 @@ public void bulkUpdate(BulkCensusRequest request) { String bulkCensusUpdateQuery = queryBuilder.getBulkCensusQuery(); // Prepare rows for bulk update - List rows = request.getCensus().stream().map(census -> { - - PGobject jsonObject = new PGobject(); - jsonObject.setType("jsonb"); - try { - jsonObject.setValue(census.getAdditionalDetails().toString()); // Convert ObjectNode to JSON string - } catch (SQLException e) { - throw new RuntimeException(e); - } - - return new Object[] { + List rows = request.getCensus().stream().map(census -> new Object[] { census.getStatus(), census.getAssignee(), census.getAuditDetails().getLastModifiedBy(), census.getAuditDetails().getLastModifiedTime(), - jsonObject, // Pass PGobject instead of plain string - census.getFacilityAssigned(), census.getId() - }; }).toList(); // Perform bulk update From 98d8405fcdab77f41b9de3e55cc14804e6d98531 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 17:11:23 +0530 Subject: [PATCH 270/351] parsing additional details in bulk update api --- .../repository/impl/CensusRepositoryImpl.java | 4 ++-- .../src/main/java/digit/util/CommonUtil.java | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index fa279b4493e..f1b567ae911 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -9,12 +9,10 @@ import digit.util.CommonUtil; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; -import org.postgresql.util.PGobject; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import org.springframework.util.ObjectUtils; -import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -137,6 +135,8 @@ public void bulkUpdate(BulkCensusRequest request) { census.getAssignee(), census.getAuditDetails().getLastModifiedBy(), census.getAuditDetails().getLastModifiedTime(), + commonUtil.convertToPgObject(census.getAdditionalDetails()), + census.getFacilityAssigned(), census.getId() }).toList(); diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index a0db311f9cd..eb0363f891b 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -1,5 +1,6 @@ package digit.util; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import digit.web.models.CensusSearchCriteria; @@ -9,9 +10,11 @@ import org.egov.common.contract.workflow.BusinessService; import org.egov.common.contract.workflow.State; import org.egov.tracer.model.CustomException; +import org.postgresql.util.PGobject; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +import java.sql.SQLException; import java.util.*; import static digit.config.ServiceConstants.*; @@ -106,4 +109,21 @@ public List getStatusFromBusinessService(RequestInfo requestInfo, String .filter(state -> !ObjectUtils.isEmpty(state)) .toList(); } + + public PGobject convertToPgObject(Object additionalDetails) { + PGobject pGobject = new PGobject(); + + try { + String json = objectMapper.writeValueAsString(additionalDetails); + + pGobject.setType("jsonb"); + pGobject.setValue(json); + } catch (JsonProcessingException e) { + log.error("Error while processing JSON object to string", e); + } catch (SQLException e) { + log.error("Error while setting JSONB object", e); + } + + return pGobject; + } } From 0397c21cd01fa11e5965692c61953920c4a4cb59 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 18:17:54 +0530 Subject: [PATCH 271/351] Added plan config name in plan employee's and plan facility's search criteria --- .../impl/PlanEmployeeAssignmentImpl.java | 1 + .../impl/PlanFacilityRepositoryImpl.java | 1 + .../PlanEmployeeAssignmentQueryBuilder.java | 10 ++++-- .../PlanFacilityQueryBuilder.java | 7 +++++ .../PlanEmployeeAssignmentRowMapper.java | 1 + .../rowmapper/PlanFacilityRowMapper.java | 1 + .../PlanEmployeeAssignmentEnricher.java | 20 ++---------- .../enrichment/PlanFacilityEnricher.java | 31 ++++++++++++++++--- .../web/models/PlanEmployeeAssignment.java | 4 +++ .../web/models/PlanEmployeeAssignmentDTO.java | 3 ++ .../PlanEmployeeAssignmentSearchCriteria.java | 3 ++ .../java/digit/web/models/PlanFacility.java | 4 +++ .../digit/web/models/PlanFacilityDTO.java | 3 ++ .../models/PlanFacilitySearchCriteria.java | 3 ++ ...242904173200__add_plan_config_name_ddl.sql | 3 ++ 15 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index c1e5725c0d2..5ec16de3794 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -103,6 +103,7 @@ public PlanEmployeeAssignmentRequestDTO convertToReqDTO(PlanEmployeeAssignmentRe .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) .employeeId(planEmployeeAssignment.getEmployeeId()) .role(planEmployeeAssignment.getRole()) + .planConfigurationName(planEmployeeAssignment.getPlanConfigurationName()) .hierarchyLevel(planEmployeeAssignment.getHierarchyLevel()) .jurisdiction(String.join(",", planEmployeeAssignment.getJurisdiction())) .additionalDetails(planEmployeeAssignment.getAdditionalDetails()) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 3042b9561ec..a08ec14a6e3 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -58,6 +58,7 @@ public PlanFacilityRequestDTO convertToDTO(PlanFacilityRequest planFacilityReque .id(planFacility.getId()) .tenantId(planFacility.getTenantId()) .planConfigurationId(planFacility.getPlanConfigurationId()) + .planConfigurationName(planFacility.getPlanConfigurationName()) .facilityId(planFacility.getFacilityId()) .residingBoundary(planFacility.getResidingBoundary()) .serviceBoundaries(convertArrayToString(planFacility.getServiceBoundaries())) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 4094c6dffa1..2509fe62d3b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -18,9 +18,9 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { this.queryUtil = queryUtil; } - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, plan_configuration_name, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (plan_configuration_id) id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (plan_configuration_id) id, tenant_id, plan_configuration_id, plan_configuration_name, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; @@ -86,6 +86,12 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit preparedStmtList.add(searchCriteria.getPlanConfigurationId()); } + if (searchCriteria.getPlanConfigurationName() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" plan_configuration_name = ?"); + preparedStmtList.add(searchCriteria.getPlanConfigurationName()); + } + if (!CollectionUtils.isEmpty(searchCriteria.getEmployeeId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index 6dabdab2bf4..bd84a368e37 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -26,6 +26,7 @@ public PlanFacilityQueryBuilder(Configuration config, QueryUtil queryUtil) { "SELECT plan_facility_linkage.id as plan_facility_id, " + "plan_facility_linkage.tenant_id as plan_facility_tenant_id, " + "plan_facility_linkage.plan_configuration_id as plan_facility_plan_configuration_id, " + + "plan_facility_linkage.plan_configuration_name as plan_facility_plan_configuration_name, " + "plan_facility_linkage.facility_id as plan_facility_facility_id, " + "plan_facility_linkage.residing_boundary as plan_facility_residing_boundary, " + "plan_facility_linkage.service_boundaries as plan_facility_service_boundaries, " + @@ -68,6 +69,12 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil preparedStmtList.add(planFacilitySearchCriteria.getPlanConfigurationId()); } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getPlanConfigurationName())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" plan_configuration_name = ? "); + preparedStmtList.add(planFacilitySearchCriteria.getPlanConfigurationName()); + } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" facility_id = ? "); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java index 9a0ce4a2037..fc8a9053e92 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -47,6 +47,7 @@ public List extractData(ResultSet rs) throws SQLExceptio planEmployeeAssignment.setId(planEmployeeAssignmentId); planEmployeeAssignment.setTenantId(rs.getString("tenant_id")); planEmployeeAssignment.setPlanConfigurationId(rs.getString("plan_configuration_id")); + planEmployeeAssignment.setPlanConfigurationName(rs.getString("plan_configuration_name")); planEmployeeAssignment.setEmployeeId(rs.getString("employee_id")); planEmployeeAssignment.setRole(rs.getString("role")); planEmployeeAssignment.setHierarchyLevel(rs.getString("hierarchy_level")); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java index 48331c86b75..f65310b4452 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java @@ -46,6 +46,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAcc planFacilityEntry.setId(planFacilityId); planFacilityEntry.setTenantId(rs.getString("plan_facility_tenant_id")); planFacilityEntry.setPlanConfigurationId(rs.getString("plan_facility_plan_configuration_id")); + planFacilityEntry.setPlanConfigurationName(rs.getString("plan_facility_plan_configuration_name")); planFacilityEntry.setFacilityId(rs.getString("plan_facility_facility_id")); planFacilityEntry.setResidingBoundary(rs.getString("plan_facility_residing_boundary")); String serviceBoundaries = rs.getString("plan_facility_service_boundaries"); diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java index ad4e1a8ae9f..1db4af09587 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -70,28 +70,14 @@ public void enrichUpdate(PlanEmployeeAssignmentRequest request) { } /** - * This method enriches the additional details of plan employee assignment object with the planConfigName to which employee is mapped. + * This method enriches the plan employee assignment object with the planConfigName to which employee is mapped. * - * @param planEmployeeAssignment the object whose additional details is to be enriched + * @param planEmployeeAssignment the object to be enriched */ private void enrichWithPlanConfigName(PlanEmployeeAssignment planEmployeeAssignment) { String planConfigName = getPlanConfigNameById(planEmployeeAssignment.getPlanConfigurationId(), planEmployeeAssignment.getTenantId()); - - try { - - // Get or create the additionalDetails as an ObjectNode - ObjectNode objectNode = objectMapper.convertValue(planEmployeeAssignment.getAdditionalDetails(), ObjectNode.class); - - // Update or Add the field in additional details object - objectNode.put(PLAN_CONFIG_NAME_FIELD, planConfigName); - - // Set the updated additionalDetails back into the planEmployeeAssignment - planEmployeeAssignment.setAdditionalDetails(objectMapper.convertValue(objectNode, Map.class)); - - } catch (Exception e) { - throw new CustomException(ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_MESSAGE); - } + planEmployeeAssignment.setPlanConfigurationName(planConfigName); } private String getPlanConfigNameById(String planConfigId, String tenantId) { diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 3aef5852f76..2796d196a55 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -1,9 +1,7 @@ package digit.service.enrichment; -import digit.web.models.PlanFacility; -import digit.web.models.PlanFacilityRequest; -import digit.web.models.PlanFacilitySearchCriteria; -import digit.web.models.PlanFacilitySearchRequest; +import digit.util.CommonUtil; +import digit.web.models.*; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.AuditDetailsEnrichmentUtil; @@ -13,6 +11,7 @@ import org.springframework.util.ObjectUtils; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import static digit.config.ServiceConstants.*; @@ -22,6 +21,12 @@ @Slf4j public class PlanFacilityEnricher { + private CommonUtil commonUtil; + + public PlanFacilityEnricher(CommonUtil commonUtil) { + this.commonUtil = commonUtil; + } + /** * Enriches the plan facility create request * @@ -39,6 +44,8 @@ public void enrichPlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequ //Set Active planFacilityRequest.getPlanFacility().setActive(Boolean.TRUE); + // Add plan config name to which the facility is mapped + enrichWithPlanConfigName(planFacilityRequest.getPlanFacility()); } /** @@ -82,4 +89,20 @@ public void enrichSearchRequest(PlanFacilitySearchRequest planFacilitySearchRequ if(!CollectionUtils.isEmpty(filtersMap)) planFacilitySearchCriteria.setFiltersMap(filtersMap); } + + /** + * This method enriches the plan facility object with the planConfigName to which facility is mapped. + * + * @param planFacility the object to be enriched + */ + private void enrichWithPlanConfigName(PlanFacility planFacility) { + + String planConfigName = getPlanConfigNameById(planFacility.getPlanConfigurationId(), planFacility.getTenantId()); + planFacility.setPlanConfigurationName(planConfigName); + } + + private String getPlanConfigNameById(String planConfigId, String tenantId) { + List planConfigurations = commonUtil.searchPlanConfigId(planConfigId, tenantId); + return planConfigurations.get(0).getName(); + } } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java index 750f21fa9e9..535708d7b06 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java @@ -1,5 +1,6 @@ package digit.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; import jakarta.validation.Valid; @@ -36,6 +37,9 @@ public class PlanEmployeeAssignment { @Size(min = 2, max = 64) private String planConfigurationId = null; + @JsonIgnore + private String planConfigurationName = null; + @JsonProperty("employeeId") @NotNull @Size(min = 2, max = 64) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java index 095d7b54fa6..555d916c1ff 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java @@ -36,6 +36,9 @@ public class PlanEmployeeAssignmentDTO { @Size(min = 2, max = 64) private String planConfigurationId = null; + @JsonProperty("planConfigurationName") + private String planConfigurationName = null; + @JsonProperty("employeeId") @NotNull @Size(min = 2, max = 64) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 8039edc86ac..0cd2bd098cc 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -36,6 +36,9 @@ public class PlanEmployeeAssignmentSearchCriteria { @Size(max = 64) private String planConfigurationId = null; + @JsonProperty("planConfigurationName") + private String planConfigurationName = null; + @JsonProperty("role") @Valid private List role = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 54aa0fcbcc2..363457951a4 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -1,5 +1,6 @@ package digit.web.models; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -37,6 +38,9 @@ public class PlanFacility { @Size(max = 64) private String planConfigurationId = null; + @JsonIgnore + private String planConfigurationName = null; + @JsonProperty("facilityId") @NotNull @Size(max = 64) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java index 0270be18d5e..4188db11979 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java @@ -36,6 +36,9 @@ public class PlanFacilityDTO { @Size(max = 64) private String planConfigurationId = null; + @JsonProperty("planConfigurationName") + private String planConfigurationName = null; + @JsonProperty("facilityId") @NotNull @Size(max = 64) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java index fd3e750bae7..e56ec2278a1 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java @@ -31,6 +31,9 @@ public class PlanFacilitySearchCriteria { @NotNull private String planConfigurationId = null; + @JsonProperty("planConfigurationName") + private String planConfigurationName = null; + @JsonProperty("facilityName") private String facilityName = null; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql new file mode 100644 index 00000000000..cca2d0430c7 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql @@ -0,0 +1,3 @@ +ALTER TABLE plan_employee_assignment ADD plan_configuration_name character varying(128); + +ALTER TABLE plan_facility_linkage ADD plan_configuration_name character varying(128); \ No newline at end of file From 38f812355ea1194233cae7b01da1aa6138745b1e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 4 Nov 2024 18:35:35 +0530 Subject: [PATCH 272/351] Bypassing validations for operations when source is CUSTOM --- .../validator/PlanConfigurationValidator.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 6759695bde3..7e4fd7c4f12 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -4,14 +4,10 @@ import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; import digit.util.CampaignUtil; +import digit.util.CommonUtil; import digit.util.MdmsUtil; import digit.util.MdmsV2Util; -import digit.util.CommonUtil; import digit.web.models.*; - -import java.util.*; -import java.util.stream.Collectors; - import digit.web.models.mdmsV2.Mdms; import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; @@ -22,6 +18,9 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.util.*; +import java.util.stream.Collectors; + import static digit.config.ServiceConstants.*; @Component @@ -538,13 +537,13 @@ private void validateOperationInputs(PlanConfiguration planConfiguration, HashSe for (Operation operation : planConfiguration.getOperations()) { // Validate input - if (!allowedColumns.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput())) { + if (!allowedColumns.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput()) && operation.getSource() == Source.MDMS) { log.error("Input Value " + operation.getInput() + " is not present in allowed columns or previous outputs"); throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE + operation.getInput()); } // Add current operation's output to previousOutputs if it's active - if (operation.getActive()) { + if (operation.getActive() && operation.getSource() == Source.MDMS) { previousOutputs.add(operation.getOutput()); } } @@ -565,13 +564,13 @@ private void validateOperationAssumptionValues(PlanConfiguration planConfigurati String assumptionValue = operation.getAssumptionValue(); // Validate assumption value - if (!allowedColumns.contains(assumptionValue) && !activeAssumptionKeys.contains(assumptionValue) && !previousOutputs.contains(assumptionValue)) { + if (!allowedColumns.contains(assumptionValue) && !activeAssumptionKeys.contains(assumptionValue) && !previousOutputs.contains(assumptionValue) && operation.getSource() == Source.MDMS) { log.error("Assumption Value " + assumptionValue + " is not present in allowed columns, previous outputs, or active Assumption Keys"); throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + assumptionValue); } // Add current operation's output to previousOutputs if it's active - if (operation.getActive()) { + if (operation.getActive() && operation.getSource() == Source.MDMS) { previousOutputs.add(operation.getOutput()); } } From aeea479a8f891854dfd722c7719ba3f21b5c1594 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 4 Nov 2024 20:33:20 +0530 Subject: [PATCH 273/351] added workflow validations --- .../service/PlanConfigurationService.java | 7 +- .../validator/PlanConfigurationValidator.java | 108 +------------- .../service/validator/WorkflowValidator.java | 141 ++++++++++++++++++ .../service/workflow/WorkflowService.java | 10 -- 4 files changed, 148 insertions(+), 118 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java diff --git a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java index a6c9af454d3..e7ab762d507 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java @@ -3,6 +3,7 @@ import digit.repository.PlanConfigurationRepository; import digit.service.enrichment.EnrichmentService; import digit.service.validator.PlanConfigurationValidator; +import digit.service.validator.WorkflowValidator; import digit.service.workflow.WorkflowService; import digit.util.ResponseInfoFactory; import digit.web.models.PlanConfigurationRequest; @@ -27,14 +28,17 @@ public class PlanConfigurationService { private ResponseInfoFactory responseInfoFactory; + private WorkflowValidator workflowValidator; + private WorkflowService workflowService; - public PlanConfigurationService(EnrichmentService enrichmentService, PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService) { + public PlanConfigurationService(EnrichmentService enrichmentService, PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService, WorkflowValidator workflowValidator) { this.enrichmentService = enrichmentService; this.validator = validator; this.repository = repository; this.responseInfoFactory = responseInfoFactory; this.workflowService = workflowService; + this.workflowValidator = workflowValidator; } /** @@ -80,6 +84,7 @@ public PlanConfigurationResponse search(PlanConfigurationSearchRequest request) public PlanConfigurationResponse update(PlanConfigurationRequest request) { validator.validateUpdateRequest(request); enrichmentService.enrichUpdate(request); + workflowValidator.validateWorkflow(request); workflowService.invokeWorkflowForStatusUpdate(request); repository.update(request); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index b23f6f34da0..2c98510afe2 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -3,21 +3,16 @@ import com.fasterxml.jackson.databind.JsonNode; import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; -import digit.service.PlanService; import digit.util.*; import digit.web.models.*; import java.util.*; import java.util.stream.Collectors; -import digit.web.models.census.CensusResponse; -import digit.web.models.census.CensusSearchCriteria; -import digit.web.models.census.CensusSearchRequest; import digit.web.models.mdmsV2.Mdms; import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.egov.common.contract.request.RequestInfo; import org.egov.common.utils.MultiStateInstanceUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; @@ -42,19 +37,13 @@ public class PlanConfigurationValidator { private CampaignUtil campaignUtil; - private CensusUtil censusUtil; - - private PlanService planService; - - public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil, CensusUtil censusUtil, PlanService planService) { + public PlanConfigurationValidator(MdmsUtil mdmsUtil, MdmsV2Util mdmsV2Util, PlanConfigurationRepository planConfigRepository, CommonUtil commonUtil, MultiStateInstanceUtil centralInstanceUtil, CampaignUtil campaignUtil) { this.mdmsUtil = mdmsUtil; this.mdmsV2Util = mdmsV2Util; this.planConfigRepository = planConfigRepository; this.commonUtil = commonUtil; this.centralInstanceUtil = centralInstanceUtil; this.campaignUtil = campaignUtil; - this.censusUtil = censusUtil; - this.planService = planService; } /** @@ -389,75 +378,6 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration } } - /** - * Validates if all the census records are validated before approving census data for the given planConfigId. - * - * @param planConfigurationRequest request with plan config id. - */ - public void validateCensusData(PlanConfigurationRequest planConfigurationRequest) { - PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); - - CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); - - // Fetches census records for given planConfigId - CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); - - Map statusCount = censusResponse.getStatusCount(); - Integer totalCount = censusResponse.getTotalCount(); - - // Throws exception if all census records are not validated - if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { - throw new CustomException(CANNOT_APPROVE_CENSUS_DATA_CODE, CANNOT_APPROVE_CENSUS_DATA_MESSAGE); - } - } - - /** - * Validates if all boundaries have facility assigned before finalizing catchment mapping for a given planConfigID. - * - * @param planConfigurationRequest request with plan config id. - */ - public void validateCatchmentMapping(PlanConfigurationRequest planConfigurationRequest) { - PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); - - CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); - - // Fetches all census records for given planConfigId - CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); - Integer totalCensusCount = censusResponse.getTotalCount(); - - censusSearchRequest.getCensusSearchCriteria().setFacilityAssigned(Boolean.TRUE); - - // Fetches all census records for given planConfigId where facility is assigned - CensusResponse censusWithFacilityAssigned = censusUtil.fetchCensusRecords(censusSearchRequest); - Integer totalCensusWithFacilityAssigned = censusWithFacilityAssigned.getTotalCount(); - - if (!totalCensusCount.equals(totalCensusWithFacilityAssigned)) { - throw new CustomException(CANNOT_FINALIZE_CATCHMENT_MAPPING_CODE, CANNOT_FINALIZE_CATCHMENT_MAPPING_MESSAGE); - } - } - - /** - * Validates if all the plan estimations are validated before approving estimations for the given planConfigId. - * - * @param planConfigurationRequest request with plan config id. - */ - public void validateResourceEstimations(PlanConfigurationRequest planConfigurationRequest) { - PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); - - PlanSearchRequest searchRequest = getPlanSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); - - // Fetches plans for given planConfigId - PlanResponse planResponse = planService.searchPlan(searchRequest); - - Map statusCount = planResponse.getStatusCount(); - Integer totalCount = planResponse.getTotalCount(); - - // Throws exception if all plans are not validated - if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { - throw new CustomException(CANNOT_APPROVE_ESTIMATIONS_CODE, CANNOT_APPROVE_ESTIMATIONS_MESSAGE); - } - } - /** * Checks if the setup process is completed based on the workflow action in the plan configuration. * @@ -653,30 +573,4 @@ private void validateOperationAssumptionValues(PlanConfiguration planConfigurati } } } - - // Prepares Census search request for given planConfigId - private CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { - CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() - .tenantId(tenantId) - .source(planConfigId) - .build(); - - return CensusSearchRequest.builder() - .requestInfo(requestInfo) - .censusSearchCriteria(searchCriteria) - .build(); - } - - // Prepares Plan search request for given planConfigId - private PlanSearchRequest getPlanSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { - PlanSearchCriteria searchCriteria = PlanSearchCriteria.builder() - .tenantId(tenantId) - .planConfigurationId(planConfigId) - .build(); - - return PlanSearchRequest.builder() - .requestInfo(requestInfo) - .planSearchCriteria(searchCriteria) - .build(); - } } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java new file mode 100644 index 00000000000..321cdb36ecc --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java @@ -0,0 +1,141 @@ +package digit.service.validator; + +import digit.service.PlanService; +import digit.util.CensusUtil; +import digit.web.models.*; +import digit.web.models.census.CensusResponse; +import digit.web.models.census.CensusSearchCriteria; +import digit.web.models.census.CensusSearchRequest; +import org.egov.common.contract.request.RequestInfo; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.util.Map; + +import static digit.config.ServiceConstants.*; +import static digit.config.ServiceConstants.CANNOT_APPROVE_ESTIMATIONS_MESSAGE; + +@Component +public class WorkflowValidator { + + private CensusUtil censusUtil; + + private PlanService planService; + + public WorkflowValidator(CensusUtil censusUtil, PlanService planService) { + this.censusUtil = censusUtil; + this.planService = planService; + } + + public void validateWorkflow(PlanConfigurationRequest planConfigurationRequest) { + if (ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow())) + return; + + String workflowAction = planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction(); + + if(workflowAction.equals(APPROVE_CENSUS_DATA_ACTION)) { + validateCensusData(planConfigurationRequest); + } else if(workflowAction.equals(FINALIZE_CATCHMENT_MAPPING_ACTION)) { + validateCatchmentMapping(planConfigurationRequest); + } else if(workflowAction.equals(APPROVE_ESTIMATIONS_ACTION)) { + validateResourceEstimations(planConfigurationRequest); + } + } + + /** + * Validates if all the census records are validated before approving census data for the given planConfigId. + * + * @param planConfigurationRequest request with plan config id. + */ + private void validateCensusData(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches census records for given planConfigId + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + + Map statusCount = censusResponse.getStatusCount(); + Integer totalCount = censusResponse.getTotalCount(); + + // Throws exception if all census records are not validated + if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { + throw new CustomException(CANNOT_APPROVE_CENSUS_DATA_CODE, CANNOT_APPROVE_CENSUS_DATA_MESSAGE); + } + } + + /** + * Validates if all boundaries have facility assigned before finalizing catchment mapping for a given planConfigID. + * + * @param planConfigurationRequest request with plan config id. + */ + private void validateCatchmentMapping(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches all census records for given planConfigId + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + Integer totalCensusCount = censusResponse.getTotalCount(); + + censusSearchRequest.getCensusSearchCriteria().setFacilityAssigned(Boolean.TRUE); + + // Fetches all census records for given planConfigId where facility is assigned + CensusResponse censusWithFacilityAssigned = censusUtil.fetchCensusRecords(censusSearchRequest); + Integer totalCensusWithFacilityAssigned = censusWithFacilityAssigned.getTotalCount(); + + if (!totalCensusCount.equals(totalCensusWithFacilityAssigned)) { + throw new CustomException(CANNOT_FINALIZE_CATCHMENT_MAPPING_CODE, CANNOT_FINALIZE_CATCHMENT_MAPPING_MESSAGE); + } + } + + /** + * Validates if all the plan estimations are validated before approving estimations for the given planConfigId. + * + * @param planConfigurationRequest request with plan config id. + */ + private void validateResourceEstimations(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + PlanSearchRequest searchRequest = getPlanSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches plans for given planConfigId + PlanResponse planResponse = planService.searchPlan(searchRequest); + + Map statusCount = planResponse.getStatusCount(); + Integer totalCount = planResponse.getTotalCount(); + + // Throws exception if all plans are not validated + if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { + throw new CustomException(CANNOT_APPROVE_ESTIMATIONS_CODE, CANNOT_APPROVE_ESTIMATIONS_MESSAGE); + } + } + + // Prepares Census search request for given planConfigId + private CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() + .tenantId(tenantId) + .source(planConfigId) + .build(); + + return CensusSearchRequest.builder() + .requestInfo(requestInfo) + .censusSearchCriteria(searchCriteria) + .build(); + } + + // Prepares Plan search request for given planConfigId + private PlanSearchRequest getPlanSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { + PlanSearchCriteria searchCriteria = PlanSearchCriteria.builder() + .tenantId(tenantId) + .planConfigurationId(planConfigId) + .build(); + + return PlanSearchRequest.builder() + .requestInfo(requestInfo) + .planSearchCriteria(searchCriteria) + .build(); + } + +} diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index e4afe7ee8ad..1545adebebf 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -63,16 +63,6 @@ public void invokeWorkflowForStatusUpdate(PlanConfigurationRequest planConfigura if (ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow())) return; - String workflowAction = planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction(); - - if(workflowAction.equals(APPROVE_CENSUS_DATA_ACTION)) { - planConfigurationValidator.validateCensusData(planConfigurationRequest); - } else if(workflowAction.equals(FINALIZE_CATCHMENT_MAPPING_ACTION)) { - planConfigurationValidator.validateCatchmentMapping(planConfigurationRequest); - } else if(workflowAction.equals(APPROVE_ESTIMATIONS_ACTION)) { - planConfigurationValidator.validateResourceEstimations(planConfigurationRequest); - } - ProcessInstanceRequest processInstanceRequest = createWorkflowRequest(planConfigurationRequest); ProcessInstanceResponse processInstanceResponse = callWorkflowTransition(processInstanceRequest); From cd3bcb8afa3bcbe99dc984482fccf9d807ae6a58 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 5 Nov 2024 12:32:31 +0530 Subject: [PATCH 274/351] removing unused service constants --- .../src/main/java/digit/config/ServiceConstants.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 248472cc27b..ff1a26eba2d 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -26,8 +26,6 @@ public class ServiceConstants { public static final String ROOT_PREFIX = "ROOT"; - public static final String PLAN_CONFIG_NAME_FIELD = "planConfigName"; - public static final String USERINFO_MISSING_CODE = "USERINFO_MISSING"; public static final String USERINFO_MISSING_MESSAGE = "UserInfo is missing in Request Info "; @@ -181,9 +179,6 @@ public class ServiceConstants { public static final String PROCESS_INSTANCE_NOT_FOUND_CODE = "PROCESS_INSTANCE_NOT_FOUND"; public static final String PROCESS_INSTANCE_NOT_FOUND_MESSAGE = "No process instance found with businessId: "; - public static final String ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_CODE = "ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS"; - public static final String ERROR_WHILE_ENRICHING_ADDITIONAL_DETAILS_MESSAGE = "Exception occurred while enriching additional details: "; - public static final String FILES_NOT_FOUND_CODE = "FILES_NOT_FOUND"; public static final String FILES_NOT_FOUND_MESSAGE = "Files are not present in Plan Configuration."; From d762db7c89ee50aa9133f0289265f496bec115e8 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 5 Nov 2024 13:50:00 +0530 Subject: [PATCH 275/351] Changes for triggering plan-facility mapping --- .../egov/processor/config/Configuration.java | 3 + .../processor/config/ServiceConstants.java | 1 + .../service/ResourceEstimationService.java | 30 +++------- .../util/CampaignIntegrationUtil.java | 57 +++++++++++++++++++ .../campaignManager/ResourceDetails.java | 9 +-- 5 files changed, 71 insertions(+), 29 deletions(-) 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 d3b104d04e8..77fe42eb6e2 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 @@ -56,6 +56,9 @@ public class Configuration { @Value("${egov.project.factory.update.endpoint}") private String campaignIntegrationUpdateEndPoint; + @Value("${egov.project.factory.data.create.endpoint}") + private String campaignIntegrationDataCreateEndPoint; + @Value("${egov.project.factory.host}") private String projectFactoryHostEndPoint; 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 e418600d0c8..811a7e2b53a 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 @@ -46,6 +46,7 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE_FOR_LOCALITY = "Exception occurred while fetching plan configuration from plan service for Locality "; public static final String ERROR_WHILE_PUSHING_TO_PLAN_SERVICE_FOR_LOCALITY = "Exception occurred while fetching plan configuration from plan service for Locality "; public static final String ERROR_WHILE_SEARCHING_CAMPAIGN = "Exception occurred while searching/updating campaign."; + public static final String ERROR_WHILE_DATA_CREATE_CALL = "Exception occurred while creating data for campaign - "; public static final String FILE_NAME = "output.xls"; public static final String FILE_TYPE = "boundaryWithTarget"; diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java index 263fa75433a..e941427a9cc 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java @@ -11,15 +11,11 @@ import org.egov.processor.web.models.PlanConfigurationRequest; import org.egov.processor.web.models.campaignManager.CampaignResponse; import org.egov.processor.web.models.campaignManager.CampaignSearchRequest; -import org.egov.processor.web.models.campaignManager.ResourceDetails; -import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; -import static org.egov.processor.config.ServiceConstants.*; - @Service @Slf4j public class ResourceEstimationService { @@ -114,25 +110,17 @@ public Map getInputFileTypeMap() return parserMap; } + /** + * Processes the facility file by parsing the campaign response and initiating + * a data creation call to the Project Factory service. + * + * @param planConfigurationRequest the request containing plan configuration details + * @param campaignResponseObject the campaign response object to be parsed + */ public void processFacilityFile(PlanConfigurationRequest planConfigurationRequest, Object campaignResponseObject) { - PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); CampaignResponse campaignResponse = campaignIntegrationUtil.parseCampaignResponse(campaignResponseObject); - String facilityFilestoreId = String.valueOf(planConfig.getFiles().stream() - .filter(file -> FILE_TEMPLATE_IDENTIFIER_FACILITY.equals(file.getTemplateIdentifier())) - .map(File::getFilestoreId) - .findFirst() - .orElseThrow(() -> new CustomException(FILE_NOT_FOUND_CODE, FILE_NOT_FOUND_MESSAGE + FILE_TEMPLATE_IDENTIFIER_FACILITY))); - - ResourceDetails.builder() - .type(TYPE_FACILITY) - .hierarchyType(campaignResponse.getCampaign().get(0).getHierarchyType()) - .tenantId(planConfig.getTenantId()) - .fileStoreId(facilityFilestoreId) - .action(ACTION_CREATE) - .campaignId(planConfig.getCampaignId()) - .additionalDetails(campaignIntegrationUtil.createAdditionalDetailsforFacilityCreate(MICROPLAN_SOURCE_KEY, planConfig.getId())) - .build(); - + campaignIntegrationUtil.createProjectFactoryDataCall(planConfigurationRequest, campaignResponse); + log.info("Facility Data creation successful."); } } 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 71116ab7cbe..ca9e0ffe9d7 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 @@ -65,6 +65,27 @@ public void updateCampaignDetails(PlanConfigurationRequest planConfigurationRequ } } + /** + * Sends a data creation request to the Project Factory service using the provided + * plan and campaign details. + * + * @param planConfigurationRequest the plan configuration request containing campaign data + * @param campaignResponse the response with additional campaign information + * @throws CustomException if the data creation call fails + */ + public void createProjectFactoryDataCall(PlanConfigurationRequest planConfigurationRequest, CampaignResponse campaignResponse) { + try { + serviceRequestRepository.fetchResult( + new StringBuilder(config.getProjectFactoryHostEndPoint() + config.getCampaignIntegrationDataCreateEndPoint()), + buildResourceDetailsObjectForFacilityCreate(planConfigurationRequest, campaignResponse)); + log.info("Campaign Data create successful."); + } catch (Exception e) { + log.error(ServiceConstants.ERROR_WHILE_DATA_CREATE_CALL + + planConfigurationRequest.getPlanConfiguration().getCampaignId(), e); + throw new CustomException("Failed to update campaign details in CampaignIntegration class within method updateCampaignDetails.", e.toString()); + } + } + /** * Updates the campaign resources in the given campaign response based on the files specified in the plan configuration request. * @@ -100,6 +121,42 @@ private CampaignRequest buildCampaignRequestForUpdate(PlanConfigurationRequest p } + /** + * Builds a {@link ResourceDetailsRequest} object for facility creation using the provided + * plan configuration and campaign details. + * + * @param planConfigurationRequest the request containing plan configuration data + * @param campaignResponse the campaign response with additional data + * @return a {@link ResourceDetailsRequest} for facility creation + * @throws CustomException if the required facility file is not found + */ + private ResourceDetailsRequest buildResourceDetailsObjectForFacilityCreate(PlanConfigurationRequest planConfigurationRequest, + CampaignResponse campaignResponse) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + + String facilityFilestoreId = String.valueOf(planConfig.getFiles().stream() + .filter(file -> FILE_TEMPLATE_IDENTIFIER_FACILITY.equals(file.getTemplateIdentifier())) + .map(File::getFilestoreId) + .findFirst() + .orElseThrow(() -> new CustomException(FILE_NOT_FOUND_CODE, FILE_NOT_FOUND_MESSAGE + FILE_TEMPLATE_IDENTIFIER_FACILITY))); + + ResourceDetails resourceDetails = ResourceDetails.builder() + .type(TYPE_FACILITY) + .hierarchyType(campaignResponse.getCampaign().get(0).getHierarchyType()) + .tenantId(planConfig.getTenantId()) + .fileStoreId(facilityFilestoreId) + .action(ACTION_CREATE) + .campaignId(planConfig.getCampaignId()) + .additionalDetails(createAdditionalDetailsforFacilityCreate(MICROPLAN_SOURCE_KEY, planConfig.getId())) + .build(); + + return ResourceDetailsRequest.builder() + .requestInfo(planConfigurationRequest.getRequestInfo()) + .resourceDetails(resourceDetails) + .build(); + + } + /** * Updates campaign boundary based on the provided plan configuration, feature, assumption values, mapped values, column index map, boundary list, and result map. * diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java index 6fdfda8a5a5..b35c0343469 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java @@ -1,16 +1,13 @@ package org.egov.processor.web.models.campaignManager; -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; import com.fasterxml.jackson.annotation.JsonProperty; - -import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; @Validated @Data @@ -45,10 +42,6 @@ public class ResourceDetails { @JsonProperty("campaignId") private String campaignId; - @JsonProperty("auditDetails") - @Valid - private AuditDetails auditDetails; - @JsonProperty("additionalDetails") private Object additionalDetails = null; From f25c1b4b58c5bc4897d8686433eeaf1d35dc932c Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 5 Nov 2024 13:52:47 +0530 Subject: [PATCH 276/351] adding project factory data create host --- .../resource-generator/src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index 7211b3c8bf3..3848081b68f 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -70,6 +70,7 @@ egov.plan.create.endpoint=/plan-service/plan/_create #Campaign Manager egov.project.factory.search.endpoint=/project-factory/v1/project-type/search egov.project.factory.update.endpoint=/project-factory/v1/project-type/update +egov.project.factory.data.create.endpoint=/project-factory/v1/data/_create egov.project.factory.host=https://unified-dev.digit.org #egov.project.factory.host=http://localhost:8090 integrate.with.admin.console=true From 1e9737dd143f3b5d1a44836f069fa773d39bf788 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 5 Nov 2024 13:55:54 +0530 Subject: [PATCH 277/351] handling case for empty areaCodes in search criteria --- .../java/digit/repository/impl/CensusRepositoryImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index f1b567ae911..988cc6d655f 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -66,6 +66,10 @@ public void create(CensusRequest censusRequest) { */ @Override public List search(CensusSearchCriteria censusSearchCriteria) { + + if(censusSearchCriteria.getAreaCodes().isEmpty()) + return new ArrayList<>(); + List preparedStmtList = new ArrayList<>(); String query = queryBuilder.getCensusQuery(censusSearchCriteria, preparedStmtList); @@ -80,6 +84,10 @@ public List search(CensusSearchCriteria censusSearchCriteria) { */ @Override public Integer count(CensusSearchCriteria censusSearchCriteria) { + + if(censusSearchCriteria.getAreaCodes().isEmpty()) + return 0; + List preparedStmtList = new ArrayList<>(); String query = queryBuilder.getCensusCountQuery(censusSearchCriteria, preparedStmtList); From d6462f8877c8548771606d669b1c3ee7c45c3f08 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 5 Nov 2024 15:23:49 +0530 Subject: [PATCH 278/351] handling case for empty areaCodes in search criteria --- .../main/java/digit/repository/impl/CensusRepositoryImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 988cc6d655f..3a9c293a89a 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -67,7 +67,7 @@ public void create(CensusRequest censusRequest) { @Override public List search(CensusSearchCriteria censusSearchCriteria) { - if(censusSearchCriteria.getAreaCodes().isEmpty()) + if(censusSearchCriteria.getAreaCodes() != null && censusSearchCriteria.getAreaCodes().isEmpty()) return new ArrayList<>(); List preparedStmtList = new ArrayList<>(); @@ -85,7 +85,7 @@ public List search(CensusSearchCriteria censusSearchCriteria) { @Override public Integer count(CensusSearchCriteria censusSearchCriteria) { - if(censusSearchCriteria.getAreaCodes().isEmpty()) + if(censusSearchCriteria.getAreaCodes() != null && censusSearchCriteria.getAreaCodes().isEmpty()) return 0; List preparedStmtList = new ArrayList<>(); From 482ebf43299d67cf2a78bbfb698972ec495ccb4d Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 5 Nov 2024 15:37:46 +0530 Subject: [PATCH 279/351] adding project factory data create host --- .../org/egov/processor/service/ResourceEstimationService.java | 2 +- .../src/main/resources/application.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java index e941427a9cc..50ea0558f54 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java @@ -48,8 +48,8 @@ public void estimateResources(PlanConfigurationRequest planConfigurationRequest) Map parserMap = getInputFileTypeMap(); Object campaignSearchResponse = performCampaignSearch(planConfigurationRequest); - processFiles(planConfigurationRequest, planConfiguration, parserMap, campaignSearchResponse); processFacilityFile(planConfigurationRequest, campaignSearchResponse); + processFiles(planConfigurationRequest, planConfiguration, parserMap, campaignSearchResponse); } /** diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index 3848081b68f..fb9a5eda3d6 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -73,7 +73,7 @@ egov.project.factory.update.endpoint=/project-factory/v1/project-type/update egov.project.factory.data.create.endpoint=/project-factory/v1/data/_create egov.project.factory.host=https://unified-dev.digit.org #egov.project.factory.host=http://localhost:8090 -integrate.with.admin.console=true +integrate.with.admin.console=false #Kafka topics for creating or updating records in dependent microservices resource.microplan.create.topic=resource-microplan-create-topic From 4d90389dd4a40a7aff6d202a8b64323d39eef4a3 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 5 Nov 2024 16:00:49 +0530 Subject: [PATCH 280/351] Adding facility create trigger status --- .../java/org/egov/processor/config/Configuration.java | 3 +++ .../main/java/org/egov/processor/kafka/PlanConsumer.java | 3 ++- .../egov/processor/service/ResourceEstimationService.java | 8 +++++--- .../src/main/resources/application.properties | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) 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 77fe42eb6e2..42388c7f226 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 @@ -84,6 +84,9 @@ public class Configuration { @Value("${plan.config.trigger.census.records.status}") private String planConfigTriggerCensusRecordsStatus; + @Value("${plan.config.trigger.plan.facility.mappings.status}") + private String planConfigTriggerPlanFacilityMappingsStatus; + //Kafka topics for creating or updating records in dependent microservices @Value("${resource.microplan.create.topic}") private String resourceMicroplanCreateTopic; diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java index f4bdbda2c5d..7d06ab1b3c8 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java @@ -35,7 +35,8 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE try { PlanConfigurationRequest planConfigurationRequest = objectMapper.convertValue(consumerRecord, PlanConfigurationRequest.class); if (planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus()) - || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { + || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus()) + || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanFacilityMappingsStatus())) { resourceEstimationService.estimateResources(planConfigurationRequest); log.info("Successfully estimated resources for plan."); } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java index 50ea0558f54..978633933b9 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/service/ResourceEstimationService.java @@ -118,9 +118,11 @@ public Map getInputFileTypeMap() * @param campaignResponseObject the campaign response object to be parsed */ public void processFacilityFile(PlanConfigurationRequest planConfigurationRequest, Object campaignResponseObject) { - CampaignResponse campaignResponse = campaignIntegrationUtil.parseCampaignResponse(campaignResponseObject); - campaignIntegrationUtil.createProjectFactoryDataCall(planConfigurationRequest, campaignResponse); - log.info("Facility Data creation successful."); + if (planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanFacilityMappingsStatus())) { + CampaignResponse campaignResponse = campaignIntegrationUtil.parseCampaignResponse(campaignResponseObject); + campaignIntegrationUtil.createProjectFactoryDataCall(planConfigurationRequest, campaignResponse); + log.info("Facility Data creation successful."); + } } } diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index fb9a5eda3d6..78607ad9dd5 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -90,6 +90,7 @@ egov.locale.search.endpoint=/localization/messages/v1/_search?module={module}&lo #trigger statuses plan.config.trigger.plan.estimates.status=RESOURCE_ESTIMATION_IN_PROGRESS plan.config.trigger.census.records.status=EXECUTION_TO_BE_DONE +plan.config.trigger.plan.facility.mappings.status=EXECUTION_TO_BE_DONE # Pagination config resource.default.offset=0 From 1c238a0af0f6c21f9959f86ae2db9ff7f00f4b35 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 5 Nov 2024 18:51:03 +0530 Subject: [PATCH 281/351] Adding additionalField table in census --- .../repository/impl/CensusRepositoryImpl.java | 1 + .../querybuilder/CensusQueryBuilder.java | 11 +++-- .../repository/rowmapper/CensusRowMapper.java | 37 +++++++++++++++ .../service/enrichment/CensusEnrichment.java | 10 ++++ .../digit/web/models/AdditionalField.java | 46 +++++++++++++++++++ .../main/java/digit/web/models/Census.java | 4 ++ .../main/java/digit/web/models/CensusDTO.java | 4 ++ ...00__census_additional_field_create_ddl.sql | 12 +++++ 8 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 health-services/census-service/src/main/java/digit/web/models/AdditionalField.java create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 3a9c293a89a..ca1214dc864 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -172,6 +172,7 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .type(census.getType().toString()) .totalPopulation(census.getTotalPopulation()) .populationByDemographics(census.getPopulationByDemographics()) + .additionalFields(census.getAdditionalFields()) .effectiveFrom(census.getEffectiveFrom()) .effectiveTo(census.getEffectiveTo()) .source(census.getSource()) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 6124d568f3e..cbc1a556068 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -23,15 +23,17 @@ public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { } private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_ancestral_path as census_boundary_ancestral_path, cen.facility_assigned as census_facility_assigned, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + - "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time \n" + + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time, \n" + + "\t adf.id as additional_field_id, adf.census_id as additional_field_census_id, adf.key as additional_field_key, adf.value as additional_field_value, adf.show_on_ui as additional_field_show_on_ui, adf.editable as additional_field_editable, adf.order as additional_field_order \n" + "\t FROM census cen \n" + - "\t LEFT JOIN population_by_demographics pbd ON cen.id = pbd.census_id"; + "\t LEFT JOIN population_by_demographics pbd ON cen.id = pbd.census_id \n" + + "\t LEFT JOIN additional_field adf ON cen.id = adf.census_id"; private static final String CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY cen.last_modified_time DESC"; - private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(census_id) AS total_count FROM ( "; + private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(DISTINCT census_id) AS total_count FROM ( "; - private static final String CENSUS_STATUS_COUNT_WRAPPER = "SELECT COUNT(census_id) as census_status_count, census_status FROM ({INTERNAL_QUERY}) as census_status_map GROUP BY census_status"; + private static final String CENSUS_STATUS_COUNT_WRAPPER = "SELECT COUNT(DISTINCT census_id) as census_status_count, census_status FROM ({INTERNAL_QUERY}) as census_status_map GROUP BY census_status"; private static final String BULK_CENSUS_UPDATE_QUERY = "UPDATE census SET status = ?, assignee = ?, last_modified_by = ?, last_modified_time = ?, additional_details = ?, facility_assigned = ? WHERE id = ?"; @@ -58,6 +60,7 @@ public String getCensusQuery(CensusSearchCriteria searchCriteria, List p * @return A SQL query string to get the total count of Census records for a given search criteria. */ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder().build(); return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.TRUE, Boolean.FALSE); } diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index eae77786dc4..572bc38d8b3 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -1,6 +1,7 @@ package digit.repository.rowmapper; import digit.util.QueryUtil; +import digit.web.models.AdditionalField; import digit.web.models.Census; import digit.web.models.PopulationByDemographic; import org.egov.common.contract.models.AuditDetails; @@ -36,6 +37,7 @@ public CensusRowMapper(QueryUtil queryUtil) { public List extractData(ResultSet rs) throws SQLException, DataAccessException { Map censusMap = new LinkedHashMap<>(); Map populationByDemographicMap = new LinkedHashMap<>(); + Map additionalFieldMap = new LinkedHashMap<>(); while (rs.next()) { String censusId = rs.getString("census_id"); @@ -65,6 +67,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setAuditDetails(auditDetails); } addPopulationByDemographic(rs, populationByDemographicMap, censusEntry); + addAdditionalField(rs, additionalFieldMap, censusEntry); censusMap.put(censusId, censusEntry); } @@ -72,6 +75,40 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc return new ArrayList<>(censusMap.values()); } + /** + * Adds a AdditionalField object to the census entry based on the result set. + * + * @param rs The ResultSet containing the data. + * @param additionalFieldMap A map to keep track of added AdditionalField objects. + * @param censusEntry The Census entry to which the AdditionalField object will be added. + * @throws SQLException If an SQL error occurs. + */ + private void addAdditionalField(ResultSet rs, Map additionalFieldMap, Census censusEntry) throws SQLException { + String additionalFieldId = rs.getString("additional_field_id"); + + if (ObjectUtils.isEmpty(additionalFieldId) || additionalFieldMap.containsKey(additionalFieldId)) { + return; + } + + AdditionalField additionalField = new AdditionalField(); + additionalField.setId(rs.getString("additional_field_id")); + additionalField.setKey(rs.getString("additional_field_key")); + additionalField.setValue(rs.getString("additional_field_value")); + additionalField.setShowOnUi(rs.getBoolean("additional_field_show_on_ui")); + additionalField.setEditable(rs.getBoolean("additional_field_editable")); + additionalField.setOrder(rs.getInt("additional_field_order")); + + if (CollectionUtils.isEmpty(censusEntry.getAdditionalFields())) { + List additionalFields = new ArrayList<>(); + additionalFields.add(additionalField); + censusEntry.setAdditionalFields(additionalFields); + } else { + censusEntry.getAdditionalFields().add(additionalField); + } + + additionalFieldMap.put(additionalFieldId, additionalField); + } + /** * Adds a PopulationByDemographics object to the census entry based on the result set. diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index 7d3c9deaf09..7c50111bf10 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -39,6 +39,9 @@ public void enrichCreate(CensusRequest request) { census.getPopulationByDemographics().forEach(populationByDemographics -> UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id")); } + // Generate id for additionalFields + census.getAdditionalFields().forEach(additionalField -> UUIDEnrichmentUtil.enrichRandomUuid(additionalField, "id")); + // Set audit details for census record census.setAuditDetails(prepareAuditDetails(census.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); @@ -84,6 +87,13 @@ public void enrichUpdate(CensusRequest request) { } }); } + + //Generate id for additionalFields + census.getAdditionalFields().forEach(additionalField -> { + if (ObjectUtils.isEmpty(additionalField.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(additionalField, "id"); + } + }); } } diff --git a/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java b/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java new file mode 100644 index 00000000000..4d436ce8a1d --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java @@ -0,0 +1,46 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +/** + * AdditionalField + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class AdditionalField { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("key") + @Valid + @NotNull + private String key = null; + + @JsonProperty("value") + @Valid + @NotNull + private String value = null; + + @JsonProperty("showOnUi") + private Boolean showOnUi = Boolean.TRUE; + + @JsonProperty("editable") + private Boolean editable = Boolean.TRUE; + + @JsonProperty("order") + private Integer order = null; +} diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 75252101032..b74aa2110b8 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -67,6 +67,10 @@ public class Census { @Valid private List populationByDemographics = null; + @JsonProperty("additionalFields") + @Valid + private List additionalFields = null; + @JsonProperty("effectiveFrom") private Long effectiveFrom = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 2c370441ad8..f34f1770af5 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -64,6 +64,10 @@ public class CensusDTO { @Valid private List populationByDemographics = null; + @JsonProperty("additionalFields") + @Valid + private List additionalFields = null; + @JsonProperty("effectiveFrom") private Long effectiveFrom = null; diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql new file mode 100644 index 00000000000..f6168017fad --- /dev/null +++ b/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql @@ -0,0 +1,12 @@ +-- Table: additional_field +CREATE TABLE additional_field ( + id character varying(64) NOT NULL, + census_id character varying(64) NOT NULL, + "key" character varying(64) NOT NULL, + "value" character varying(64) NOT NULL, + show_on_ui boolean DEFAULT true NOT NULL, + editable boolean DEFAULT true NOT NULL, + "order" bigint NOT NULL, + CONSTRAINT uk_additional_field_id PRIMARY KEY (id), + FOREIGN KEY (census_id) REFERENCES census(id) +); From aa8b784918bd020e611df65f7cd7895f67b262a6 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 5 Nov 2024 19:48:56 +0530 Subject: [PATCH 282/351] adding plan config name in plan employee and plan facility pojo --- .../src/main/java/digit/web/models/PlanEmployeeAssignment.java | 2 +- .../src/main/java/digit/web/models/PlanFacility.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java index 535708d7b06..48f5cf9ae85 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java @@ -37,7 +37,7 @@ public class PlanEmployeeAssignment { @Size(min = 2, max = 64) private String planConfigurationId = null; - @JsonIgnore + @JsonProperty("planConfigurationName") private String planConfigurationName = null; @JsonProperty("employeeId") diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 891ada8135c..a47f7198bc1 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -38,7 +38,7 @@ public class PlanFacility { @Size(max = 64) private String planConfigurationId = null; - @JsonIgnore + @JsonProperty("planConfigurationName") private String planConfigurationName = null; @JsonProperty("facilityId") From 8159e91591af8f9d36b3542d4ea0e44a756313b7 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 6 Nov 2024 10:49:52 +0530 Subject: [PATCH 283/351] Adding additionalField table in census --- .../java/digit/repository/querybuilder/CensusQueryBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index cbc1a556068..8ec4b430a27 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -60,7 +60,6 @@ public String getCensusQuery(CensusSearchCriteria searchCriteria, List p * @return A SQL query string to get the total count of Census records for a given search criteria. */ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { - CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder().build(); return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.TRUE, Boolean.FALSE); } From 0efeb33d78bf123efa9a2f843d04c622db37be2c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 6 Nov 2024 11:33:57 +0530 Subject: [PATCH 284/351] implemented partial search in plan config name --- .../repository/querybuilder/PlanConfigQueryBuilder.java | 2 +- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 6 ++++-- .../repository/querybuilder/PlanFacilityQueryBuilder.java | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 3357073e976..fe8faa3e5dc 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -118,7 +118,7 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter if (criteria.getName() != null) { addClauseIfRequired(preparedStmtList, builder); builder.append(" pc.name LIKE ?"); - preparedStmtList.add(criteria.getName() + PERCENTAGE_WILDCARD); + preparedStmtList.add(PERCENTAGE_WILDCARD + criteria.getName() + PERCENTAGE_WILDCARD); } if (!CollectionUtils.isEmpty(criteria.getStatus())) { diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 2509fe62d3b..cccc784389e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -9,6 +9,8 @@ import java.util.LinkedHashSet; import java.util.List; +import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; + @Component public class PlanEmployeeAssignmentQueryBuilder { @@ -88,8 +90,8 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit if (searchCriteria.getPlanConfigurationName() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_configuration_name = ?"); - preparedStmtList.add(searchCriteria.getPlanConfigurationName()); + builder.append(" plan_configuration_name LIKE ?"); + preparedStmtList.add(PERCENTAGE_WILDCARD + searchCriteria.getPlanConfigurationName() + PERCENTAGE_WILDCARD); } if (!CollectionUtils.isEmpty(searchCriteria.getEmployeeId())) { diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index bd84a368e37..755b79de6b8 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Set; +import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; + @Component public class PlanFacilityQueryBuilder { @@ -71,8 +73,8 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getPlanConfigurationName())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_configuration_name = ? "); - preparedStmtList.add(planFacilitySearchCriteria.getPlanConfigurationName()); + builder.append(" plan_configuration_name LIKE ? "); + preparedStmtList.add(PERCENTAGE_WILDCARD + planFacilitySearchCriteria.getPlanConfigurationName() + PERCENTAGE_WILDCARD); } if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityId())) { From 675126e93e70068703f0b35c437582ea6c4670ba Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 6 Nov 2024 14:00:40 +0530 Subject: [PATCH 285/351] Changing datatype of value --- .../main/java/digit/repository/rowmapper/CensusRowMapper.java | 2 +- .../src/main/java/digit/web/models/AdditionalField.java | 4 +++- .../V20241105152700__census_additional_field_create_ddl.sql | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 572bc38d8b3..365af9f84c0 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -93,7 +93,7 @@ private void addAdditionalField(ResultSet rs, Map addit AdditionalField additionalField = new AdditionalField(); additionalField.setId(rs.getString("additional_field_id")); additionalField.setKey(rs.getString("additional_field_key")); - additionalField.setValue(rs.getString("additional_field_value")); + additionalField.setValue(rs.getBigDecimal("additional_field_value")); additionalField.setShowOnUi(rs.getBoolean("additional_field_show_on_ui")); additionalField.setEditable(rs.getBoolean("additional_field_editable")); additionalField.setOrder(rs.getInt("additional_field_order")); diff --git a/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java b/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java index 4d436ce8a1d..10351283cdb 100644 --- a/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java +++ b/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java @@ -10,6 +10,8 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; + /** * AdditionalField */ @@ -33,7 +35,7 @@ public class AdditionalField { @JsonProperty("value") @Valid @NotNull - private String value = null; + private BigDecimal value = null; @JsonProperty("showOnUi") private Boolean showOnUi = Boolean.TRUE; diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql index f6168017fad..9887f73656f 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql @@ -3,7 +3,7 @@ CREATE TABLE additional_field ( id character varying(64) NOT NULL, census_id character varying(64) NOT NULL, "key" character varying(64) NOT NULL, - "value" character varying(64) NOT NULL, + "value" numeric(12,2) NOT NULL, show_on_ui boolean DEFAULT true NOT NULL, editable boolean DEFAULT true NOT NULL, "order" bigint NOT NULL, From 96a3b9e23e9cbbfdfa15f0b7fde3dfffd297a70b Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 6 Nov 2024 15:05:13 +0530 Subject: [PATCH 286/351] HCMPRE-1162 enrich additionalfieldForCensus --- .../egov/processor/config/Configuration.java | 9 +++ .../processor/config/ServiceConstants.java | 4 ++ .../egov/processor/service/ExcelParser.java | 13 +++-- .../org/egov/processor/util/CensusUtil.java | 56 +++++++++++++++---- .../web/models/census/AdditionalField.java | 48 ++++++++++++++++ .../processor/web/models/census/Census.java | 4 ++ .../src/main/resources/application.properties | 5 +- 7 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java 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 42388c7f226..ac5851bce48 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 @@ -11,6 +11,8 @@ import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.List; + @Component @Data @Import({ TracerConfiguration.class }) @@ -104,4 +106,11 @@ public class Configuration { @Value("${resource.default.limit}") private Integer defaultLimit; + //census additonal field configs + @Value("${census.additional.field.override.keys}") + public List censusAdditionalFieldOverrideKeys; + + @Value("${census.additional.field.prefix.append.keys}") + public List censusAdditionalPrefixAppendKeys; + } 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 811a7e2b53a..60e231e2f80 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 @@ -105,4 +105,8 @@ public class ServiceConstants { public static final String SOURCE_KEY = "source"; public static final String MICROPLAN_SOURCE_KEY = "microplan"; public static final String MICROPLAN_ID_KEY = "microplanId"; + + //Census additional field constants + public static final String UPLOADED_KEY = "UPLOADED_"; + public static final String CONFIRMED_KEY = "CONFIRMED_"; } 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 3aa7ebde5de..0ceb6772b49 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,6 +13,7 @@ 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; @@ -27,10 +28,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import static org.egov.processor.config.ServiceConstants.HCM_ADMIN_CONSOLE_BOUNDARY_DATA; @@ -248,7 +246,12 @@ private void processRowsForCensusRecords(PlanConfigurationRequest planConfigurat Map mappedValues = planConfig.getResourceMapping().stream() .filter(f -> f.getFilestoreId().equals(fileStoreId)) - .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); + .collect(Collectors.toMap( + ResourceMapping::getMappedTo, + ResourceMapping::getMappedFrom, + (existing, replacement) -> existing, + LinkedHashMap::new + )); Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java index 0f544d7b9dc..703072f289e 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java @@ -7,14 +7,17 @@ import org.egov.processor.config.ServiceConstants; import org.egov.processor.kafka.Producer; import org.egov.processor.repository.ServiceRequestRepository; -import org.egov.processor.web.models.*; +import org.egov.processor.web.models.PlanConfiguration; +import org.egov.processor.web.models.PlanConfigurationRequest; +import org.egov.processor.web.models.census.AdditionalField; import org.egov.processor.web.models.census.Census; import org.egov.processor.web.models.census.CensusRequest; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import java.math.BigDecimal; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import static org.egov.processor.config.ServiceConstants.*; @@ -79,7 +82,7 @@ private CensusRequest buildCensusRequest(PlanConfigurationRequest planConfigurat .totalPopulation((BigDecimal) parsingUtil.extractMappedValueFromFeatureForAnInput(ServiceConstants.TOTAL_POPULATION, feature, mappedValues)) .workflow(Workflow.builder().action(WORKFLOW_ACTION_INITIATE).comments(WORKFLOW_COMMENTS_INITIATING_CENSUS).build()) .source(planConfig.getId()) - .additionalDetails(enrichAdditionalDetails(feature, mappedValues)).build()) + .additionalFields(enrichAdditionalField(feature, mappedValues)).build()) .requestInfo(planConfigurationRequest.getRequestInfo()).build(); } @@ -91,21 +94,54 @@ private CensusRequest buildCensusRequest(PlanConfigurationRequest planConfigurat * @param mappedValues The mapped values for extracting properties. * @return A map containing enriched additional details based on the extracted values. */ - public Map enrichAdditionalDetails(JsonNode feature, Map mappedValues) { - // Create additionalDetails object to hold the enriched data - Map additionalDetails = new HashMap<>(); + public List enrichAdditionalField(JsonNode feature, Map mappedValues) { + // Initialize orderCounter inside the function + List additionalFieldList = new ArrayList<>(); + int orderCounter = 1; - // Iterate over mappedValues keys for (String key : mappedValues.keySet()) { + // Skip keys in the override list + if (config.getCensusAdditionalFieldOverrideKeys().contains(key)) + continue; + // Get the corresponding value from the feature JsonNode Object valueFromRow = parsingUtil.extractMappedValueFromFeatureForAnInput(key, feature, mappedValues); - // Check if the value exists in the JSON and add it to additonalDetails map + + // Check if the value exists in the JSON if (!ObjectUtils.isEmpty(valueFromRow)) { - additionalDetails.put(key, valueFromRow); + // Add additional fields with "UPLOADED" and "CONFIRMED" prefixes if key is in override list + if (config.getCensusAdditionalFieldOverrideKeys().contains(key)) { + AdditionalField uploadedField = AdditionalField.builder() + .key(UPLOADED_KEY + key) + .value((BigDecimal) valueFromRow) + .editable(Boolean.TRUE) + .showOnUi(Boolean.TRUE) + .order(orderCounter++) // Increment for "UPLOADED" field + .build(); + additionalFieldList.add(uploadedField); + + AdditionalField confirmedField = AdditionalField.builder() + .key(CONFIRMED_KEY + key) + .value((BigDecimal) valueFromRow) + .editable(Boolean.TRUE) + .showOnUi(Boolean.TRUE) + .order(orderCounter++) // Increment for "CONFIRMED" field + .build(); + additionalFieldList.add(confirmedField); + } else { + AdditionalField additionalField = AdditionalField.builder() + .key(key) + .value((BigDecimal) valueFromRow) + .editable(Boolean.TRUE) + .showOnUi(Boolean.TRUE) + .order(orderCounter++) // Use and increment the local orderCounter + .build(); + additionalFieldList.add(additionalField); + } } } - return additionalDetails; + return additionalFieldList; } } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java new file mode 100644 index 00000000000..972ca77bb4b --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java @@ -0,0 +1,48 @@ +package org.egov.processor.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.math.BigDecimal; + +/** + * AdditionalField + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class AdditionalField { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("key") + @Valid + @NotNull + private String key = null; + + @JsonProperty("value") + @Valid + @NotNull + private BigDecimal value = null; + + @JsonProperty("showOnUi") + private Boolean showOnUi = Boolean.TRUE; + + @JsonProperty("editable") + private Boolean editable = Boolean.TRUE; + + @JsonProperty("order") + private Integer order = null; +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java index 9b6c76df2a6..f895f6c75f1 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java @@ -96,6 +96,10 @@ public class Census { @JsonProperty("additionalDetails") private Object additionalDetails = null; + @JsonProperty("additionalFields") + @Valid + private List additionalFields = null; + @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index 78607ad9dd5..1188a17b894 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -94,4 +94,7 @@ plan.config.trigger.plan.facility.mappings.status=EXECUTION_TO_BE_DONE # Pagination config resource.default.offset=0 -resource.default.limit=10 \ No newline at end of file +resource.default.limit=10 + +census.additional.field.override.keys=HCM_ADMIN_CONSOLE_TARGET_LAT_OPT,HCM_ADMIN_CONSOLE_TARGET_LONG_OPT,HCM_ADMIN_CONSOLE_BOUNDARY_CODE +census.additional.field.prefix.append.keys=HCM_ADMIN_CONSOLE_TOTAL_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59 \ No newline at end of file From 6f2d6ff2c85ed5f1b25c783e89cb8107c699c60f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 6 Nov 2024 15:28:17 +0530 Subject: [PATCH 287/351] HCMPRE-1162 enrich additionalfieldForCensus --- .../src/main/java/org/egov/processor/util/CensusUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java index 703072f289e..a2a5d18dc07 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java @@ -110,7 +110,7 @@ public List enrichAdditionalField(JsonNode feature, Map Date: Fri, 8 Nov 2024 13:24:58 +0530 Subject: [PATCH 288/351] updated query builder for census --- .../repository/impl/CensusRepositoryImpl.java | 29 +++++++- .../querybuilder/CensusQueryBuilder.java | 71 +++++++++++++------ 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index ca1214dc864..62d25ce0c21 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -10,7 +10,9 @@ import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import java.util.ArrayList; @@ -70,10 +72,33 @@ public List search(CensusSearchCriteria censusSearchCriteria) { if(censusSearchCriteria.getAreaCodes() != null && censusSearchCriteria.getAreaCodes().isEmpty()) return new ArrayList<>(); - List preparedStmtList = new ArrayList<>(); - String query = queryBuilder.getCensusQuery(censusSearchCriteria, preparedStmtList); + // Fetch census ids from database + List censusIds = queryDatabaseForCensusIds(censusSearchCriteria); + + // Return empty list back as response if no census ids are found + if(CollectionUtils.isEmpty(censusIds)) { + log.info("No census ids found for provided census search criteria."); + return new ArrayList<>(); + } + + // Fetch census from database based on the acquired ids + return searchCensusByIds(censusIds); + } + + private List searchCensusByIds(List censusIds) { + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getCensusQuery(censusIds, preparedStmtList); + log.info("Census query: " + query); return jdbcTemplate.query(query, censusRowMapper, preparedStmtList.toArray()); + + } + + private List queryDatabaseForCensusIds(CensusSearchCriteria censusSearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getCensusSearchQuery(censusSearchCriteria, preparedStmtList); + log.info("Census search query: " + query); + return jdbcTemplate.query(query, new SingleColumnRowMapper<>(String.class), preparedStmtList.toArray()); } /** diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 8ec4b430a27..71d03bd20ac 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -8,6 +8,7 @@ import org.springframework.util.ObjectUtils; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; @Component @@ -22,7 +23,9 @@ public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { this.queryUtil = queryUtil; } - private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_ancestral_path as census_boundary_ancestral_path, cen.facility_assigned as census_facility_assigned, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + + private static final String CENSUS_SEARCH_BASE_QUERY = "SELECT id FROM census cen"; + + private static final String CENSUS_QUERY = "SELECT cen.id as census_id, cen.tenant_id as census_tenant_id, cen.hierarchy_type as census_hierarchy_type, cen.boundary_code as census_boundary_code, cen.type as census_type, cen.total_population as census_total_population, cen.effective_from as census_effective_from, cen.effective_to as census_effective_to, cen.source as census_source, cen.status as census_status, cen.assignee as census_assignee, cen.boundary_ancestral_path as census_boundary_ancestral_path, cen.facility_assigned as census_facility_assigned, cen.additional_details as census_additional_details, cen.created_by as census_created_by, cen.created_time as census_created_time, cen.last_modified_by as census_last_modified_by, cen.last_modified_time as census_last_modified_time, \n" + "\t pbd.id as population_by_demographics_id, pbd.census_id as population_by_demographics_census_id, pbd.demographic_variable as population_by_demographics_demographic_variable, pbd.population_distribution as population_by_demographics_population_distribution, pbd.created_by as population_by_demographics_created_by, pbd.created_time as population_by_demographics_created_time, pbd.last_modified_by as population_by_demographics_last_modified_by, pbd.last_modified_time as population_by_demographics_last_modified_time, \n" + "\t adf.id as additional_field_id, adf.census_id as additional_field_census_id, adf.key as additional_field_key, adf.value as additional_field_value, adf.show_on_ui as additional_field_show_on_ui, adf.editable as additional_field_editable, adf.order as additional_field_order \n" + "\t FROM census cen \n" + @@ -31,9 +34,9 @@ public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { private static final String CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY cen.last_modified_time DESC"; - private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(DISTINCT census_id) AS total_count FROM ( "; + private static final String CENSUS_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; - private static final String CENSUS_STATUS_COUNT_WRAPPER = "SELECT COUNT(DISTINCT census_id) as census_status_count, census_status FROM ({INTERNAL_QUERY}) as census_status_map GROUP BY census_status"; + private static final String CENSUS_STATUS_COUNT_QUERY = "SELECT COUNT(id) as census_status_count, status as census_status FROM (SELECT id, status FROM census {INTERNAL_QUERY}) as census_status_map GROUP BY census_status"; private static final String BULK_CENSUS_UPDATE_QUERY = "UPDATE census SET status = ?, assignee = ?, last_modified_by = ?, last_modified_time = ?, additional_details = ?, facility_assigned = ? WHERE id = ?"; @@ -41,14 +44,32 @@ public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { * Constructs a SQL query string for searching Census records based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. * - * @param searchCriteria The criteria used for filtering Census records. + * @param ids The census ids used for filtering Census records. * @param preparedStmtList A list to store prepared statement parameters. * @return A complete SQL query string for searching Census records. */ - public String getCensusQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { - String query = buildCensusQuery(searchCriteria, preparedStmtList, Boolean.FALSE, Boolean.FALSE); + public String getCensusQuery(List ids, List preparedStmtList) { + String query = buildCensusQuery(ids, preparedStmtList); query = queryUtil.addOrderByClause(query, CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); - query = getPaginatedQuery(query, preparedStmtList, searchCriteria); + return query; + } + + private String buildCensusQuery(List ids, List preparedStmtList) { + StringBuilder builder = new StringBuilder(CENSUS_QUERY); + + if (!CollectionUtils.isEmpty(ids)) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" cen.id IN ( ").append(queryUtil.createQuery(ids.size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(ids)); + } + + return builder.toString(); + } + + public String getCensusSearchQuery(CensusSearchCriteria censusSearchCriteria, List preparedStmtList) { + String query = buildCensusSearchQuery(censusSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.FALSE); + query = queryUtil.addOrderByClause(query, CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = getPaginatedQuery(query, preparedStmtList, censusSearchCriteria); return query; } @@ -60,7 +81,7 @@ public String getCensusQuery(CensusSearchCriteria searchCriteria, List p * @return A SQL query string to get the total count of Census records for a given search criteria. */ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { - return buildCensusQuery(searchCriteria, preparedStmtList, Boolean.TRUE, Boolean.FALSE); + return buildCensusSearchQuery(searchCriteria, preparedStmtList, Boolean.TRUE, Boolean.FALSE); } /** @@ -72,74 +93,78 @@ public String getCensusCountQuery(CensusSearchCriteria searchCriteria, List preparedStmtList) { CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder().tenantId(searchCriteria.getTenantId()).source(searchCriteria.getSource()).jurisdiction(searchCriteria.getJurisdiction()).build(); - return buildCensusQuery(censusSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); + return buildCensusSearchQuery(censusSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); } /** * Constructs query based on the provided search criteria * - * @param criteria The criteria used for filtering Census records. + * @param criteria The criteria used for filtering Census ids. * @param preparedStmtList A list to store prepared statement parameters. - * @return SQL query string for searching Census records + * @return SQL query string for searching Census ids based on search criteria */ - private String buildCensusQuery(CensusSearchCriteria criteria, List preparedStmtList, Boolean isCount, Boolean isStatusCount) { + private String buildCensusSearchQuery(CensusSearchCriteria criteria, List preparedStmtList, Boolean isCount, Boolean isStatusCount) { StringBuilder builder = new StringBuilder(CENSUS_SEARCH_BASE_QUERY); + if(isStatusCount) { + builder = new StringBuilder(); + } + if (!ObjectUtils.isEmpty(criteria.getId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.id = ?"); + builder.append(" id = ?"); preparedStmtList.add(criteria.getId()); } if (!CollectionUtils.isEmpty(criteria.getIds())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.id IN ( ").append(queryUtil.createQuery(criteria.getIds().size())).append(" )"); + builder.append(" id IN ( ").append(queryUtil.createQuery(criteria.getIds().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, criteria.getIds()); } if (!ObjectUtils.isEmpty(criteria.getTenantId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.tenant_id = ?"); + builder.append(" tenant_id = ?"); preparedStmtList.add(criteria.getTenantId()); } if (!ObjectUtils.isEmpty(criteria.getStatus())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.status = ?"); + builder.append(" status = ?"); preparedStmtList.add(criteria.getStatus()); } if (!ObjectUtils.isEmpty(criteria.getAssignee())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.assignee = ?"); + builder.append(" assignee = ?"); preparedStmtList.add(criteria.getAssignee()); } if (!ObjectUtils.isEmpty(criteria.getSource())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.source = ?"); + builder.append(" source = ?"); preparedStmtList.add(criteria.getSource()); } if (!ObjectUtils.isEmpty(criteria.getFacilityAssigned())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.facility_assigned = ?"); + builder.append(" facility_assigned = ?"); preparedStmtList.add(criteria.getFacilityAssigned()); } if (!ObjectUtils.isEmpty(criteria.getEffectiveTo())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); if (criteria.getEffectiveTo() == 0) { - builder.append(" cen.effective_to IS NULL "); + builder.append(" effective_to IS NULL "); } else { - builder.append(" cen.effective_to = ?"); + builder.append(" effective_to = ?"); preparedStmtList.add(criteria.getEffectiveTo()); } } if (!CollectionUtils.isEmpty(criteria.getAreaCodes())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" cen.boundary_code IN ( ").append(queryUtil.createQuery(criteria.getAreaCodes().size())).append(" )"); + builder.append(" boundary_code IN ( ").append(queryUtil.createQuery(criteria.getAreaCodes().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(criteria.getAreaCodes())); } @@ -159,7 +184,7 @@ private String buildCensusQuery(CensusSearchCriteria criteria, List prep } if (isStatusCount) { - return CENSUS_STATUS_COUNT_WRAPPER.replace("{INTERNAL_QUERY}", builder); + return CENSUS_STATUS_COUNT_QUERY.replace("{INTERNAL_QUERY}", builder); } return builder.toString(); From f6ed213b8a0ba38bbeb45151b53dff71376b2dca Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 8 Nov 2024 15:26:28 +0530 Subject: [PATCH 289/351] handling null pointer exception on updating additional details --- .../census-service/src/main/java/digit/util/CommonUtil.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index eb0363f891b..74b4c65f087 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.NullNode; import com.fasterxml.jackson.databind.node.ObjectNode; import digit.web.models.CensusSearchCriteria; import digit.web.models.CensusSearchRequest; @@ -43,7 +44,9 @@ public Map updateFieldInAdditionalDetails(Object additionalDetai try { // Get or create the additionalDetails as an ObjectNode - ObjectNode objectNode = objectMapper.convertValue(additionalDetails, ObjectNode.class); + ObjectNode objectNode = additionalDetails instanceof NullNode + ? objectMapper.createObjectNode() + : objectMapper.convertValue(additionalDetails, ObjectNode.class); // Update or Add the field in additional details object objectNode.put(fieldToUpdate, updatedValue); From af3a206f363855c24c24762fba3a21f06502ccb8 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 8 Nov 2024 16:00:35 +0530 Subject: [PATCH 290/351] Changes to allow assumption values in input --- .../validator/PlanConfigurationValidator.java | 18 ++++---- .../egov/processor/util/CalculationUtil.java | 45 ++++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 0533fd8bb15..3edc1cb017a 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -3,12 +3,11 @@ import com.fasterxml.jackson.databind.JsonNode; import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; -import digit.util.*; +import digit.util.CampaignUtil; +import digit.util.CommonUtil; +import digit.util.MdmsUtil; +import digit.util.MdmsV2Util; import digit.web.models.*; - -import java.util.*; -import java.util.stream.Collectors; - import digit.web.models.mdmsV2.Mdms; import digit.web.models.projectFactory.CampaignResponse; import lombok.extern.slf4j.Slf4j; @@ -19,6 +18,9 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.util.*; +import java.util.stream.Collectors; + import static digit.config.ServiceConstants.*; @Component @@ -442,7 +444,7 @@ public void validateOperations(PlanConfigurationRequest request, CampaignRespons HashSet allowedColumns = getAllowedColumnsFromMDMS(request, campaignResponse.getCampaignDetails().get(0).getProjectType()); Set activeAssumptionKeys = getActiveAssumptionKeys(planConfiguration); - validateOperationInputs(planConfiguration, allowedColumns); + validateOperationInputs(planConfiguration, allowedColumns, activeAssumptionKeys); validateOperationAssumptionValues(planConfiguration, allowedColumns, activeAssumptionKeys); } } @@ -529,13 +531,13 @@ private Set getActiveAssumptionKeys(PlanConfiguration planConfiguration) * @param planConfiguration The plan configuration containing operations. * @param allowedColumns The allowed column names for input validation. */ - private void validateOperationInputs(PlanConfiguration planConfiguration, HashSet allowedColumns) { + private void validateOperationInputs(PlanConfiguration planConfiguration, HashSet allowedColumns, Set activeAssumptionKeys) { // Set to keep track of previous outputs Set previousOutputs = new HashSet<>(); for (Operation operation : planConfiguration.getOperations()) { // Validate input - if (!allowedColumns.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput()) && operation.getSource() == Source.MDMS) { + if (!allowedColumns.contains(operation.getInput()) && !activeAssumptionKeys.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput()) && operation.getSource() == Source.MDMS) { log.error("Input Value " + operation.getInput() + " is not present in allowed columns or previous outputs"); throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE + operation.getInput()); } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java index 95c504445fa..523f6eb5e70 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java @@ -2,13 +2,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - import org.egov.processor.config.ServiceConstants; import org.egov.processor.web.models.Assumption; import org.egov.processor.web.models.Operation; @@ -18,6 +11,12 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import static org.egov.processor.config.ServiceConstants.PROPERTIES; @Component @@ -84,15 +83,7 @@ public void calculateResources(JsonNode jsonNode, PlanConfigurationRequest planC } } - /** - * Retrieves the input value from the JSON node based on the input and input mapping. - * - * @param resultMap The map containing previous results. - * @param feature The JSON node feature. - * @param input The input key. - * @param columnName The input from mapping. - * @return The input value. - */ + public BigDecimal getInputValueFromJsonFeature(JsonNode feature, Map resultMap, String input, String columnName) { if (resultMap.containsKey(input)) { return resultMap.get(input); @@ -118,12 +109,22 @@ public BigDecimal getInputValueFromJsonFeature(JsonNode feature, Map resultMap, Map assumptionValueMap, String assumptionKey, String columnName) { + /** + * Retrieves the input value from the JSON node based on the input and input mapping. + * + * @param resultMap The map containing previous results. + * @param feature The JSON node feature. + * @param assumptionValueMap The assumptions and their value map from plan config. + * @param input The input key. + * @param columnName The input from mapping. + * @return The input value. + */ + private BigDecimal getInputValueFromFeatureOrMap(JsonNode feature, Map resultMap, Map assumptionValueMap, String input, String columnName) { // Try to fetch the value from resultMap, If not found in the resultMap, use the assumptionValueMap as a fallback - BigDecimal assumptionValue = resultMap.getOrDefault(assumptionKey, assumptionValueMap.get(assumptionKey)); + BigDecimal inputValue = resultMap.getOrDefault(input, assumptionValueMap.get(input)); // Try to fetch the value from the feature (if it exists) - if(ObjectUtils.isEmpty(assumptionValue)) { + if(ObjectUtils.isEmpty(inputValue)) { if (feature.has(PROPERTIES) && feature.get(PROPERTIES).has(columnName)) { try { String cellValue = String.valueOf(feature.get(PROPERTIES).get(columnName)); @@ -137,11 +138,11 @@ private BigDecimal getInputValueFromFeatureOrMap(JsonNode feature, Map resultMap -> assumptionValueMap String assumptionKey = operation.getAssumptionValue(); From 832daba111b995f62a8c57ea4ead2a4f9a6afe7e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 11 Nov 2024 10:48:45 +0530 Subject: [PATCH 291/351] Removing older method for getting input value --- .../egov/processor/util/CalculationUtil.java | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java index 523f6eb5e70..551206d9b94 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java @@ -83,32 +83,6 @@ public void calculateResources(JsonNode jsonNode, PlanConfigurationRequest planC } } - - public BigDecimal getInputValueFromJsonFeature(JsonNode feature, Map resultMap, String input, String columnName) { - if (resultMap.containsKey(input)) { - return resultMap.get(input); - } else { - if (feature.get(PROPERTIES).get(columnName) != null) { - try { - String cellValue = String.valueOf(feature.get(PROPERTIES).get(columnName)); - BigDecimal value; - // Handle scientific notation - if (cellValue.contains(ServiceConstants.SCIENTIFIC_NOTATION_INDICATOR)) { - value = new BigDecimal(cellValue); - } else { - String cleanedValue = cellValue.replaceAll("[^\\d.\\-E]", ""); - value = new BigDecimal(cleanedValue); - } - return value; - } catch (NumberFormatException | NullPointerException e) { - return BigDecimal.ZERO; - } - } else { - throw new CustomException("INPUT_VALUE_NOT_FOUND", "Input value not found: " + input); - } - } - } - /** * Retrieves the input value from the JSON node based on the input and input mapping. * From 543934bc7ebd0c16d6a4dd1ec2e53d51970cfcf2 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 11 Nov 2024 10:55:50 +0530 Subject: [PATCH 292/351] Making editable false for uploaded additional field during census create --- .../src/main/java/org/egov/processor/util/CensusUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java index a2a5d18dc07..eccc736bf92 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java @@ -114,7 +114,7 @@ public List enrichAdditionalField(JsonNode feature, Map Date: Mon, 11 Nov 2024 15:58:37 +0530 Subject: [PATCH 293/351] HCMPRE-853 removing lat long fields from additional field overridekeys --- .../src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index 1188a17b894..9f13ea45855 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -96,5 +96,5 @@ plan.config.trigger.plan.facility.mappings.status=EXECUTION_TO_BE_DONE resource.default.offset=0 resource.default.limit=10 -census.additional.field.override.keys=HCM_ADMIN_CONSOLE_TARGET_LAT_OPT,HCM_ADMIN_CONSOLE_TARGET_LONG_OPT,HCM_ADMIN_CONSOLE_BOUNDARY_CODE +census.additional.field.override.keys=HCM_ADMIN_CONSOLE_BOUNDARY_CODE census.additional.field.prefix.append.keys=HCM_ADMIN_CONSOLE_TOTAL_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59 \ No newline at end of file From b73e04811e3b8b9cfeaee243bd95b89603087b2e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 11 Nov 2024 18:39:22 +0530 Subject: [PATCH 294/351] Changes for adding execution order for operations --- .../querybuilder/PlanConfigQueryBuilder.java | 9 +++--- .../rowmapper/PlanConfigRowMapper.java | 15 +++++----- .../service/enrichment/EnrichmentService.java | 29 ++++++++++++++++--- .../validator/PlanConfigurationValidator.java | 17 ++--------- .../src/main/java/digit/util/CommonUtil.java | 18 +++++++++--- .../main/java/digit/web/models/Operation.java | 3 ++ ...151500__alter_operations_add_order_ddl.sql | 2 ++ .../egov/processor/service/ExcelParser.java | 6 +++- .../processor/util/PlanConfigurationUtil.java | 18 +++++++----- .../egov/processor/web/models/Operation.java | 3 ++ 10 files changed, 76 insertions(+), 44 deletions(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 3357073e976..dca32316c89 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -1,16 +1,15 @@ package digit.repository.querybuilder; import digit.config.Configuration; - import digit.util.QueryUtil; import digit.web.models.PlanConfigurationSearchCriteria; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.LinkedHashSet; import java.util.List; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; @Component @@ -30,7 +29,7 @@ public PlanConfigQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_CONFIG_QUERY = "SELECT pc.id as plan_configuration_id, pc.tenant_id as plan_configuration_tenant_id, pc.name as plan_configuration_name, pc.campaign_id as plan_configuration_campaign_id, pc.status as plan_configuration_status, pc.additional_details as plan_configuration_additional_details, pc.created_by as plan_configuration_created_by, pc.created_time as plan_configuration_created_time, pc.last_modified_by as plan_configuration_last_modified_by, pc.last_modified_time as plan_configuration_last_modified_time, \n" + "\t pcf.id as plan_configuration_files_id, pcf.plan_configuration_id as plan_configuration_files_plan_configuration_id, pcf.filestore_id as plan_configuration_files_filestore_id, pcf.input_file_type as plan_configuration_files_input_file_type, pcf.template_identifier as plan_configuration_files_template_identifier, pcf.active as plan_configuration_files_active, pcf.created_by as plan_configuration_files_created_by, pcf.created_time as plan_configuration_files_created_time, pcf.last_modified_by as plan_configuration_files_last_modified_by, pcf.last_modified_time as plan_configuration_files_last_modified_time,\n" + "\t pca.id as plan_configuration_assumptions_id, pca.key as plan_configuration_assumptions_key, pca.value as plan_configuration_assumptions_value, pca.source as plan_configuration_assumptions_source, pca.category as plan_configuration_assumptions_category, pca.active as plan_configuration_assumptions_active, pca.plan_configuration_id as plan_configuration_assumptions_plan_configuration_id, pca.created_by as plan_configuration_assumptions_created_by, pca.created_time as plan_configuration_assumptions_created_time, pca.last_modified_by as plan_configuration_assumptions_last_modified_by, pca.last_modified_time as plan_configuration_assumptions_last_modified_time,\n" + - "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.source as plan_configuration_operations_source, pco.category as plan_configuration_operations_category, pco.active as plan_configuration_operations_active, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + + "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.source as plan_configuration_operations_source, pco.category as plan_configuration_operations_category, pco.active as plan_configuration_operations_active, pco.execution_order as plan_configuration_execution_order, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + "\t pcm.id as plan_configuration_mapping_id, pcm.filestore_id as plan_configuration_mapping_filestore_id, pcm.mapped_from as plan_configuration_mapping_mapped_from, pcm.mapped_to as plan_configuration_mapping_mapped_to, pcm.active as plan_configuration_mapping_active, pcm.plan_configuration_id as plan_configuration_mapping_plan_configuration_id, pcm.created_by as plan_configuration_mapping_created_by, pcm.created_time as plan_configuration_mapping_created_time, pcm.last_modified_by as plan_configuration_mapping_last_modified_by, pcm.last_modified_time as plan_configuration_mapping_last_modified_time\n" + "\t FROM plan_configuration pc\n" + "\t LEFT JOIN plan_configuration_files pcf ON pc.id = pcf.plan_configuration_id\n" + diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index 83ca049b8cb..f289c5d4818 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java @@ -2,13 +2,6 @@ import digit.util.QueryUtil; import digit.web.models.*; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; import org.egov.common.contract.models.AuditDetails; import org.postgresql.util.PGobject; import org.springframework.dao.DataAccessException; @@ -17,6 +10,13 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + @Component public class PlanConfigRowMapper implements ResultSetExtractor> { @@ -158,6 +158,7 @@ private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Map< operation.setShowOnEstimationDashboard(rs.getBoolean("plan_configuration_operations_show_on_estimation_dashboard")); operation.setSource(Source.valueOf(rs.getString("plan_configuration_operations_source"))); operation.setCategory(rs.getString("plan_configuration_operations_category")); + operation.setExecutionOrder(rs.getInt("plan_configuration_execution_order")); if (CollectionUtils.isEmpty(planConfigEntry.getOperations())) { List operationList = new ArrayList<>(); diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index 3847513043c..df7a8a81261 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java @@ -1,6 +1,7 @@ package digit.service.enrichment; import digit.config.Configuration; +import digit.util.CommonUtil; import digit.web.models.File; import digit.web.models.PlanConfiguration; import digit.web.models.PlanConfigurationRequest; @@ -9,22 +10,24 @@ import org.egov.common.utils.UUIDEnrichmentUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.List; import static digit.config.ServiceConstants.DRAFT_STATUS; -import org.springframework.util.CollectionUtils; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; -import org.springframework.util.ObjectUtils; - @Component @Slf4j public class EnrichmentService { private Configuration config; - public EnrichmentService(Configuration config) { + private CommonUtil commonUtil; + + public EnrichmentService(Configuration config, CommonUtil commonUtil) { this.config = config; + this.commonUtil = commonUtil; } /** @@ -120,6 +123,11 @@ public void enrichUpdate(PlanConfigurationRequest request) { } planConfiguration.setAuditDetails(prepareAuditDetails(request.getPlanConfiguration().getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); + + //enrich execution order for operations on setup complete + if (commonUtil.isSetupCompleted(planConfiguration)) { + enrichExecutionOrderForOperations(planConfiguration); + } } /** @@ -181,4 +189,17 @@ public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest req } } + /** + * Sets a sequential execution order for each operation in the given PlanConfiguration. + * + * @param planConfiguration the configuration containing operations to order + */ + public void enrichExecutionOrderForOperations(PlanConfiguration planConfiguration) { + int executionOrderCounter = 1; + + for (Operation operation : planConfiguration.getOperations()) { + operation.setExecutionOrder(executionOrderCounter++); + } + } + } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 3edc1cb017a..d142d9f8328 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -16,7 +16,6 @@ import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; import java.util.*; import java.util.stream.Collectors; @@ -242,7 +241,7 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque } // Ensure at least one active file for each required template identifier - if(isSetupCompleted(planConfiguration)){ + if(commonUtil.isSetupCompleted(planConfiguration)){ requiredTemplateIdentifierSetFromMDMS.forEach(requiredTemplate -> { if (!activeRequiredTemplates.contains(requiredTemplate)) { log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); @@ -380,18 +379,6 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration } } - /** - * Checks if the setup process is completed based on the workflow action in the plan configuration. - * - * @param planConfiguration The plan configuration to check. - * @return true if the setup is completed, otherwise false. - */ - public boolean isSetupCompleted(PlanConfiguration planConfiguration) { - if(!ObjectUtils.isEmpty(planConfiguration.getWorkflow())) - return Objects.equals(planConfiguration.getWorkflow().getAction(), SETUP_COMPLETED_ACTION); - - return false; - } /** * Checks if files are empty or null when the setup action is marked as completed. @@ -438,7 +425,7 @@ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { public void validateOperations(PlanConfigurationRequest request, CampaignResponse campaignResponse) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - if (isSetupCompleted(planConfiguration)) { + if (commonUtil.isSetupCompleted(planConfiguration)) { performEmptyChecks(planConfiguration); HashSet allowedColumns = getAllowedColumnsFromMDMS(request, campaignResponse.getCampaignDetails().get(0).getProjectType()); diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index fc50b278d41..0d47cdf9765 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -12,10 +12,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import static digit.config.ServiceConstants.*; @@ -188,4 +185,17 @@ public Map getMicroplanHierarchy(Object mdmsData) { return hierarchyMap; } + + /** + * Checks if the setup process is completed based on the workflow action in the plan configuration. + * + * @param planConfiguration The plan configuration to check. + * @return true if the setup is completed, otherwise false. + */ + public boolean isSetupCompleted(PlanConfiguration planConfiguration) { + if(!ObjectUtils.isEmpty(planConfiguration.getWorkflow())) + return Objects.equals(planConfiguration.getWorkflow().getAction(), SETUP_COMPLETED_ACTION); + + return false; + } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/Operation.java b/health-services/plan-service/src/main/java/digit/web/models/Operation.java index c4b7922da14..7e102e83b60 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Operation.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Operation.java @@ -61,6 +61,9 @@ public class Operation { @Size(min = 2, max = 64) private String category = null; + @JsonProperty("executionOrder") + private Integer executionOrder = null; + @JsonProperty("active") @NotNull private Boolean active = true; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql new file mode 100644 index 00000000000..55852f824c2 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql @@ -0,0 +1,2 @@ +ALTER TABLE plan_configuration_operations +ADD COLUMN execution_order numeric(12,2); 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 0ceb6772b49..591909f428f 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 @@ -62,9 +62,11 @@ public class ExcelParser implements FileParser { private EnrichmentUtil enrichmentUtil; + private PlanConfigurationUtil planConfigurationUtil; + 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) { + Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil, EnrichmentUtil enrichmentUtil, PlanConfigurationUtil planConfigurationUtil) { this.objectMapper = objectMapper; this.parsingUtil = parsingUtil; this.filestoreUtil = filestoreUtil; @@ -77,6 +79,7 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore this.localeUtil = localeUtil; this.censusUtil = censusUtil; this.enrichmentUtil = enrichmentUtil; + this.planConfigurationUtil = planConfigurationUtil; } /** @@ -198,6 +201,7 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, LocaleResponse localeResponse = localeUtil.searchLocale(request); Object mdmsData = mdmsUtil. fetchMdmsData(request.getRequestInfo(), request.getPlanConfiguration().getTenantId()); + planConfigurationUtil.orderPlanConfigurationOperations(request); enrichmentUtil.enrichResourceMapping(request, localeResponse, campaign.getCampaign().get(0).getProjectType(), fileStoreId); Map attributeNameVsDataTypeMap = prepareAttributeVsIndexMap(request, fileStoreId, campaign, request.getPlanConfiguration(), mdmsData); diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java index 26a11dcf976..55a8651ec56 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java @@ -1,19 +1,17 @@ package org.egov.processor.util; import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import lombok.extern.slf4j.Slf4j; - import org.egov.processor.config.Configuration; import org.egov.processor.repository.ServiceRequestRepository; -import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.PlanConfigurationResponse; -import org.egov.processor.web.models.PlanConfigurationSearchRequest; +import org.egov.processor.web.models.*; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + import static org.egov.processor.config.ServiceConstants.ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE; @Component @@ -54,4 +52,8 @@ public List search(PlanConfigurationSearchRequest planConfigu else return planConfigurationList; } + + public void orderPlanConfigurationOperations(PlanConfigurationRequest planConfigurationRequest) { + planConfigurationRequest.getPlanConfiguration().getOperations().sort(Comparator.comparingInt(Operation::getExecutionOrder)); + } } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java index 6147edb0f02..5194da66b18 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java @@ -61,6 +61,9 @@ public class Operation { @Size(min = 2, max = 64) private String category = null; + @JsonProperty("executionOrder") + private Integer executionOrder = null; + @JsonProperty("active") @NotNull private Boolean active = true; From 10025ffeb8465a5e8ca293fc13795cb926d1dd54 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 11 Nov 2024 18:41:20 +0530 Subject: [PATCH 295/351] Changes for adding execution order for operations --- .../java/digit/service/enrichment/EnrichmentService.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index df7a8a81261..0172642fa11 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java @@ -2,10 +2,7 @@ import digit.config.Configuration; import digit.util.CommonUtil; -import digit.web.models.File; -import digit.web.models.PlanConfiguration; -import digit.web.models.PlanConfigurationRequest; -import digit.web.models.ResourceMapping; +import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.UUIDEnrichmentUtil; import org.egov.tracer.model.CustomException; From 670383b4f66195bd7473c2391586c2c7bb891e15 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 12 Nov 2024 11:30:12 +0530 Subject: [PATCH 296/351] Adding facilityName column and enriching servingPop --- .../java/digit/config/ServiceConstants.java | 6 ++ .../impl/PlanFacilityRepositoryImpl.java | 1 + .../PlanFacilityQueryBuilder.java | 9 ++ .../rowmapper/PlanFacilityRowMapper.java | 1 + .../enrichment/PlanFacilityEnricher.java | 75 +++++++++++++++-- .../validator/PlanConfigurationValidator.java | 10 +-- .../validator/PlanFacilityValidator.java | 23 ++++- .../src/main/java/digit/util/CommonUtil.java | 84 +++++++++++++++++-- .../java/digit/web/models/PlanFacility.java | 5 +- .../digit/web/models/PlanFacilityDTO.java | 3 + .../models/census/CensusSearchCriteria.java | 10 +++ ...0__plan_facility_add_facility_name_ddl.sql | 1 + 12 files changed, 209 insertions(+), 19 deletions(-) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 3afbcb359fa..5a8925f2c26 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -179,6 +179,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 ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE = "ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS"; + public static final String ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE = "Exception occurred while updating additional details : "; + public static final String WORKFLOW_INTEGRATION_ERROR_CODE = "WORKFLOW_INTEGRATION_ERROR"; public static final String WORKFLOW_INTEGRATION_ERROR_MESSAGE = "Exception occured while integrating with workflow : "; @@ -349,4 +352,7 @@ public class ServiceConstants { public static final String FACILITY_TYPE_SEARCH_PARAMETER_KEY = "facilityType"; public static final String COMMA_DELIMITER = ","; + + public static final String SERVING_POPULATION_CODE = "servingPopulation"; + } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index a28b3989279..6d37cbf7f9c 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -58,6 +58,7 @@ public PlanFacilityRequestDTO convertToDTO(PlanFacilityRequest planFacilityReque .tenantId(planFacility.getTenantId()) .planConfigurationId(planFacility.getPlanConfigurationId()) .facilityId(planFacility.getFacilityId()) + .facilityName(planFacility.getFacilityName()) .residingBoundary(planFacility.getResidingBoundary()) .serviceBoundaries(convertArrayToString(planFacility.getServiceBoundaries())) .initiallySetServiceBoundaries(planFacility.getInitiallySetServiceBoundaries()) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index 6dabdab2bf4..4de3bbe3f11 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Set; +import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; + @Component public class PlanFacilityQueryBuilder { @@ -27,6 +29,7 @@ public PlanFacilityQueryBuilder(Configuration config, QueryUtil queryUtil) { "plan_facility_linkage.tenant_id as plan_facility_tenant_id, " + "plan_facility_linkage.plan_configuration_id as plan_facility_plan_configuration_id, " + "plan_facility_linkage.facility_id as plan_facility_facility_id, " + + "plan_facility_linkage.facility_name as plan_facility_facility_name, " + "plan_facility_linkage.residing_boundary as plan_facility_residing_boundary, " + "plan_facility_linkage.service_boundaries as plan_facility_service_boundaries, " + "plan_facility_linkage.additional_details as plan_facility_additional_details, " + @@ -74,6 +77,12 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil preparedStmtList.add(planFacilitySearchCriteria.getFacilityId()); } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityName())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" facility_name LIKE ? "); + preparedStmtList.add(PERCENTAGE_WILDCARD + planFacilitySearchCriteria.getFacilityName() + PERCENTAGE_WILDCARD); + } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getResidingBoundaries())) { List residingBoundaries = planFacilitySearchCriteria.getResidingBoundaries(); queryUtil.addClauseIfRequired(builder, preparedStmtList); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java index 48331c86b75..ed0545f49e4 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java @@ -47,6 +47,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAcc planFacilityEntry.setTenantId(rs.getString("plan_facility_tenant_id")); planFacilityEntry.setPlanConfigurationId(rs.getString("plan_facility_plan_configuration_id")); planFacilityEntry.setFacilityId(rs.getString("plan_facility_facility_id")); + planFacilityEntry.setFacilityName(rs.getString("plan_facility_facility_name")); planFacilityEntry.setResidingBoundary(rs.getString("plan_facility_residing_boundary")); String serviceBoundaries = rs.getString("plan_facility_service_boundaries"); planFacilityEntry.setServiceBoundaries(ObjectUtils.isEmpty(serviceBoundaries) ? new ArrayList<>() : Arrays.asList(serviceBoundaries.split(","))); diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 3aef5852f76..a658963f62c 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -1,9 +1,15 @@ package digit.service.enrichment; +import digit.util.CensusUtil; +import digit.util.CommonUtil; import digit.web.models.PlanFacility; import digit.web.models.PlanFacilityRequest; import digit.web.models.PlanFacilitySearchCriteria; import digit.web.models.PlanFacilitySearchRequest; +import digit.web.models.census.Census; +import digit.web.models.census.CensusResponse; +import digit.web.models.census.CensusSearchCriteria; +import digit.web.models.census.CensusSearchRequest; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.AuditDetailsEnrichmentUtil; @@ -12,8 +18,8 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; import static digit.config.ServiceConstants.*; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @@ -22,6 +28,15 @@ @Slf4j public class PlanFacilityEnricher { + private CommonUtil commonUtil; + + private CensusUtil censusUtil; + + public PlanFacilityEnricher(CommonUtil commonUtil, CensusUtil censusUtil) { + this.commonUtil = commonUtil; + this.censusUtil = censusUtil; + } + /** * Enriches the plan facility create request * @@ -51,6 +66,57 @@ public void enrichPlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { //enrich audit details planFacility.setAuditDetails(prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.FALSE)); + + // enrich serving population + enrichServingPopulation(planFacilityRequest); + } + + private void enrichServingPopulation(PlanFacilityRequest planFacilityRequest) { + PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + Set boundariesToBeSearched = new HashSet<>(planFacility.getServiceBoundaries()); + boundariesToBeSearched.addAll(planFacility.getInitiallySetServiceBoundaries()); + + if(!CollectionUtils.isEmpty(boundariesToBeSearched)) { + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder() + .tenantId(planFacility.getTenantId()) + .source(planFacility.getPlanConfigurationId()) + .areaCodes(new ArrayList<>(boundariesToBeSearched)) + .limit(boundariesToBeSearched.size()) + .build(); + + CensusResponse censusResponse = censusUtil.fetchCensusRecords(CensusSearchRequest.builder() + .requestInfo(planFacilityRequest.getRequestInfo()) + .censusSearchCriteria(censusSearchCriteria) + .build()); + + // Create a population map + Map boundaryToPopMap = censusResponse.getCensus().stream() + .collect(Collectors.toMap(Census::getBoundaryCode, Census::getTotalPopulation)); + + // Get existing servingPopulation or default to 0 + Double servingPopulation = (Double) commonUtil.extractFieldsFromJsonObject(planFacility.getAdditionalDetails(), SERVING_POPULATION_CODE); + + updateServingPopulation(boundariesToBeSearched, planFacility, boundaryToPopMap, servingPopulation); + } + } + + private void updateServingPopulation(Set boundariesToBeSearched, PlanFacility planFacility, Map boundaryToPopMap, Double servingPopulation) { + Set currentServiceBoundaries = new HashSet<>(planFacility.getServiceBoundaries()); + Set initialServiceBoundaries = new HashSet<>(planFacility.getInitiallySetServiceBoundaries()); + + for(String boundary : boundariesToBeSearched) { + Long totalPopulation = boundaryToPopMap.get(boundary); + + if (!currentServiceBoundaries.contains(boundary)) { + servingPopulation -= totalPopulation; + } else if (!initialServiceBoundaries.contains(boundary)) { + servingPopulation += totalPopulation; + } + } + Map fieldToUpdate = new HashMap<>(); + fieldToUpdate.put(SERVING_POPULATION_CODE, servingPopulation); + + planFacility.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(planFacility.getAdditionalDetails(), fieldToUpdate)); } /** @@ -64,11 +130,6 @@ public void enrichSearchRequest(PlanFacilitySearchRequest planFacilitySearchRequ // Filter map for filtering facility meta data present in additional details Map filtersMap = new LinkedHashMap<>(); - // Add facility name as a filter if present in search criteria - if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityName())) { - filtersMap.put(FACILITY_NAME_SEARCH_PARAMETER_KEY, planFacilitySearchCriteria.getFacilityName()); - } - // Add facility status as a filter if present in search criteria if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityStatus())) { filtersMap.put(FACILITY_STATUS_SEARCH_PARAMETER_KEY, planFacilitySearchCriteria.getFacilityStatus()); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 0533fd8bb15..832d7732d65 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -149,11 +149,11 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O throw new CustomException(ADDITIONAL_DETAILS_MISSING_CODE, ADDITIONAL_DETAILS_MISSING_MESSAGE); } - String jsonPathForAssumption = commonUtil.createJsonPathForAssumption(commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); + String jsonPathForAssumption = commonUtil.createJsonPathForAssumption((String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); List assumptionListFromMDMS = null; try { log.info(jsonPathForAssumption); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 7fbea162514..95a68a7fa27 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -5,6 +5,7 @@ import digit.repository.PlanFacilityRepository; import digit.util.*; import digit.web.models.*; +import digit.web.models.facility.Facility; import digit.web.models.facility.FacilityResponse; import digit.web.models.projectFactory.CampaignDetail; import digit.web.models.projectFactory.CampaignResponse; @@ -29,14 +30,16 @@ public class PlanFacilityValidator { private MultiStateInstanceUtil centralInstanceUtil; private MdmsUtil mdmsUtil; private FacilityUtil facilityUtil; + private CommonUtil commonUtil; - public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil) { + public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil, CommonUtil commonUtil) { this.planFacilityRepository = planFacilityRepository; this.planConfigurationRepository = planConfigurationRepository; this.campaignUtil = campaignUtil; this.centralInstanceUtil = centralInstanceUtil; this.mdmsUtil = mdmsUtil; this.facilityUtil = facilityUtil; + this.commonUtil = commonUtil; } /** @@ -264,6 +267,24 @@ private void validateFacilityExistence(PlanFacilityRequest planFacilityRequest) if (ObjectUtils.isEmpty(facilityResponse) || CollectionUtils.isEmpty(facilityResponse.getFacilities())) { throw new CustomException("FACILITY_NOT_FOUND", "Facility with ID " + planFacilityRequest.getPlanFacility().getFacilityId() + " not found in the system."); } + + enrichFacilityDetails(facilityResponse.getFacilities().get(0), planFacilityRequest); + } + + private void enrichFacilityDetails(Facility facility, PlanFacilityRequest planFacilityRequest) { + String facilityName = facility.getName(); + planFacilityRequest.getPlanFacility().setFacilityName(facilityName); + Double initialServingPop = 0.0; + + Map fieldsToBeAdded = new HashMap<>(); + fieldsToBeAdded.put("facilityUsage", facility.getUsage()); + fieldsToBeAdded.put("storageCapacity", facility.getStorageCapacity()); + fieldsToBeAdded.put("facilityType", facility.getAddress().getType()); + fieldsToBeAdded.put("isPermanent", facility.isPermanent()); + fieldsToBeAdded.put("servingPopulation", initialServingPop); + + planFacilityRequest.getPlanFacility().setAdditionalDetails( + commonUtil.updateFieldInAdditionalDetails(planFacilityRequest.getPlanFacility().getAdditionalDetails(), fieldsToBeAdded)); } } diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index fc50b278d41..9bde0cd5a65 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.DecimalNode; +import com.fasterxml.jackson.databind.node.NullNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; import digit.web.models.*; @@ -55,17 +58,26 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri * @return the value of the specified field as a string * @throws CustomException if the field does not exist */ - public String extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract) { + 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) { - // Convert the node to a String - return objectMapper.convertValue(node, String.class); + if (node != null && !node.isNull()) { + // Check for different types of JSON nodes + if (node instanceof DecimalNode) { + return ((DecimalNode) node).decimalValue(); + } else if (node.isDouble() || node.isFloat()) { + return node.asDouble(); + } else if (node.isLong() || node.isInt()) { + return node.asLong(); + } else if (node.isBoolean()) { + return node.asBoolean(); + } else if (node.isTextual()) { + return node.asText(); + } } - // Return null if the node is empty return null; } catch (Exception e) { log.error(e.getMessage() + fieldToExtract); @@ -73,6 +85,7 @@ public String extractFieldsFromJsonObject(Object additionalDetails, String field } } + /** * Extracts provided field from the additional details object * @@ -188,4 +201,65 @@ public Map getMicroplanHierarchy(Object mdmsData) { return hierarchyMap; } + + /** + * Adds or updates the provided fields in the additional details object. + * + * @param additionalDetails the additional details object to be updated. + * @param fieldsToBeUpdated map of field to be updated and it's updated value. + * @return returns the updated additional details object. + */ + + public Map updateFieldInAdditionalDetails(Object additionalDetails, Map fieldsToBeUpdated) { + try { + // Debug print statements for inspection + System.out.println("Initial additionalDetails: " + additionalDetails); + System.out.println("Fields to be updated: " + fieldsToBeUpdated); + + // Get or create the additionalDetails as an ObjectNode + ObjectNode objectNode = (additionalDetails == null || additionalDetails instanceof NullNode) + ? objectMapper.createObjectNode() + : objectMapper.convertValue(additionalDetails, ObjectNode.class); + + // Debugging ObjectNode before update + System.out.println("ObjectNode before update: " + objectNode); + + // Update or add the field in additional details object + fieldsToBeUpdated.forEach((key, value) -> objectNode.set(key, objectMapper.valueToTree(value))); + + // Debugging ObjectNode after update + System.out.println("ObjectNode after update: " + objectNode); + + // Convert updated ObjectNode back to a Map + Map updatedMap = objectMapper.convertValue(objectNode, Map.class); + System.out.println("Updated Map to return: " + updatedMap); + + return updatedMap; + + } catch (Exception e) { + throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE + e); + } + } + +// public Map updateFieldInAdditionalDetails(Object additionalDetails, Map fieldsToBeUpdated) { +// try { +// +// // Get or create the additionalDetails as an ObjectNode +// ObjectNode objectNode = (additionalDetails == null || additionalDetails instanceof NullNode) +// ? objectMapper.createObjectNode() +// : objectMapper.convertValue(additionalDetails, ObjectNode.class); +// +// // Update or Add the field in additional details object +// fieldsToBeUpdated.forEach((key, value) -> objectNode.set(key, objectMapper.valueToTree(value))); +// +// // Convert updated ObjectNode back to a Map +// return objectMapper.convertValue(objectNode, Map.class); +// +// } catch (Exception e) { +// throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE + e); +// } +// +// +// +// } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 7237d7c8bd6..71390c5a33b 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -43,6 +43,9 @@ public class PlanFacility { @Size(max = 64) private String facilityId = null; + @JsonProperty("facilityName") + private String facilityName = null; + @JsonProperty("residingBoundary") @NotNull @Size(min = 1, max = 64) @@ -54,7 +57,7 @@ public class PlanFacility { private List serviceBoundaries; @JsonIgnore - private List initiallySetServiceBoundaries; + private List initiallySetServiceBoundaries = new ArrayList<>(); @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java index 3683177792e..4a59a947d35 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java @@ -53,6 +53,9 @@ public class PlanFacilityDTO { @JsonProperty("initiallySetServiceBoundaries") private List initiallySetServiceBoundaries; + @JsonProperty("facilityName") + private String facilityName = null; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java index f512c04732f..4a5a1414d19 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.springframework.validation.annotation.Validated; import jakarta.validation.constraints.*; @@ -26,6 +27,9 @@ public class CensusSearchCriteria { @JsonProperty("id") private String id = null; + @JsonProperty("ids") + private Set ids = null; + @JsonProperty("tenantId") @Size(min = 1, max = 100) private String tenantId = null; @@ -51,6 +55,12 @@ public class CensusSearchCriteria { @JsonProperty("effectiveTo") private Long effectiveTo = null; + @JsonProperty("limit") + private Integer limit = null; + + @JsonProperty("offset") + private Integer offset = null; + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { this.areaCodes = new ArrayList<>(); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql new file mode 100644 index 00000000000..7a10bbde149 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE plan_facility_linkage ADD facility_name character varying(64); \ No newline at end of file From cfc21d2bdd919afc32d24447b1d1d6be96a3c5cf Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 8 Nov 2024 13:16:22 +0530 Subject: [PATCH 297/351] HCMPRE-853 added chnages for census search and fetching boundarycodes from one sheet --- .../egov/processor/config/Configuration.java | 7 ++ .../processor/config/ServiceConstants.java | 5 + .../egov/processor/service/ExcelParser.java | 32 ++----- .../util/CampaignIntegrationUtil.java | 39 +------- .../org/egov/processor/util/CensusUtil.java | 47 +++++++++- .../egov/processor/util/EnrichmentUtil.java | 49 +++++++++- .../org/egov/processor/util/ParsingUtil.java | 91 ++++++++++++++----- .../src/main/resources/application.properties | 4 + 8 files changed, 187 insertions(+), 87 deletions(-) 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 ac5851bce48..cac270a815b 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 @@ -113,4 +113,11 @@ public class Configuration { @Value("${census.additional.field.prefix.append.keys}") public List censusAdditionalPrefixAppendKeys; + //census host + @Value("${egov.census.host}") + private String censusHost; + + @Value("${egov.census.search.endpoint}") + private String censusSearchEndPoint; + } 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 60e231e2f80..d217a5026f5 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 @@ -12,6 +12,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; + public static final String ERROR_WHILE_FETCHING_FROM_CENSUS = "Exception occurred while fetching records from census: "; + public static final String TENANTID_REPLACER = "{tenantId}"; public static final String TENANTID = "tenantId"; @@ -40,6 +42,9 @@ public class ServiceConstants { 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."; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE = "NO_CENSUS_FOUND_FOR_GIVEN_DETAILS"; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE = "Census records does not exists for the given details: "; + public static final String BOUNDARY_CODE = "HCM_ADMIN_CONSOLE_BOUNDARY_CODE"; public static final String TOTAL_POPULATION = "HCM_ADMIN_CONSOLE_TOTAL_POPULATION"; 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 591909f428f..9dd07dbd973 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 @@ -212,6 +212,7 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, if (isSheetAllowedToProcess(request, excelWorkbookSheet.getSheetName(), localeResponse)) { if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { + enrichmentUtil.enrichsheetWithApprovedCensusRecords(excelWorkbookSheet, request, fileStoreId); processRows(request, excelWorkbookSheet, dataFormatter, fileStoreId, campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); } else if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { @@ -258,12 +259,12 @@ private void processRowsForCensusRecords(PlanConfigurationRequest planConfigurat )); Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); - Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, - campaignIntegrationUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); Row firstRow = null; for (Row row : sheet) { - if (isRowEmpty(row)) + if (parsingUtil.isRowEmpty(row)) continue; if (row.getRowNum() == 0) { @@ -341,11 +342,11 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat .convertAssumptionsToMap(planConfig.getAssumptions()); Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); - Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, - campaignIntegrationUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); for (Row row : sheet) { - if(isRowEmpty(row)) + if(parsingUtil.isRowEmpty(row)) continue; if (row.getRowNum() == 0) { @@ -368,25 +369,6 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat } } - /** - * Checks if a given row is empty. - * - * A row is considered empty if it is null or if all of its cells are empty or of type BLANK. - * - * @param row the Row to check - * @return true if the row is empty, false otherwise - */ - public static boolean isRowEmpty(Row row) { - if (row == null) { - return true; - } - for (Cell cell : row) { - if (cell != null && cell.getCellType() != CellType.BLANK) { - return false; - } - } - return true; - } /** * Performs calculations on operations for a specific row in the sheet. 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 ca9e0ffe9d7..7a6fe38d6fa 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 @@ -28,6 +28,7 @@ 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) { @@ -35,6 +36,7 @@ public CampaignIntegrationUtil(ServiceRequestRepository serviceRequestRepository this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.mapper = mapper; + this.parsingUtil= parsingUtil; } /** @@ -177,29 +179,13 @@ public void updateCampaignBoundary(PlanConfiguration planConfig, JsonNode featur boolean validToAdd = false; Integer indexValue = 0; Boundary boundary = new Boundary(); - List> sortedColumnList = sortColumnByIndex(mapOfColumnNameAndIndex); - indexValue = getIndexOfBoundaryCode(indexValue, sortedColumnList, mappedValues); + 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); } - /** - * Retrieves the index value of the boundary code from the sorted column list based on the mapped values. - * - * @param indexValue The initial index value. - * @param sortedColumnList The sorted list of column names and indices. - * @param mappedValues The map containing mapped values. - * @return The index value of the boundary code. - */ - public Integer getIndexOfBoundaryCode(Integer indexValue, List> sortedColumnList,Map mappedValues) { - for (Map.Entry entry : sortedColumnList) { - if (entry.getKey().equals(mappedValues.get(ServiceConstants.BOUNDARY_CODE))) { - indexValue = entry.getValue(); - } - } - return indexValue; - } /** * Prepares a campaign boundary based on the provided index values, sorted column list, feature, and mapped values. @@ -253,22 +239,7 @@ private boolean isValidToAdd(List boundaryList, Map> sortColumnByIndex(Map mapOfColumnNameAndIndex) { - List> sortedColumnList = new ArrayList<>(mapOfColumnNameAndIndex.entrySet()); - Collections.sort(sortedColumnList, new Comparator>() { - @Override - public int compare(Map.Entry o1, Map.Entry o2) { - return o1.getValue().compareTo(o2.getValue()); - } - }); - return sortedColumnList; - } + /** * Retrieves the value of the boundary code from the feature JSON node based on the mapped values. diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java index eccc736bf92..2dde03575c8 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java @@ -1,6 +1,7 @@ package org.egov.processor.util; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.Workflow; import org.egov.processor.config.Configuration; @@ -9,10 +10,10 @@ import org.egov.processor.repository.ServiceRequestRepository; import org.egov.processor.web.models.PlanConfiguration; import org.egov.processor.web.models.PlanConfigurationRequest; -import org.egov.processor.web.models.census.AdditionalField; -import org.egov.processor.web.models.census.Census; -import org.egov.processor.web.models.census.CensusRequest; +import org.egov.processor.web.models.census.*; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import java.math.BigDecimal; @@ -34,11 +35,14 @@ public class CensusUtil { private ParsingUtil parsingUtil; - public CensusUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, Producer producer, ParsingUtil parsingUtil) { + private ObjectMapper mapper; + + public CensusUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, Producer producer, ParsingUtil parsingUtil, ObjectMapper objectMapper) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.producer = producer; this.parsingUtil = parsingUtil; + this.mapper = objectMapper; } /** @@ -144,4 +148,39 @@ public List enrichAdditionalField(JsonNode feature, Map mappedValues = planConfig.getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + + List boundaryCodes = getBoundaryCodesFromTheSheet(sheet, indexOfBoundaryCode); + System.out.println(boundaryCodes); + + } + + public List getBoundaryCodesFromTheSheet(Sheet sheet, Integer indexOfBoundaryCode) { + List boundaryCodes = new ArrayList<>(); + + for (Row row : sheet) { + // Skip the header row and empty rows + if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { + continue; + } + + // Get the boundary code cell + Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); + + // Check if the cell is non-empty and collect its value + if (boundaryCodeCell != null && boundaryCodeCell.getCellType() == CellType.STRING) { + String boundaryCode = boundaryCodeCell.getStringCellValue().trim(); + if (!boundaryCode.isEmpty()) { + boundaryCodes.add(boundaryCode); + } + } + } + + return boundaryCodes; + } } 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 96eed325956..1548a3a8160 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 @@ -1,37 +1,29 @@ package org.egov.processor.util; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.DecimalNode; +import lombok.extern.slf4j.Slf4j; +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.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import com.fasterxml.jackson.databind.node.DecimalNode; -import org.apache.commons.io.FileUtils; -import org.apache.poi.ss.usermodel.*; -import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.ResourceMapping; -import org.egov.tracer.model.CustomException; -import org.springframework.stereotype.Component; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.util.ObjectUtils; - import static org.egov.processor.config.ServiceConstants.PROPERTIES; @Slf4j @@ -313,4 +305,59 @@ public List extractPropertyNamesFromAdminSchema(JsonNode rootNode) { return names; } + + /** + * Checks if a given row is empty. + * + * A row is considered empty if it is null or if all of its cells are empty or of type BLANK. + * + * @param row the Row to check + * @return true if the row is empty, false otherwise + */ + public static boolean isRowEmpty(Row row) { + if (row == null) { + return true; + } + for (Cell cell : row) { + if (cell != null && cell.getCellType() != CellType.BLANK) { + return false; + } + } + return true; + } + + /** + * Retrieves the index value of the boundary code from the sorted column list based on the mapped values. + * + * @param indexValue The initial index value. + * @param sortedColumnList The sorted list of column names and indices. + * @param mappedValues The map containing mapped values. + * @return The index value of the boundary code. + */ + public Integer getIndexOfBoundaryCode(Integer indexValue, List> sortedColumnList,Map mappedValues) { + for (Map.Entry entry : sortedColumnList) { + if (entry.getKey().equals(mappedValues.get(ServiceConstants.BOUNDARY_CODE))) { + indexValue = entry.getValue(); + } + } + return indexValue; + } + + /** + * Sorts the column names and indices based on the provided map of column names and indices. + * + * @param mapOfColumnNameAndIndex The map containing column names and their corresponding indices. + * @return The sorted list of column names and indices. + */ + public List> sortColumnByIndex(Map mapOfColumnNameAndIndex) { + List> sortedColumnList = new ArrayList<>(mapOfColumnNameAndIndex.entrySet()); + Collections.sort(sortedColumnList, new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return o1.getValue().compareTo(o2.getValue()); + } + }); + return sortedColumnList; + } + } diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index 9f13ea45855..f7e0f3e9ab5 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -96,5 +96,9 @@ plan.config.trigger.plan.facility.mappings.status=EXECUTION_TO_BE_DONE resource.default.offset=0 resource.default.limit=10 +# Census +egov.census.host=https://unified-dev.digit.org +egov.census.search.endpoint=/census-service/_search + census.additional.field.override.keys=HCM_ADMIN_CONSOLE_BOUNDARY_CODE census.additional.field.prefix.append.keys=HCM_ADMIN_CONSOLE_TOTAL_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59 \ No newline at end of file From ab09e8fc72f68808b5ddb4a2fbcceef6d9bbbd67 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 11 Nov 2024 15:44:52 +0530 Subject: [PATCH 298/351] HCMPRE-853 changes for updating file with approved census data --- .../egov/processor/service/ExcelParser.java | 55 +++------ .../egov/processor/util/EnrichmentUtil.java | 109 ++++++++++++++++-- .../org/egov/processor/util/ParsingUtil.java | 32 +++++ 3 files changed, 147 insertions(+), 49 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 9dd07dbd973..f407aa7ed36 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 @@ -194,12 +194,12 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi */ //TODO: processsheetforestimate and processsheetforcensus private void processSheets(PlanConfigurationRequest request, String fileStoreId, - Object campaignResponse, Workbook excelWorkbook, - List campaignBoundaryList, - DataFormatter dataFormatter) { + Object campaignResponse, Workbook excelWorkbook, + List campaignBoundaryList, + DataFormatter dataFormatter) { CampaignResponse campaign = campaignIntegrationUtil.parseCampaignResponse(campaignResponse); LocaleResponse localeResponse = localeUtil.searchLocale(request); - Object mdmsData = mdmsUtil. fetchMdmsData(request.getRequestInfo(), + Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), request.getPlanConfiguration().getTenantId()); planConfigurationUtil.orderPlanConfigurationOperations(request); enrichmentUtil.enrichResourceMapping(request, localeResponse, campaign.getCampaign().get(0).getProjectType(), fileStoreId); @@ -207,12 +207,19 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, fileStoreId, campaign, request.getPlanConfiguration(), mdmsData); List boundaryCodeList = getBoundaryCodeList(request, campaign); - + Map mappedValues = request.getPlanConfiguration().getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap( + ResourceMapping::getMappedTo, + ResourceMapping::getMappedFrom, + (existing, replacement) -> existing, + LinkedHashMap::new + )); excelWorkbook.forEach(excelWorkbookSheet -> { if (isSheetAllowedToProcess(request, excelWorkbookSheet.getSheetName(), localeResponse)) { if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { - enrichmentUtil.enrichsheetWithApprovedCensusRecords(excelWorkbookSheet, request, fileStoreId); + enrichmentUtil.enrichsheetWithApprovedCensusRecords(excelWorkbookSheet, request, fileStoreId, mappedValues); processRows(request, excelWorkbookSheet, dataFormatter, fileStoreId, campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); } else if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { @@ -365,7 +372,7 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat mapOfColumnNameAndIndex, campaignBoundaryList, resultMap); planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); // TODO: remove after testing - printRow(sheet, row); + parsingUtil.printRow(sheet, row); } } @@ -504,40 +511,6 @@ private JsonNode createFeatureNodeFromRow(Row row, Map columnIn return featureNode; } - public void printRow(Sheet sheet, Row row) { - System.out.print("Row -> "); - for (Cell cell : row) { - int columnIndex = cell.getColumnIndex(); - // String columnName = sheet.getRow(0).getCell(columnIndex).toString(); - // System.out.print("Column " + columnName + " - "); - switch (cell.getCellType()) { - case STRING: - System.out.print(cell.getStringCellValue() + "\t"); - break; - case NUMERIC: - if (DateUtil.isCellDateFormatted(cell)) { - System.out.print(cell.getDateCellValue() + "\t"); - } else { - System.out.print(cell.getNumericCellValue() + "\t"); - } - break; - case BOOLEAN: - System.out.print(cell.getBooleanCellValue() + "\t"); - break; - case FORMULA: - System.out.print(cell.getCellFormula() + "\t"); - break; - case BLANK: - System.out.print("\t"); - break; - default: - System.out.print("\t"); - break; - } - } - System.out.println(); // Move to the next line after printing the row - } - /** * Validates the data in a 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 c61df28055a..a47f0599955 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 @@ -6,13 +6,21 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.egov.common.utils.UUIDEnrichmentUtil; +import org.egov.processor.config.Configuration; import org.egov.processor.web.models.LocaleResponse; import org.egov.processor.web.models.PlanConfiguration; import org.egov.processor.web.models.PlanConfigurationRequest; import org.egov.processor.web.models.ResourceMapping; +import org.egov.processor.web.models.census.Census; +import org.egov.processor.web.models.census.CensusResponse; +import org.egov.processor.web.models.census.CensusSearchCriteria; +import org.egov.processor.web.models.census.CensusSearchRequest; import org.egov.processor.web.models.mdmsV2.Mdms; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -30,13 +38,18 @@ public class EnrichmentUtil { private ParsingUtil parsingUtil; + private CensusUtil censusUtil; + + private Configuration config; // private MultiStateInstanceUtil centralInstanceUtil; - public EnrichmentUtil(MdmsV2Util mdmsV2Util, LocaleUtil localeUtil, ParsingUtil parsingUtil) { + public EnrichmentUtil(MdmsV2Util mdmsV2Util, LocaleUtil localeUtil, ParsingUtil parsingUtil, CensusUtil censusUtil, Configuration config) { this.mdmsV2Util = mdmsV2Util; this.localeUtil = localeUtil; // this.centralInstanceUtil = centralInstanceUtil; this.parsingUtil = parsingUtil; + this.censusUtil = censusUtil; + this.config = config; } /** @@ -73,7 +86,63 @@ public void enrichResourceMapping(PlanConfigurationRequest request, LocaleRespon } - public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationRequest planConfigurationRequest, String fileStoreId, Map mappedValues) { + List boundaryCodes = getBoundaryCodesFromTheSheet(sheet, planConfigurationRequest, fileStoreId); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + + //Getting census records for the list of boundaryCodes + List censusList = getCensusRecordsForEnrichment(planConfigurationRequest, boundaryCodes); + + // Create a map from boundaryCode to Census for quick lookups + Map censusMap = censusList.stream() + .collect(Collectors.toMap(Census::getBoundaryCode, census -> census)); + + + for(Row row: sheet) { + parsingUtil.printRow(sheet, row); + if (row.getRowNum() == 0) continue; // Skip header row + + // Get the boundaryCode in the current row + Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); + String boundaryCode = boundaryCodeCell.getStringCellValue(); + + Census census = censusMap.get(boundaryCode); + + if (census != null) { + // For each field in the sheetToCensusMap, update the cell if the field is editable + for (Map.Entry entry : mappedValues.entrySet()) { + String censusKey = entry.getKey(); + String sheetColumn = entry.getValue(); + + if(config.getCensusAdditionalFieldOverrideKeys().contains(censusKey)) + continue; + censusKey = config.getCensusAdditionalPrefixAppendKeys().contains(censusKey) ? CONFIRMED_KEY + censusKey : censusKey; + + // Get the column index from the mapOfColumnNameAndIndex + Integer columnIndex = mapOfColumnNameAndIndex.get(sheetColumn); + if (columnIndex != null) { + // Get the value for this field in the census, if editable + BigDecimal editableValue = getEditableValue(census, censusKey); + + if(ObjectUtils.isEmpty(editableValue)) continue; + + Cell cell = row.getCell(columnIndex); + if (cell == null) { + cell = row.createCell(columnIndex); + } + cell.setCellValue(editableValue.doubleValue()); + + } + } + } + log.info("Successfully update file with approved census data."); + } + } + + public List getBoundaryCodesFromTheSheet(Sheet sheet, PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); Map mappedValues = planConfig.getResourceMapping().stream() @@ -85,12 +154,6 @@ public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationR Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); - List boundaryCodes = getBoundaryCodesFromTheSheet(sheet, indexOfBoundaryCode); - System.out.println(boundaryCodes); - - } - - public List getBoundaryCodesFromTheSheet(Sheet sheet, Integer indexOfBoundaryCode) { List boundaryCodes = new ArrayList<>(); for (Row row : sheet) { @@ -113,4 +176,34 @@ public List getBoundaryCodesFromTheSheet(Sheet sheet, Integer indexOfBou return boundaryCodes; } + + public List getCensusRecordsForEnrichment(PlanConfigurationRequest planConfigurationRequest, List boundaryCodes) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder() + .tenantId(planConfig.getTenantId()) + .areaCodes(boundaryCodes) + .source(planConfig.getId()).build(); + + CensusSearchRequest censusSearchRequest = CensusSearchRequest.builder() + .censusSearchCriteria(censusSearchCriteria) + .requestInfo(planConfigurationRequest.getRequestInfo()).build(); + + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + + if(censusResponse.getCensus().isEmpty()) + throw new CustomException(NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE, NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE); + + return censusResponse.getCensus(); + + } + + private BigDecimal getEditableValue(Census census, String key) { + return census.getAdditionalFields().stream() + .filter(field -> field.getEditable() && key.equals(field.getKey())) // Filter by editability and matching key + .map(field -> field.getValue()) + .findFirst() + .orElse(null); + } + + } 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 1548a3a8160..ba10327e4c8 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 @@ -360,4 +360,36 @@ public int compare(Map.Entry o1, Map.Entry o2) return sortedColumnList; } + public void printRow(Sheet sheet, Row row) { + System.out.print("Row -> "); + for (Cell cell : row) { + int columnIndex = cell.getColumnIndex(); + switch (cell.getCellType()) { + case STRING: + System.out.print(cell.getStringCellValue() + "\t"); + break; + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + System.out.print(cell.getDateCellValue() + "\t"); + } else { + System.out.print(cell.getNumericCellValue() + "\t"); + } + break; + case BOOLEAN: + System.out.print(cell.getBooleanCellValue() + "\t"); + break; + case FORMULA: + System.out.print(cell.getCellFormula() + "\t"); + break; + case BLANK: + System.out.print("\t"); + break; + default: + System.out.print("\t"); + break; + } + } + System.out.println(); // Move to the next line after printing the row + } + } From 214b333c65688fd211108d676fe1cbc6d342e502 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 11 Nov 2024 15:47:56 +0530 Subject: [PATCH 299/351] HCMPRE-853 adding logs --- .../main/java/org/egov/processor/util/EnrichmentUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 a47f0599955..be9579af525 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 @@ -138,7 +138,11 @@ public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationR } } } - log.info("Successfully update file with approved census data."); + //TODO: remove after testing + log.info("After updating values in sheet -> "); + parsingUtil.printRow(sheet, row); + + log.info("Successfully update file with approved census data."); } } From cee6a615080b624c9a4915d20e192e3fbdf48418 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 12 Nov 2024 12:18:31 +0530 Subject: [PATCH 300/351] pull from microplanning-dev --- .../src/main/java/digit/web/models/PlanFacility.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index 71390c5a33b..856b175bbfa 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -57,7 +57,7 @@ public class PlanFacility { private List serviceBoundaries; @JsonIgnore - private List initiallySetServiceBoundaries = new ArrayList<>(); + private List initiallySetServiceBoundaries; @JsonProperty("additionalDetails") private Object additionalDetails = null; From d9635ee2516d1f6b60bc291c18d62c8c43946ce2 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 12 Nov 2024 12:33:03 +0530 Subject: [PATCH 301/351] HCMPRE-853 integrating with project factory with updated resources --- .../egov/processor/config/Configuration.java | 3 ++ .../processor/config/ServiceConstants.java | 2 + .../egov/processor/service/ExcelParser.java | 2 +- .../util/CampaignIntegrationUtil.java | 43 +++++++++++++++++++ .../campaignManager/MicroplanDetails.java | 32 ++++++++++++++ .../MicroplanDetailsRequest.java | 26 +++++++++++ .../src/main/resources/application.properties | 1 + 7 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java 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 cac270a815b..2b7a1d1dd24 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 @@ -61,6 +61,9 @@ public class Configuration { @Value("${egov.project.factory.data.create.endpoint}") private String campaignIntegrationDataCreateEndPoint; + @Value("${egov.project.factory.fetch.from.microplan.endpoint}") + private String campaignIntegrationFetchFromMicroplanEndPoint; + @Value("${egov.project.factory.host}") private String projectFactoryHostEndPoint; 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 d217a5026f5..1d0cb5ee05b 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 @@ -52,6 +52,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_PUSHING_TO_PLAN_SERVICE_FOR_LOCALITY = "Exception occurred while fetching plan configuration from plan service for Locality "; public static final String ERROR_WHILE_SEARCHING_CAMPAIGN = "Exception occurred while searching/updating campaign."; 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 FILE_NAME = "output.xls"; public static final String FILE_TYPE = "boundaryWithTarget"; 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 f407aa7ed36..46530cf5859 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 @@ -163,9 +163,9 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); if (config.isIntegrateWithAdminConsole()) { + campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); campaignIntegrationUtil.updateCampaignResources(uploadedFileStoreId, campaignResourcesList, fileToUpload.getName()); - campaignIntegrationUtil.updateCampaignDetails(planConfigurationRequest, campaignResponse, campaignBoundaryList, campaignResourcesList); } 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 7a6fe38d6fa..9bfbe7cb62c 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 @@ -39,6 +39,49 @@ public CampaignIntegrationUtil(ServiceRequestRepository serviceRequestRepository this.parsingUtil= parsingUtil; } + /** + * Updates resources in the Project Factory by calling an external API with the given plan configuration + * request and file store ID. Logs the operation status. + * + * @param planConfigurationRequest The plan configuration request details. + * @param fileStoreId The file store ID to update. + * @throws CustomException if the API call fails. + */ + public void updateResourcesInProjectFactory(PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + try { + serviceRequestRepository.fetchResult( + new StringBuilder(config.getProjectFactoryHostEndPoint() + config.getCampaignIntegrationFetchFromMicroplanEndPoint()), + buildMicroplanDetailsForUpdate(planConfigurationRequest, fileStoreId)); + log.info("Updated resources file into project factory - " + fileStoreId); + } catch (Exception e) { + log.error(ERROR_WHILE_CALLING_MICROPLAN_API + planConfigurationRequest.getPlanConfiguration().getId(), e); + throw new CustomException(ERROR_WHILE_CALLING_MICROPLAN_API, e.toString()); + } + + } + + /** + * 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 fileStoreId The filestoreId with calculated resources + * @return The microplan details request object built for updating resource filestore id. + */ + private MicroplanDetailsRequest buildMicroplanDetailsForUpdate(PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + + MicroplanDetails microplanDetails = MicroplanDetails.builder() + .tenantId(planConfig.getTenantId()) + .planConfigurationId(planConfig.getId()) + .campaignId(planConfig.getCampaignId()) + .resourceFilestoreId(fileStoreId).build(); + + return MicroplanDetailsRequest.builder() + .microplanDetails(microplanDetails) + .requestInfo(planConfigurationRequest.getRequestInfo()).build(); + + } + /** * 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. diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java new file mode 100644 index 00000000000..4bbb44b118b --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java @@ -0,0 +1,32 @@ +package org.egov.processor.web.models.campaignManager; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Validated +public class MicroplanDetails { + + @JsonProperty("tenantId") + @NotNull + private String tenantId; + + @JsonProperty("campaignId") + @NotNull + private String campaignId; + + @JsonProperty("planConfigurationId") + @NotNull + private String planConfigurationId; + + @JsonProperty("resourceFilestoreId") + private String resourceFilestoreId; +} \ No newline at end of file diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java new file mode 100644 index 00000000000..4789ef42573 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java @@ -0,0 +1,26 @@ +package org.egov.processor.web.models.campaignManager; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class MicroplanDetailsRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("MicroplanDetails") + @Valid + private MicroplanDetails microplanDetails = null; +} diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index f7e0f3e9ab5..2edff68868d 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -71,6 +71,7 @@ egov.plan.create.endpoint=/plan-service/plan/_create egov.project.factory.search.endpoint=/project-factory/v1/project-type/search egov.project.factory.update.endpoint=/project-factory/v1/project-type/update egov.project.factory.data.create.endpoint=/project-factory/v1/data/_create +egov.project.factory.fetch.from.microplan.endpoint=/project-factory/v1/project-type/fetch-from-microplan egov.project.factory.host=https://unified-dev.digit.org #egov.project.factory.host=http://localhost:8090 integrate.with.admin.console=false From 27456b990cda26f4bd35db49a75c01788eae0e9e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 12 Nov 2024 14:38:34 +0530 Subject: [PATCH 302/351] modification in wf-service --- .../src/main/java/digit/service/workflow/WorkflowService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java index d3669bc8e73..cf363ac9b52 100644 --- a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -304,9 +304,9 @@ public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Cens // Check if this boundary code is present in assigneeJurisdiction if (census.getAssigneeJurisdiction().contains(boundaryCode)) { - if (i - 1 >= 0) { + for (int j = i - 1; j >= 0; j--) { // Check the next higher level in the hierarchy (one index above the match) - String higherBoundaryCode = heirarchysBoundaryCodes[i - 1]; + String higherBoundaryCode = heirarchysBoundaryCodes[j]; // Fetch the employeeId from the map for the higher boundary code String employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); From d9192581a4effd1f5db9e6aa42f290c543be4240 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 12 Nov 2024 14:54:42 +0530 Subject: [PATCH 303/351] workflow auto-assignee issue --- .../src/main/java/digit/service/workflow/WorkflowService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 1545adebebf..5b510beb17c 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -278,9 +278,9 @@ public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Plan // Check if this boundary code is present in assigneeJurisdiction if (plan.getAssigneeJurisdiction().contains(boundaryCode)) { - if (i - 1 >= 0) { + for (int j = i - 1; j >= 0; j--) { // Check the next higher level in the hierarchy (one index above the match) - String higherBoundaryCode = heirarchysBoundaryCodes[i - 1]; + String higherBoundaryCode = heirarchysBoundaryCodes[j]; // Fetch the employeeId from the map for the higher boundary code String employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); From a5e44f3bc880a75a842a1e83dd03efd266d72c31 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 12 Nov 2024 15:29:54 +0530 Subject: [PATCH 304/351] HCMPRE-853 commenting project factory integration --- .../src/main/java/org/egov/processor/service/ExcelParser.java | 2 +- 1 file changed, 1 insertion(+), 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 46530cf5859..821b848cf75 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 @@ -163,7 +163,7 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); if (config.isIntegrateWithAdminConsole()) { - campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); +// campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); campaignIntegrationUtil.updateCampaignResources(uploadedFileStoreId, campaignResourcesList, fileToUpload.getName()); campaignIntegrationUtil.updateCampaignDetails(planConfigurationRequest, campaignResponse, From 024c4a7ba80e08a70de44a6882f4aeadb2557add Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 12 Nov 2024 15:47:20 +0530 Subject: [PATCH 305/351] adding pagination for plan-employee api --- .../PlanEmployeeAssignmentQueryBuilder.java | 26 ++++++++++++++++--- .../PlanEmployeeAssignmentSearchCriteria.java | 6 +++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 4094c6dffa1..52c37a21f97 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -1,9 +1,11 @@ package digit.repository.querybuilder; +import digit.config.Configuration; import digit.util.QueryUtil; import digit.web.models.PlanEmployeeAssignmentSearchCriteria; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.HashSet; import java.util.LinkedHashSet; @@ -14,8 +16,12 @@ public class PlanEmployeeAssignmentQueryBuilder { private QueryUtil queryUtil; - public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { + private Configuration config; + + public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration config) { + this.queryUtil = queryUtil; + this.config = config; } private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; @@ -26,7 +32,7 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. @@ -40,7 +46,7 @@ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteri String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE : PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); - query = queryUtil.getPaginatedQuery(query, preparedStmtList); + query = getPaginatedQuery(query, searchCriteria, preparedStmtList); return query; } @@ -127,4 +133,18 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit return builder.toString(); } + + private String getPaginatedQuery(String query, PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { + StringBuilder paginatedQuery = new StringBuilder(query); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(ObjectUtils.isEmpty(searchCriteria.getOffset()) ? config.getDefaultOffset() : searchCriteria.getOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(ObjectUtils.isEmpty(searchCriteria.getLimit()) ? config.getDefaultLimit() : searchCriteria.getLimit()); + + return paginatedQuery.toString(); + } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 8039edc86ac..32d250bbfdd 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -55,4 +55,10 @@ public class PlanEmployeeAssignmentSearchCriteria { @Builder.Default private Boolean filterUniqueByPlanConfig = Boolean.FALSE; + @JsonProperty("offset") + private Integer offset = null; + + @JsonProperty("limit") + private Integer limit = null; + } From ce4e484e48ee4d55d98aabaa2ebc1c8a74c91294 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 12 Nov 2024 18:14:18 +0530 Subject: [PATCH 306/351] changed the data type of BigDecimal --- .../service/enrichment/PlanFacilityEnricher.java | 9 +++++---- .../service/validator/PlanFacilityValidator.java | 3 ++- .../src/main/java/digit/util/CommonUtil.java | 14 ++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index a658963f62c..92414801615 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -18,6 +18,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @@ -94,13 +95,13 @@ private void enrichServingPopulation(PlanFacilityRequest planFacilityRequest) { .collect(Collectors.toMap(Census::getBoundaryCode, Census::getTotalPopulation)); // Get existing servingPopulation or default to 0 - Double servingPopulation = (Double) commonUtil.extractFieldsFromJsonObject(planFacility.getAdditionalDetails(), SERVING_POPULATION_CODE); + BigDecimal servingPopulation = (BigDecimal) commonUtil.extractFieldsFromJsonObject(planFacility.getAdditionalDetails(), SERVING_POPULATION_CODE); updateServingPopulation(boundariesToBeSearched, planFacility, boundaryToPopMap, servingPopulation); } } - private void updateServingPopulation(Set boundariesToBeSearched, PlanFacility planFacility, Map boundaryToPopMap, Double servingPopulation) { + private void updateServingPopulation(Set boundariesToBeSearched, PlanFacility planFacility, Map boundaryToPopMap, BigDecimal servingPopulation) { Set currentServiceBoundaries = new HashSet<>(planFacility.getServiceBoundaries()); Set initialServiceBoundaries = new HashSet<>(planFacility.getInitiallySetServiceBoundaries()); @@ -108,9 +109,9 @@ private void updateServingPopulation(Set boundariesToBeSearched, PlanFac Long totalPopulation = boundaryToPopMap.get(boundary); if (!currentServiceBoundaries.contains(boundary)) { - servingPopulation -= totalPopulation; + servingPopulation = servingPopulation.subtract(BigDecimal.valueOf(totalPopulation)); } else if (!initialServiceBoundaries.contains(boundary)) { - servingPopulation += totalPopulation; + servingPopulation = servingPopulation.add(BigDecimal.valueOf(totalPopulation)); } } Map fieldToUpdate = new HashMap<>(); diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 81f65f7ea55..713d390f70d 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -19,6 +19,7 @@ import static digit.config.ServiceConstants.*; +import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @@ -277,7 +278,7 @@ private void validateFacilityExistence(PlanFacilityRequest planFacilityRequest) private void enrichFacilityDetails(Facility facility, PlanFacilityRequest planFacilityRequest) { String facilityName = facility.getName(); planFacilityRequest.getPlanFacility().setFacilityName(facilityName); - Double initialServingPop = 0.0; + BigDecimal initialServingPop = BigDecimal.ZERO; Map fieldsToBeAdded = new HashMap<>(); fieldsToBeAdded.put("facilityUsage", facility.getUsage()); diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index 9ae3fe05919..458c1e33ae5 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +import java.math.BigDecimal; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -62,13 +63,12 @@ public Object extractFieldsFromJsonObject(Object additionalDetails, String field JsonNode node = rootNode.get(fieldToExtract); if (node != null && !node.isNull()) { + // Check for different types of JSON nodes - if (node instanceof DecimalNode) { - return ((DecimalNode) node).decimalValue(); - } else if (node.isDouble() || node.isFloat()) { - return node.asDouble(); + if (node.isDouble() || node.isFloat()) { + return BigDecimal.valueOf(node.asDouble()); // Convert Double to BigDecimal } else if (node.isLong() || node.isInt()) { - return node.asLong(); + return BigDecimal.valueOf(node.asLong()); // Convert Long to BigDecimal } else if (node.isBoolean()) { return node.asBoolean(); } else if (node.isTextual()) { @@ -231,9 +231,7 @@ public Map updateFieldInAdditionalDetails(Object additionalDetai fieldsToBeUpdated.forEach((key, value) -> objectNode.set(key, objectMapper.valueToTree(value))); // Convert updated ObjectNode back to a Map - Map updatedMap = objectMapper.convertValue(objectNode, Map.class); - - return updatedMap; + return objectMapper.convertValue(objectNode, Map.class); } catch (Exception e) { throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE + e); From 475e690ea7afc76824d30a20a39972b03e5c42b3 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 12 Nov 2024 18:33:46 +0530 Subject: [PATCH 307/351] HCMPRE-1282 changes for updating estimates into plan --- .../querybuilder/PlanQueryBuilder.java | 6 +- .../java/digit/web/models/Assumption.java | 4 +- .../digit/web/models/PlanSearchCriteria.java | 15 ++- .../egov/processor/config/Configuration.java | 6 ++ .../processor/config/ServiceConstants.java | 10 +- .../egov/processor/service/ExcelParser.java | 10 +- .../egov/processor/util/EnrichmentUtil.java | 94 ++++++++++++++++++- .../org/egov/processor/util/PlanUtil.java | 64 +++++++++---- .../org/egov/processor/web/PlanResponse.java | 42 +++++++++ .../processor/web/PlanSearchCriteria.java | 57 +++++++++++ .../egov/processor/web/PlanSearchRequest.java | 30 ++++++ 11 files changed, 298 insertions(+), 40 deletions(-) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/PlanResponse.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchCriteria.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchRequest.java diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 353a95bbdc1..073316b517b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -122,10 +122,10 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< queryUtil.addToPreparedStatement(preparedStmtList, planSearchCriteria.getIds()); } - if (!ObjectUtils.isEmpty(planSearchCriteria.getLocality())) { + if (!CollectionUtils.isEmpty(planSearchCriteria.getLocality())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" locality = ? "); - preparedStmtList.add(planSearchCriteria.getLocality()); + builder.append(" locality IN ( ").append(queryUtil.createQuery(planSearchCriteria.getLocality().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(planSearchCriteria.getLocality())); } if (!ObjectUtils.isEmpty(planSearchCriteria.getCampaignId())) { diff --git a/health-services/plan-service/src/main/java/digit/web/models/Assumption.java b/health-services/plan-service/src/main/java/digit/web/models/Assumption.java index 7d2cd52286a..81486894093 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Assumption.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Assumption.java @@ -38,8 +38,8 @@ public class Assumption { @NotNull @Valid @DecimalMin(value = "0.01", inclusive = true, message = "The Assumption value must be greater than 0") - @DecimalMax(value = "9999999999.99", inclusive = true, message = "The assumption value must not exceed 10 digits in total, including up to 2 decimal places.") - @Digits(integer = 10, fraction = 2, message = "The Assumption value must have up to 10 digits and up to 2 decimal points") + @DecimalMax(value = "1000.00", inclusive = true, message = "The assumption value must not exceed 4 digits in total, including up to 2 decimal places.") + @Digits(integer = 4, fraction = 2, message = "The Assumption value must have up to 10 digits and up to 2 decimal points") private BigDecimal value = null; @JsonProperty("source") diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java index 4e840e8a644..357b306fa8f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java @@ -1,17 +1,16 @@ package digit.web.models; -import java.util.List; -import java.util.Set; - import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import org.springframework.validation.annotation.Validated; import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Data; import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; +import java.util.Set; /** * PlanSearchCriteria @@ -31,7 +30,7 @@ public class PlanSearchCriteria { private String tenantId = null; @JsonProperty("locality") - private String locality = null; + private List locality = null; @JsonProperty("campaignId") private String campaignId = null; 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 2b7a1d1dd24..cfb9214e18b 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 @@ -38,6 +38,9 @@ public class Configuration { @Value("${egov.plan.config.endpoint}") private String planConfigEndPoint; + @Value("${egov.plan.search.endpoint}") + private String planSearchEndPoint; + // Filestore @Value("${egov.filestore.service.host}") @@ -89,6 +92,9 @@ public class Configuration { @Value("${plan.config.trigger.census.records.status}") private String planConfigTriggerCensusRecordsStatus; + @Value("${plan.config.update.plan.estimates.into.output.file.status}") + private String planConfigUpdatePlanEstimatesIntoOutputFileStatus; + @Value("${plan.config.trigger.plan.facility.mappings.status}") private String planConfigTriggerPlanFacilityMappingsStatus; 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 1d0cb5ee05b..c20cf1c6034 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,8 +42,11 @@ public class ServiceConstants { 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."; - public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE = "NO_CENSUS_FOUND_FOR_GIVEN_DETAILS"; - public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE = "Census records does not exists for the given details: "; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE = "NO_PLAN_FOUND_FOR_GIVEN_DETAILS"; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE = "Census records do not exists for the given details: "; + + public static final String NO_PLAN_FOUND_FOR_GIVEN_DETAILS_CODE = "NO_PLAN_FOUND_FOR_GIVEN_DETAILS"; + public static final String NO_PLAN_FOUND_FOR_GIVEN_DETAILS_MESSAGE = "Plan records do not exists for the given details: "; public static final String BOUNDARY_CODE = "HCM_ADMIN_CONSOLE_BOUNDARY_CODE"; public static final String TOTAL_POPULATION = "HCM_ADMIN_CONSOLE_TOTAL_POPULATION"; @@ -80,7 +83,8 @@ public class ServiceConstants { public static final String NAME = "name"; public static final String ERROR_WHILE_UPDATING_PLAN_CONFIG = "Exception occurred while updating plan configuration."; - + public static final String ERROR_WHILE_SEARCHING_PLAN = "Exception occurred while search plans."; + public static final String VALIDATE_STRING_REGX = "^(?!\\d+$).+$"; public static final String VALIDATE_NUMBER_REGX = "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$"; public static final String VALIDATE_BOOLEAN_REGX = "^(?i)(true|false)$"; 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 821b848cf75..4e61cd1a0da 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 @@ -161,9 +161,12 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi try { fileToUpload = convertWorkbookToXls(workbook); String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); - + if (planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { + planUtil.setFileStoreIdForPopulationTemplate(planConfigurationRequest, uploadedFileStoreId); + planUtil.update(planConfigurationRequest); + } if (config.isIntegrateWithAdminConsole()) { -// campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); + campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); campaignIntegrationUtil.updateCampaignResources(uploadedFileStoreId, campaignResourcesList, fileToUpload.getName()); campaignIntegrationUtil.updateCampaignDetails(planConfigurationRequest, campaignResponse, @@ -217,7 +220,6 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, )); excelWorkbook.forEach(excelWorkbookSheet -> { if (isSheetAllowedToProcess(request, excelWorkbookSheet.getSheetName(), localeResponse)) { - if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { enrichmentUtil.enrichsheetWithApprovedCensusRecords(excelWorkbookSheet, request, fileStoreId, mappedValues); processRows(request, excelWorkbookSheet, dataFormatter, fileStoreId, @@ -225,6 +227,8 @@ private void processSheets(PlanConfigurationRequest request, String fileStoreId, } else if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { processRowsForCensusRecords(request, excelWorkbookSheet, fileStoreId, attributeNameVsDataTypeMap, boundaryCodeList, campaign.getCampaign().get(0).getHierarchyType()); + } else if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigUpdatePlanEstimatesIntoOutputFileStatus())) { + enrichmentUtil.enrichsheetWithApprovedPlanEstimates(excelWorkbookSheet, request, fileStoreId, mappedValues); } } }); 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 be9579af525..461b7c1f999 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 @@ -7,10 +7,10 @@ import org.apache.poi.ss.usermodel.Sheet; import org.egov.common.utils.UUIDEnrichmentUtil; import org.egov.processor.config.Configuration; -import org.egov.processor.web.models.LocaleResponse; -import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.PlanConfigurationRequest; -import org.egov.processor.web.models.ResourceMapping; +import org.egov.processor.web.PlanResponse; +import org.egov.processor.web.PlanSearchCriteria; +import org.egov.processor.web.PlanSearchRequest; +import org.egov.processor.web.models.*; import org.egov.processor.web.models.census.Census; import org.egov.processor.web.models.census.CensusResponse; import org.egov.processor.web.models.census.CensusSearchCriteria; @@ -40,15 +40,18 @@ public class EnrichmentUtil { private CensusUtil censusUtil; + private PlanUtil planUtil; + private Configuration config; // private MultiStateInstanceUtil centralInstanceUtil; - public EnrichmentUtil(MdmsV2Util mdmsV2Util, LocaleUtil localeUtil, ParsingUtil parsingUtil, CensusUtil censusUtil, Configuration config) { + public EnrichmentUtil(MdmsV2Util mdmsV2Util, LocaleUtil localeUtil, ParsingUtil parsingUtil, CensusUtil censusUtil, PlanUtil planUtil, Configuration config) { this.mdmsV2Util = mdmsV2Util; this.localeUtil = localeUtil; // this.centralInstanceUtil = centralInstanceUtil; this.parsingUtil = parsingUtil; this.censusUtil = censusUtil; + this.planUtil = planUtil; this.config = config; } @@ -209,5 +212,86 @@ private BigDecimal getEditableValue(Census census, String key) { .orElse(null); } + public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationRequest planConfigurationRequest, String fileStoreId, Map mappedValues) { + List boundaryCodes = getBoundaryCodesFromTheSheet(sheet, planConfigurationRequest, fileStoreId); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + + //Getting census records for the list of boundaryCodes + List planList = getPlanRecordsForEnrichment(planConfigurationRequest, boundaryCodes); + + // Create a map from boundaryCode to Census for quick lookups + Map planMap = planList.stream() + .collect(Collectors.toMap(Plan::getLocality, plan -> plan)); + + List outputColumnList = planList.get(0).getResources().stream() + .map(Resource::getResourceType) + .toList(); + + + for(Row row: sheet) { + parsingUtil.printRow(sheet, row); + if (row.getRowNum() == 0) continue; // Skip header row + + // Get the boundaryCode in the current row + Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); + String boundaryCode = boundaryCodeCell.getStringCellValue(); + + Plan planEstimate = planMap.get(boundaryCode); + + if (planEstimate != null) { + Map resourceTypeToEstimatedNumberMap = planEstimate.getResources().stream() + .collect(Collectors.toMap(Resource::getResourceType, Resource::getEstimatedNumber)); + + // Iterate over each output column to update the row cells with resource values + for (String resourceType : outputColumnList) { + BigDecimal estimatedValue = resourceTypeToEstimatedNumberMap.get(resourceType); + + if (estimatedValue != null) { + // Get the index of the column to update + Integer columnIndex = mapOfColumnNameAndIndex.get(resourceType); + if (columnIndex != null) { + // Update the cell with the resource value + Cell cell = row.getCell(columnIndex); + if (cell == null) { + cell = row.createCell(columnIndex); + } + cell.setCellValue(estimatedValue.doubleValue()); + } + } + } + } + //TODO: remove after testing + log.info("After updating values in sheet -> "); + parsingUtil.printRow(sheet, row); + + log.info("Successfully update file with approved census data."); + } + } + + + public List getPlanRecordsForEnrichment(PlanConfigurationRequest planConfigurationRequest, List boundaryCodes) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + PlanSearchCriteria planSearchCriteria = PlanSearchCriteria.builder() + .tenantId(planConfig.getTenantId()) + .locality(boundaryCodes) + .planConfigurationId(planConfig.getId()).build(); + + PlanSearchRequest planSearchRequest = PlanSearchRequest.builder() + .planSearchCriteria(planSearchCriteria) + .requestInfo(planConfigurationRequest.getRequestInfo()).build(); + + PlanResponse planResponse = planUtil.search(planSearchRequest); + + if(planResponse.getPlan().isEmpty()) + throw new CustomException(NO_PLAN_FOUND_FOR_GIVEN_DETAILS_CODE, NO_PLAN_FOUND_FOR_GIVEN_DETAILS_MESSAGE); + + return planResponse.getPlan(); + } + + + } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java index b5be6c40bc9..dbcb1329813 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java @@ -1,26 +1,24 @@ package org.egov.processor.util; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Map; -import java.util.stream.Collectors; - +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.Workflow; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; -import org.egov.processor.repository.ServiceRequestRepository; import org.egov.processor.kafka.Producer; -import org.egov.processor.web.models.Plan; -import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.PlanConfigurationRequest; -import org.egov.processor.web.models.PlanRequest; -import org.egov.processor.web.models.Resource; +import org.egov.processor.repository.ServiceRequestRepository; +import org.egov.processor.web.PlanResponse; +import org.egov.processor.web.PlanSearchRequest; +import org.egov.processor.web.models.*; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; -import com.fasterxml.jackson.databind.JsonNode; - -import lombok.extern.slf4j.Slf4j; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Map; +import java.util.stream.Collectors; import static org.egov.processor.config.ServiceConstants.*; @@ -33,11 +31,14 @@ public class PlanUtil { private Producer producer; - public PlanUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, Producer producer) { + private ObjectMapper mapper; + + public PlanUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, Producer producer, ObjectMapper mapper) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.producer = producer; - } + this.mapper = mapper; + } /** * Creates a plan configuration request, builds a plan request from it, and pushes it to the messaging system for further processing. @@ -127,4 +128,35 @@ public void update(PlanConfigurationRequest planConfigurationRequest) { log.error(ServiceConstants.ERROR_WHILE_UPDATING_PLAN_CONFIG); } } + + + public PlanResponse search(PlanSearchRequest planSearchRequest) { + + PlanResponse planResponse = null; + try { + Object response = serviceRequestRepository.fetchResult(getPlanSearchUri(), planSearchRequest); + planResponse = mapper.convertValue(response, PlanResponse.class); + } catch (Exception e) { + log.error(ServiceConstants.ERROR_WHILE_SEARCHING_PLAN); + } + + if (CollectionUtils.isEmpty(planResponse.getPlan())) { + throw new CustomException(NO_PLAN_FOUND_FOR_GIVEN_DETAILS_CODE, NO_PLAN_FOUND_FOR_GIVEN_DETAILS_MESSAGE); + } + + return planResponse; + } + + private StringBuilder getPlanSearchUri() { + return new StringBuilder().append(config.getPlanConfigHost()).append(config.getPlanSearchEndPoint()); + } + + public void setFileStoreIdForPopulationTemplate(PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + planConfigurationRequest.getPlanConfiguration().getFiles().stream() + .filter(file -> FILE_TEMPLATE_IDENTIFIER_POPULATION.equals(file.getTemplateIdentifier())) + .findFirst() + .ifPresent(file -> file.setFilestoreId(fileStoreId)); + } + + } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanResponse.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanResponse.java new file mode 100644 index 00000000000..5f4fc7b1882 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanResponse.java @@ -0,0 +1,42 @@ +package org.egov.processor.web; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.egov.processor.web.models.Plan; +import org.springframework.validation.annotation.Validated; + +import java.util.List; +import java.util.Map; + +/** + * PlanSearchResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Plan") + @Valid + private List plan = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; + + @JsonProperty("StatusCount") + @Valid + private Map statusCount = null; + +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchCriteria.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchCriteria.java new file mode 100644 index 00000000000..eec1a370b39 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchCriteria.java @@ -0,0 +1,57 @@ +package org.egov.processor.web; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.util.List; +import java.util.Set; + +/** + * PlanSearchCriteria + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanSearchCriteria { + + @JsonProperty("ids") + private Set ids = null; + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("locality") + private List locality = null; + + @JsonProperty("campaignId") + private String campaignId = null; + + @JsonProperty("planConfigurationId") + private String planConfigurationId = null; + + @JsonProperty("status") + private String status = null; + + @JsonProperty("assignee") + private String assignee = null; + + @JsonProperty("jurisdiction") + @Valid + private List jurisdiction = null; + + @JsonProperty("offset") + private Integer offset = null; + + @JsonProperty("limit") + private Integer limit = null; + +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchRequest.java new file mode 100644 index 00000000000..23e4c7eb9bc --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchRequest.java @@ -0,0 +1,30 @@ +package org.egov.processor.web; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * PlanSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanSearchRequest { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanSearchCriteria") + @Valid + private PlanSearchCriteria planSearchCriteria = null; + + +} From 85c982645661ebea6703ec66808b266d0fbffd2f Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 12 Nov 2024 18:34:32 +0530 Subject: [PATCH 308/351] HCMPRE-1282 app.prop changes --- .../src/main/resources/application.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index 2edff68868d..011312d87be 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -66,6 +66,7 @@ plan.config.consumer.kafka.update.topic=plan-config-update-topic #Plan Create egov.plan.create.endpoint=/plan-service/plan/_create +egov.plan.search.endpoint=/plan-service/plan/_search #Campaign Manager egov.project.factory.search.endpoint=/project-factory/v1/project-type/search @@ -92,6 +93,7 @@ egov.locale.search.endpoint=/localization/messages/v1/_search?module={module}&lo plan.config.trigger.plan.estimates.status=RESOURCE_ESTIMATION_IN_PROGRESS plan.config.trigger.census.records.status=EXECUTION_TO_BE_DONE 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 From 04c537c0521de030256e57f96e39a6a302174f64 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Wed, 13 Nov 2024 14:30:29 +0530 Subject: [PATCH 309/351] Adding case for when celltype is formula. --- .../egov/processor/config/ServiceConstants.java | 2 +- .../org/egov/processor/service/ExcelParser.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) 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 1d0cb5ee05b..7b226f1f38d 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 @@ -93,7 +93,7 @@ public class ServiceConstants { public static final String ATTRIBUTE_IS_REQUIRED ="isRequired"; public static final int DEFAULT_SCALE=2; - public static final String MDMS_LOCALE_SEARCH_MODULE ="rainmaker-microplanning,rainmaker-boundary-undefined,rainmaker-hcm-admin-schemas"; + public static final String MDMS_LOCALE_SEARCH_MODULE ="rainmaker-microplanning,rainmaker-boundary-undefined,hcm-admin-schemas"; public static final String ERROR_WHILE_SEARCHING_LOCALE = "Exception occurred while searching locale. "; public static final String MDMS_MASTER_COMMON_CONSTANTS = "CommonConstants"; 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 821b848cf75..bbc011af106 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 @@ -502,6 +502,23 @@ private JsonNode createFeatureNodeFromRow(Row row, Map columnIn case BOOLEAN: propertiesNode.put(columnName, cell.getBooleanCellValue()); break; + case FORMULA: + // Attempt to get the cached formula result value directly + switch (cell.getCachedFormulaResultType()) { + case NUMERIC: + propertiesNode.put(columnName, BigDecimal.valueOf(cell.getNumericCellValue())); + break; + case STRING: + propertiesNode.put(columnName, cell.getStringCellValue()); + break; + case BOOLEAN: + propertiesNode.put(columnName, cell.getBooleanCellValue()); + break; + default: + propertiesNode.putNull(columnName); + break; + } + break; default: propertiesNode.putNull(columnName); break; From d896b7b2616776ef11f13ba0e3cdd3cca50a486a Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 13 Nov 2024 17:41:06 +0530 Subject: [PATCH 310/351] enriching additional details with additional field key-value --- .../main/java/digit/config/Configuration.java | 3 +++ .../java/digit/config/ServiceConstants.java | 3 +++ .../repository/impl/CensusRepositoryImpl.java | 1 + .../service/enrichment/CensusEnrichment.java | 20 ++++++++++++++++++- .../service/validator/CensusValidator.java | 17 ++++++++++++++++ .../src/main/java/digit/util/CommonUtil.java | 19 ++++++++++++++++++ .../src/main/resources/application.properties | 1 + 7 files changed, 63 insertions(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 4d280ecc3e0..4db8509ed4a 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -28,6 +28,9 @@ public class Configuration { @Value("${census.update.topic}") private String censusUpdateTopic; + @Value("${census.bulk.update.topic}") + private String censusBulkUpdateTopic; + @Value("${plan.facility.update.topic}") private String planFcailityUpdateTopic; diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index faeda8989ac..7427544dbb8 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -86,6 +86,9 @@ public class ServiceConstants { public static final String WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE_CODE = "WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE"; public static final String WORKFLOW_NOT_FOUND_FOR_BULK_UPDATE_MESSAGE = "Workflow information is mandatory for each entry for bulk update"; + public static final String DUPLICATE_KEY_IN_ADDITIONAL_FIELD_CODE = "DUPLICATE_KEY_IN_ADDITIONAL_FIELD"; + public static final String DUPLICATE_KEY_IN_ADDITIONAL_FIELD_MESSGAE = "Duplicate key found in additional field : "; + public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_CODE = "DIFFERENT_WORKFLOW_FOR_BULK_UPDATE"; public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_MESSAGE = "All entries should be in the same state for bulk transitioning census records."; diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 62d25ce0c21..4192662f100 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -175,6 +175,7 @@ public void bulkUpdate(BulkCensusRequest request) { // Perform bulk update jdbcTemplate.batchUpdate(bulkCensusUpdateQuery, rows); + producer.push(config.getCensusBulkUpdateTopic(), request); } /** diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index 7c50111bf10..6e8916d7440 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -1,5 +1,7 @@ package digit.service.enrichment; +import digit.util.CommonUtil; +import digit.web.models.AdditionalField; import digit.web.models.Census; import digit.web.models.CensusRequest; import digit.web.models.boundary.EnrichedBoundary; @@ -11,13 +13,18 @@ import org.springframework.util.ObjectUtils; import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @Component public class CensusEnrichment { - public CensusEnrichment() { + private CommonUtil commonUtil; + + public CensusEnrichment(CommonUtil commonUtil) { + this.commonUtil = commonUtil; } /** @@ -47,6 +54,15 @@ public void enrichCreate(CensusRequest request) { // Enrich effectiveFrom for the census record census.setEffectiveFrom(census.getAuditDetails().getCreatedTime()); + + denormalizeAdditionalFields(request.getCensus()); + } + + private void denormalizeAdditionalFields(Census census) { + Map fieldsToAdd = census.getAdditionalFields().stream() + .collect(Collectors.toMap(AdditionalField::getKey, AdditionalField::getValue)); + + census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), fieldsToAdd)); } /** @@ -94,6 +110,8 @@ public void enrichUpdate(CensusRequest request) { UUIDEnrichmentUtil.enrichRandomUuid(additionalField, "id"); } }); + + denormalizeAdditionalFields(request.getCensus()); } } diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 566a662d87f..5d0979df4e9 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -57,6 +57,20 @@ public void validateCreate(CensusRequest request) { // Validate partner assignment and jurisdiction against plan service validatePartnerForCensus(request); + + // Validate keys in additional field + validateAdditionalFields(request); + } + + private void validateAdditionalFields(CensusRequest request) { + Set additionalFieldKeys = new HashSet<>(); + + request.getCensus().getAdditionalFields().forEach(additionalField -> { + if(additionalFieldKeys.contains(additionalField.getKey())) { + throw new CustomException(DUPLICATE_KEY_IN_ADDITIONAL_FIELD_CODE, DUPLICATE_KEY_IN_ADDITIONAL_FIELD_MESSGAE + additionalField.getKey()); + } + additionalFieldKeys.add(additionalField.getKey()); + }); } /** @@ -129,6 +143,9 @@ public void validateUpdate(CensusRequest request) { // Validate partner assignment and jurisdiction against plan service validatePartnerForCensus(request); + + // Validate keys in additional field + validateAdditionalFields(request); } /** diff --git a/health-services/census-service/src/main/java/digit/util/CommonUtil.java b/health-services/census-service/src/main/java/digit/util/CommonUtil.java index 74b4c65f087..bf473f57cac 100644 --- a/health-services/census-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -60,6 +60,25 @@ public Map updateFieldInAdditionalDetails(Object additionalDetai } } + public Map updateFieldInAdditionalDetails(Object additionalDetails, Map fieldsToBeUpdated) { + try { + + // Get or create the additionalDetails as an ObjectNode + ObjectNode objectNode = (additionalDetails == null || additionalDetails instanceof NullNode) + ? objectMapper.createObjectNode() + : objectMapper.convertValue(additionalDetails, ObjectNode.class); + + // Update or add the field in additional details object + fieldsToBeUpdated.forEach((key, value) -> objectNode.set(key, objectMapper.valueToTree(value))); + + // Convert updated ObjectNode back to a Map + return objectMapper.convertValue(objectNode, Map.class); + + } catch (Exception e) { + throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE + e); + } + } + /** * Removes the field to be removed from the additional details object. * @param additionalDetails diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index a293305e516..257da97bfa6 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -44,6 +44,7 @@ kafka.producer.config.buffer_memory_config=33554432 #PERSISTER KAFKA TOPICS census.create.topic=census-create-topic census.update.topic=census-update-topic +census.bulk.update.topic=census-bulk-update-topic egov.sms.notification.topic=egov.core.notification.sms kafka.topics.receipt.create=dss-collection From a1acecd28b1b2341c2f1cc9d899ded0568d6f0fb Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 14 Nov 2024 12:35:21 +0530 Subject: [PATCH 311/351] modified orderBy clause --- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 52c37a21f97..871ddd6d376 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -30,7 +30,7 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration con private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC, plan_configuration_id"; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; From 96ee7e5d249ec41d68145e25e437d58d49f06c6a Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 14 Nov 2024 14:28:11 +0530 Subject: [PATCH 312/351] made changes in order by clause --- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 871ddd6d376..212665224af 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -30,10 +30,11 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration con private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC, plan_configuration_id"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; + private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT * FROM ( {INTERNAL_QUERY} ) AS latest_assignments ORDER BY last_modified_time DESC"; /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. @@ -47,7 +48,7 @@ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteri query = queryUtil.addOrderByClause(query, Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE : PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); query = getPaginatedQuery(query, searchCriteria, preparedStmtList); - return query; + return Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY.replace("{INTERNAL_QUERY}", query) : query; } /** From d7bf01787769aa3378b5b9a417c2bbbb24c52474 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 14 Nov 2024 15:20:36 +0530 Subject: [PATCH 313/351] added facilityType --- .../java/digit/service/validator/PlanFacilityValidator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 713d390f70d..fb6e46c88a4 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -282,8 +282,9 @@ private void enrichFacilityDetails(Facility facility, PlanFacilityRequest planFa Map fieldsToBeAdded = new HashMap<>(); fieldsToBeAdded.put("facilityUsage", facility.getUsage()); - fieldsToBeAdded.put("storageCapacity", facility.getStorageCapacity()); - fieldsToBeAdded.put("facilityType", facility.getAddress().getType()); + fieldsToBeAdded.put("capacity", facility.getStorageCapacity()); + fieldsToBeAdded.put("facilityStatus", facility.getAddress().getType()); + fieldsToBeAdded.put("facilityType", facility.getUsage()); fieldsToBeAdded.put("isPermanent", facility.isPermanent()); fieldsToBeAdded.put("servingPopulation", initialServingPop); From e1cb018f7e49361a7cdafb62fa75c8ae8cfb63ea Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 14 Nov 2024 17:08:02 +0530 Subject: [PATCH 314/351] pull from microplanning-dev --- .../main/java/digit/config/Configuration.java | 7 + .../java/digit/config/ServiceConstants.java | 29 ++++ .../repository/PlanFacilityRepository.java | 2 + .../impl/PlanFacilityRepositoryImpl.java | 16 ++ .../querybuilder/PlanConfigQueryBuilder.java | 9 +- .../PlanEmployeeAssignmentQueryBuilder.java | 26 ++- .../PlanFacilityQueryBuilder.java | 33 +++- .../rowmapper/PlanConfigRowMapper.java | 15 +- .../rowmapper/PlanFacilityRowMapper.java | 1 + .../service/PlanConfigurationService.java | 7 +- .../digit/service/PlanFacilityService.java | 1 + .../service/enrichment/EnrichmentService.java | 34 +++- .../PlanEmployeeAssignmentEnricher.java | 18 +-- .../enrichment/PlanFacilityEnricher.java | 94 ++++++++--- .../validator/PlanConfigurationValidator.java | 33 ++-- .../validator/PlanFacilityValidator.java | 28 +++- .../service/validator/WorkflowValidator.java | 141 +++++++++++++++++ .../service/workflow/WorkflowService.java | 10 +- .../src/main/java/digit/util/CensusUtil.java | 60 +++++++ .../src/main/java/digit/util/CommonUtil.java | 81 ++++++++-- .../main/java/digit/web/models/Operation.java | 3 + .../PlanConfigurationSearchCriteria.java | 1 - .../PlanEmployeeAssignmentSearchCriteria.java | 6 + .../java/digit/web/models/PlanFacility.java | 3 + .../digit/web/models/PlanFacilityDTO.java | 3 + .../web/models/PlanFacilityResponse.java | 4 + .../java/digit/web/models/census/Census.java | 136 ++++++++++++++++ .../web/models/census/CensusResponse.java | 42 +++++ .../models/census/CensusSearchCriteria.java | 72 +++++++++ .../models/census/CensusSearchRequest.java | 31 ++++ .../census/PopulationByDemographic.java | 69 ++++++++ .../src/main/resources/application.properties | 4 + ...151500__alter_operations_add_order_ddl.sql | 2 + ...0__plan_facility_add_facility_name_ddl.sql | 1 + .../egov/processor/config/Configuration.java | 19 +++ .../processor/config/ServiceConstants.java | 11 ++ .../egov/processor/service/ExcelParser.java | 106 ++++--------- .../egov/processor/util/CalculationUtil.java | 59 ++----- .../util/CampaignIntegrationUtil.java | 82 ++++++---- .../org/egov/processor/util/CensusUtil.java | 101 ++++++++++-- .../egov/processor/util/EnrichmentUtil.java | 148 +++++++++++++++++- .../org/egov/processor/util/ParsingUtil.java | 123 ++++++++++++--- .../processor/util/PlanConfigurationUtil.java | 18 ++- .../egov/processor/web/models/Operation.java | 3 + .../campaignManager/MicroplanDetails.java | 32 ++++ .../MicroplanDetailsRequest.java | 26 +++ .../web/models/census/AdditionalField.java | 48 ++++++ .../processor/web/models/census/Census.java | 4 + .../src/main/resources/application.properties | 10 +- 49 files changed, 1510 insertions(+), 302 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java create mode 100644 health-services/plan-service/src/main/java/digit/util/CensusUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/Census.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index cb7fce09dbe..bb7bb371844 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -87,6 +87,13 @@ public class Configuration { @Value("${plan.default.limit}") private Integer defaultLimit; + //Census + @Value("${egov.census.host}") + private String censusHost; + + @Value("${egov.census.search.endpoint}") + private String censusSearchEndPoint; + //Facility @Value("${egov.facility.host}") private String facilityHost; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index ff1a26eba2d..5a8925f2c26 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -16,6 +16,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY = "Exception occurred while fetching campaign details from project factory: "; + public static final String ERROR_WHILE_FETCHING_FROM_CENSUS = "Exception occurred while fetching records from census: "; + public static final String ERROR_WHILE_FETCHING_BOUNDARY_DETAILS = "Exception occurred while fetching boundary relationship from boundary service: "; public static final String ERROR_WHILE_FETCHING_DATA_FROM_HRMS = "Exception occurred while fetching employee from hrms: "; @@ -71,6 +73,10 @@ public class ServiceConstants { public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_CODE = "NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID"; public static final String NO_CAMPAIGN_DETAILS_FOUND_FOR_GIVEN_CAMPAIGN_ID_MESSAGE = "Invalid or incorrect campaign id. No campaign details found for provided campaign id."; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE = "NO_CENSUS_FOUND_FOR_GIVEN_DETAILS"; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE = "Census records does not exists for the given details: "; + + public static final String INVALID_EMPLOYEE_JURISDICTION_CODE = "INVALID_EMPLOYEE_JURISDICTION"; public static final String INVALID_EMPLOYEE_JURISDICTION_MESSAGE = "The employee's jurisdiction provided is invalid"; @@ -173,6 +179,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 ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE = "ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS"; + public static final String ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE = "Exception occurred while updating additional details : "; + public static final String WORKFLOW_INTEGRATION_ERROR_CODE = "WORKFLOW_INTEGRATION_ERROR"; public static final String WORKFLOW_INTEGRATION_ERROR_MESSAGE = "Exception occured while integrating with workflow : "; @@ -296,6 +305,14 @@ public class ServiceConstants { public static final String URI_BUSINESS_SERVICE_QUERY_TEMPLATE = "?tenantId={tenantId}&businessServices={businessService}"; + public static final String APPROVE_CENSUS_DATA_ACTION = "APPROVE_CENSUS_DATA"; + + public static final String FINALIZE_CATCHMENT_MAPPING_ACTION = "FINALIZE_CATCHMENT_MAPPING"; + + public static final String APPROVE_ESTIMATIONS_ACTION = "APPROVE_ESTIMATIONS"; + + public static final String VALIDATED_STATUS = "VALIDATED"; + //Query constants public static final String PERCENTAGE_WILDCARD = "%"; @@ -314,6 +331,15 @@ public class ServiceConstants { public static final String INVALID_RESIDING_BOUNDARY_CODE = "INVALID_RESIDING_BOUNDARY"; public static final String INVALID_RESIDING_BOUNDARY_MESSAGE = "The provided residing boundary is invalid"; + public static final String CANNOT_APPROVE_CENSUS_DATA_CODE = "CANNOT_APPROVE_CENSUS_DATA"; + public static final String CANNOT_APPROVE_CENSUS_DATA_MESSAGE = "Census data can't be approved until all the census records are validated"; + + public static final String CANNOT_APPROVE_ESTIMATIONS_CODE = "CANNOT_APPROVE_ESTIMATIONS"; + public static final String CANNOT_APPROVE_ESTIMATIONS_MESSAGE = "Estimations can't be approved until all the estimations are validated"; + + public static final String CANNOT_FINALIZE_CATCHMENT_MAPPING_CODE = "CANNOT_FINALIZE_CATCHMENT_MAPPING"; + public static final String CANNOT_FINALIZE_CATCHMENT_MAPPING_MESSAGE = "Catchment mapping can't be finalized until all boundaries have facility assigned"; + public static final String HIERARCHY_NOT_FOUND_IN_MDMS_CODE = "HIERARCHY_NOT_FOUND_IN_MDMS"; public static final String HIERARCHY_NOT_FOUND_IN_MDMS_MESSAGE = "Hierarchy key not found in mdms"; @@ -326,4 +352,7 @@ public class ServiceConstants { public static final String FACILITY_TYPE_SEARCH_PARAMETER_KEY = "facilityType"; public static final String COMMA_DELIMITER = ","; + + public static final String SERVING_POPULATION_CODE = "servingPopulation"; + } diff --git a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java index 875392dab40..ce94f569086 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java @@ -10,4 +10,6 @@ public interface PlanFacilityRepository { public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria); void update(PlanFacilityRequest planFacilityRequest); + + public Integer count(PlanFacilitySearchCriteria planFacilitySearchCriteria); } diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java index 8a9a48d325e..d17b3dcb470 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -59,6 +59,7 @@ public PlanFacilityRequestDTO convertToDTO(PlanFacilityRequest planFacilityReque .planConfigurationId(planFacility.getPlanConfigurationId()) .planConfigurationName(planFacility.getPlanConfigurationName()) .facilityId(planFacility.getFacilityId()) + .facilityName(planFacility.getFacilityName()) .residingBoundary(planFacility.getResidingBoundary()) .serviceBoundaries(convertArrayToString(planFacility.getServiceBoundaries())) .initiallySetServiceBoundaries(planFacility.getInitiallySetServiceBoundaries()) @@ -114,6 +115,21 @@ public void update(PlanFacilityRequest planFacilityRequest) { } } + /** + * Counts the number of plan facilities based on the provided search criteria. + * + * @param planFacilitySearchCriteria The search criteria for filtering plan facilities. + * @return The total count of plan facilities matching the search criteria. + */ + @Override + public Integer count(PlanFacilitySearchCriteria planFacilitySearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = planFacilityQueryBuilder.getPlanFacilityCountQuery(planFacilitySearchCriteria, preparedStmtList); + Integer count = jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); + + return count; + } + /** * Helper method to query database for plan facilities based on the provided search criteria. * diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index fe8faa3e5dc..ef79343841e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -1,16 +1,15 @@ package digit.repository.querybuilder; import digit.config.Configuration; - import digit.util.QueryUtil; import digit.web.models.PlanConfigurationSearchCriteria; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.LinkedHashSet; import java.util.List; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; @Component @@ -30,7 +29,7 @@ public PlanConfigQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_CONFIG_QUERY = "SELECT pc.id as plan_configuration_id, pc.tenant_id as plan_configuration_tenant_id, pc.name as plan_configuration_name, pc.campaign_id as plan_configuration_campaign_id, pc.status as plan_configuration_status, pc.additional_details as plan_configuration_additional_details, pc.created_by as plan_configuration_created_by, pc.created_time as plan_configuration_created_time, pc.last_modified_by as plan_configuration_last_modified_by, pc.last_modified_time as plan_configuration_last_modified_time, \n" + "\t pcf.id as plan_configuration_files_id, pcf.plan_configuration_id as plan_configuration_files_plan_configuration_id, pcf.filestore_id as plan_configuration_files_filestore_id, pcf.input_file_type as plan_configuration_files_input_file_type, pcf.template_identifier as plan_configuration_files_template_identifier, pcf.active as plan_configuration_files_active, pcf.created_by as plan_configuration_files_created_by, pcf.created_time as plan_configuration_files_created_time, pcf.last_modified_by as plan_configuration_files_last_modified_by, pcf.last_modified_time as plan_configuration_files_last_modified_time,\n" + "\t pca.id as plan_configuration_assumptions_id, pca.key as plan_configuration_assumptions_key, pca.value as plan_configuration_assumptions_value, pca.source as plan_configuration_assumptions_source, pca.category as plan_configuration_assumptions_category, pca.active as plan_configuration_assumptions_active, pca.plan_configuration_id as plan_configuration_assumptions_plan_configuration_id, pca.created_by as plan_configuration_assumptions_created_by, pca.created_time as plan_configuration_assumptions_created_time, pca.last_modified_by as plan_configuration_assumptions_last_modified_by, pca.last_modified_time as plan_configuration_assumptions_last_modified_time,\n" + - "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.source as plan_configuration_operations_source, pco.category as plan_configuration_operations_category, pco.active as plan_configuration_operations_active, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + + "\t pco.id as plan_configuration_operations_id, pco.input as plan_configuration_operations_input, pco.operator as plan_configuration_operations_operator, pco.assumption_value as plan_configuration_operations_assumption_value, pco.output as plan_configuration_operations_output, pco.source as plan_configuration_operations_source, pco.category as plan_configuration_operations_category, pco.active as plan_configuration_operations_active, pco.execution_order as plan_configuration_execution_order, pco.show_on_estimation_dashboard as plan_configuration_operations_show_on_estimation_dashboard,pco.plan_configuration_id as plan_configuration_operations_plan_configuration_id, pco.created_by as plan_configuration_operations_created_by, pco.created_time as plan_configuration_operations_created_time, pco.last_modified_by as plan_configuration_operations_last_modified_by, pco.last_modified_time as plan_configuration_operations_last_modified_time,\n" + "\t pcm.id as plan_configuration_mapping_id, pcm.filestore_id as plan_configuration_mapping_filestore_id, pcm.mapped_from as plan_configuration_mapping_mapped_from, pcm.mapped_to as plan_configuration_mapping_mapped_to, pcm.active as plan_configuration_mapping_active, pcm.plan_configuration_id as plan_configuration_mapping_plan_configuration_id, pcm.created_by as plan_configuration_mapping_created_by, pcm.created_time as plan_configuration_mapping_created_time, pcm.last_modified_by as plan_configuration_mapping_last_modified_by, pcm.last_modified_time as plan_configuration_mapping_last_modified_time\n" + "\t FROM plan_configuration pc\n" + "\t LEFT JOIN plan_configuration_files pcf ON pc.id = pcf.plan_configuration_id\n" + diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index cccc784389e..571ff425e51 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -1,9 +1,11 @@ package digit.repository.querybuilder; +import digit.config.Configuration; import digit.util.QueryUtil; import digit.web.models.PlanEmployeeAssignmentSearchCriteria; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.HashSet; import java.util.LinkedHashSet; @@ -16,8 +18,12 @@ public class PlanEmployeeAssignmentQueryBuilder { private QueryUtil queryUtil; - public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { + private Configuration config; + + public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration config) { + this.queryUtil = queryUtil; + this.config = config; } private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, plan_configuration_name, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; @@ -28,7 +34,7 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil) { private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. @@ -42,7 +48,7 @@ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteri String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE : PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); - query = queryUtil.getPaginatedQuery(query, preparedStmtList); + query = getPaginatedQuery(query, searchCriteria, preparedStmtList); return query; } @@ -135,4 +141,18 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit return builder.toString(); } + + private String getPaginatedQuery(String query, PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList) { + StringBuilder paginatedQuery = new StringBuilder(query); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(ObjectUtils.isEmpty(searchCriteria.getOffset()) ? config.getDefaultOffset() : searchCriteria.getOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(ObjectUtils.isEmpty(searchCriteria.getLimit()) ? config.getDefaultLimit() : searchCriteria.getLimit()); + + return paginatedQuery.toString(); + } } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index 755b79de6b8..017532f0623 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -30,6 +30,7 @@ public PlanFacilityQueryBuilder(Configuration config, QueryUtil queryUtil) { "plan_facility_linkage.plan_configuration_id as plan_facility_plan_configuration_id, " + "plan_facility_linkage.plan_configuration_name as plan_facility_plan_configuration_name, " + "plan_facility_linkage.facility_id as plan_facility_facility_id, " + + "plan_facility_linkage.facility_name as plan_facility_facility_name, " + "plan_facility_linkage.residing_boundary as plan_facility_residing_boundary, " + "plan_facility_linkage.service_boundaries as plan_facility_service_boundaries, " + "plan_facility_linkage.additional_details as plan_facility_additional_details, " + @@ -42,14 +43,28 @@ public PlanFacilityQueryBuilder(Configuration config, QueryUtil queryUtil) { private static final String PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE = " order by plan_facility_linkage.last_modified_time desc "; + private static final String PLAN_FACILITY_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(*) AS total_count FROM ( "; + public String getPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { - String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); + String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE); query = getPaginatedQuery(query, planFacilitySearchCriteria, preparedStmtList); return query; } - private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { + /** + * Constructs the count query to get the total count of plan facilities based on search criteria. + * + * @param planFacilitySearchCriteria The criteria used for filtering PlanFacility objects. + * @param preparedStmtList A list to store prepared statement parameters. + * @return A SQL query string to get the total count of plan facilities. + */ + public String getPlanFacilityCountQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList) { + String query = buildPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList, Boolean.TRUE); + return query; + } + + private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacilitySearchCriteria, List preparedStmtList, boolean isCount) { StringBuilder builder = new StringBuilder(PLAN_FACILITY_QUERY); if (!CollectionUtils.isEmpty(planFacilitySearchCriteria.getIds())) { @@ -83,6 +98,12 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil preparedStmtList.add(planFacilitySearchCriteria.getFacilityId()); } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityName())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" facility_name LIKE ? "); + preparedStmtList.add(PERCENTAGE_WILDCARD + planFacilitySearchCriteria.getFacilityName() + PERCENTAGE_WILDCARD); + } + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getResidingBoundaries())) { List residingBoundaries = planFacilitySearchCriteria.getResidingBoundaries(); queryUtil.addClauseIfRequired(builder, preparedStmtList); @@ -97,6 +118,14 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil preparedStmtList.add(partialQueryJsonString); } + StringBuilder countQuery = new StringBuilder(); + if (isCount) { + countQuery.append(PLAN_FACILITY_SEARCH_QUERY_COUNT_WRAPPER).append(builder); + countQuery.append(") AS subquery"); + + return countQuery.toString(); + } + return builder.toString(); } diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index 83ca049b8cb..f289c5d4818 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java @@ -2,13 +2,6 @@ import digit.util.QueryUtil; import digit.web.models.*; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; import org.egov.common.contract.models.AuditDetails; import org.postgresql.util.PGobject; import org.springframework.dao.DataAccessException; @@ -17,6 +10,13 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + @Component public class PlanConfigRowMapper implements ResultSetExtractor> { @@ -158,6 +158,7 @@ private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Map< operation.setShowOnEstimationDashboard(rs.getBoolean("plan_configuration_operations_show_on_estimation_dashboard")); operation.setSource(Source.valueOf(rs.getString("plan_configuration_operations_source"))); operation.setCategory(rs.getString("plan_configuration_operations_category")); + operation.setExecutionOrder(rs.getInt("plan_configuration_execution_order")); if (CollectionUtils.isEmpty(planConfigEntry.getOperations())) { List operationList = new ArrayList<>(); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java index f65310b4452..ceb88cd2c05 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java @@ -48,6 +48,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAcc planFacilityEntry.setPlanConfigurationId(rs.getString("plan_facility_plan_configuration_id")); planFacilityEntry.setPlanConfigurationName(rs.getString("plan_facility_plan_configuration_name")); planFacilityEntry.setFacilityId(rs.getString("plan_facility_facility_id")); + planFacilityEntry.setFacilityName(rs.getString("plan_facility_facility_name")); planFacilityEntry.setResidingBoundary(rs.getString("plan_facility_residing_boundary")); String serviceBoundaries = rs.getString("plan_facility_service_boundaries"); planFacilityEntry.setServiceBoundaries(ObjectUtils.isEmpty(serviceBoundaries) ? new ArrayList<>() : Arrays.asList(serviceBoundaries.split(","))); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java index a6c9af454d3..e7ab762d507 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java @@ -3,6 +3,7 @@ import digit.repository.PlanConfigurationRepository; import digit.service.enrichment.EnrichmentService; import digit.service.validator.PlanConfigurationValidator; +import digit.service.validator.WorkflowValidator; import digit.service.workflow.WorkflowService; import digit.util.ResponseInfoFactory; import digit.web.models.PlanConfigurationRequest; @@ -27,14 +28,17 @@ public class PlanConfigurationService { private ResponseInfoFactory responseInfoFactory; + private WorkflowValidator workflowValidator; + private WorkflowService workflowService; - public PlanConfigurationService(EnrichmentService enrichmentService, PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService) { + public PlanConfigurationService(EnrichmentService enrichmentService, PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService, WorkflowValidator workflowValidator) { this.enrichmentService = enrichmentService; this.validator = validator; this.repository = repository; this.responseInfoFactory = responseInfoFactory; this.workflowService = workflowService; + this.workflowValidator = workflowValidator; } /** @@ -80,6 +84,7 @@ public PlanConfigurationResponse search(PlanConfigurationSearchRequest request) public PlanConfigurationResponse update(PlanConfigurationRequest request) { validator.validateUpdateRequest(request); enrichmentService.enrichUpdate(request); + workflowValidator.validateWorkflow(request); workflowService.invokeWorkflowForStatusUpdate(request); repository.update(request); diff --git a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java index 442b91ab87b..8282a0fea74 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -68,6 +68,7 @@ public PlanFacilityResponse searchPlanFacility(PlanFacilitySearchRequest planFac return PlanFacilityResponse.builder() .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(planFacilitySearchRequest.getRequestInfo(), Boolean.TRUE)) .planFacility(planFacilityList) + .totalCount(planFacilityRepository.count(planFacilitySearchRequest.getPlanFacilitySearchCriteria())) .build(); } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index 3847513043c..0172642fa11 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java @@ -1,30 +1,30 @@ package digit.service.enrichment; import digit.config.Configuration; -import digit.web.models.File; -import digit.web.models.PlanConfiguration; -import digit.web.models.PlanConfigurationRequest; -import digit.web.models.ResourceMapping; +import digit.util.CommonUtil; +import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.UUIDEnrichmentUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.List; import static digit.config.ServiceConstants.DRAFT_STATUS; -import org.springframework.util.CollectionUtils; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; -import org.springframework.util.ObjectUtils; - @Component @Slf4j public class EnrichmentService { private Configuration config; - public EnrichmentService(Configuration config) { + private CommonUtil commonUtil; + + public EnrichmentService(Configuration config, CommonUtil commonUtil) { this.config = config; + this.commonUtil = commonUtil; } /** @@ -120,6 +120,11 @@ public void enrichUpdate(PlanConfigurationRequest request) { } planConfiguration.setAuditDetails(prepareAuditDetails(request.getPlanConfiguration().getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); + + //enrich execution order for operations on setup complete + if (commonUtil.isSetupCompleted(planConfiguration)) { + enrichExecutionOrderForOperations(planConfiguration); + } } /** @@ -181,4 +186,17 @@ public void enrichPlanConfigurationBeforeValidation(PlanConfigurationRequest req } } + /** + * Sets a sequential execution order for each operation in the given PlanConfiguration. + * + * @param planConfiguration the configuration containing operations to order + */ + public void enrichExecutionOrderForOperations(PlanConfiguration planConfiguration) { + int executionOrderCounter = 1; + + for (Operation operation : planConfiguration.getOperations()) { + operation.setExecutionOrder(executionOrderCounter++); + } + } + } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java index 1db4af09587..c4072ca637e 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -52,7 +52,7 @@ public void enrichCreate(PlanEmployeeAssignmentRequest request) { Boolean.TRUE)); // Add plan config name to which the employee is mapped - enrichWithPlanConfigName(planEmployeeAssignment); + planEmployeeAssignment.setPlanConfigurationName(commonUtil.getPlanConfigName(planEmployeeAssignment.getTenantId(), planEmployeeAssignment.getPlanConfigurationId())); } /** @@ -68,20 +68,4 @@ public void enrichUpdate(PlanEmployeeAssignmentRequest request) { request.getRequestInfo(), Boolean.FALSE)); } - - /** - * This method enriches the plan employee assignment object with the planConfigName to which employee is mapped. - * - * @param planEmployeeAssignment the object to be enriched - */ - private void enrichWithPlanConfigName(PlanEmployeeAssignment planEmployeeAssignment) { - - String planConfigName = getPlanConfigNameById(planEmployeeAssignment.getPlanConfigurationId(), planEmployeeAssignment.getTenantId()); - planEmployeeAssignment.setPlanConfigurationName(planConfigName); - } - - private String getPlanConfigNameById(String planConfigId, String tenantId) { - List planConfigurations = commonUtil.searchPlanConfigId(planConfigId, tenantId); - return planConfigurations.get(0).getName(); - } } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 2796d196a55..b156b0ebab8 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -1,5 +1,15 @@ package digit.service.enrichment; +import digit.util.CensusUtil; +import digit.util.CommonUtil; +import digit.web.models.PlanFacility; +import digit.web.models.PlanFacilityRequest; +import digit.web.models.PlanFacilitySearchCriteria; +import digit.web.models.PlanFacilitySearchRequest; +import digit.web.models.census.Census; +import digit.web.models.census.CensusResponse; +import digit.web.models.census.CensusSearchCriteria; +import digit.web.models.census.CensusSearchRequest; import digit.util.CommonUtil; import digit.web.models.*; import jakarta.validation.Valid; @@ -10,9 +20,8 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; import static digit.config.ServiceConstants.*; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @@ -23,8 +32,11 @@ public class PlanFacilityEnricher { private CommonUtil commonUtil; - public PlanFacilityEnricher(CommonUtil commonUtil) { + private CensusUtil censusUtil; + + public PlanFacilityEnricher(CommonUtil commonUtil, CensusUtil censusUtil) { this.commonUtil = commonUtil; + this.censusUtil = censusUtil; } /** @@ -45,7 +57,7 @@ public void enrichPlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequ planFacilityRequest.getPlanFacility().setActive(Boolean.TRUE); // Add plan config name to which the facility is mapped - enrichWithPlanConfigName(planFacilityRequest.getPlanFacility()); + planFacilityRequest.getPlanFacility().setPlanConfigurationName(commonUtil.getPlanConfigName(planFacilityRequest.getPlanFacility().getTenantId(), planFacilityRequest.getPlanFacility().getPlanConfigurationId())); } /** @@ -58,6 +70,57 @@ public void enrichPlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { //enrich audit details planFacility.setAuditDetails(prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.FALSE)); + + // enrich serving population + enrichServingPopulation(planFacilityRequest); + } + + private void enrichServingPopulation(PlanFacilityRequest planFacilityRequest) { + PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + Set boundariesToBeSearched = new HashSet<>(planFacility.getServiceBoundaries()); + boundariesToBeSearched.addAll(planFacility.getInitiallySetServiceBoundaries()); + + if(!CollectionUtils.isEmpty(boundariesToBeSearched)) { + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder() + .tenantId(planFacility.getTenantId()) + .source(planFacility.getPlanConfigurationId()) + .areaCodes(new ArrayList<>(boundariesToBeSearched)) + .limit(boundariesToBeSearched.size()) + .build(); + + CensusResponse censusResponse = censusUtil.fetchCensusRecords(CensusSearchRequest.builder() + .requestInfo(planFacilityRequest.getRequestInfo()) + .censusSearchCriteria(censusSearchCriteria) + .build()); + + // Create a population map + Map boundaryToPopMap = censusResponse.getCensus().stream() + .collect(Collectors.toMap(Census::getBoundaryCode, Census::getTotalPopulation)); + + // Get existing servingPopulation or default to 0 + Double servingPopulation = (Double) commonUtil.extractFieldsFromJsonObject(planFacility.getAdditionalDetails(), SERVING_POPULATION_CODE); + + updateServingPopulation(boundariesToBeSearched, planFacility, boundaryToPopMap, servingPopulation); + } + } + + private void updateServingPopulation(Set boundariesToBeSearched, PlanFacility planFacility, Map boundaryToPopMap, Double servingPopulation) { + Set currentServiceBoundaries = new HashSet<>(planFacility.getServiceBoundaries()); + Set initialServiceBoundaries = new HashSet<>(planFacility.getInitiallySetServiceBoundaries()); + + for(String boundary : boundariesToBeSearched) { + Long totalPopulation = boundaryToPopMap.get(boundary); + + if (!currentServiceBoundaries.contains(boundary)) { + servingPopulation -= totalPopulation; + } else if (!initialServiceBoundaries.contains(boundary)) { + servingPopulation += totalPopulation; + } + } + Map fieldToUpdate = new HashMap<>(); + fieldToUpdate.put(SERVING_POPULATION_CODE, servingPopulation); + + planFacility.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(planFacility.getAdditionalDetails(), fieldToUpdate)); } /** @@ -71,11 +134,6 @@ public void enrichSearchRequest(PlanFacilitySearchRequest planFacilitySearchRequ // Filter map for filtering facility meta data present in additional details Map filtersMap = new LinkedHashMap<>(); - // Add facility name as a filter if present in search criteria - if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityName())) { - filtersMap.put(FACILITY_NAME_SEARCH_PARAMETER_KEY, planFacilitySearchCriteria.getFacilityName()); - } - // Add facility status as a filter if present in search criteria if(!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityStatus())) { filtersMap.put(FACILITY_STATUS_SEARCH_PARAMETER_KEY, planFacilitySearchCriteria.getFacilityStatus()); @@ -89,20 +147,4 @@ public void enrichSearchRequest(PlanFacilitySearchRequest planFacilitySearchRequ if(!CollectionUtils.isEmpty(filtersMap)) planFacilitySearchCriteria.setFiltersMap(filtersMap); } - - /** - * This method enriches the plan facility object with the planConfigName to which facility is mapped. - * - * @param planFacility the object to be enriched - */ - private void enrichWithPlanConfigName(PlanFacility planFacility) { - - String planConfigName = getPlanConfigNameById(planFacility.getPlanConfigurationId(), planFacility.getTenantId()); - planFacility.setPlanConfigurationName(planConfigName); - } - - private String getPlanConfigNameById(String planConfigId, String tenantId) { - List planConfigurations = commonUtil.searchPlanConfigId(planConfigId, tenantId); - return planConfigurations.get(0).getName(); - } } \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 7e4fd7c4f12..9e022c663d7 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -16,7 +16,6 @@ import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; import java.util.*; import java.util.stream.Collectors; @@ -151,11 +150,11 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O throw new CustomException(ADDITIONAL_DETAILS_MISSING_CODE, ADDITIONAL_DETAILS_MISSING_MESSAGE); } - String jsonPathForAssumption = commonUtil.createJsonPathForAssumption(commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE), - commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); + String jsonPathForAssumption = commonUtil.createJsonPathForAssumption((String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_CAMPAIGN_TYPE), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_DISTRIBUTION_PROCESS), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_REGISTRATION_PROCESS), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_RESOURCE_DISTRIBUTION_STRATEGY_CODE), + (String) commonUtil.extractFieldsFromJsonObject(additionalDetails, JSON_FIELD_IS_REGISTRATION_AND_DISTRIBUTION_TOGETHER)); List assumptionListFromMDMS = null; try { log.info(jsonPathForAssumption); @@ -242,7 +241,7 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque } // Ensure at least one active file for each required template identifier - if(isSetupCompleted(planConfiguration)){ + if(commonUtil.isSetupCompleted(planConfiguration)){ requiredTemplateIdentifierSetFromMDMS.forEach(requiredTemplate -> { if (!activeRequiredTemplates.contains(requiredTemplate)) { log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); @@ -380,18 +379,6 @@ public void validateVehicleIdsFromAdditionalDetailsAgainstMDMS(PlanConfiguration } } - /** - * Checks if the setup process is completed based on the workflow action in the plan configuration. - * - * @param planConfiguration The plan configuration to check. - * @return true if the setup is completed, otherwise false. - */ - public boolean isSetupCompleted(PlanConfiguration planConfiguration) { - if(!ObjectUtils.isEmpty(planConfiguration.getWorkflow())) - return Objects.equals(planConfiguration.getWorkflow().getAction(), SETUP_COMPLETED_ACTION); - - return false; - } /** * Checks if files are empty or null when the setup action is marked as completed. @@ -438,13 +425,13 @@ private void checkForEmptyOperation(PlanConfiguration planConfiguration) { public void validateOperations(PlanConfigurationRequest request, CampaignResponse campaignResponse) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - if (isSetupCompleted(planConfiguration)) { + if (commonUtil.isSetupCompleted(planConfiguration)) { performEmptyChecks(planConfiguration); HashSet allowedColumns = getAllowedColumnsFromMDMS(request, campaignResponse.getCampaignDetails().get(0).getProjectType()); Set activeAssumptionKeys = getActiveAssumptionKeys(planConfiguration); - validateOperationInputs(planConfiguration, allowedColumns); + validateOperationInputs(planConfiguration, allowedColumns, activeAssumptionKeys); validateOperationAssumptionValues(planConfiguration, allowedColumns, activeAssumptionKeys); } } @@ -531,13 +518,13 @@ private Set getActiveAssumptionKeys(PlanConfiguration planConfiguration) * @param planConfiguration The plan configuration containing operations. * @param allowedColumns The allowed column names for input validation. */ - private void validateOperationInputs(PlanConfiguration planConfiguration, HashSet allowedColumns) { + private void validateOperationInputs(PlanConfiguration planConfiguration, HashSet allowedColumns, Set activeAssumptionKeys) { // Set to keep track of previous outputs Set previousOutputs = new HashSet<>(); for (Operation operation : planConfiguration.getOperations()) { // Validate input - if (!allowedColumns.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput()) && operation.getSource() == Source.MDMS) { + if (!allowedColumns.contains(operation.getInput()) && !activeAssumptionKeys.contains(operation.getInput()) && !previousOutputs.contains(operation.getInput()) && operation.getSource() == Source.MDMS) { log.error("Input Value " + operation.getInput() + " is not present in allowed columns or previous outputs"); throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE + operation.getInput()); } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java index 7fbea162514..81f65f7ea55 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -5,6 +5,7 @@ import digit.repository.PlanFacilityRepository; import digit.util.*; import digit.web.models.*; +import digit.web.models.facility.Facility; import digit.web.models.facility.FacilityResponse; import digit.web.models.projectFactory.CampaignDetail; import digit.web.models.projectFactory.CampaignResponse; @@ -15,9 +16,12 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; + import static digit.config.ServiceConstants.*; + import java.util.*; import java.util.stream.Collectors; + import digit.web.models.projectFactory.Boundary; @Component @@ -29,14 +33,16 @@ public class PlanFacilityValidator { private MultiStateInstanceUtil centralInstanceUtil; private MdmsUtil mdmsUtil; private FacilityUtil facilityUtil; + private CommonUtil commonUtil; - public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil) { + public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil, CommonUtil commonUtil) { this.planFacilityRepository = planFacilityRepository; this.planConfigurationRepository = planConfigurationRepository; this.campaignUtil = campaignUtil; this.centralInstanceUtil = centralInstanceUtil; this.mdmsUtil = mdmsUtil; this.facilityUtil = facilityUtil; + this.commonUtil = commonUtil; } /** @@ -242,7 +248,7 @@ public List fetchPlanConfigurationById(String planConfigurati .id(planConfigurationId) .tenantId(tenantId) .build()); - log.info("planConfigurations: "+planConfigurations); + log.info("planConfigurations: " + planConfigurations); // Validate planConfiguration exists if (CollectionUtils.isEmpty(planConfigurations)) { @@ -264,6 +270,24 @@ private void validateFacilityExistence(PlanFacilityRequest planFacilityRequest) if (ObjectUtils.isEmpty(facilityResponse) || CollectionUtils.isEmpty(facilityResponse.getFacilities())) { throw new CustomException("FACILITY_NOT_FOUND", "Facility with ID " + planFacilityRequest.getPlanFacility().getFacilityId() + " not found in the system."); } + + enrichFacilityDetails(facilityResponse.getFacilities().get(0), planFacilityRequest); + } + + private void enrichFacilityDetails(Facility facility, PlanFacilityRequest planFacilityRequest) { + String facilityName = facility.getName(); + planFacilityRequest.getPlanFacility().setFacilityName(facilityName); + Double initialServingPop = 0.0; + + Map fieldsToBeAdded = new HashMap<>(); + fieldsToBeAdded.put("facilityUsage", facility.getUsage()); + fieldsToBeAdded.put("storageCapacity", facility.getStorageCapacity()); + fieldsToBeAdded.put("facilityType", facility.getAddress().getType()); + fieldsToBeAdded.put("isPermanent", facility.isPermanent()); + fieldsToBeAdded.put("servingPopulation", initialServingPop); + + planFacilityRequest.getPlanFacility().setAdditionalDetails( + commonUtil.updateFieldInAdditionalDetails(planFacilityRequest.getPlanFacility().getAdditionalDetails(), fieldsToBeAdded)); } } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java new file mode 100644 index 00000000000..321cdb36ecc --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java @@ -0,0 +1,141 @@ +package digit.service.validator; + +import digit.service.PlanService; +import digit.util.CensusUtil; +import digit.web.models.*; +import digit.web.models.census.CensusResponse; +import digit.web.models.census.CensusSearchCriteria; +import digit.web.models.census.CensusSearchRequest; +import org.egov.common.contract.request.RequestInfo; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.util.Map; + +import static digit.config.ServiceConstants.*; +import static digit.config.ServiceConstants.CANNOT_APPROVE_ESTIMATIONS_MESSAGE; + +@Component +public class WorkflowValidator { + + private CensusUtil censusUtil; + + private PlanService planService; + + public WorkflowValidator(CensusUtil censusUtil, PlanService planService) { + this.censusUtil = censusUtil; + this.planService = planService; + } + + public void validateWorkflow(PlanConfigurationRequest planConfigurationRequest) { + if (ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow())) + return; + + String workflowAction = planConfigurationRequest.getPlanConfiguration().getWorkflow().getAction(); + + if(workflowAction.equals(APPROVE_CENSUS_DATA_ACTION)) { + validateCensusData(planConfigurationRequest); + } else if(workflowAction.equals(FINALIZE_CATCHMENT_MAPPING_ACTION)) { + validateCatchmentMapping(planConfigurationRequest); + } else if(workflowAction.equals(APPROVE_ESTIMATIONS_ACTION)) { + validateResourceEstimations(planConfigurationRequest); + } + } + + /** + * Validates if all the census records are validated before approving census data for the given planConfigId. + * + * @param planConfigurationRequest request with plan config id. + */ + private void validateCensusData(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches census records for given planConfigId + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + + Map statusCount = censusResponse.getStatusCount(); + Integer totalCount = censusResponse.getTotalCount(); + + // Throws exception if all census records are not validated + if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { + throw new CustomException(CANNOT_APPROVE_CENSUS_DATA_CODE, CANNOT_APPROVE_CENSUS_DATA_MESSAGE); + } + } + + /** + * Validates if all boundaries have facility assigned before finalizing catchment mapping for a given planConfigID. + * + * @param planConfigurationRequest request with plan config id. + */ + private void validateCatchmentMapping(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + CensusSearchRequest censusSearchRequest = getCensusSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches all census records for given planConfigId + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + Integer totalCensusCount = censusResponse.getTotalCount(); + + censusSearchRequest.getCensusSearchCriteria().setFacilityAssigned(Boolean.TRUE); + + // Fetches all census records for given planConfigId where facility is assigned + CensusResponse censusWithFacilityAssigned = censusUtil.fetchCensusRecords(censusSearchRequest); + Integer totalCensusWithFacilityAssigned = censusWithFacilityAssigned.getTotalCount(); + + if (!totalCensusCount.equals(totalCensusWithFacilityAssigned)) { + throw new CustomException(CANNOT_FINALIZE_CATCHMENT_MAPPING_CODE, CANNOT_FINALIZE_CATCHMENT_MAPPING_MESSAGE); + } + } + + /** + * Validates if all the plan estimations are validated before approving estimations for the given planConfigId. + * + * @param planConfigurationRequest request with plan config id. + */ + private void validateResourceEstimations(PlanConfigurationRequest planConfigurationRequest) { + PlanConfiguration planConfiguration = planConfigurationRequest.getPlanConfiguration(); + + PlanSearchRequest searchRequest = getPlanSearchRequest(planConfiguration.getTenantId(), planConfiguration.getId(), planConfigurationRequest.getRequestInfo()); + + // Fetches plans for given planConfigId + PlanResponse planResponse = planService.searchPlan(searchRequest); + + Map statusCount = planResponse.getStatusCount(); + Integer totalCount = planResponse.getTotalCount(); + + // Throws exception if all plans are not validated + if (!statusCount.get(VALIDATED_STATUS).equals(totalCount)) { + throw new CustomException(CANNOT_APPROVE_ESTIMATIONS_CODE, CANNOT_APPROVE_ESTIMATIONS_MESSAGE); + } + } + + // Prepares Census search request for given planConfigId + private CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() + .tenantId(tenantId) + .source(planConfigId) + .build(); + + return CensusSearchRequest.builder() + .requestInfo(requestInfo) + .censusSearchCriteria(searchCriteria) + .build(); + } + + // Prepares Plan search request for given planConfigId + private PlanSearchRequest getPlanSearchRequest(String tenantId, String planConfigId, RequestInfo requestInfo) { + PlanSearchCriteria searchCriteria = PlanSearchCriteria.builder() + .tenantId(tenantId) + .planConfigurationId(planConfigId) + .build(); + + return PlanSearchRequest.builder() + .requestInfo(requestInfo) + .planSearchCriteria(searchCriteria) + .build(); + } + +} diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 5a46a0b7e53..5b510beb17c 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -4,6 +4,7 @@ import digit.config.Configuration; import digit.repository.ServiceRequestRepository; import digit.service.PlanEmployeeService; +import digit.service.validator.PlanConfigurationValidator; import digit.util.CommonUtil; import digit.web.models.*; import lombok.extern.slf4j.Slf4j; @@ -38,14 +39,17 @@ public class WorkflowService { private PlanEmployeeService planEmployeeService; + private PlanConfigurationValidator planConfigurationValidator; + private RestTemplate restTemplate; - public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil, PlanEmployeeService planEmployeeService, RestTemplate restTemplate) { + public WorkflowService(ServiceRequestRepository serviceRequestRepository, Configuration config, ObjectMapper mapper, CommonUtil commonUtil, PlanEmployeeService planEmployeeService, PlanConfigurationValidator planConfigurationValidator, RestTemplate restTemplate) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.mapper = mapper; this.commonUtil = commonUtil; this.planEmployeeService = planEmployeeService; + this.planConfigurationValidator = planConfigurationValidator; this.restTemplate = restTemplate; } @@ -274,9 +278,9 @@ public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Plan // Check if this boundary code is present in assigneeJurisdiction if (plan.getAssigneeJurisdiction().contains(boundaryCode)) { - if (i - 1 >= 0) { + for (int j = i - 1; j >= 0; j--) { // Check the next higher level in the hierarchy (one index above the match) - String higherBoundaryCode = heirarchysBoundaryCodes[i - 1]; + String higherBoundaryCode = heirarchysBoundaryCodes[j]; // Fetch the employeeId from the map for the higher boundary code String employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); diff --git a/health-services/plan-service/src/main/java/digit/util/CensusUtil.java b/health-services/plan-service/src/main/java/digit/util/CensusUtil.java new file mode 100644 index 00000000000..fa45518c44a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/CensusUtil.java @@ -0,0 +1,60 @@ +package digit.util; + +import digit.config.Configuration; +import digit.web.models.census.CensusResponse; +import digit.web.models.census.CensusSearchRequest; +import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.web.client.RestTemplate; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class CensusUtil { + + private RestTemplate restTemplate; + + private Configuration config; + + public CensusUtil(RestTemplate restTemplate, Configuration config) { + this.restTemplate = restTemplate; + this.config = config; + } + + /** + * This method fetches data from Census based on the given census search request. + * + * @param searchRequest The census search request containing the search criteria. + * @return returns the census response. + */ + public CensusResponse fetchCensusRecords(CensusSearchRequest searchRequest) { + + // Get census search uri + String uri = getCensusUri().toString(); + + CensusResponse censusResponse = null; + try { + censusResponse = restTemplate.postForObject(uri, searchRequest, CensusResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_CENSUS, e); + } + + if (CollectionUtils.isEmpty(censusResponse.getCensus())) { + throw new CustomException(NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE, NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE); + } + + return censusResponse; + } + + /** + * Builds the census search uri. + * + * @return returns the complete uri for census search. + */ + private StringBuilder getCensusUri() { + return new StringBuilder().append(config.getCensusHost()).append(config.getCensusSearchEndPoint()); + } +} diff --git a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java index fc50b278d41..5d4c593b821 100644 --- a/health-services/plan-service/src/main/java/digit/util/CommonUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.DecimalNode; +import com.fasterxml.jackson.databind.node.NullNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.jayway.jsonpath.JsonPath; import digit.repository.PlanConfigurationRepository; import digit.web.models.*; @@ -12,10 +15,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import static digit.config.ServiceConstants.*; @@ -55,17 +55,26 @@ public Boolean validateStringAgainstRegex(String patternString, String inputStri * @return the value of the specified field as a string * @throws CustomException if the field does not exist */ - public String extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract) { + 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) { - // Convert the node to a String - return objectMapper.convertValue(node, String.class); + if (node != null && !node.isNull()) { + // Check for different types of JSON nodes + if (node instanceof DecimalNode) { + return ((DecimalNode) node).decimalValue(); + } else if (node.isDouble() || node.isFloat()) { + return node.asDouble(); + } else if (node.isLong() || node.isInt()) { + return node.asLong(); + } else if (node.isBoolean()) { + return node.asBoolean(); + } else if (node.isTextual()) { + return node.asText(); + } } - // Return null if the node is empty return null; } catch (Exception e) { log.error(e.getMessage() + fieldToExtract); @@ -148,6 +157,18 @@ public List searchPlanConfigId(String planConfigId, String te return planConfigurations; } + /** + * This method returns the planConfigName for the provided planConfig id + * + * @param tenantId + * @param planConfigId + */ + public String getPlanConfigName(String tenantId, String planConfigId) { + + List planConfigsFromSearch = searchPlanConfigId(planConfigId, tenantId); + return planConfigsFromSearch.get(0).getName(); + } + /** * Validates the user information within the provided PlanConfigurationRequest. * @@ -188,4 +209,46 @@ public Map getMicroplanHierarchy(Object mdmsData) { return hierarchyMap; } + + /** + * Checks if the setup process is completed based on the workflow action in the plan configuration. + * + * @param planConfiguration The plan configuration to check. + * @return true if the setup is completed, otherwise false. + */ + public boolean isSetupCompleted(PlanConfiguration planConfiguration) { + if(!ObjectUtils.isEmpty(planConfiguration.getWorkflow())) + return Objects.equals(planConfiguration.getWorkflow().getAction(), SETUP_COMPLETED_ACTION); + + return false; + } + + /** + * Adds or updates the provided fields in the additional details object. + * + * @param additionalDetails the additional details object to be updated. + * @param fieldsToBeUpdated map of field to be updated and it's updated value. + * @return returns the updated additional details object. + */ + + public Map updateFieldInAdditionalDetails(Object additionalDetails, Map fieldsToBeUpdated) { + try { + + // Get or create the additionalDetails as an ObjectNode + ObjectNode objectNode = (additionalDetails == null || additionalDetails instanceof NullNode) + ? objectMapper.createObjectNode() + : objectMapper.convertValue(additionalDetails, ObjectNode.class); + + // Update or add the field in additional details object + fieldsToBeUpdated.forEach((key, value) -> objectNode.set(key, objectMapper.valueToTree(value))); + + // Convert updated ObjectNode back to a Map + Map updatedMap = objectMapper.convertValue(objectNode, Map.class); + + return updatedMap; + + } catch (Exception e) { + throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE + e); + } + } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/Operation.java b/health-services/plan-service/src/main/java/digit/web/models/Operation.java index c4b7922da14..7e102e83b60 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Operation.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Operation.java @@ -61,6 +61,9 @@ public class Operation { @Size(min = 2, max = 64) private String category = null; + @JsonProperty("executionOrder") + private Integer executionOrder = null; + @JsonProperty("active") @NotNull private Boolean active = true; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java index 8ff4d9ca704..1f0b8f6be6f 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanConfigurationSearchCriteria.java @@ -54,5 +54,4 @@ public class PlanConfigurationSearchCriteria { @Min(1) @Max(50) private Integer limit; - } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 0cd2bd098cc..79020b68907 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -58,4 +58,10 @@ public class PlanEmployeeAssignmentSearchCriteria { @Builder.Default private Boolean filterUniqueByPlanConfig = Boolean.FALSE; + @JsonProperty("offset") + private Integer offset = null; + + @JsonProperty("limit") + private Integer limit = null; + } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java index a47f7198bc1..8377d11d971 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -46,6 +46,9 @@ public class PlanFacility { @Size(max = 64) private String facilityId = null; + @JsonProperty("facilityName") + private String facilityName = null; + @JsonProperty("residingBoundary") @NotNull @Size(min = 1, max = 64) diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java index 08a2799c683..812ec05516d 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java @@ -56,6 +56,9 @@ public class PlanFacilityDTO { @JsonProperty("initiallySetServiceBoundaries") private List initiallySetServiceBoundaries; + @JsonProperty("facilityName") + private String facilityName = null; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java index e2ca983a8a8..1ac3db052c6 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java @@ -26,4 +26,8 @@ public class PlanFacilityResponse { @JsonProperty("PlanFacility") @Valid private List planFacility = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; } diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/Census.java b/health-services/plan-service/src/main/java/digit/web/models/census/Census.java new file mode 100644 index 00000000000..11a196dd81b --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/Census.java @@ -0,0 +1,136 @@ +package digit.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.List; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; + + +/** + * Census + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Census { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("tenantId") + @NotNull + private String tenantId = null; + + @JsonProperty("hierarchyType") + @NotNull + private String hierarchyType = null; + + @JsonProperty("boundaryCode") + @NotNull + private String boundaryCode = null; + + @JsonProperty("assignee") + @NotNull + private String assignee = null; + + @JsonProperty("status") + @NotNull + private StatusEnum status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("effectiveFrom") + private Long effectiveFrom = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("source") + @NotNull + private String source = null; + + @JsonIgnore + private List boundaryAncestralPath = null; + + @JsonIgnore + private boolean partnerAssignmentValidationEnabled; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; + + /** + * The status used in the Census + */ + public enum StatusEnum { + VALIDATED, + APPROVED, + PENDING_FOR_APPROVAL, + PENDING_FOR_VALIDATION + } + + /** + * Gets or Sets type + */ + public enum TypeEnum { + PEOPLE("people"), + ANIMALS("animals"), + PLANTS("plants"), + OTHER("other"); + + private String value; + + TypeEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TypeEnum fromValue(String text) { + for (TypeEnum b : TypeEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java b/health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java new file mode 100644 index 00000000000..dabc56422b6 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java @@ -0,0 +1,42 @@ +package digit.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; +import java.util.Map; + +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusResponse + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("Census") + @Valid + private List census = null; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; + + @JsonProperty("StatusCount") + @Valid + private Map statusCount = null; + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java new file mode 100644 index 00000000000..4a5a1414d19 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java @@ -0,0 +1,72 @@ +package digit.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.springframework.validation.annotation.Validated; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchCriteria + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchCriteria { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("ids") + private Set ids = null; + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + private String tenantId = null; + + @JsonProperty("areaCodes") + private List areaCodes = null; + + @JsonProperty("status") + private String status = null; + + @JsonProperty("assignee") + private String assignee = null; + + @JsonProperty("source") + private String source = null; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("jurisdiction") + private List jurisdiction = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("limit") + private Integer limit = null; + + @JsonProperty("offset") + private Integer offset = null; + + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { + if (this.areaCodes == null) { + this.areaCodes = new ArrayList<>(); + } + this.areaCodes.add(areaCodesItem); + return this; + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java new file mode 100644 index 00000000000..157cf16870f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java @@ -0,0 +1,31 @@ +package digit.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * CensusSearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class CensusSearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("CensusSearchCriteria") + @Valid + private CensusSearchCriteria censusSearchCriteria = null; + + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java b/health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java new file mode 100644 index 00000000000..b36d25b21de --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java @@ -0,0 +1,69 @@ +package digit.web.models.census; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * PopulationByDemographic + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PopulationByDemographic { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("demographicVariable") + private DemographicVariableEnum demographicVariable = null; + + @JsonProperty("populationDistribution") + private Object populationDistribution = null; + + /** + * Gets or Sets demographicVariable + */ + public enum DemographicVariableEnum { + AGE("age"), + + GENDER("gender"), + + ETHNICITY("ethnicity"); + + private String value; + + DemographicVariableEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static DemographicVariableEnum fromValue(String text) { + for (DemographicVariableEnum b : DemographicVariableEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index b7e96a1bd4b..685d0549a07 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -55,6 +55,10 @@ plan.facility.create.topic=save-plan-facility plan.employee.assignment.create.topic=plan-employee-assignment-create-topic plan.employee.assignment.update.topic=plan-employee-assignment-update-topic +# Census +egov.census.host=https://unified-dev.digit.org +egov.census.search.endpoint=/census-service/_search + # Facility egov.facility.host=https://unified-dev.digit.org egov.facility.search.endpoint=/facility/v1/_search diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql new file mode 100644 index 00000000000..55852f824c2 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql @@ -0,0 +1,2 @@ +ALTER TABLE plan_configuration_operations +ADD COLUMN execution_order numeric(12,2); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql new file mode 100644 index 00000000000..7a10bbde149 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE plan_facility_linkage ADD facility_name character varying(64); \ No newline at end of file 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 42388c7f226..2b7a1d1dd24 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 @@ -11,6 +11,8 @@ import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.List; + @Component @Data @Import({ TracerConfiguration.class }) @@ -59,6 +61,9 @@ public class Configuration { @Value("${egov.project.factory.data.create.endpoint}") private String campaignIntegrationDataCreateEndPoint; + @Value("${egov.project.factory.fetch.from.microplan.endpoint}") + private String campaignIntegrationFetchFromMicroplanEndPoint; + @Value("${egov.project.factory.host}") private String projectFactoryHostEndPoint; @@ -104,4 +109,18 @@ public class Configuration { @Value("${resource.default.limit}") private Integer defaultLimit; + //census additonal field configs + @Value("${census.additional.field.override.keys}") + public List censusAdditionalFieldOverrideKeys; + + @Value("${census.additional.field.prefix.append.keys}") + public List censusAdditionalPrefixAppendKeys; + + //census host + @Value("${egov.census.host}") + private String censusHost; + + @Value("${egov.census.search.endpoint}") + private String censusSearchEndPoint; + } 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 811a7e2b53a..1d0cb5ee05b 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 @@ -12,6 +12,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; + public static final String ERROR_WHILE_FETCHING_FROM_CENSUS = "Exception occurred while fetching records from census: "; + public static final String TENANTID_REPLACER = "{tenantId}"; public static final String TENANTID = "tenantId"; @@ -40,6 +42,9 @@ public class ServiceConstants { 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."; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE = "NO_CENSUS_FOUND_FOR_GIVEN_DETAILS"; + public static final String NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE = "Census records does not exists for the given details: "; + public static final String BOUNDARY_CODE = "HCM_ADMIN_CONSOLE_BOUNDARY_CODE"; public static final String TOTAL_POPULATION = "HCM_ADMIN_CONSOLE_TOTAL_POPULATION"; @@ -47,6 +52,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_PUSHING_TO_PLAN_SERVICE_FOR_LOCALITY = "Exception occurred while fetching plan configuration from plan service for Locality "; public static final String ERROR_WHILE_SEARCHING_CAMPAIGN = "Exception occurred while searching/updating campaign."; 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 FILE_NAME = "output.xls"; public static final String FILE_TYPE = "boundaryWithTarget"; @@ -105,4 +112,8 @@ public class ServiceConstants { public static final String SOURCE_KEY = "source"; public static final String MICROPLAN_SOURCE_KEY = "microplan"; public static final String MICROPLAN_ID_KEY = "microplanId"; + + //Census additional field constants + public static final String UPLOADED_KEY = "UPLOADED_"; + public static final String CONFIRMED_KEY = "CONFIRMED_"; } 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 3aa7ebde5de..821b848cf75 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,6 +13,7 @@ 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; @@ -27,10 +28,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import static org.egov.processor.config.ServiceConstants.HCM_ADMIN_CONSOLE_BOUNDARY_DATA; @@ -64,9 +62,11 @@ public class ExcelParser implements FileParser { private EnrichmentUtil enrichmentUtil; + private PlanConfigurationUtil planConfigurationUtil; + 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) { + Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil, EnrichmentUtil enrichmentUtil, PlanConfigurationUtil planConfigurationUtil) { this.objectMapper = objectMapper; this.parsingUtil = parsingUtil; this.filestoreUtil = filestoreUtil; @@ -79,6 +79,7 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore this.localeUtil = localeUtil; this.censusUtil = censusUtil; this.enrichmentUtil = enrichmentUtil; + this.planConfigurationUtil = planConfigurationUtil; } /** @@ -162,9 +163,9 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); if (config.isIntegrateWithAdminConsole()) { +// campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); campaignIntegrationUtil.updateCampaignResources(uploadedFileStoreId, campaignResourcesList, fileToUpload.getName()); - campaignIntegrationUtil.updateCampaignDetails(planConfigurationRequest, campaignResponse, campaignBoundaryList, campaignResourcesList); } @@ -193,23 +194,32 @@ private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfi */ //TODO: processsheetforestimate and processsheetforcensus private void processSheets(PlanConfigurationRequest request, String fileStoreId, - Object campaignResponse, Workbook excelWorkbook, - List campaignBoundaryList, - DataFormatter dataFormatter) { + Object campaignResponse, Workbook excelWorkbook, + List campaignBoundaryList, + DataFormatter dataFormatter) { CampaignResponse campaign = campaignIntegrationUtil.parseCampaignResponse(campaignResponse); LocaleResponse localeResponse = localeUtil.searchLocale(request); - Object mdmsData = mdmsUtil. fetchMdmsData(request.getRequestInfo(), + Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), request.getPlanConfiguration().getTenantId()); + planConfigurationUtil.orderPlanConfigurationOperations(request); enrichmentUtil.enrichResourceMapping(request, localeResponse, campaign.getCampaign().get(0).getProjectType(), fileStoreId); Map attributeNameVsDataTypeMap = prepareAttributeVsIndexMap(request, fileStoreId, campaign, request.getPlanConfiguration(), mdmsData); List boundaryCodeList = getBoundaryCodeList(request, campaign); - + Map mappedValues = request.getPlanConfiguration().getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap( + ResourceMapping::getMappedTo, + ResourceMapping::getMappedFrom, + (existing, replacement) -> existing, + LinkedHashMap::new + )); excelWorkbook.forEach(excelWorkbookSheet -> { if (isSheetAllowedToProcess(request, excelWorkbookSheet.getSheetName(), localeResponse)) { if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { + enrichmentUtil.enrichsheetWithApprovedCensusRecords(excelWorkbookSheet, request, fileStoreId, mappedValues); processRows(request, excelWorkbookSheet, dataFormatter, fileStoreId, campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); } else if (request.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus())) { @@ -248,15 +258,20 @@ private void processRowsForCensusRecords(PlanConfigurationRequest planConfigurat Map mappedValues = planConfig.getResourceMapping().stream() .filter(f -> f.getFilestoreId().equals(fileStoreId)) - .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); + .collect(Collectors.toMap( + ResourceMapping::getMappedTo, + ResourceMapping::getMappedFrom, + (existing, replacement) -> existing, + LinkedHashMap::new + )); Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); - Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, - campaignIntegrationUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); Row firstRow = null; for (Row row : sheet) { - if (isRowEmpty(row)) + if (parsingUtil.isRowEmpty(row)) continue; if (row.getRowNum() == 0) { @@ -334,11 +349,11 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat .convertAssumptionsToMap(planConfig.getAssumptions()); Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); - Integer indexOfBoundaryCode = campaignIntegrationUtil.getIndexOfBoundaryCode(0, - campaignIntegrationUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); for (Row row : sheet) { - if(isRowEmpty(row)) + if(parsingUtil.isRowEmpty(row)) continue; if (row.getRowNum() == 0) { @@ -357,29 +372,10 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat mapOfColumnNameAndIndex, campaignBoundaryList, resultMap); planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); // TODO: remove after testing - printRow(sheet, row); + parsingUtil.printRow(sheet, row); } } - /** - * Checks if a given row is empty. - * - * A row is considered empty if it is null or if all of its cells are empty or of type BLANK. - * - * @param row the Row to check - * @return true if the row is empty, false otherwise - */ - public static boolean isRowEmpty(Row row) { - if (row == null) { - return true; - } - for (Cell cell : row) { - if (cell != null && cell.getCellType() != CellType.BLANK) { - return false; - } - } - return true; - } /** * Performs calculations on operations for a specific row in the sheet. @@ -515,40 +511,6 @@ private JsonNode createFeatureNodeFromRow(Row row, Map columnIn return featureNode; } - public void printRow(Sheet sheet, Row row) { - System.out.print("Row -> "); - for (Cell cell : row) { - int columnIndex = cell.getColumnIndex(); - // String columnName = sheet.getRow(0).getCell(columnIndex).toString(); - // System.out.print("Column " + columnName + " - "); - switch (cell.getCellType()) { - case STRING: - System.out.print(cell.getStringCellValue() + "\t"); - break; - case NUMERIC: - if (DateUtil.isCellDateFormatted(cell)) { - System.out.print(cell.getDateCellValue() + "\t"); - } else { - System.out.print(cell.getNumericCellValue() + "\t"); - } - break; - case BOOLEAN: - System.out.print(cell.getBooleanCellValue() + "\t"); - break; - case FORMULA: - System.out.print(cell.getCellFormula() + "\t"); - break; - case BLANK: - System.out.print("\t"); - break; - default: - System.out.print("\t"); - break; - } - } - System.out.println(); // Move to the next line after printing the row - } - /** * Validates the data in a row. * diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java index 95c504445fa..551206d9b94 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java @@ -2,13 +2,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - import org.egov.processor.config.ServiceConstants; import org.egov.processor.web.models.Assumption; import org.egov.processor.web.models.Operation; @@ -18,6 +11,12 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import static org.egov.processor.config.ServiceConstants.PROPERTIES; @Component @@ -87,43 +86,19 @@ public void calculateResources(JsonNode jsonNode, PlanConfigurationRequest planC /** * Retrieves the input value from the JSON node based on the input and input mapping. * - * @param resultMap The map containing previous results. - * @param feature The JSON node feature. - * @param input The input key. - * @param columnName The input from mapping. + * @param resultMap The map containing previous results. + * @param feature The JSON node feature. + * @param assumptionValueMap The assumptions and their value map from plan config. + * @param input The input key. + * @param columnName The input from mapping. * @return The input value. */ - public BigDecimal getInputValueFromJsonFeature(JsonNode feature, Map resultMap, String input, String columnName) { - if (resultMap.containsKey(input)) { - return resultMap.get(input); - } else { - if (feature.get(PROPERTIES).get(columnName) != null) { - try { - String cellValue = String.valueOf(feature.get(PROPERTIES).get(columnName)); - BigDecimal value; - // Handle scientific notation - if (cellValue.contains(ServiceConstants.SCIENTIFIC_NOTATION_INDICATOR)) { - value = new BigDecimal(cellValue); - } else { - String cleanedValue = cellValue.replaceAll("[^\\d.\\-E]", ""); - value = new BigDecimal(cleanedValue); - } - return value; - } catch (NumberFormatException | NullPointerException e) { - return BigDecimal.ZERO; - } - } else { - throw new CustomException("INPUT_VALUE_NOT_FOUND", "Input value not found: " + input); - } - } - } - - private BigDecimal getInputValueFromFeatureOrMap(JsonNode feature, Map resultMap, Map assumptionValueMap, String assumptionKey, String columnName) { + private BigDecimal getInputValueFromFeatureOrMap(JsonNode feature, Map resultMap, Map assumptionValueMap, String input, String columnName) { // Try to fetch the value from resultMap, If not found in the resultMap, use the assumptionValueMap as a fallback - BigDecimal assumptionValue = resultMap.getOrDefault(assumptionKey, assumptionValueMap.get(assumptionKey)); + BigDecimal inputValue = resultMap.getOrDefault(input, assumptionValueMap.get(input)); // Try to fetch the value from the feature (if it exists) - if(ObjectUtils.isEmpty(assumptionValue)) { + if(ObjectUtils.isEmpty(inputValue)) { if (feature.has(PROPERTIES) && feature.get(PROPERTIES).has(columnName)) { try { String cellValue = String.valueOf(feature.get(PROPERTIES).get(columnName)); @@ -137,11 +112,11 @@ private BigDecimal getInputValueFromFeatureOrMap(JsonNode feature, Map resultMap -> assumptionValueMap String assumptionKey = operation.getAssumptionValue(); 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 ca9e0ffe9d7..9bfbe7cb62c 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 @@ -28,6 +28,7 @@ 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) { @@ -35,6 +36,50 @@ public CampaignIntegrationUtil(ServiceRequestRepository serviceRequestRepository this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.mapper = mapper; + this.parsingUtil= parsingUtil; + } + + /** + * Updates resources in the Project Factory by calling an external API with the given plan configuration + * request and file store ID. Logs the operation status. + * + * @param planConfigurationRequest The plan configuration request details. + * @param fileStoreId The file store ID to update. + * @throws CustomException if the API call fails. + */ + public void updateResourcesInProjectFactory(PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + try { + serviceRequestRepository.fetchResult( + new StringBuilder(config.getProjectFactoryHostEndPoint() + config.getCampaignIntegrationFetchFromMicroplanEndPoint()), + buildMicroplanDetailsForUpdate(planConfigurationRequest, fileStoreId)); + log.info("Updated resources file into project factory - " + fileStoreId); + } catch (Exception e) { + log.error(ERROR_WHILE_CALLING_MICROPLAN_API + planConfigurationRequest.getPlanConfiguration().getId(), e); + throw new CustomException(ERROR_WHILE_CALLING_MICROPLAN_API, e.toString()); + } + + } + + /** + * 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 fileStoreId The filestoreId with calculated resources + * @return The microplan details request object built for updating resource filestore id. + */ + private MicroplanDetailsRequest buildMicroplanDetailsForUpdate(PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + + MicroplanDetails microplanDetails = MicroplanDetails.builder() + .tenantId(planConfig.getTenantId()) + .planConfigurationId(planConfig.getId()) + .campaignId(planConfig.getCampaignId()) + .resourceFilestoreId(fileStoreId).build(); + + return MicroplanDetailsRequest.builder() + .microplanDetails(microplanDetails) + .requestInfo(planConfigurationRequest.getRequestInfo()).build(); + } /** @@ -177,29 +222,13 @@ public void updateCampaignBoundary(PlanConfiguration planConfig, JsonNode featur boolean validToAdd = false; Integer indexValue = 0; Boundary boundary = new Boundary(); - List> sortedColumnList = sortColumnByIndex(mapOfColumnNameAndIndex); - indexValue = getIndexOfBoundaryCode(indexValue, sortedColumnList, mappedValues); + 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); } - /** - * Retrieves the index value of the boundary code from the sorted column list based on the mapped values. - * - * @param indexValue The initial index value. - * @param sortedColumnList The sorted list of column names and indices. - * @param mappedValues The map containing mapped values. - * @return The index value of the boundary code. - */ - public Integer getIndexOfBoundaryCode(Integer indexValue, List> sortedColumnList,Map mappedValues) { - for (Map.Entry entry : sortedColumnList) { - if (entry.getKey().equals(mappedValues.get(ServiceConstants.BOUNDARY_CODE))) { - indexValue = entry.getValue(); - } - } - return indexValue; - } /** * Prepares a campaign boundary based on the provided index values, sorted column list, feature, and mapped values. @@ -253,22 +282,7 @@ private boolean isValidToAdd(List boundaryList, Map> sortColumnByIndex(Map mapOfColumnNameAndIndex) { - List> sortedColumnList = new ArrayList<>(mapOfColumnNameAndIndex.entrySet()); - Collections.sort(sortedColumnList, new Comparator>() { - @Override - public int compare(Map.Entry o1, Map.Entry o2) { - return o1.getValue().compareTo(o2.getValue()); - } - }); - return sortedColumnList; - } + /** * Retrieves the value of the boundary code from the feature JSON node based on the mapped values. diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java index 0f544d7b9dc..2dde03575c8 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java @@ -1,20 +1,24 @@ package org.egov.processor.util; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.models.Workflow; import org.egov.processor.config.Configuration; import org.egov.processor.config.ServiceConstants; import org.egov.processor.kafka.Producer; import org.egov.processor.repository.ServiceRequestRepository; -import org.egov.processor.web.models.*; -import org.egov.processor.web.models.census.Census; -import org.egov.processor.web.models.census.CensusRequest; +import org.egov.processor.web.models.PlanConfiguration; +import org.egov.processor.web.models.PlanConfigurationRequest; +import org.egov.processor.web.models.census.*; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import java.math.BigDecimal; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import static org.egov.processor.config.ServiceConstants.*; @@ -31,11 +35,14 @@ public class CensusUtil { private ParsingUtil parsingUtil; - public CensusUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, Producer producer, ParsingUtil parsingUtil) { + private ObjectMapper mapper; + + public CensusUtil(ServiceRequestRepository serviceRequestRepository, Configuration config, Producer producer, ParsingUtil parsingUtil, ObjectMapper objectMapper) { this.serviceRequestRepository = serviceRequestRepository; this.config = config; this.producer = producer; this.parsingUtil = parsingUtil; + this.mapper = objectMapper; } /** @@ -79,7 +86,7 @@ private CensusRequest buildCensusRequest(PlanConfigurationRequest planConfigurat .totalPopulation((BigDecimal) parsingUtil.extractMappedValueFromFeatureForAnInput(ServiceConstants.TOTAL_POPULATION, feature, mappedValues)) .workflow(Workflow.builder().action(WORKFLOW_ACTION_INITIATE).comments(WORKFLOW_COMMENTS_INITIATING_CENSUS).build()) .source(planConfig.getId()) - .additionalDetails(enrichAdditionalDetails(feature, mappedValues)).build()) + .additionalFields(enrichAdditionalField(feature, mappedValues)).build()) .requestInfo(planConfigurationRequest.getRequestInfo()).build(); } @@ -91,21 +98,89 @@ private CensusRequest buildCensusRequest(PlanConfigurationRequest planConfigurat * @param mappedValues The mapped values for extracting properties. * @return A map containing enriched additional details based on the extracted values. */ - public Map enrichAdditionalDetails(JsonNode feature, Map mappedValues) { - // Create additionalDetails object to hold the enriched data - Map additionalDetails = new HashMap<>(); + public List enrichAdditionalField(JsonNode feature, Map mappedValues) { + // Initialize orderCounter inside the function + List additionalFieldList = new ArrayList<>(); + int orderCounter = 1; - // Iterate over mappedValues keys for (String key : mappedValues.keySet()) { + // Skip keys in the override list + if (config.getCensusAdditionalFieldOverrideKeys().contains(key)) + continue; + // Get the corresponding value from the feature JsonNode Object valueFromRow = parsingUtil.extractMappedValueFromFeatureForAnInput(key, feature, mappedValues); - // Check if the value exists in the JSON and add it to additonalDetails map + + // Check if the value exists in the JSON if (!ObjectUtils.isEmpty(valueFromRow)) { - additionalDetails.put(key, valueFromRow); + // Add additional fields with "UPLOADED" and "CONFIRMED" prefixes if key is in override list + if (config.getCensusAdditionalPrefixAppendKeys().contains(key)) { + AdditionalField uploadedField = AdditionalField.builder() + .key(UPLOADED_KEY + key) + .value((BigDecimal) valueFromRow) + .editable(Boolean.FALSE) + .showOnUi(Boolean.TRUE) + .order(orderCounter++) // Increment for "UPLOADED" field + .build(); + additionalFieldList.add(uploadedField); + + AdditionalField confirmedField = AdditionalField.builder() + .key(CONFIRMED_KEY + key) + .value((BigDecimal) valueFromRow) + .editable(Boolean.TRUE) + .showOnUi(Boolean.TRUE) + .order(orderCounter++) // Increment for "CONFIRMED" field + .build(); + additionalFieldList.add(confirmedField); + } else { + AdditionalField additionalField = AdditionalField.builder() + .key(key) + .value((BigDecimal) valueFromRow) + .editable(Boolean.TRUE) + .showOnUi(Boolean.TRUE) + .order(orderCounter++) // Use and increment the local orderCounter + .build(); + additionalFieldList.add(additionalField); + } } } - return additionalDetails; + return additionalFieldList; + } + + /** + * This method fetches data from Census based on the given census search request. + * + * @param searchRequest The census search request containing the search criteria. + * @return returns the census response. + */ + public CensusResponse fetchCensusRecords(CensusSearchRequest searchRequest) { + + // Get census search uri + String uri = getCensusUri().toString(); + + CensusResponse censusResponse = null; + try { + Object response = serviceRequestRepository.fetchResult(new StringBuilder(uri), searchRequest); + censusResponse = mapper.convertValue(response, CensusResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_CENSUS, e); + } + + if (CollectionUtils.isEmpty(censusResponse.getCensus())) { + throw new CustomException(NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE, NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE); + } + + return censusResponse; + } + + /** + * Builds the census search uri. + * + * @return returns the complete uri for census search. + */ + private StringBuilder getCensusUri() { + return new StringBuilder().append(config.getCensusHost()).append(config.getCensusSearchEndPoint()); } } 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 5ae922fbe01..be9579af525 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 @@ -1,17 +1,30 @@ package org.egov.processor.util; -import com.fasterxml.jackson.databind.JsonNode; import lombok.extern.slf4j.Slf4j; -import org.egov.common.utils.MultiStateInstanceUtil; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; import org.egov.common.utils.UUIDEnrichmentUtil; +import org.egov.processor.config.Configuration; import org.egov.processor.web.models.LocaleResponse; +import org.egov.processor.web.models.PlanConfiguration; import org.egov.processor.web.models.PlanConfigurationRequest; import org.egov.processor.web.models.ResourceMapping; +import org.egov.processor.web.models.census.Census; +import org.egov.processor.web.models.census.CensusResponse; +import org.egov.processor.web.models.census.CensusSearchCriteria; +import org.egov.processor.web.models.census.CensusSearchRequest; import org.egov.processor.web.models.mdmsV2.Mdms; +import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import static org.egov.processor.config.ServiceConstants.*; @@ -25,13 +38,18 @@ public class EnrichmentUtil { private ParsingUtil parsingUtil; + private CensusUtil censusUtil; + + private Configuration config; // private MultiStateInstanceUtil centralInstanceUtil; - public EnrichmentUtil(MdmsV2Util mdmsV2Util, LocaleUtil localeUtil, ParsingUtil parsingUtil) { + public EnrichmentUtil(MdmsV2Util mdmsV2Util, LocaleUtil localeUtil, ParsingUtil parsingUtil, CensusUtil censusUtil, Configuration config) { this.mdmsV2Util = mdmsV2Util; this.localeUtil = localeUtil; // this.centralInstanceUtil = centralInstanceUtil; this.parsingUtil = parsingUtil; + this.censusUtil = censusUtil; + this.config = config; } /** @@ -68,4 +86,128 @@ public void enrichResourceMapping(PlanConfigurationRequest request, LocaleRespon } + public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationRequest planConfigurationRequest, String fileStoreId, Map mappedValues) { + List boundaryCodes = getBoundaryCodesFromTheSheet(sheet, planConfigurationRequest, fileStoreId); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + + //Getting census records for the list of boundaryCodes + List censusList = getCensusRecordsForEnrichment(planConfigurationRequest, boundaryCodes); + + // Create a map from boundaryCode to Census for quick lookups + Map censusMap = censusList.stream() + .collect(Collectors.toMap(Census::getBoundaryCode, census -> census)); + + + for(Row row: sheet) { + parsingUtil.printRow(sheet, row); + if (row.getRowNum() == 0) continue; // Skip header row + + // Get the boundaryCode in the current row + Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); + String boundaryCode = boundaryCodeCell.getStringCellValue(); + + Census census = censusMap.get(boundaryCode); + + if (census != null) { + // For each field in the sheetToCensusMap, update the cell if the field is editable + for (Map.Entry entry : mappedValues.entrySet()) { + String censusKey = entry.getKey(); + String sheetColumn = entry.getValue(); + + if(config.getCensusAdditionalFieldOverrideKeys().contains(censusKey)) + continue; + censusKey = config.getCensusAdditionalPrefixAppendKeys().contains(censusKey) ? CONFIRMED_KEY + censusKey : censusKey; + + // Get the column index from the mapOfColumnNameAndIndex + Integer columnIndex = mapOfColumnNameAndIndex.get(sheetColumn); + if (columnIndex != null) { + // Get the value for this field in the census, if editable + BigDecimal editableValue = getEditableValue(census, censusKey); + + if(ObjectUtils.isEmpty(editableValue)) continue; + + Cell cell = row.getCell(columnIndex); + if (cell == null) { + cell = row.createCell(columnIndex); + } + cell.setCellValue(editableValue.doubleValue()); + + } + } + } + //TODO: remove after testing + log.info("After updating values in sheet -> "); + parsingUtil.printRow(sheet, row); + + log.info("Successfully update file with approved census data."); + } + } + + public List getBoundaryCodesFromTheSheet(Sheet sheet, PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + + Map mappedValues = planConfig.getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + + List boundaryCodes = new ArrayList<>(); + + for (Row row : sheet) { + // Skip the header row and empty rows + if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { + continue; + } + + // Get the boundary code cell + Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); + + // Check if the cell is non-empty and collect its value + if (boundaryCodeCell != null && boundaryCodeCell.getCellType() == CellType.STRING) { + String boundaryCode = boundaryCodeCell.getStringCellValue().trim(); + if (!boundaryCode.isEmpty()) { + boundaryCodes.add(boundaryCode); + } + } + } + + return boundaryCodes; + } + + public List getCensusRecordsForEnrichment(PlanConfigurationRequest planConfigurationRequest, List boundaryCodes) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder() + .tenantId(planConfig.getTenantId()) + .areaCodes(boundaryCodes) + .source(planConfig.getId()).build(); + + CensusSearchRequest censusSearchRequest = CensusSearchRequest.builder() + .censusSearchCriteria(censusSearchCriteria) + .requestInfo(planConfigurationRequest.getRequestInfo()).build(); + + CensusResponse censusResponse = censusUtil.fetchCensusRecords(censusSearchRequest); + + if(censusResponse.getCensus().isEmpty()) + throw new CustomException(NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_CODE, NO_CENSUS_FOUND_FOR_GIVEN_DETAILS_MESSAGE); + + return censusResponse.getCensus(); + + } + + private BigDecimal getEditableValue(Census census, String key) { + return census.getAdditionalFields().stream() + .filter(field -> field.getEditable() && key.equals(field.getKey())) // Filter by editability and matching key + .map(field -> field.getValue()) + .findFirst() + .orElse(null); + } + + } 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 96eed325956..ba10327e4c8 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 @@ -1,37 +1,29 @@ package org.egov.processor.util; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.DecimalNode; +import lombok.extern.slf4j.Slf4j; +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.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import com.fasterxml.jackson.databind.node.DecimalNode; -import org.apache.commons.io.FileUtils; -import org.apache.poi.ss.usermodel.*; -import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.ResourceMapping; -import org.egov.tracer.model.CustomException; -import org.springframework.stereotype.Component; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.util.ObjectUtils; - import static org.egov.processor.config.ServiceConstants.PROPERTIES; @Slf4j @@ -313,4 +305,91 @@ public List extractPropertyNamesFromAdminSchema(JsonNode rootNode) { return names; } + + /** + * Checks if a given row is empty. + * + * A row is considered empty if it is null or if all of its cells are empty or of type BLANK. + * + * @param row the Row to check + * @return true if the row is empty, false otherwise + */ + public static boolean isRowEmpty(Row row) { + if (row == null) { + return true; + } + for (Cell cell : row) { + if (cell != null && cell.getCellType() != CellType.BLANK) { + return false; + } + } + return true; + } + + /** + * Retrieves the index value of the boundary code from the sorted column list based on the mapped values. + * + * @param indexValue The initial index value. + * @param sortedColumnList The sorted list of column names and indices. + * @param mappedValues The map containing mapped values. + * @return The index value of the boundary code. + */ + public Integer getIndexOfBoundaryCode(Integer indexValue, List> sortedColumnList,Map mappedValues) { + for (Map.Entry entry : sortedColumnList) { + if (entry.getKey().equals(mappedValues.get(ServiceConstants.BOUNDARY_CODE))) { + indexValue = entry.getValue(); + } + } + return indexValue; + } + + /** + * Sorts the column names and indices based on the provided map of column names and indices. + * + * @param mapOfColumnNameAndIndex The map containing column names and their corresponding indices. + * @return The sorted list of column names and indices. + */ + public List> sortColumnByIndex(Map mapOfColumnNameAndIndex) { + List> sortedColumnList = new ArrayList<>(mapOfColumnNameAndIndex.entrySet()); + Collections.sort(sortedColumnList, new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return o1.getValue().compareTo(o2.getValue()); + } + }); + return sortedColumnList; + } + + public void printRow(Sheet sheet, Row row) { + System.out.print("Row -> "); + for (Cell cell : row) { + int columnIndex = cell.getColumnIndex(); + switch (cell.getCellType()) { + case STRING: + System.out.print(cell.getStringCellValue() + "\t"); + break; + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + System.out.print(cell.getDateCellValue() + "\t"); + } else { + System.out.print(cell.getNumericCellValue() + "\t"); + } + break; + case BOOLEAN: + System.out.print(cell.getBooleanCellValue() + "\t"); + break; + case FORMULA: + System.out.print(cell.getCellFormula() + "\t"); + break; + case BLANK: + System.out.print("\t"); + break; + default: + System.out.print("\t"); + break; + } + } + System.out.println(); // Move to the next line after printing the row + } + } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java index 26a11dcf976..55a8651ec56 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java @@ -1,19 +1,17 @@ package org.egov.processor.util; import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import lombok.extern.slf4j.Slf4j; - import org.egov.processor.config.Configuration; import org.egov.processor.repository.ServiceRequestRepository; -import org.egov.processor.web.models.PlanConfiguration; -import org.egov.processor.web.models.PlanConfigurationResponse; -import org.egov.processor.web.models.PlanConfigurationSearchRequest; +import org.egov.processor.web.models.*; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + import static org.egov.processor.config.ServiceConstants.ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE; @Component @@ -54,4 +52,8 @@ public List search(PlanConfigurationSearchRequest planConfigu else return planConfigurationList; } + + public void orderPlanConfigurationOperations(PlanConfigurationRequest planConfigurationRequest) { + planConfigurationRequest.getPlanConfiguration().getOperations().sort(Comparator.comparingInt(Operation::getExecutionOrder)); + } } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java index 6147edb0f02..5194da66b18 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Operation.java @@ -61,6 +61,9 @@ public class Operation { @Size(min = 2, max = 64) private String category = null; + @JsonProperty("executionOrder") + private Integer executionOrder = null; + @JsonProperty("active") @NotNull private Boolean active = true; diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java new file mode 100644 index 00000000000..4bbb44b118b --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java @@ -0,0 +1,32 @@ +package org.egov.processor.web.models.campaignManager; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Validated +public class MicroplanDetails { + + @JsonProperty("tenantId") + @NotNull + private String tenantId; + + @JsonProperty("campaignId") + @NotNull + private String campaignId; + + @JsonProperty("planConfigurationId") + @NotNull + private String planConfigurationId; + + @JsonProperty("resourceFilestoreId") + private String resourceFilestoreId; +} \ No newline at end of file diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java new file mode 100644 index 00000000000..4789ef42573 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java @@ -0,0 +1,26 @@ +package org.egov.processor.web.models.campaignManager; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class MicroplanDetailsRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("MicroplanDetails") + @Valid + private MicroplanDetails microplanDetails = null; +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java new file mode 100644 index 00000000000..972ca77bb4b --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java @@ -0,0 +1,48 @@ +package org.egov.processor.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.math.BigDecimal; + +/** + * AdditionalField + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class AdditionalField { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("key") + @Valid + @NotNull + private String key = null; + + @JsonProperty("value") + @Valid + @NotNull + private BigDecimal value = null; + + @JsonProperty("showOnUi") + private Boolean showOnUi = Boolean.TRUE; + + @JsonProperty("editable") + private Boolean editable = Boolean.TRUE; + + @JsonProperty("order") + private Integer order = null; +} diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java index 9b6c76df2a6..f895f6c75f1 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java @@ -96,6 +96,10 @@ public class Census { @JsonProperty("additionalDetails") private Object additionalDetails = null; + @JsonProperty("additionalFields") + @Valid + private List additionalFields = null; + @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; diff --git a/health-services/resource-generator/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties index 78607ad9dd5..2edff68868d 100644 --- a/health-services/resource-generator/src/main/resources/application.properties +++ b/health-services/resource-generator/src/main/resources/application.properties @@ -71,6 +71,7 @@ egov.plan.create.endpoint=/plan-service/plan/_create egov.project.factory.search.endpoint=/project-factory/v1/project-type/search egov.project.factory.update.endpoint=/project-factory/v1/project-type/update egov.project.factory.data.create.endpoint=/project-factory/v1/data/_create +egov.project.factory.fetch.from.microplan.endpoint=/project-factory/v1/project-type/fetch-from-microplan egov.project.factory.host=https://unified-dev.digit.org #egov.project.factory.host=http://localhost:8090 integrate.with.admin.console=false @@ -94,4 +95,11 @@ plan.config.trigger.plan.facility.mappings.status=EXECUTION_TO_BE_DONE # Pagination config resource.default.offset=0 -resource.default.limit=10 \ No newline at end of file +resource.default.limit=10 + +# Census +egov.census.host=https://unified-dev.digit.org +egov.census.search.endpoint=/census-service/_search + +census.additional.field.override.keys=HCM_ADMIN_CONSOLE_BOUNDARY_CODE +census.additional.field.prefix.append.keys=HCM_ADMIN_CONSOLE_TOTAL_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11,HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59 \ No newline at end of file From 996e5ee0651c97d3dc5133abb186129b4be582c3 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 14 Nov 2024 21:00:22 +0530 Subject: [PATCH 315/351] making fuzzy search cAse-insenSItive --- .../digit/repository/querybuilder/PlanConfigQueryBuilder.java | 2 +- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 2 +- .../repository/querybuilder/PlanFacilityQueryBuilder.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index ef79343841e..d7affcd04ef 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java @@ -116,7 +116,7 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter if (criteria.getName() != null) { addClauseIfRequired(preparedStmtList, builder); - builder.append(" pc.name LIKE ?"); + builder.append(" pc.name ILIKE ?"); preparedStmtList.add(PERCENTAGE_WILDCARD + criteria.getName() + PERCENTAGE_WILDCARD); } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 571ff425e51..790ea73983c 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -96,7 +96,7 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit if (searchCriteria.getPlanConfigurationName() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_configuration_name LIKE ?"); + builder.append(" plan_configuration_name ILIKE ?"); preparedStmtList.add(PERCENTAGE_WILDCARD + searchCriteria.getPlanConfigurationName() + PERCENTAGE_WILDCARD); } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java index 017532f0623..ba7969846ba 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -88,7 +88,7 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getPlanConfigurationName())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_configuration_name LIKE ? "); + builder.append(" plan_configuration_name ILIKE ? "); preparedStmtList.add(PERCENTAGE_WILDCARD + planFacilitySearchCriteria.getPlanConfigurationName() + PERCENTAGE_WILDCARD); } @@ -100,7 +100,7 @@ private String buildPlanFacilitySearchQuery(PlanFacilitySearchCriteria planFacil if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityName())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" facility_name LIKE ? "); + builder.append(" facility_name ILIKE ? "); preparedStmtList.add(PERCENTAGE_WILDCARD + planFacilitySearchCriteria.getFacilityName() + PERCENTAGE_WILDCARD); } From cd2aed6ee84c8f0d502ab276d81ddf2a4b4f0b74 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 15 Nov 2024 11:41:55 +0530 Subject: [PATCH 316/351] making fuzzy search cAse-insenSItive --- .../PlanEmployeeAssignmentQueryBuilder.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 212665224af..337d2f01fff 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -24,17 +24,17 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration con this.config = config; } - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa "; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (plan_configuration_id) id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (pa.plan_configuration_id) pa.id, pa.tenant_id, pa.plan_configuration_id, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa"; - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.last_modified_time DESC"; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.plan_configuration_id, pa.last_modified_time DESC"; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; - private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT * FROM ( {INTERNAL_QUERY} ) AS latest_assignments ORDER BY last_modified_time DESC"; + private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM ( {INTERNAL_QUERY} ) AS pa JOIN plan_configuration pc ON pa.plan_configuration_id = pc.id ORDER BY pc.last_modified_time DESC"; /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. @@ -77,46 +77,47 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit if (searchCriteria.getId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" id = ?"); + builder.append(" pa.id = ?"); preparedStmtList.add(searchCriteria.getId()); } if (searchCriteria.getTenantId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" tenant_id = ?"); + builder.append(" pa.tenant_id = ?"); preparedStmtList.add(searchCriteria.getTenantId()); } if (searchCriteria.getPlanConfigurationId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_configuration_id = ?"); + builder.append(" pa.plan_configuration_id = ?"); preparedStmtList.add(searchCriteria.getPlanConfigurationId()); } if (!CollectionUtils.isEmpty(searchCriteria.getEmployeeId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); + builder.append(" pa.employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getEmployeeId())); } if (!CollectionUtils.isEmpty(searchCriteria.getRole())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); + builder.append(" pa.role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getRole())); } if(searchCriteria.getHierarchyLevel() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" hierarchy_level = ?"); + builder.append(" pa.hierarchy_level = ?"); preparedStmtList.add(searchCriteria.getHierarchyLevel()); } if (searchCriteria.getActive() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" active = ?"); + builder.append(" pa.active = ?"); preparedStmtList.add(searchCriteria.getActive()); } + //TODO if (!CollectionUtils.isEmpty(searchCriteria.getJurisdiction())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" ARRAY [ ").append(queryUtil.createQuery(searchCriteria.getJurisdiction().size())).append(" ]").append("::text[] "); From d63133baad64676defc1274703968bc125c8dc45 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 15 Nov 2024 11:45:11 +0530 Subject: [PATCH 317/351] making fuzzy search cAse-insenSItive --- .../PlanEmployeeAssignmentQueryBuilder.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 337d2f01fff..dbe14807137 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -24,17 +24,17 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration con this.config = config; } - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment"; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (pa.plan_configuration_id) pa.id, pa.tenant_id, pa.plan_configuration_id, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (plan_configuration_id) id, tenant_id, plan_configuration_id, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment"; - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.last_modified_time DESC"; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.plan_configuration_id, pa.last_modified_time DESC"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; - private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM ( {INTERNAL_QUERY} ) AS pa JOIN plan_configuration pc ON pa.plan_configuration_id = pc.id ORDER BY pc.last_modified_time DESC"; + private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM ( {INTERNAL_QUERY} ) AS pa JOIN plan_configuration pc ON plan_configuration_id = pc.id ORDER BY pc.last_modified_time DESC"; /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. @@ -77,43 +77,43 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit if (searchCriteria.getId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pa.id = ?"); + builder.append(" id = ?"); preparedStmtList.add(searchCriteria.getId()); } if (searchCriteria.getTenantId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pa.tenant_id = ?"); + builder.append(" tenant_id = ?"); preparedStmtList.add(searchCriteria.getTenantId()); } if (searchCriteria.getPlanConfigurationId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pa.plan_configuration_id = ?"); + builder.append(" plan_configuration_id = ?"); preparedStmtList.add(searchCriteria.getPlanConfigurationId()); } if (!CollectionUtils.isEmpty(searchCriteria.getEmployeeId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pa.employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); + builder.append(" employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getEmployeeId())); } if (!CollectionUtils.isEmpty(searchCriteria.getRole())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pa.role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); + builder.append(" role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getRole())); } if(searchCriteria.getHierarchyLevel() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pa.hierarchy_level = ?"); + builder.append(" hierarchy_level = ?"); preparedStmtList.add(searchCriteria.getHierarchyLevel()); } if (searchCriteria.getActive() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" pa.active = ?"); + builder.append(" active = ?"); preparedStmtList.add(searchCriteria.getActive()); } From 702d825c56094e6e1e597623bc49b4c9fbc842c1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 15 Nov 2024 11:57:25 +0530 Subject: [PATCH 318/351] pull from microplanning-dev --- .../java/digit/repository/impl/PlanEmployeeAssignmentImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index 40bcb9c4875..5ec16de3794 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -57,7 +57,7 @@ public List search(PlanEmployeeAssignmentSearchCriteria List preparedStmtList = new ArrayList<>(); String searchQuery = queryBuilder.getPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); List planEmployeeAssignments = jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); - log.info(searchQuery); + return planEmployeeAssignments; } From 0f26de04abea3553be55cc2e7fd47c064c49bf93 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 15 Nov 2024 11:58:40 +0530 Subject: [PATCH 319/351] pull from microplanning-dev --- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index c8f9d0e1ced..a40bc04438f 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -125,7 +125,6 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit preparedStmtList.add(searchCriteria.getActive()); } - //TODO if (!CollectionUtils.isEmpty(searchCriteria.getJurisdiction())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" ARRAY [ ").append(queryUtil.createQuery(searchCriteria.getJurisdiction().size())).append(" ]").append("::text[] "); From 9c47c8b962cbd19f185446d5836ee28f108d57e0 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 15 Nov 2024 14:05:43 +0530 Subject: [PATCH 320/351] modified pagination --- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index a40bc04438f..9333737e568 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -49,8 +49,9 @@ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteri String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE : PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY.replace("{INTERNAL_QUERY}", query) : query; query = getPaginatedQuery(query, searchCriteria, preparedStmtList); - return Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY.replace("{INTERNAL_QUERY}", query) : query; + return query; } /** From c0ed5ccc6a4a96220f7ce86c1e10b96b18fbaf5e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 15 Nov 2024 14:29:03 +0530 Subject: [PATCH 321/351] HCMPRE-1282 changes for updating approved plans into file for campaign integration --- .../src/main/java/digit/kafka/UpdatePlanConfigConsumer.java | 1 + .../main/java/org/egov/processor/kafka/PlanConsumer.java | 6 ++++-- .../src/main/java/org/egov/processor/util/PlanUtil.java | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/kafka/UpdatePlanConfigConsumer.java b/health-services/plan-service/src/main/java/digit/kafka/UpdatePlanConfigConsumer.java index ca72bb21058..b2a97f1d77d 100644 --- a/health-services/plan-service/src/main/java/digit/kafka/UpdatePlanConfigConsumer.java +++ b/health-services/plan-service/src/main/java/digit/kafka/UpdatePlanConfigConsumer.java @@ -28,6 +28,7 @@ public UpdatePlanConfigConsumer(PlanConfigurationService planConfigurationServic public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { try { PlanConfigurationRequest planConfigurationRequest = objectMapper.convertValue(consumerRecord, PlanConfigurationRequest.class); + log.info("Update plan config from resource generator."); planConfigurationService.update(planConfigurationRequest); } catch (Exception exception) { log.error("Error in update plan configuration consumer while processing topic {}: {}", topic, consumerRecord, exception); diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java index 7d06ab1b3c8..8b0c54a4010 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/kafka/PlanConsumer.java @@ -11,6 +11,7 @@ import org.springframework.kafka.support.KafkaHeaders; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; import java.util.Map; @@ -34,9 +35,10 @@ public PlanConsumer(ObjectMapper objectMapper, ResourceEstimationService resourc public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { try { PlanConfigurationRequest planConfigurationRequest = objectMapper.convertValue(consumerRecord, PlanConfigurationRequest.class); - if (planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus()) + if (!ObjectUtils.isEmpty(planConfigurationRequest.getPlanConfiguration().getWorkflow()) && (planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus()) || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerCensusRecordsStatus()) - || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanFacilityMappingsStatus())) { + || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanFacilityMappingsStatus()) + || planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigUpdatePlanEstimatesIntoOutputFileStatus()))) { resourceEstimationService.estimateResources(planConfigurationRequest); log.info("Successfully estimated resources for plan."); } diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java index dbcb1329813..63293d94104 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/PlanUtil.java @@ -123,7 +123,7 @@ public void update(PlanConfigurationRequest planConfigurationRequest) { try { producer.push(config.getResourceUpdatePlanConfigConsumerTopic(), planConfigurationRequest); - log.info("Plan Config updated because of Invalid data."); + log.info("Plan Config updated after processing."); } catch (Exception e) { log.error(ServiceConstants.ERROR_WHILE_UPDATING_PLAN_CONFIG); } @@ -156,6 +156,8 @@ public void setFileStoreIdForPopulationTemplate(PlanConfigurationRequest planCon .filter(file -> FILE_TEMPLATE_IDENTIFIER_POPULATION.equals(file.getTemplateIdentifier())) .findFirst() .ifPresent(file -> file.setFilestoreId(fileStoreId)); + + planConfigurationRequest.getPlanConfiguration().setWorkflow(null); } From c6191d3a33bce3d45796a5a3e4bd9bba4f22f3ca Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 15 Nov 2024 15:18:58 +0530 Subject: [PATCH 322/351] added planConfigStatus in search criteria --- .../impl/PlanEmployeeAssignmentImpl.java | 2 +- .../PlanEmployeeAssignmentQueryBuilder.java | 32 +++++++++++-------- .../PlanEmployeeAssignmentSearchCriteria.java | 5 +++ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index 5ec16de3794..007a460ca8b 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -57,7 +57,7 @@ public List search(PlanEmployeeAssignmentSearchCriteria List preparedStmtList = new ArrayList<>(); String searchQuery = queryBuilder.getPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); List planEmployeeAssignments = jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); - + log.info("Plan Employee Assignment search query : " + searchQuery); return planEmployeeAssignments; } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 9333737e568..f43cc0772c8 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -26,17 +26,17 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration con this.config = config; } - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT id, tenant_id, plan_configuration_id, plan_configuration_name, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa "; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (plan_configuration_id) id, tenant_id, plan_configuration_id, plan_configuration_name, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM plan_employee_assignment "; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (pa.plan_configuration_id) pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa JOIN plan_configuration pc ON pa.plan_configuration_id = pc.id"; - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY last_modified_time DESC"; + private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.last_modified_time DESC"; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY plan_configuration_id, last_modified_time DESC"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.plan_configuration_id, pa.last_modified_time DESC"; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; - private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM ( {INTERNAL_QUERY} ) AS pa JOIN plan_configuration pc ON plan_configuration_id = pc.id ORDER BY pc.last_modified_time DESC"; + private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM ( {INTERNAL_QUERY} ) AS pa JOIN plan_configuration pc ON pa.plan_configuration_id = pc.id ORDER BY pc.last_modified_time DESC"; /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. @@ -80,49 +80,55 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit if (searchCriteria.getId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" id = ?"); + builder.append(" pa.id = ?"); preparedStmtList.add(searchCriteria.getId()); } if (searchCriteria.getTenantId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" tenant_id = ?"); + builder.append(" pa.tenant_id = ?"); preparedStmtList.add(searchCriteria.getTenantId()); } if (searchCriteria.getPlanConfigurationId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_configuration_id = ?"); + builder.append(" pa.plan_configuration_id = ?"); preparedStmtList.add(searchCriteria.getPlanConfigurationId()); } if (searchCriteria.getPlanConfigurationName() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" plan_configuration_name ILIKE ?"); + builder.append(" pa.plan_configuration_name ILIKE ?"); preparedStmtList.add(PERCENTAGE_WILDCARD + searchCriteria.getPlanConfigurationName() + PERCENTAGE_WILDCARD); } if (!CollectionUtils.isEmpty(searchCriteria.getEmployeeId())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); + builder.append(" pa.employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getEmployeeId())); } + if (!CollectionUtils.isEmpty(searchCriteria.getPlanConfigurationStatus())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pc.status IN ( ").append(queryUtil.createQuery(searchCriteria.getPlanConfigurationStatus().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getPlanConfigurationStatus())); + } + if (!CollectionUtils.isEmpty(searchCriteria.getRole())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); + builder.append(" pa.role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); queryUtil.addToPreparedStatement(preparedStmtList, new LinkedHashSet<>(searchCriteria.getRole())); } if(searchCriteria.getHierarchyLevel() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" hierarchy_level = ?"); + builder.append(" pa.hierarchy_level = ?"); preparedStmtList.add(searchCriteria.getHierarchyLevel()); } if (searchCriteria.getActive() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" active = ?"); + builder.append(" pa.active = ?"); preparedStmtList.add(searchCriteria.getActive()); } diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java index 79020b68907..22008b64135 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; +import java.util.Set; + import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -39,6 +41,9 @@ public class PlanEmployeeAssignmentSearchCriteria { @JsonProperty("planConfigurationName") private String planConfigurationName = null; + @JsonProperty("planConfigurationStatus") + private Set planConfigurationStatus = null; + @JsonProperty("role") @Valid private List role = null; From 34ce67c07df8d00a74022f7f094eacf0b504f1a2 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Fri, 15 Nov 2024 16:38:17 +0530 Subject: [PATCH 323/351] HCMPRE-1282 changes for updating approved plans into file for campaign integration --- .../egov/processor/service/ExcelParser.java | 31 +++++++++---------- .../web/models/campaignManager/Campaign.java | 18 ++++++----- 2 files changed, 26 insertions(+), 23 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 4e61cd1a0da..16bb7583a59 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 @@ -94,7 +94,7 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore */ @Override public Object parseFileData(PlanConfigurationRequest planConfigurationRequest, String fileStoreId, - Object campaignResponse) { + Object campaignResponse) { PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); byte[] byteArray = filestoreUtil.getFile(planConfig.getTenantId(), fileStoreId); File file = parsingUtil.convertByteArrayToFile(byteArray, ServiceConstants.FILE_EXTENSION); @@ -103,7 +103,8 @@ public Object parseFileData(PlanConfigurationRequest planConfigurationRequest, S throw new CustomException("FileNotFound", "The file with ID " + fileStoreId + " was not found in the tenant " + planConfig.getTenantId()); } - return processExcelFile(planConfigurationRequest, file, fileStoreId, campaignResponse); + processExcelFile(planConfigurationRequest, file, fileStoreId, campaignResponse); + return null; } /** @@ -117,19 +118,17 @@ public Object parseFileData(PlanConfigurationRequest planConfigurationRequest, S * @param fileStoreId The ID of the file in the file store. * @param campaignResponse The response object to be updated with * processed data. - * @return The ID of the uploaded file. */ - private String processExcelFile(PlanConfigurationRequest planConfigurationRequest, File file, String fileStoreId, + private void processExcelFile(PlanConfigurationRequest planConfigurationRequest, File file, String fileStoreId, Object campaignResponse) { - PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); try (Workbook workbook = new XSSFWorkbook(file)) { List campaignBoundaryList = new ArrayList<>(); List campaignResourcesList = new ArrayList<>(); DataFormatter dataFormatter = new DataFormatter(); processSheets(planConfigurationRequest, fileStoreId, campaignResponse, workbook, campaignBoundaryList, dataFormatter); - return uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse, - planConfig, workbook, campaignBoundaryList, campaignResourcesList); + uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse, + workbook, campaignBoundaryList, campaignResourcesList); } catch (FileNotFoundException e) { log.error("File not found: {}", e.getMessage()); throw new CustomException("FileNotFound", "The specified file was not found."); @@ -152,27 +151,27 @@ private String processExcelFile(PlanConfigurationRequest planConfigurationReques * @param workbook The workbook containing data to be uploaded and integrated. * @param campaignBoundaryList List of boundary objects related to the campaign. * @param campaignResourcesList List of campaign resources to be integrated. - * @return The ID of the uploaded file in the file store. */ - private String uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigurationRequest, - Object campaignResponse, PlanConfiguration planConfig, Workbook workbook, + private void uploadFileAndIntegrateCampaign(PlanConfigurationRequest planConfigurationRequest, + Object campaignResponse, Workbook workbook, List campaignBoundaryList, List campaignResourcesList) { File fileToUpload = null; try { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); fileToUpload = convertWorkbookToXls(workbook); - String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); - if (planConfigurationRequest.getPlanConfiguration().getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { + if (planConfig.getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { + String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); planUtil.setFileStoreIdForPopulationTemplate(planConfigurationRequest, uploadedFileStoreId); planUtil.update(planConfigurationRequest); } - if (config.isIntegrateWithAdminConsole()) { - campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); + if (planConfig.getStatus().equals(config.getPlanConfigUpdatePlanEstimatesIntoOutputFileStatus()) && config.isIntegrateWithAdminConsole()) { + String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); campaignIntegrationUtil.updateCampaignResources(uploadedFileStoreId, campaignResourcesList, fileToUpload.getName()); campaignIntegrationUtil.updateCampaignDetails(planConfigurationRequest, campaignResponse, campaignBoundaryList, campaignResourcesList); - } - return uploadedFileStoreId; + campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); + } } finally { try { if (fileToUpload != null && !fileToUpload.delete()) { diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java index 352b29b693b..51c390a2af5 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java @@ -1,12 +1,6 @@ package org.egov.processor.web.models.campaignManager; -import java.util.List; - -import org.egov.common.contract.models.AuditDetails; -import org.springframework.validation.annotation.Validated; - import com.fasterxml.jackson.annotation.JsonProperty; - import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -14,6 +8,10 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import java.util.List; @Validated @Data @@ -37,7 +35,13 @@ public class Campaign { @JsonProperty("action") @Size(min = 1, max = 64) private String action; - + + @JsonProperty("isActive") + private boolean isActive; + + @JsonProperty("parentId") + private String parentId; + @JsonProperty("campaignNumber") @Valid private String campaignNumber; From 856953c9ab9fb586d2f71f2449d03959e403aa2e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 18 Nov 2024 12:20:34 +0530 Subject: [PATCH 324/351] HCMPRE-771 merging multiple alter table migration scripts into create table scripts. --- ...0240305113045__plan_configuration_create_ddl.sql | 7 ++++++- ...__plan_configuration_add_source_category_ddl.sql | 13 ------------- ...10200000__plan_add_boundaryAncestralPath_ddl.sql | 4 ---- .../V20240923113045__plan_facility_create_ddl.sql | 4 +++- .../V20241001113045__plan_facility_alter_ddl.sql | 2 -- ...241111151500__alter_operations_add_order_ddl.sql | 2 -- ...9141800__plan_employee_assignment_create_ddl.sql | 2 ++ .../main/V20242310151500__plan_update_size_ddl.sql | 1 - ..._employee_assignment_add_hierarchy_level_ddl.sql | 1 - .../V20242904173200__add_plan_config_name_ddl.sql | 3 --- ...0143300__plan_facility_add_facility_name_ddl.sql | 1 - 11 files changed, 11 insertions(+), 29 deletions(-) delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_level_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql index 00bf8f03232..fa1cc87dc6a 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240305113045__plan_configuration_create_ddl.sql @@ -36,6 +36,8 @@ CREATE TABLE plan_configuration_assumptions ( id character varying(64), key character varying(256) not null, value numeric(12,2) not null, + source character varying(64), + category character varying(64), plan_configuration_id character varying(64), active boolean not null, created_by character varying(64), @@ -53,9 +55,12 @@ CREATE TABLE plan_configuration_operations ( input character varying(256) not null, operator character varying(64) not null, assumption_value character varying(256) not null, - output character varying(64) not null, + output character varying(256) not null, show_on_estimation_dashboard boolean, + source character varying(64), + category character varying(64), active boolean not null, + execution_order numeric(12,2), plan_configuration_id character varying(64), created_by character varying(64), created_time bigint, diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql deleted file mode 100644 index 96e962faf12..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240910150000__plan_configuration_add_source_category_ddl.sql +++ /dev/null @@ -1,13 +0,0 @@ -ALTER TABLE plan_configuration_assumptions -ADD COLUMN source varchar(64), -ADD COLUMN category varchar(64); - -UPDATE plan_configuration_assumptions SET source = 'MDMS' WHERE source IS NULL; -UPDATE plan_configuration_assumptions SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; - -ALTER TABLE plan_configuration_operations -ADD COLUMN source varchar(64), -ADD COLUMN category varchar(64); - -UPDATE plan_configuration_operations SET source = 'MDMS' WHERE source IS NULL; -UPDATE plan_configuration_operations SET category = 'GENERAL_INFORMATION' WHERE category IS NULL; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql deleted file mode 100644 index 99ddf042da3..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240910200000__plan_add_boundaryAncestralPath_ddl.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE plan -ADD boundary_ancestral_path TEXT, -ADD status character varying(64) NOT NULL DEFAULT 'VALIDATED', -ADD assignee varchar(64); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql index f0d64025b62..9cd8f2dfa6a 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql @@ -5,8 +5,10 @@ CREATE TABLE plan_facility_linkage ( plan_configuration_id varchar(64), facility_id varchar(64), residing_boundary varchar(64), - service_boundaries varchar(2048), + service_boundaries TYPE TEXT, additional_details JSONB, + plan_configuration_name character varying(128), + facility_name character varying(64), active boolean, created_by varchar(64), created_time bigint, diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql deleted file mode 100644 index 51b8acf6eed..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20241001113045__plan_facility_alter_ddl.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE plan_facility_linkage -ALTER COLUMN service_boundaries TYPE TEXT; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql deleted file mode 100644 index 55852f824c2..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20241111151500__alter_operations_add_order_ddl.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE plan_configuration_operations -ADD COLUMN execution_order numeric(12,2); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql index 002b34d35ff..1e28950ca6f 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql @@ -5,7 +5,9 @@ CREATE TABLE plan_employee_assignment ( plan_configuration_id character varying(64), employee_id character varying(64), role character varying(64), + hierarchy_level character varying(64), jurisdiction TEXT, + plan_configuration_name character varying(128), additional_details JSONB, active boolean DEFAULT true, created_by character varying(64), diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql deleted file mode 100644 index 4083a5a34a9..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242310151500__plan_update_size_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE plan_configuration_operations ALTER COLUMN output TYPE character varying(256); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_level_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_level_ddl.sql deleted file mode 100644 index 69bc3d84e7a..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242810151500__plan_employee_assignment_add_hierarchy_level_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE plan_employee_assignment ADD hierarchy_level character varying(64); diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql deleted file mode 100644 index cca2d0430c7..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242904173200__add_plan_config_name_ddl.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE plan_employee_assignment ADD plan_configuration_name character varying(128); - -ALTER TABLE plan_facility_linkage ADD plan_configuration_name character varying(128); \ No newline at end of file diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql deleted file mode 100644 index 7a10bbde149..00000000000 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20242910143300__plan_facility_add_facility_name_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE plan_facility_linkage ADD facility_name character varying(64); \ No newline at end of file From e62c3ee9c8f70f4351ce63d1f1604be6e3b913e1 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 18 Nov 2024 12:24:35 +0530 Subject: [PATCH 325/351] Adding workflow restricted roles in census --- .../main/java/digit/config/Configuration.java | 3 +++ .../java/digit/config/ServiceConstants.java | 3 +++ .../service/validator/CensusValidator.java | 21 ++++++++++++++++++- .../src/main/resources/application.properties | 3 ++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index 4d280ecc3e0..06dfdc7a6c3 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -21,6 +21,9 @@ public class Configuration { @Value("#{${allowed.census.roles}}") private List allowedCensusRoles; + @Value("#{${workflow.restricted.roles}}") + private List workflowRestrictedRoles; + // Persister Topic @Value("${census.create.topic}") private String censusCreateTopic; diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index faeda8989ac..00824098294 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -89,6 +89,9 @@ public class ServiceConstants { public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_CODE = "DIFFERENT_WORKFLOW_FOR_BULK_UPDATE"; public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_MESSAGE = "All entries should be in the same state for bulk transitioning census records."; + public static final String WORKFLOW_NOT_NULL_CODE = "WORKFLOW_NOT_NULL"; + public static final String WORKFLOW_NOT_NULL_MESSAGE = "Census workflow should be null for the provided role"; + public static final String SEARCH_CRITERIA_EMPTY_CODE = "SEARCH_CRITERIA_EMPTY"; public static final String SEARCH_CRITERIA_EMPTY_MESSAGE = "Search criteria cannot be empty"; diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 566a662d87f..2c3880e9591 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -1,6 +1,7 @@ package digit.service.validator; import digit.config.Configuration; +import digit.models.coremodels.user.Role; import digit.repository.CensusRepository; import digit.service.enrichment.CensusEnrichment; import digit.util.BoundaryUtil; @@ -95,11 +96,14 @@ private void validatePartnerForCensus(CensusRequest request) { User userInfo = request.getRequestInfo().getUserInfo(); List jurisdiction = Arrays.asList(request.getCensus().getBoundaryAncestralPath().get(0).split("\\|")); + Set roles = new HashSet<>(configs.getAllowedCensusRoles()); + validateWorkflowAccess(userInfo, census, roles); + PlanEmployeeAssignmentSearchCriteria searchCriteria = PlanEmployeeAssignmentSearchCriteria.builder() .employeeId(Collections.singletonList(userInfo.getUuid())) .planConfigurationId(request.getCensus().getSource()) .tenantId(request.getCensus().getTenantId()) - .role(configs.getAllowedCensusRoles()) + .role(roles.stream().toList()) .jurisdiction(jurisdiction) .build(); @@ -117,6 +121,21 @@ private void validatePartnerForCensus(CensusRequest request) { } } + private void validateWorkflowAccess(User userInfo, Census census, Set roles) { + Boolean hasCensusRoles = userInfo.getRoles().stream() + .anyMatch(role -> configs.getAllowedCensusRoles().contains(role.getCode())); + + Boolean hasWfRestrictedRoles = userInfo.getRoles().stream() + .anyMatch(role -> configs.getWorkflowRestrictedRoles().contains(role.getCode())); + + if(hasWfRestrictedRoles) { + roles.addAll(configs.getWorkflowRestrictedRoles()); + + if(!hasCensusRoles && !ObjectUtils.isEmpty(census.getWorkflow())) + throw new CustomException(WORKFLOW_NOT_NULL_CODE, WORKFLOW_NOT_NULL_MESSAGE); + } + } + /** * Validates partner assignment and jurisdiction for census update request. * diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index a293305e516..207e2b409ac 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -75,4 +75,5 @@ resource.config.consumer.census.update.topic=resource-census-update-topic plan.facility.update.topic=update-plan-facility #Roles for census -allowed.census.roles={'POPULATION_DATA_APPROVER','ROOT_POPULATION_DATA_APPROVER'} \ No newline at end of file +allowed.census.roles={'POPULATION_DATA_APPROVER','ROOT_POPULATION_DATA_APPROVER'} +workflow.restricted.roles={'ROOT_FACILITY_CATCHMENT_MAPPER','FACILITY_CATCHMENT_MAPPER'} \ No newline at end of file From 0336082d57ae37d6ea2a83f1ba35d3c0a9d85c17 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 18 Nov 2024 14:02:06 +0530 Subject: [PATCH 326/351] Adding workflow restricted roles in census --- .../src/main/java/digit/config/ServiceConstants.java | 4 ++-- .../main/java/digit/service/validator/CensusValidator.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 00824098294..04213676214 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -89,8 +89,8 @@ public class ServiceConstants { public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_CODE = "DIFFERENT_WORKFLOW_FOR_BULK_UPDATE"; public static final String DIFFERENT_WORKFLOW_FOR_BULK_UPDATE_MESSAGE = "All entries should be in the same state for bulk transitioning census records."; - public static final String WORKFLOW_NOT_NULL_CODE = "WORKFLOW_NOT_NULL"; - public static final String WORKFLOW_NOT_NULL_MESSAGE = "Census workflow should be null for the provided role"; + public static final String UNAUTHORIZED_WORKFLOW_ACCESS_CODE = "UNAUTHORIZED_WORKFLOW_ACCESS"; + public static final String UNAUTHORIZED_WORKFLOW_ACCESS_MESSAGE = "User with provided roles cannot have an active workflow. Please remove the workflow or update user roles."; public static final String SEARCH_CRITERIA_EMPTY_CODE = "SEARCH_CRITERIA_EMPTY"; public static final String SEARCH_CRITERIA_EMPTY_MESSAGE = "Search criteria cannot be empty"; diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index 2c3880e9591..7a600ab0b0c 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -132,7 +132,7 @@ private void validateWorkflowAccess(User userInfo, Census census, Set ro roles.addAll(configs.getWorkflowRestrictedRoles()); if(!hasCensusRoles && !ObjectUtils.isEmpty(census.getWorkflow())) - throw new CustomException(WORKFLOW_NOT_NULL_CODE, WORKFLOW_NOT_NULL_MESSAGE); + throw new CustomException(UNAUTHORIZED_WORKFLOW_ACCESS_CODE, UNAUTHORIZED_WORKFLOW_ACCESS_MESSAGE); } } From 59e6c9d82ebd042b845ed4434bdd5b9302f98989 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 18 Nov 2024 16:38:29 +0530 Subject: [PATCH 327/351] Fixing limit and adding check for empty row --- .../org/egov/processor/util/EnrichmentUtil.java | 13 ++++++++++--- .../web/models/census/CensusSearchCriteria.java | 10 ++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) 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 461b7c1f999..d0cd40201ff 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 @@ -106,7 +106,10 @@ public void enrichsheetWithApprovedCensusRecords(Sheet sheet, PlanConfigurationR for(Row row: sheet) { parsingUtil.printRow(sheet, row); - if (row.getRowNum() == 0) continue; // Skip header row + // Skip the header row and empty rows + if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { + continue; + } // Get the boundaryCode in the current row Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); @@ -189,6 +192,7 @@ public List getCensusRecordsForEnrichment(PlanConfigurationRequest planC CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder() .tenantId(planConfig.getTenantId()) .areaCodes(boundaryCodes) + .limit(boundaryCodes.size()) .source(planConfig.getId()).build(); CensusSearchRequest censusSearchRequest = CensusSearchRequest.builder() @@ -233,8 +237,10 @@ public void enrichsheetWithApprovedPlanEstimates(Sheet sheet, PlanConfigurationR for(Row row: sheet) { parsingUtil.printRow(sheet, row); - if (row.getRowNum() == 0) continue; // Skip header row - + // Skip the header row and empty rows + if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { + continue; + } // Get the boundaryCode in the current row Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); String boundaryCode = boundaryCodeCell.getStringCellValue(); @@ -277,6 +283,7 @@ public List getPlanRecordsForEnrichment(PlanConfigurationRequest planConfi PlanSearchCriteria planSearchCriteria = PlanSearchCriteria.builder() .tenantId(planConfig.getTenantId()) .locality(boundaryCodes) + .limit(boundaryCodes.size()) .planConfigurationId(planConfig.getId()).build(); PlanSearchRequest planSearchRequest = PlanSearchRequest.builder() diff --git a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java index 78509561418..9ed59d11d63 100644 --- a/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * CensusSearchCriteria @@ -25,6 +26,9 @@ public class CensusSearchCriteria { @JsonProperty("id") private String id = null; + @JsonProperty("ids") + private Set ids = null; + @JsonProperty("tenantId") @Size(min = 1, max = 100) private String tenantId = null; @@ -50,6 +54,12 @@ public class CensusSearchCriteria { @JsonProperty("effectiveTo") private Long effectiveTo = null; + @JsonProperty("limit") + private Integer limit = null; + + @JsonProperty("offset") + private Integer offset = null; + public CensusSearchCriteria addAreaCodesItem(String areaCodesItem) { if (this.areaCodes == null) { this.areaCodes = new ArrayList<>(); From db113ac902c59858477da7ddf317ed31d4dfd8c0 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Mon, 18 Nov 2024 17:27:23 +0530 Subject: [PATCH 328/351] Fixing limit and adding check for empty row --- .../main/V20240923113045__plan_facility_create_ddl.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql index 9cd8f2dfa6a..0f037765d8f 100644 --- a/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql @@ -5,7 +5,7 @@ CREATE TABLE plan_facility_linkage ( plan_configuration_id varchar(64), facility_id varchar(64), residing_boundary varchar(64), - service_boundaries TYPE TEXT, + service_boundaries TEXT, additional_details JSONB, plan_configuration_name character varying(128), facility_name character varying(64), From 54b4a5fa56d3164c13599405498acd9381faf8ff Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 18 Nov 2024 18:03:06 +0530 Subject: [PATCH 329/351] added ranked query for plan employee assignment --- .../PlanEmployeeAssignmentQueryBuilder.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index f43cc0772c8..44e06bee82e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -28,15 +28,16 @@ public PlanEmployeeAssignmentQueryBuilder(QueryUtil queryUtil, Configuration con private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa "; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY = "SELECT DISTINCT ON (pa.plan_configuration_id) pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM plan_employee_assignment pa JOIN plan_configuration pc ON pa.plan_configuration_id = pc.id"; - private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.last_modified_time DESC"; - private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pa.plan_configuration_id, pa.last_modified_time DESC"; + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_RANKED_QUERY = "WITH ranked_assignments AS ( SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name,pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time, pc.last_modified_time AS pc_last_modified_time, ROW_NUMBER() OVER ( PARTITION BY pa.plan_configuration_id ORDER BY pc.last_modified_time DESC ) AS row_num FROM plan_employee_assignment pa JOIN plan_configuration pc ON pa.plan_configuration_id = pc.id "; + + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_MAIN_SEARCH_QUERY = " SELECT id, tenant_id, plan_configuration_id, plan_configuration_name, employee_id, role, hierarchy_level, jurisdiction, additional_details, active, created_by, created_time, last_modified_by, last_modified_time FROM ranked_assignments WHERE row_num = 1 "; + + private static final String UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY pc_last_modified_time DESC "; private static final String PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER = "SELECT COUNT(id) AS total_count FROM ( "; - private static final String LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY = "SELECT pa.id, pa.tenant_id, pa.plan_configuration_id, pa.plan_configuration_name, pa.employee_id, pa.role, pa.hierarchy_level, pa.jurisdiction, pa.additional_details, pa.active, pa.created_by, pa.created_time, pa.last_modified_by, pa.last_modified_time FROM ( {INTERNAL_QUERY} ) AS pa JOIN plan_configuration pc ON pa.plan_configuration_id = pc.id ORDER BY pc.last_modified_time DESC"; /** * Constructs a SQL query string for searching PlanEmployeeAssignment objects based on the provided search criteria. * Also adds an ORDER BY clause and handles pagination. @@ -49,7 +50,6 @@ public String getPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteri String query = buildPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList, Boolean.FALSE); query = queryUtil.addOrderByClause(query, Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE : PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE); - query = Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? LATEST_PLAN_EMPLOYEE_ASSIGNMENT_ORDER_BY_QUERY.replace("{INTERNAL_QUERY}", query) : query; query = getPaginatedQuery(query, searchCriteria, preparedStmtList); return query; } @@ -76,7 +76,7 @@ public String getPlanEmployeeAssignmentCountQuery(PlanEmployeeAssignmentSearchCr */ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCriteria searchCriteria, List preparedStmtList, Boolean isCount) { StringBuilder builder = Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? - new StringBuilder(UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY) : new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); + new StringBuilder(UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_RANKED_QUERY) : new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); if (searchCriteria.getId() != null) { queryUtil.addClauseIfRequired(builder, preparedStmtList); @@ -139,6 +139,11 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(searchCriteria.getJurisdiction())); } + if(searchCriteria.getFilterUniqueByPlanConfig()) { + builder.append(" )").append(UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_MAIN_SEARCH_QUERY); + return builder.toString(); + } + StringBuilder countQuery = new StringBuilder(); if (isCount) { countQuery.append(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_COUNT_WRAPPER).append(builder); From 766044ba22ea434d6084470f10afe80eca5bbc42 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 18 Nov 2024 18:35:59 +0530 Subject: [PATCH 330/351] added ranked query for plan employee assignment --- .../java/digit/repository/impl/PlanEmployeeAssignmentImpl.java | 3 ++- .../querybuilder/PlanEmployeeAssignmentQueryBuilder.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java index 007a460ca8b..bba32818812 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -56,8 +56,9 @@ public void create(PlanEmployeeAssignmentRequest planEmployeeAssignmentRequest) public List search(PlanEmployeeAssignmentSearchCriteria searchCriteria) { List preparedStmtList = new ArrayList<>(); String searchQuery = queryBuilder.getPlanEmployeeAssignmentQuery(searchCriteria, preparedStmtList); - List planEmployeeAssignments = jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); log.info("Plan Employee Assignment search query : " + searchQuery); + + List planEmployeeAssignments = jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); return planEmployeeAssignments; } diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java index 44e06bee82e..b97b3ee9aad 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -141,7 +141,6 @@ private String buildPlanEmployeeAssignmentQuery(PlanEmployeeAssignmentSearchCrit if(searchCriteria.getFilterUniqueByPlanConfig()) { builder.append(" )").append(UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_MAIN_SEARCH_QUERY); - return builder.toString(); } StringBuilder countQuery = new StringBuilder(); From e84d7e321f9afd8605ffee281003e11bb4f50efa Mon Sep 17 00:00:00 2001 From: Priyanka-eGov Date: Tue, 19 Nov 2024 12:48:35 +0530 Subject: [PATCH 331/351] HCMPRE-1300 DB migration script cleanup --- .../db/migration/main/V20240925155908__census_create_ddl.sql | 3 ++- .../main/V20241018122004__census_add_facility_assigned_ddl.sql | 2 -- .../main/V202410223151500__census_update_status_ddl.sql | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql delete mode 100644 health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql index c8063b3de88..cf80c461292 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -9,8 +9,9 @@ CREATE TABLE census ( effective_from bigint NOT NULL, effective_to bigint, source character varying(255) NOT NULL, - status character varying(255) NOT NULL, + status character varying(255), assignee character varying(255), + facility_assigned boolean, boundary_ancestral_path TEXT NOT NULL, additional_details JSONB, created_by character varying(64) NOT NULL, diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql deleted file mode 100644 index 134e46bc9dd..00000000000 --- a/health-services/census-service/src/main/resources/db/migration/main/V20241018122004__census_add_facility_assigned_ddl.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE census ADD facility_assigned boolean; -UPDATE census SET facility_assigned = false WHERE facility_assigned IS NULL; \ No newline at end of file diff --git a/health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql deleted file mode 100644 index 4cb1ea833ea..00000000000 --- a/health-services/census-service/src/main/resources/db/migration/main/V202410223151500__census_update_status_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE census ALTER COLUMN status DROP NOT NULL; \ No newline at end of file From e085bdffc551be14913600abab07c054865921e3 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 19 Nov 2024 16:02:01 +0530 Subject: [PATCH 332/351] adding plan bulk update topic --- .../plan-service/src/main/java/digit/config/Configuration.java | 3 +++ .../main/java/digit/repository/impl/PlanRepositoryImpl.java | 1 + .../plan-service/src/main/resources/application.properties | 1 + 3 files changed, 5 insertions(+) diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index bb7bb371844..8eefe828952 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -75,6 +75,9 @@ public class Configuration { @Value("${plan.update.topic}") private String planUpdateTopic; + @Value("${plan.bulk.update.topic}") + private String planBulkUpdateTopic; + @Value("${plan.facility.create.topic}") private String planFacilityCreateTopic; diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 5919bf71976..22287a59be9 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -128,6 +128,7 @@ public void bulkUpdate(BulkPlanRequest body) { // Perform batch update jdbcTemplate.batchUpdate(bulkPlanUpdateQuery, rows); + producer.push(config.getPlanBulkUpdateTopic(), body); } /** diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 685d0549a07..3967ee5ff4f 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -48,6 +48,7 @@ plan.configuration.update.topic=plan-config-update-topic plan.create.topic=save-plan plan.update.topic=update-plan +plan.bulk.update.topic=bulk-update-plan plan.facility.update.topic=update-plan-facility plan.facility.create.topic=save-plan-facility From 357e4cd23297c76bbe6af52e68a6d22942c316cc Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 19 Nov 2024 18:06:11 +0530 Subject: [PATCH 333/351] Adding facility name in census additional details --- .../src/main/java/digit/config/ServiceConstants.java | 1 + .../main/java/digit/kafka/FacilityCatchmentConsumer.java | 4 ++++ .../main/java/digit/web/models/plan/PlanFacilityDTO.java | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 5ddf7ce02a3..17ba4df3758 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -45,6 +45,7 @@ public class ServiceConstants { public static final String USER = "user"; public static final String PIPE_REGEX = "\\|"; public static final String FACILITY_ID_FIELD = "facilityId"; + public static final String FACILITY_NAME_FIELD = "facilityName"; public static final String PARSING_ERROR_CODE = "PARSING ERROR"; public static final String PARSING_ERROR_MESSAGE = "Failed to parse JSON data from PGobject"; diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index caa67560f67..60c731efb33 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -21,6 +21,7 @@ import java.util.Set; import static digit.config.ServiceConstants.FACILITY_ID_FIELD; +import static digit.config.ServiceConstants.FACILITY_NAME_FIELD; @Component @Slf4j @@ -51,6 +52,7 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE List censusFromSearch = censusResponse.getCensus(); String facilityId = planFacilityRequestDTO.getPlanFacilityDTO().getFacilityId(); + String facilityName = planFacilityRequestDTO.getPlanFacilityDTO().getFacilityName(); Set boundariesWithFacility = new HashSet<>(List.of(planFacilityDTO.getServiceBoundaries().split(","))); Set boundariesWithNoFacility = new HashSet<>(planFacilityDTO.getInitiallySetServiceBoundaries()); @@ -62,6 +64,7 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE // Unassigning facilities to the boundaries which were initially assigned that facility census.setAdditionalDetails(commonUtil.removeFieldFromAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD)); + census.setAdditionalDetails(commonUtil.removeFieldFromAdditionalDetails(census.getAdditionalDetails(), FACILITY_NAME_FIELD)); census.setFacilityAssigned(Boolean.FALSE); census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); @@ -69,6 +72,7 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE // Assigning facilities to the newly added boundaries in the update request. census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_ID_FIELD, facilityId)); + census.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_NAME_FIELD, facilityName)); census.setFacilityAssigned(Boolean.TRUE); census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); } diff --git a/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java index 832299c296b..ce15f091cec 100644 --- a/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java @@ -34,6 +34,9 @@ public class PlanFacilityDTO { @Size(max = 64) private String planConfigurationId = null; + @JsonProperty("planConfigurationName") + private String planConfigurationName = null; + @JsonProperty("facilityId") @NotNull @Size(max = 64) @@ -53,6 +56,9 @@ public class PlanFacilityDTO { @JsonProperty("initiallySetServiceBoundaries") private List initiallySetServiceBoundaries; + @JsonProperty("facilityName") + private String facilityName = null; + @JsonProperty("additionalDetails") private Object additionalDetails = null; From 7a2234b649d78fc2c882af43cbc0575d811cf56e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 20 Nov 2024 16:20:43 +0530 Subject: [PATCH 334/351] Wf auto assignment to multiple people --- .../repository/impl/CensusRepositoryImpl.java | 6 ++- .../querybuilder/CensusQueryBuilder.java | 14 ++++--- .../repository/rowmapper/CensusRowMapper.java | 5 ++- .../service/workflow/WorkflowService.java | 38 ++++++++++--------- .../main/java/digit/web/models/Census.java | 3 +- .../main/java/digit/web/models/CensusDTO.java | 2 - 6 files changed, 37 insertions(+), 31 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 4192662f100..5e6e3a9bd31 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -165,7 +165,7 @@ public void bulkUpdate(BulkCensusRequest request) { // Prepare rows for bulk update List rows = request.getCensus().stream().map(census -> new Object[] { census.getStatus(), - census.getAssignee(), + String.join(",", census.getAssignee()), census.getAuditDetails().getLastModifiedBy(), census.getAuditDetails().getLastModifiedTime(), commonUtil.convertToPgObject(census.getAdditionalDetails()), @@ -187,13 +187,15 @@ public void bulkUpdate(BulkCensusRequest request) { private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { Census census = censusRequest.getCensus(); + String assignee = !CollectionUtils.isEmpty(census.getAssignee()) ? String.join(",", census.getAssignee()) : null; + // Creating a new data transfer object (DTO) for Census CensusDTO censusDTO = CensusDTO.builder() .id(census.getId()) .tenantId(census.getTenantId()) .hierarchyType(census.getHierarchyType()) .boundaryCode(census.getBoundaryCode()) - .assignee(census.getAssignee()) + .assignee(assignee) .status(census.getStatus()) .type(census.getType().toString()) .totalPopulation(census.getTotalPopulation()) diff --git a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java index 71d03bd20ac..e126b7a3c8f 100644 --- a/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -7,6 +7,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -134,12 +135,6 @@ private String buildCensusSearchQuery(CensusSearchCriteria criteria, List(criteria.getAreaCodes())); } + if (!ObjectUtils.isEmpty(criteria.getAssignee())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ").append(queryUtil.createQuery(Collections.singleton(criteria.getAssignee()).size())).append(" ]").append("::text[] "); + builder.append(" && string_to_array(assignee, ',') "); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(Collections.singleton(criteria.getAssignee()))); + } + if (!CollectionUtils.isEmpty(criteria.getJurisdiction())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); builder.append(" ARRAY [ ").append(queryUtil.createQuery(criteria.getJurisdiction().size())).append(" ]").append("::text[] "); diff --git a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java index 365af9f84c0..01612d5d98a 100644 --- a/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -49,6 +49,9 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc // Prepare audit details AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("census_created_by")).createdTime(rs.getLong("census_created_time")).lastModifiedBy(rs.getString("census_last_modified_by")).lastModifiedTime(rs.getLong("census_last_modified_time")).build(); + String commaSeparatedAssignee = rs.getString("census_assignee"); + List assignee = !ObjectUtils.isEmpty(commaSeparatedAssignee) ? Arrays.asList(commaSeparatedAssignee.split(",")) : null; + // Prepare census entry censusEntry.setId(rs.getString("census_id")); censusEntry.setTenantId(rs.getString("census_tenant_id")); @@ -60,7 +63,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExc censusEntry.setEffectiveTo(rs.getLong("census_effective_to")); censusEntry.setSource(rs.getString("census_source")); censusEntry.setStatus(rs.getString("census_status")); - censusEntry.setAssignee(rs.getString("census_assignee")); + censusEntry.setAssignee(assignee); censusEntry.setBoundaryAncestralPath(Collections.singletonList(rs.getString("census_boundary_ancestral_path"))); censusEntry.setFacilityAssigned(rs.getBoolean("census_facility_assigned")); censusEntry.setAdditionalDetails(queryUtil.parseJson((PGobject) rs.getObject("census_additional_details"))); diff --git a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java index cf363ac9b52..f36ca9167c8 100644 --- a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -108,13 +108,13 @@ private ProcessInstanceRequest createWorkflowRequest(BulkCensusRequest request) List processInstanceList = new ArrayList<>(); // Perform auto assignment - String assignee = getAssigneeForAutoAssignment(request.getCensus().get(0), request.getRequestInfo()); + List assignee = getAssigneeForAutoAssignment(request.getCensus().get(0), request.getRequestInfo()); request.getCensus().forEach(census -> { // Set assignee if (!ObjectUtils.isEmpty(assignee)) - census.getWorkflow().setAssignes(Collections.singletonList(assignee)); + census.getWorkflow().setAssignes(assignee); census.setAssignee(assignee); @@ -182,11 +182,11 @@ public ProcessInstanceRequest createWorkflowRequest(CensusRequest censusRequest) .build(); // Perform auto assignment - String assignee = getAssigneeForAutoAssignment(census, censusRequest.getRequestInfo()); + List assignee = getAssigneeForAutoAssignment(census, censusRequest.getRequestInfo()); // Set Assignee if (!ObjectUtils.isEmpty(assignee)) - census.getWorkflow().setAssignes(Collections.singletonList(assignee)); + census.getWorkflow().setAssignes(assignee); census.setAssignee(assignee); @@ -226,7 +226,7 @@ private StringBuilder getWorkflowTransitionUri() { } /** - * Returns an assignee based on the workflow action and jurisdiction hierarchy. + * Returns a list of assignee based on the workflow action and jurisdiction hierarchy. * Retrieves jurisdiction boundaries from the census request and searches for matching employee assignments. * * For INITIATE actions, assigns the employee from the lowest boundary. @@ -236,7 +236,7 @@ private StringBuilder getWorkflowTransitionUri() { * @param census the census object containing workflow and jurisdiction details * @param requestInfo the requestInfo */ - private String getAssigneeForAutoAssignment(Census census, RequestInfo requestInfo) { + private List getAssigneeForAutoAssignment(Census census, RequestInfo requestInfo) { String[] allHierarchiesBoundaryCodes = census.getBoundaryAncestralPath().get(0).split(PIPE_REGEX); String[] hierarchiesBoundaryCodes = Arrays.copyOf(allHierarchiesBoundaryCodes, allHierarchiesBoundaryCodes.length - 1); @@ -253,8 +253,8 @@ private String getAssigneeForAutoAssignment(Census census, RequestInfo requestIn .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) .requestInfo(requestInfo).build()); - // Create a map of jurisdiction to employeeId - Map jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() + // Create a map of jurisdiction to list of employeeIds + Map> jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() .filter(assignment -> !CollectionUtils.isEmpty(assignment.getJurisdiction())) .flatMap(assignment -> { String employeeId = assignment.getEmployeeId(); @@ -262,14 +262,16 @@ private String getAssigneeForAutoAssignment(Census census, RequestInfo requestIn .filter(jurisdiction -> Arrays.asList(hierarchiesBoundaryCodes).contains(jurisdiction)) .map(jurisdiction -> new AbstractMap.SimpleEntry<>(jurisdiction, employeeId)); }) - .collect(Collectors.toMap( + .collect(Collectors.groupingBy( Map.Entry::getKey, // jurisdiction as the key - Map.Entry::getValue, // employeeId as the value - (existing, replacement) -> existing, // Keep the first employeeId for duplicates - LinkedHashMap::new // Ensure insertion order is preserved + LinkedHashMap::new, // Preserve insertion order + Collectors.mapping( + Map.Entry::getValue, // employee IDs as values + Collectors.toList() // Collect employee IDs into a List + ) )); - String assignee = null; //assignee will remain null in case terminate actions are being taken + List assignee = null; //assignee will remain null in case terminate actions are being taken String action = census.getWorkflow().getAction(); if (config.getWfInitiateActions().contains(action)) { @@ -281,23 +283,23 @@ private String getAssigneeForAutoAssignment(Census census, RequestInfo requestIn } else if (config.getWfIntermediateActions().contains(action)) { assignee = assignToHigherBoundaryLevel(hierarchiesBoundaryCodes, census, jurisdictionToEmployeeMap); } else if (config.getWfSendBackActions().contains(action)) { - assignee = census.getAuditDetails().getLastModifiedBy(); + assignee = Collections.singletonList(census.getAuditDetails().getLastModifiedBy()); } return assignee; } /** - * Assigns an employee from a higher-level jurisdiction in the hierarchy. + * Assigns a list of employees from a higher-level jurisdiction in the hierarchy. * Iterates through boundary codes, checking if they match the assignee's jurisdiction. * If a higher-level boundary has an assigned employee, returns that employee's ID. * * @param heirarchysBoundaryCodes boundary codes representing the hierarchy * @param census the census object with jurisdiction details * @param jurisdictionToEmployeeMap map of jurisdiction codes to employee IDs - * @return the employee ID from the higher boundary, or null if + * @return the list of employee IDs from the higher boundary, or null if */ - public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Census census, Map jurisdictionToEmployeeMap) { + public List assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Census census, Map> jurisdictionToEmployeeMap) { for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { String boundaryCode = heirarchysBoundaryCodes[i]; @@ -309,7 +311,7 @@ public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Cens String higherBoundaryCode = heirarchysBoundaryCodes[j]; // Fetch the employeeId from the map for the higher boundary code - String employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); + List employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); // If an employee is found, set them as the assignee and break the loop if (employeeId != null) { diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index b74aa2110b8..b3313c11eaf 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -48,8 +48,7 @@ public class Census { private String boundaryCode = null; @JsonProperty("assignee") - @Size(max = 64) - private String assignee = null; + private List assignee = null; @JsonProperty("status") @Size(max = 64) diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index f34f1770af5..1fa795bf124 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -45,11 +45,9 @@ public class CensusDTO { private String boundaryCode = null; @JsonProperty("assignee") - @NotNull private String assignee = null; @JsonProperty("status") - @NotNull private String status = null; @JsonProperty("type") From cb4959297d5d782c3192158b49c0fe418600bb97 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 20 Nov 2024 17:34:28 +0530 Subject: [PATCH 335/351] Wf auto assignment to multiple people --- .../repository/impl/PlanRepositoryImpl.java | 6 ++-- .../querybuilder/PlanQueryBuilder.java | 7 ++++ .../repository/rowmapper/PlanRowMapper.java | 5 ++- .../service/workflow/WorkflowService.java | 36 ++++++++++--------- .../src/main/java/digit/web/models/Plan.java | 3 +- .../main/java/digit/web/models/PlanDTO.java | 1 - 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 22287a59be9..12d226a3100 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -120,7 +120,7 @@ public void bulkUpdate(BulkPlanRequest body) { // Prepare rows for bulk update List rows = body.getPlans().stream().map(plan -> new Object[] { plan.getStatus(), - plan.getAssignee(), + String.join(",", plan.getAssignee()), plan.getAuditDetails().getLastModifiedBy(), plan.getAuditDetails().getLastModifiedTime(), plan.getId() @@ -176,6 +176,8 @@ private List searchPlanByIds(List planIds) { private PlanRequestDTO convertToPlanReqDTO(PlanRequest planRequest) { Plan plan = planRequest.getPlan(); + String assignee = !CollectionUtils.isEmpty(plan.getAssignee()) ? String.join(",", plan.getAssignee()) : null; + // Creating a new data transfer object (DTO) for Plan PlanDTO planDTO = PlanDTO.builder() .id(plan.getId()) @@ -184,7 +186,7 @@ private PlanRequestDTO convertToPlanReqDTO(PlanRequest planRequest) { .campaignId(plan.getCampaignId()) .planConfigurationId(plan.getPlanConfigurationId()) .status(plan.getStatus()) - .assignee(plan.getAssignee()) + .assignee(assignee) .additionalDetails(plan.getAdditionalDetails()) .activities(plan.getActivities()) .resources(plan.getResources()) diff --git a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 073316b517b..b805f7a7fbd 100644 --- a/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java @@ -7,6 +7,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -152,6 +153,12 @@ private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List< preparedStmtList.add(planSearchCriteria.getAssignee()); } + if (!ObjectUtils.isEmpty(planSearchCriteria.getAssignee())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ").append(queryUtil.createQuery(Collections.singleton(planSearchCriteria.getAssignee()).size())).append(" ]").append("::text[] "); + builder.append(" && string_to_array(assignee, ',') "); + queryUtil.addToPreparedStatement(preparedStmtList, new HashSet<>(Collections.singleton(planSearchCriteria.getAssignee()))); + } if (!CollectionUtils.isEmpty(planSearchCriteria.getJurisdiction())) { queryUtil.addClauseIfRequired(builder, preparedStmtList); diff --git a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index 0e59b6bb8ef..4ba29529384 100644 --- a/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java @@ -48,13 +48,16 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep .lastModifiedTime(rs.getLong("plan_last_modified_time")) .build(); + String commaSeparatedAssignee = rs.getString("plan_assignee"); + List assignee = !ObjectUtils.isEmpty(commaSeparatedAssignee) ? Arrays.asList(commaSeparatedAssignee.split(",")) : null; + // Prepare plan object planEntry.setId(planId); planEntry.setTenantId(rs.getString("plan_tenant_id")); planEntry.setLocality(rs.getString("plan_locality")); planEntry.setCampaignId(rs.getString("plan_campaign_id")); planEntry.setStatus(rs.getString("plan_status")); - planEntry.setAssignee(rs.getString("plan_assignee")); + planEntry.setAssignee(assignee); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); planEntry.setBoundaryAncestralPath(rs.getString("plan_boundary_ancestral_path")); planEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 5b510beb17c..1a45d0ac0d8 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -155,11 +155,11 @@ public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { .documents(plan.getWorkflow().getDocuments()) .build(); - String assignee = getAssigneeForAutoAssignment(plan, planRequest.getRequestInfo()); + List assignee = getAssigneeForAutoAssignment(plan, planRequest.getRequestInfo()); // Set Assignee if(!ObjectUtils.isEmpty(assignee)) - plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + plan.getWorkflow().setAssignes(assignee); plan.setAssignee(assignee); @@ -198,7 +198,7 @@ private StringBuilder getWorkflowTransitionUri() { } /** - * Automatically assigns an assignee based on the workflow action and jurisdiction hierarchy. + * Automatically assigns a list of assignee based on the workflow action and jurisdiction hierarchy. * Retrieves jurisdiction boundaries from the plan request and searches for matching employee assignments. * * For INITIATE actions, assigns the employee from the lowest boundary. @@ -210,7 +210,7 @@ private StringBuilder getWorkflowTransitionUri() { * @param requestInfo auth details for making internal calls * @param plan the plan object containing workflow and jurisdiction details */ - private String getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) { + private List getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) { String[] allheirarchysBoundaryCodes = plan.getBoundaryAncestralPath().split(PIPE_REGEX); String[] heirarchysBoundaryCodes = Arrays.copyOf(allheirarchysBoundaryCodes, allheirarchysBoundaryCodes.length - 1); @@ -227,8 +227,8 @@ private String getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) .requestInfo(requestInfo).build()); - // Create a map of jurisdiction to employeeId - Map jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() + // Create a map of jurisdiction to list of employeeIds + Map> jurisdictionToEmployeeMap = planEmployeeAssignmentResponse.getPlanEmployeeAssignment().stream() .filter(assignment -> assignment.getJurisdiction() != null && !assignment.getJurisdiction().isEmpty()) .flatMap(assignment -> { String employeeId = assignment.getEmployeeId(); @@ -236,14 +236,16 @@ private String getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) .filter(jurisdiction -> Arrays.asList(heirarchysBoundaryCodes).contains(jurisdiction)) .map(jurisdiction -> new AbstractMap.SimpleEntry<>(jurisdiction, employeeId)); }) - .collect(Collectors.toMap( + .collect(Collectors.groupingBy( Map.Entry::getKey, // jurisdiction as the key - Map.Entry::getValue, // employeeId as the value - (existing, replacement) -> existing, // Keep the first employeeId for duplicates - LinkedHashMap::new // Ensure insertion order is preserved + LinkedHashMap::new, // Preserve insertion order + Collectors.mapping( + Map.Entry::getValue, // employee IDs as values + Collectors.toList() // Collect employee IDs into a List + ) )); - String assignee = null; //assignee will remain null in case terminate actions are being taken + List assignee = null; //assignee will remain null in case terminate actions are being taken String action = plan.getWorkflow().getAction(); if (config.getWfInitiateActions().contains(action)) { @@ -255,14 +257,14 @@ private String getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) } else if (config.getWfIntermediateActions().contains(action)) { assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, plan, jurisdictionToEmployeeMap); } else if (config.getWfSendBackActions().contains(action)) { - assignee = plan.getAuditDetails().getLastModifiedBy(); + assignee = Collections.singletonList(plan.getAuditDetails().getLastModifiedBy()); } return assignee; } /** - * Assigns an employee from a higher-level jurisdiction in the hierarchy. + * Assigns a list of employees from a higher-level jurisdiction in the hierarchy. * Iterates through boundary codes, checking if they match the assignee's jurisdiction. * If a higher-level boundary has an assigned employee, returns that employee's ID. * @@ -271,7 +273,7 @@ private String getAssigneeForAutoAssignment(Plan plan, RequestInfo requestInfo) * @param jurisdictionToEmployeeMap map of jurisdiction codes to employee IDs * @return the employee ID from the higher boundary, or null if */ - public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Plan plan, Map jurisdictionToEmployeeMap) { + public List assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Plan plan, Map> jurisdictionToEmployeeMap) { for (int i = heirarchysBoundaryCodes.length - 1; i >= 0; i--) { String boundaryCode = heirarchysBoundaryCodes[i]; @@ -283,7 +285,7 @@ public String assignToHigherBoundaryLevel(String[] heirarchysBoundaryCodes, Plan String higherBoundaryCode = heirarchysBoundaryCodes[j]; // Fetch the employeeId from the map for the higher boundary code - String employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); + List employeeId = jurisdictionToEmployeeMap.get(higherBoundaryCode); // If an employee is found, set them as the assignee and break the loop if (employeeId != null) { @@ -318,14 +320,14 @@ private ProcessInstanceRequest createWorkflowRequest(BulkPlanRequest bulkPlanReq List processInstanceList = new ArrayList<>(); // Perform auto assignment - String assignee = getAssigneeForAutoAssignment(bulkPlanRequest.getPlans().get(0), + List assignee = getAssigneeForAutoAssignment(bulkPlanRequest.getPlans().get(0), bulkPlanRequest.getRequestInfo()); bulkPlanRequest.getPlans().forEach(plan -> { // Set assignee if(!ObjectUtils.isEmpty(assignee)) - plan.getWorkflow().setAssignes(Collections.singletonList(assignee)); + plan.getWorkflow().setAssignes(assignee); plan.setAssignee(assignee); diff --git a/health-services/plan-service/src/main/java/digit/web/models/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index b1c989bf1dc..b8bd16b8891 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Plan.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Plan.java @@ -50,8 +50,7 @@ public class Plan { private String status = null; @JsonProperty("assignee") - @Size(max = 64) - private String assignee = null; + private List assignee = null; @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java index 2cf0aaea4d3..88314e105af 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java @@ -50,7 +50,6 @@ public class PlanDTO { private String status = null; @JsonProperty("assignee") - @Size(max = 64) private String assignee = null; @JsonProperty("additionalDetails") From da3d1f804bd95d038de9fc847875fcb6f427607a Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 22 Nov 2024 11:12:48 +0530 Subject: [PATCH 336/351] Adding boundaryTypeHierarchy Pojos and search endpoint --- .../main/java/digit/config/Configuration.java | 3 ++ .../java/digit/config/ServiceConstants.java | 2 + .../main/java/digit/util/BoundaryUtil.java | 29 ++++++++++++ .../main/java/digit/web/models/Census.java | 4 ++ .../main/java/digit/web/models/CensusDTO.java | 4 ++ .../boundary/BoundaryTypeHierarchy.java | 30 +++++++++++++ .../BoundaryTypeHierarchyDefinition.java | 45 +++++++++++++++++++ .../BoundaryTypeHierarchyResponse.java | 36 +++++++++++++++ .../BoundaryTypeHierarchySearchCriteria.java | 38 ++++++++++++++++ .../BoundaryTypeHierarchySearchRequest.java | 33 ++++++++++++++ .../src/main/resources/application.properties | 1 + 11 files changed, 225 insertions(+) create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java diff --git a/health-services/census-service/src/main/java/digit/config/Configuration.java b/health-services/census-service/src/main/java/digit/config/Configuration.java index f133e3431d6..8459885357e 100644 --- a/health-services/census-service/src/main/java/digit/config/Configuration.java +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -44,6 +44,9 @@ public class Configuration { @Value("${egov.boundary.relationship.search.endpoint}") private String boundaryRelationshipSearchEndpoint; + @Value("${egov.boundary.hierarchy.search.endpoint}") + private String boundaryHierarchySearchEndpoint; + // Plan Service @Value("${egov.plan.service.host}") private String planServiceHost; diff --git a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java index 17ba4df3758..9a43fe27d5f 100644 --- a/health-services/census-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -17,6 +17,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_BOUNDARY_DETAILS = "Exception occurred while fetching boundary relationship from boundary service: "; + public static final String ERROR_WHILE_FETCHING_BOUNDARY_HIERARCHY_DETAILS = "Exception occurred while fetching boundary hierarchy details from boundary service: "; + public static final String ERROR_WHILE_FETCHING_EMPLOYEE_ASSIGNMENT_DETAILS = "Exception occurred while fetching plan employee assignment details from plan service: "; public static final String ERROR_WHILE_FETCHING_BUSINESS_SERVICE_DETAILS = "Exception occurred while fetching business service details: "; diff --git a/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java b/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java index 42f7b86fee7..8e977cf3ccb 100644 --- a/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java +++ b/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java @@ -3,6 +3,9 @@ import digit.config.Configuration; import digit.web.models.RequestInfoWrapper; import digit.web.models.boundary.BoundarySearchResponse; +import digit.web.models.boundary.BoundaryTypeHierarchyResponse; +import digit.web.models.boundary.BoundaryTypeHierarchySearchCriteria; +import digit.web.models.boundary.BoundaryTypeHierarchySearchRequest; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.springframework.stereotype.Component; @@ -12,6 +15,7 @@ import java.util.Map; import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_BOUNDARY_DETAILS; +import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_BOUNDARY_HIERARCHY_DETAILS; @Slf4j @Component @@ -79,4 +83,29 @@ private StringBuilder getBoundaryRelationshipSearchUri(Map uriPa return uri; } + + public BoundaryTypeHierarchyResponse fetchBoundaryHierarchy(RequestInfo requestInfo, String tenantId, String hierarchyType) { + + // Create Boundary hierarchy search uri + String uri = getBoundaryHierarchySearchUri(); + + // Create request body + BoundaryTypeHierarchySearchCriteria searchCriteria = BoundaryTypeHierarchySearchCriteria.builder().tenantId(tenantId).hierarchyType(hierarchyType).build(); + BoundaryTypeHierarchySearchRequest searchRequest = BoundaryTypeHierarchySearchRequest.builder().requestInfo(requestInfo).boundaryTypeHierarchySearchCriteria(searchCriteria).build(); + BoundaryTypeHierarchyResponse searchResponse = new BoundaryTypeHierarchyResponse(); + + try { + searchResponse = restTemplate.postForObject(uri, searchRequest, BoundaryTypeHierarchyResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_BOUNDARY_HIERARCHY_DETAILS, e); + } + + return searchResponse; + } + + private String getBoundaryHierarchySearchUri() { + StringBuilder uri = new StringBuilder(); + uri.append(configs.getBoundaryServiceHost()).append(configs.getBoundaryHierarchySearchEndpoint()); + return uri.toString(); + } } diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index b74aa2110b8..362e85ca7c1 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonValue; import java.util.List; +import java.util.Map; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -98,6 +99,9 @@ public class Census { @JsonIgnore private List assigneeJurisdiction; + @JsonIgnore + private Map jurisdictionMapping; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index f34f1770af5..82ea9bb7b71 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; +import java.util.Map; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -94,6 +95,9 @@ public class CensusDTO { @JsonIgnore private List assigneeJurisdiction; + @JsonIgnore + private Map jurisdictionMapping; + @JsonProperty("additionalDetails") private Object additionalDetails = null; diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java new file mode 100644 index 00000000000..45ab5a19141 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java @@ -0,0 +1,30 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +/** + * BoundaryTypeHierarchy + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchy { + + @JsonProperty("boundaryType") + private String boundaryType = null; + + @JsonProperty("parentBoundaryType") + private String parentBoundaryType = null; + + @JsonProperty("active") + private Boolean active = null; + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java new file mode 100644 index 00000000000..6faf8ac0b49 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java @@ -0,0 +1,45 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * BoundaryTypeHierarchyDefinition + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchyDefinition { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + private String tenantId = null; + + @JsonProperty("hierarchyType") + private String hierarchyType = null; + + @JsonProperty("boundaryHierarchy") + @Valid + private List boundaryHierarchy = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; + + @JsonProperty("boundaryHierarchyJsonNode") + private JsonNode boundaryHierarchyJsonNode = null; + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java new file mode 100644 index 00000000000..6372620c43c --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java @@ -0,0 +1,36 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * BoundaryTypeHierarchyResponse + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchyResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("totalCount") + private Integer totalCount = null; + + @JsonProperty("BoundaryHierarchy") + @Valid + private List boundaryHierarchy = null; + +} diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java new file mode 100644 index 00000000000..7ad5be0790f --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java @@ -0,0 +1,38 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * BoundaryTypeHierarchySearchCriteria + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchySearchCriteria { + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + @NotNull + private String tenantId = null; + + @JsonProperty("hierarchyType") + @Size(min = 1, max = 100) + private String hierarchyType = null; + + @JsonProperty("offset") + private Integer offset; + + @JsonProperty("limit") + private Integer limit; + +} + diff --git a/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java new file mode 100644 index 00000000000..b85ffffd857 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java @@ -0,0 +1,33 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +import jakarta.validation.Valid; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * BoundaryTypeHierarchySearchRequest + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchySearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("BoundaryTypeHierarchySearchCriteria") + @Valid + private BoundaryTypeHierarchySearchCriteria boundaryTypeHierarchySearchCriteria = null; + +} diff --git a/health-services/census-service/src/main/resources/application.properties b/health-services/census-service/src/main/resources/application.properties index 5d0a12a03f7..21fbd551f92 100644 --- a/health-services/census-service/src/main/resources/application.properties +++ b/health-services/census-service/src/main/resources/application.properties @@ -52,6 +52,7 @@ kafka.topics.receipt.create=dss-collection #Boundary service urls egov.boundary.service.host=https://unified-dev.digit.org egov.boundary.relationship.search.endpoint=/boundary-service/boundary-relationships/_search +egov.boundary.hierarchy.search.endpoint=/boundary-service/boundary-hierarchy-definition/_search #Plan service urls egov.plan.service.host=https://unified-dev.digit.org From 20f416bb55c583863aa6bcfe43d7922ac1f09b5e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 22 Nov 2024 13:20:35 +0530 Subject: [PATCH 337/351] enriching jurisdiction mapping in census --- .../repository/impl/CensusRepositoryImpl.java | 1 + .../service/enrichment/CensusEnrichment.java | 59 ++++++++++++++++++- .../service/validator/CensusValidator.java | 14 ++++- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 4192662f100..7163de8447d 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -198,6 +198,7 @@ private CensusRequestDTO convertToReqDTO(CensusRequest censusRequest) { .type(census.getType().toString()) .totalPopulation(census.getTotalPopulation()) .populationByDemographics(census.getPopulationByDemographics()) + .jurisdictionMapping(census.getJurisdictionMapping()) .additionalFields(census.getAdditionalFields()) .effectiveFrom(census.getEffectiveFrom()) .effectiveTo(census.getEffectiveTo()) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index 6e8916d7440..7e4ad6c70a8 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -4,6 +4,8 @@ import digit.web.models.AdditionalField; import digit.web.models.Census; import digit.web.models.CensusRequest; +import digit.web.models.boundary.BoundaryTypeHierarchy; +import digit.web.models.boundary.BoundaryTypeHierarchyDefinition; import digit.web.models.boundary.EnrichedBoundary; import digit.web.models.boundary.HierarchyRelation; import org.egov.common.utils.UUIDEnrichmentUtil; @@ -12,8 +14,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import java.util.Collections; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @@ -114,4 +115,58 @@ public void enrichUpdate(CensusRequest request) { denormalizeAdditionalFields(request.getCensus()); } + public void enrichJurisdictionMapping(Census census, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDefinition) { + + Map boundaryHierarchyMapping = new HashMap<>(); + String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDefinition, boundaryHierarchyMapping); + + Map jurisdictionMapping = new HashMap<>(); + List boundaryCode = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); + String boundaryHierarchy = highestBoundaryHierarchy; + + for(int i = 0; i boundaryHierarchyMapping) { + String highestBoundaryHierarchy = null; + + for(BoundaryTypeHierarchy boundaryTypeHierarchy : boundaryTypeHierarchyDefinition.getBoundaryHierarchy()) { + if(ObjectUtils.isEmpty(boundaryTypeHierarchy.getParentBoundaryType())) + highestBoundaryHierarchy = boundaryTypeHierarchy.getBoundaryType(); + else boundaryHierarchyMapping.put(boundaryTypeHierarchy.getParentBoundaryType(), boundaryTypeHierarchy.getBoundaryType()); + } + + return highestBoundaryHierarchy; + } + + public void enrichJurisdictionMapping(List censusList, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDefinition) { + Map boundaryHierarchyMapping = new HashMap<>(); + String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDefinition, boundaryHierarchyMapping); + + for(Census census : censusList) { + Map jurisdictionMapping = new HashMap<>(); + List boundaryCode = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); + String boundaryHierarchy = highestBoundaryHierarchy; + + for(int i = 0; i ro * @param request the update request for Census. */ public void validateUpdate(CensusRequest request) { + BoundaryTypeHierarchyResponse boundaryTypeHierarchyResponse = boundaryUtil.fetchBoundaryHierarchy(request.getRequestInfo(), request.getCensus().getTenantId(), request.getCensus().getHierarchyType()); // Validate if Census record to be updated exists validateCensusExistence(request); @@ -165,6 +170,9 @@ public void validateUpdate(CensusRequest request) { // Validate keys in additional field validateAdditionalFields(request); + + // Enrich jurisdiction mapping in census + enrichment.enrichJurisdictionMapping(request.getCensus(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); } /** @@ -195,6 +203,7 @@ private void validateCensusExistence(CensusRequest request) { * @param request the census bulk update request. */ public void validateBulkUpdate(BulkCensusRequest request) { + BoundaryTypeHierarchyResponse boundaryTypeHierarchyResponse = boundaryUtil.fetchBoundaryHierarchy(request.getRequestInfo(), request.getCensus().get(0).getTenantId(), request.getCensus().get(0).getHierarchyType()); // Validate attributes across each census in the bulk update request validateCensusAttributes(request); @@ -204,6 +213,9 @@ public void validateBulkUpdate(BulkCensusRequest request) { // Validate partner assignment and jurisdiction against plan service validatePartnerForCensus(request); + + // Enrich jurisdiction mapping in census + enrichment.enrichJurisdictionMapping(request.getCensus(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); } /** From 05bf58151185ea87643de2e67223dda4faa040bb Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 22 Nov 2024 14:45:38 +0530 Subject: [PATCH 338/351] changing jurisdictionMapping from jsonIgnore to jsonProperty --- .../census-service/src/main/java/digit/web/models/Census.java | 2 +- .../src/main/java/digit/web/models/CensusDTO.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/web/models/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java index 362e85ca7c1..b29170aee2b 100644 --- a/health-services/census-service/src/main/java/digit/web/models/Census.java +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -99,7 +99,7 @@ public class Census { @JsonIgnore private List assigneeJurisdiction; - @JsonIgnore + @JsonProperty("jurisdictionMapping") private Map jurisdictionMapping; @JsonProperty("additionalDetails") diff --git a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java index 82ea9bb7b71..01fe1a7ee4e 100644 --- a/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -95,7 +95,7 @@ public class CensusDTO { @JsonIgnore private List assigneeJurisdiction; - @JsonIgnore + @JsonProperty("jurisdictionMapping") private Map jurisdictionMapping; @JsonProperty("additionalDetails") From 357ad76695f18393f940882c95dcaf503b9a20ec Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Fri, 22 Nov 2024 17:26:44 +0530 Subject: [PATCH 339/351] optimizing the enrichment functions and adding comments --- .../service/enrichment/CensusEnrichment.java | 115 ++++++++++++------ .../service/validator/CensusValidator.java | 6 +- 2 files changed, 80 insertions(+), 41 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index 7e4ad6c70a8..0e598fe6680 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -67,23 +67,30 @@ private void denormalizeAdditionalFields(Census census) { } /** - * Enriches the boundary ancestral path for the provided boundary code in the census request. + * Enriches the boundary ancestral path and jurisdiction mapping for the provided boundary code in the census request. * * @param census The census record whose boundary ancestral path has to be enriched. * @param tenantBoundary boundary relationship from the boundary service for the given boundary code. */ public void enrichBoundaryAncestralPath(Census census, HierarchyRelation tenantBoundary) { EnrichedBoundary boundary = tenantBoundary.getBoundary().get(0); + Map jurisdictionMapping = new LinkedHashMap<>(); + StringBuilder boundaryAncestralPath = new StringBuilder(boundary.getCode()); + jurisdictionMapping.put(boundary.getBoundaryType(), boundary.getCode()); // Iterate through the child boundary until there are no more while (!CollectionUtils.isEmpty(boundary.getChildren())) { boundary = boundary.getChildren().get(0); boundaryAncestralPath.append("|").append(boundary.getCode()); + jurisdictionMapping.put(boundary.getBoundaryType(), boundary.getCode()); } // Setting the boundary ancestral path for the provided boundary census.setBoundaryAncestralPath(Collections.singletonList(boundaryAncestralPath.toString())); + + // Setting jurisdiction mapping for the provided boundary + census.setJurisdictionMapping(jurisdictionMapping); } /** @@ -115,58 +122,94 @@ public void enrichUpdate(CensusRequest request) { denormalizeAdditionalFields(request.getCensus()); } - public void enrichJurisdictionMapping(Census census, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDefinition) { + /** + * Helper method to enrich boundary hierarchy mapping. + * Creates a mapping of parentBoundaryType to childBoundaryType from the boundaryTypeHierarchy search response. + * + * @param boundaryTypeHierarchyDef Search response from boundary hierarchy search. + * @param boundaryHierarchyMapping boundary hierarchy map to be enriched. + * @return returns the highest boundary hierarchy for the given hierarchy type. + */ + private String getBoundaryHierarchyMapping(BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDef, Map boundaryHierarchyMapping) { + String highestBoundaryHierarchy = null; - Map boundaryHierarchyMapping = new HashMap<>(); - String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDefinition, boundaryHierarchyMapping); + for (BoundaryTypeHierarchy boundaryTypeHierarchy : boundaryTypeHierarchyDef.getBoundaryHierarchy()) { + if (ObjectUtils.isEmpty(boundaryTypeHierarchy.getParentBoundaryType())) + highestBoundaryHierarchy = boundaryTypeHierarchy.getBoundaryType(); + else + boundaryHierarchyMapping.put(boundaryTypeHierarchy.getParentBoundaryType(), boundaryTypeHierarchy.getBoundaryType()); + } - Map jurisdictionMapping = new HashMap<>(); - List boundaryCode = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); + return highestBoundaryHierarchy; + } + + /** + * Enriches jurisdiction mapping in census for the given boundary ancestral path. + * + * @param census census data with boundary ancestral path. + * @param boundaryTypeHierarchyDef boundary hierarchy for the given hierarchy type. + */ + public void enrichJurisdictionMapping(Census census, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDef) { + Map boundaryHierarchyMapping = new HashMap<>(); + + // Enriches the boundaryHierarchyMapping and returns the highest boundary hierarchy for the given hierarchy type. + String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDef, boundaryHierarchyMapping); + + Map jurisdictionMapping = new LinkedHashMap<>(); String boundaryHierarchy = highestBoundaryHierarchy; - for(int i = 0; i boundaryCode = getBoundaryCodeFromAncestralPath(census.getBoundaryAncestralPath()); + + // Creates the mapping of boundary hierarchy with the corresponding boundary code. + for (String boundary : boundaryCode) { + jurisdictionMapping.put(boundaryHierarchy, boundary); + boundaryHierarchy = boundaryHierarchyMapping.get(boundaryHierarchy); } census.setJurisdictionMapping(jurisdictionMapping); } - private String getBoundaryHierarchyMapping(BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDefinition, Map boundaryHierarchyMapping) { - String highestBoundaryHierarchy = null; - - for(BoundaryTypeHierarchy boundaryTypeHierarchy : boundaryTypeHierarchyDefinition.getBoundaryHierarchy()) { - if(ObjectUtils.isEmpty(boundaryTypeHierarchy.getParentBoundaryType())) - highestBoundaryHierarchy = boundaryTypeHierarchy.getBoundaryType(); - else boundaryHierarchyMapping.put(boundaryTypeHierarchy.getParentBoundaryType(), boundaryTypeHierarchy.getBoundaryType()); - } + /** + * Enriches jurisdiction mapping for the list of census records for the given boundary ancestral path. + * + * @param censusList list of census data with boundary ancestral paths. + * @param boundaryTypeHierarchyDef boundary hierarchy for the given hierarchy type. + */ + public void enrichJurisdictionMapping(List censusList, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDef) { + Map boundaryHierarchyMapping = new HashMap<>(); - return highestBoundaryHierarchy; - } + // Enriches the boundaryHierarchyMapping and returns the highest boundary hierarchy for the given hierarchy type. + String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDef, boundaryHierarchyMapping); - public void enrichJurisdictionMapping(List censusList, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDefinition) { - Map boundaryHierarchyMapping = new HashMap<>(); - String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDefinition, boundaryHierarchyMapping); + for (Census census : censusList) { - for(Census census : censusList) { - Map jurisdictionMapping = new HashMap<>(); - List boundaryCode = Arrays.asList(census.getBoundaryAncestralPath().get(0).split("\\|")); + Map jurisdictionMapping = new LinkedHashMap<>(); String boundaryHierarchy = highestBoundaryHierarchy; - for(int i = 0; i boundaryCode = getBoundaryCodeFromAncestralPath(census.getBoundaryAncestralPath()); + + // Creates the mapping of boundary hierarchy with the corresponding boundary code. + for (String boundary : boundaryCode) { + jurisdictionMapping.put(boundaryHierarchy, boundary); + boundaryHierarchy = boundaryHierarchyMapping.get(boundaryHierarchy); } census.setJurisdictionMapping(jurisdictionMapping); } } + + /** + * Converts the boundaryAncestral path from a pipe separated string to an array of boundary codes. + * + * @param boundaryAncestralPath pipe separated boundaryAncestralPath. + * @return a list of boundary codes. + */ + private List getBoundaryCodeFromAncestralPath(List boundaryAncestralPath) { + if (CollectionUtils.isEmpty(boundaryAncestralPath)) { + return Collections.emptyList(); + } + return Arrays.asList(boundaryAncestralPath.get(0).split("\\|")); + } } diff --git a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java index c885a84d805..80b7ad8a097 100644 --- a/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -52,7 +52,6 @@ public CensusValidator(BoundaryUtil boundaryUtil, PlanEmployeeAssignmnetUtil emp public void validateCreate(CensusRequest request) { Census census = request.getCensus(); BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), census.getBoundaryCode(), census.getTenantId(), census.getHierarchyType(), Boolean.TRUE, Boolean.FALSE); - BoundaryTypeHierarchyResponse boundaryTypeHierarchyResponse = boundaryUtil.fetchBoundaryHierarchy(request.getRequestInfo(), census.getTenantId(), census.getHierarchyType()); // Validate boundary code against boundary service validateBoundaryCode(boundarySearchResponse, census); @@ -62,9 +61,6 @@ public void validateCreate(CensusRequest request) { // Validate keys in additional field validateAdditionalFields(request); - - // Enrich jurisdiction mapping in census - enrichment.enrichJurisdictionMapping(request.getCensus(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); } private void validateAdditionalFields(CensusRequest request) { @@ -91,7 +87,7 @@ private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, throw new CustomException(NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_CODE, NO_BOUNDARY_DATA_FOUND_FOR_GIVEN_BOUNDARY_CODE_MESSAGE); } - // Enrich the boundary ancestral path for the provided boundary code + // Enrich the boundary ancestral path and jurisdiction mapping for the provided boundary code enrichment.enrichBoundaryAncestralPath(census, tenantBoundary); } From f0a4db84fe7db483857163e07ea895c54044ceaf Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 25 Nov 2024 11:50:00 +0530 Subject: [PATCH 340/351] handling null pointer exception --- .../main/java/digit/repository/impl/CensusRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java index 5e6e3a9bd31..27607e4c1ec 100644 --- a/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -165,7 +165,7 @@ public void bulkUpdate(BulkCensusRequest request) { // Prepare rows for bulk update List rows = request.getCensus().stream().map(census -> new Object[] { census.getStatus(), - String.join(",", census.getAssignee()), + !CollectionUtils.isEmpty(census.getAssignee()) ? String.join(",", census.getAssignee()) : census.getAssignee(), census.getAuditDetails().getLastModifiedBy(), census.getAuditDetails().getLastModifiedTime(), commonUtil.convertToPgObject(census.getAdditionalDetails()), From 46c74056a6db48582fae9f002331aca08e4b5002 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 25 Nov 2024 14:47:51 +0530 Subject: [PATCH 341/351] Wf auto assignment to multiple people --- .../src/main/java/digit/repository/impl/PlanRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 12d226a3100..6018c3b402e 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -120,7 +120,7 @@ public void bulkUpdate(BulkPlanRequest body) { // Prepare rows for bulk update List rows = body.getPlans().stream().map(plan -> new Object[] { plan.getStatus(), - String.join(",", plan.getAssignee()), + !CollectionUtils.isEmpty(plan.getAssignee()) ? String.join(",", plan.getAssignee()) : plan.getAssignee(), plan.getAuditDetails().getLastModifiedBy(), plan.getAuditDetails().getLastModifiedTime(), plan.getId() From efb99efe5ad8681b636412d45be2ee2624f79fa2 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 25 Nov 2024 15:33:05 +0530 Subject: [PATCH 342/351] Set last modified time on update call --- .../main/java/digit/service/enrichment/CensusEnrichment.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java index 6e8916d7440..b924342651e 100644 --- a/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -111,6 +111,9 @@ public void enrichUpdate(CensusRequest request) { } }); + // Set last modified time on update call + census.getAuditDetails().setLastModifiedTime(System.currentTimeMillis()); + denormalizeAdditionalFields(request.getCensus()); } From d6650e459db44edf489074e422ed6f167b2f1c64 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 25 Nov 2024 16:16:42 +0530 Subject: [PATCH 343/351] enriching serving population with sum of confirmed target population of serving boundaries --- .../java/digit/config/ServiceConstants.java | 6 +++ .../enrichment/PlanFacilityEnricher.java | 48 ++++++++++++++++--- .../web/models/census/AdditionalField.java | 48 +++++++++++++++++++ .../java/digit/web/models/census/Census.java | 31 ++++++------ 4 files changed, 112 insertions(+), 21 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/AdditionalField.java diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 5a8925f2c26..6c1503cc380 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -355,4 +355,10 @@ public class ServiceConstants { public static final String SERVING_POPULATION_CODE = "servingPopulation"; + public static final String CONFIRMED_TARGET_POPULATION_AGE_3TO11 = "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11"; + + public static final String CONFIRMED_TARGET_POPULATION_AGE_12TO59 = "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59"; + + public static final String CONFIRMED_TARGET_POPULATION = "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION"; + } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java index 24b76936420..235e5cd3604 100644 --- a/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -6,10 +6,7 @@ import digit.web.models.PlanFacilityRequest; import digit.web.models.PlanFacilitySearchCriteria; import digit.web.models.PlanFacilitySearchRequest; -import digit.web.models.census.Census; -import digit.web.models.census.CensusResponse; -import digit.web.models.census.CensusSearchCriteria; -import digit.web.models.census.CensusSearchRequest; +import digit.web.models.census.*; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.AuditDetailsEnrichmentUtil; @@ -74,8 +71,15 @@ public void enrichPlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { enrichServingPopulation(planFacilityRequest); } + /** + * Enriches serving population based on the serving boundaries provided. + * + * @param planFacilityRequest plan facility request whose serving population is to be enriched. + */ private void enrichServingPopulation(PlanFacilityRequest planFacilityRequest) { PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + + // Prepare list of boundaries whose census records are to be fetched Set boundariesToBeSearched = new HashSet<>(planFacility.getServiceBoundaries()); boundariesToBeSearched.addAll(planFacility.getInitiallySetServiceBoundaries()); @@ -92,9 +96,8 @@ private void enrichServingPopulation(PlanFacilityRequest planFacilityRequest) { .censusSearchCriteria(censusSearchCriteria) .build()); - // Create a population map - Map boundaryToPopMap = censusResponse.getCensus().stream() - .collect(Collectors.toMap(Census::getBoundaryCode, Census::getTotalPopulation)); + // Creates a population map based on the confirmed target population of the boundary + Map boundaryToPopMap = getPopulationMap(censusResponse.getCensus()); // Get existing servingPopulation or default to 0 BigDecimal servingPopulation = (BigDecimal) commonUtil.extractFieldsFromJsonObject(planFacility.getAdditionalDetails(), SERVING_POPULATION_CODE); @@ -103,6 +106,37 @@ private void enrichServingPopulation(PlanFacilityRequest planFacilityRequest) { } } + /** + * Creates a mapping of boundary with it's confirmed target population. + * + * @param censusList Census records for the given list of serving boundaries. + * @return returns a map of boundary with its confirmed target population. + */ + private Map getPopulationMap(List censusList) { + Map boundaryToPopMap = new HashMap<>(); + + for (Census census : censusList) { + Map additionalFieldsMap = census.getAdditionalFields().stream() + .collect(Collectors.toMap(AdditionalField::getKey, AdditionalField::getValue)); + + Long confirmedTargetPopulation = 0L; + + // Get confirmed target population based on campaign type. + if (additionalFieldsMap.containsKey(CONFIRMED_TARGET_POPULATION_AGE_3TO11)) { + confirmedTargetPopulation = additionalFieldsMap.get(CONFIRMED_TARGET_POPULATION_AGE_3TO11) + .add(additionalFieldsMap.get(CONFIRMED_TARGET_POPULATION_AGE_12TO59)) + .longValue(); + } else if(additionalFieldsMap.containsKey(CONFIRMED_TARGET_POPULATION)){ + confirmedTargetPopulation = additionalFieldsMap.get(CONFIRMED_TARGET_POPULATION).longValue(); + } + + // Map the boundary code with it's confirmed target population. + boundaryToPopMap.put(census.getBoundaryCode(), confirmedTargetPopulation); + } + + return boundaryToPopMap; + } + private void updateServingPopulation(Set boundariesToBeSearched, PlanFacility planFacility, Map boundaryToPopMap, BigDecimal servingPopulation) { Set currentServiceBoundaries = new HashSet<>(planFacility.getServiceBoundaries()); Set initialServiceBoundaries = new HashSet<>(planFacility.getInitiallySetServiceBoundaries()); diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/AdditionalField.java b/health-services/plan-service/src/main/java/digit/web/models/census/AdditionalField.java new file mode 100644 index 00000000000..65ae4222831 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/AdditionalField.java @@ -0,0 +1,48 @@ +package digit.web.models.census; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.math.BigDecimal; + +/** + * AdditionalField + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class AdditionalField { + + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("key") + @Valid + @NotNull + private String key = null; + + @JsonProperty("value") + @Valid + @NotNull + private BigDecimal value = null; + + @JsonProperty("showOnUi") + private Boolean showOnUi = Boolean.TRUE; + + @JsonProperty("editable") + private Boolean editable = Boolean.TRUE; + + @JsonProperty("order") + private Integer order = null; +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/census/Census.java b/health-services/plan-service/src/main/java/digit/web/models/census/Census.java index 11a196dd81b..e8f384d1e98 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/census/Census.java +++ b/health-services/plan-service/src/main/java/digit/web/models/census/Census.java @@ -15,6 +15,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.models.Workflow; import org.springframework.validation.annotation.Validated; import jakarta.validation.Valid; @@ -47,12 +48,12 @@ public class Census { private String boundaryCode = null; @JsonProperty("assignee") - @NotNull + @Size(max = 64) private String assignee = null; @JsonProperty("status") - @NotNull - private StatusEnum status = null; + @Size(max = 64) + private String status = null; @JsonProperty("type") @NotNull @@ -66,6 +67,10 @@ public class Census { @Valid private List populationByDemographics = null; + @JsonProperty("additionalFields") + @Valid + private List additionalFields = null; + @JsonProperty("effectiveFrom") private Long effectiveFrom = null; @@ -80,27 +85,25 @@ public class Census { private List boundaryAncestralPath = null; @JsonIgnore - private boolean partnerAssignmentValidationEnabled; + @Builder.Default + private Boolean partnerAssignmentValidationEnabled = Boolean.TRUE; @JsonProperty("facilityAssigned") private Boolean facilityAssigned = null; + @JsonProperty("workflow") + @Valid + private Workflow workflow; + + @JsonIgnore + private List assigneeJurisdiction; + @JsonProperty("additionalDetails") private Object additionalDetails = null; @JsonProperty("auditDetails") private @Valid AuditDetails auditDetails; - /** - * The status used in the Census - */ - public enum StatusEnum { - VALIDATED, - APPROVED, - PENDING_FOR_APPROVAL, - PENDING_FOR_VALIDATION - } - /** * Gets or Sets type */ From f5e828f520b9d4d5ed87357213001a389d0c13e7 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 25 Nov 2024 17:41:11 +0530 Subject: [PATCH 344/351] modifying Wf for send back actions --- .../digit/service/workflow/WorkflowService.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java index f36ca9167c8..e842c5dae29 100644 --- a/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -110,7 +110,10 @@ private ProcessInstanceRequest createWorkflowRequest(BulkCensusRequest request) // Perform auto assignment List assignee = getAssigneeForAutoAssignment(request.getCensus().get(0), request.getRequestInfo()); - request.getCensus().forEach(census -> { + for (Census census : request.getCensus()) { + if (config.getWfSendBackActions().contains(census.getWorkflow().getAction())) { + assignee = Collections.singletonList(census.getAuditDetails().getLastModifiedBy()); + } // Set assignee if (!ObjectUtils.isEmpty(assignee)) @@ -134,7 +137,7 @@ private ProcessInstanceRequest createWorkflowRequest(BulkCensusRequest request) // Add entry for bulk transition processInstanceList.add(processInstance); - }); + } return ProcessInstanceRequest.builder() .requestInfo(request.getRequestInfo()) @@ -184,6 +187,10 @@ public ProcessInstanceRequest createWorkflowRequest(CensusRequest censusRequest) // Perform auto assignment List assignee = getAssigneeForAutoAssignment(census, censusRequest.getRequestInfo()); + if (config.getWfSendBackActions().contains(census.getWorkflow().getAction())) { + assignee = Collections.singletonList(census.getAuditDetails().getLastModifiedBy()); + } + // Set Assignee if (!ObjectUtils.isEmpty(assignee)) census.getWorkflow().setAssignes(assignee); @@ -248,7 +255,7 @@ private List getAssigneeForAutoAssignment(Census census, RequestInfo req .role(config.getAllowedCensusRoles()) .build(); - //search for plan-employee assignments for the ancestral heirarchy codes. + //search for plan-employee assignments for the ancestral hierarchy codes. PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeAssignmnetUtil.fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest.builder() .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) .requestInfo(requestInfo).build()); @@ -282,8 +289,6 @@ private List getAssigneeForAutoAssignment(Census census, RequestInfo req } } else if (config.getWfIntermediateActions().contains(action)) { assignee = assignToHigherBoundaryLevel(hierarchiesBoundaryCodes, census, jurisdictionToEmployeeMap); - } else if (config.getWfSendBackActions().contains(action)) { - assignee = Collections.singletonList(census.getAuditDetails().getLastModifiedBy()); } return assignee; From f5e580fb9758b53071b708ddef630e8ee3f16e6c Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Mon, 25 Nov 2024 17:45:10 +0530 Subject: [PATCH 345/351] enriching jurisdiction mapping in plan --- .../main/java/digit/config/Configuration.java | 3 + .../java/digit/config/ServiceConstants.java | 2 + .../repository/impl/PlanRepositoryImpl.java | 1 + .../main/java/digit/service/PlanEnricher.java | 102 +++++++++++++++++- .../java/digit/service/PlanValidator.java | 16 ++- .../main/java/digit/util/BoundaryUtil.java | 29 +++++ .../src/main/java/digit/web/models/Plan.java | 4 + .../main/java/digit/web/models/PlanDTO.java | 4 + .../boundary/BoundaryTypeHierarchy.java | 30 ++++++ .../BoundaryTypeHierarchyDefinition.java | 45 ++++++++ .../BoundaryTypeHierarchyResponse.java | 36 +++++++ .../BoundaryTypeHierarchySearchCriteria.java | 39 +++++++ .../BoundaryTypeHierarchySearchRequest.java | 31 ++++++ .../src/main/resources/application.properties | 1 + 14 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java diff --git a/health-services/plan-service/src/main/java/digit/config/Configuration.java b/health-services/plan-service/src/main/java/digit/config/Configuration.java index 8eefe828952..110be35646a 100644 --- a/health-services/plan-service/src/main/java/digit/config/Configuration.java +++ b/health-services/plan-service/src/main/java/digit/config/Configuration.java @@ -56,6 +56,9 @@ public class Configuration { @Value("${egov.boundary.relationship.search.endpoint}") private String boundaryRelationshipSearchEndpoint; + @Value("${egov.boundary.hierarchy.search.endpoint}") + private String boundaryHierarchySearchEndpoint; + //Persister Topic @Value("${plan.configuration.create.topic}") private String planConfigCreateTopic; diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 5a8925f2c26..371afab9317 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -20,6 +20,8 @@ public class ServiceConstants { public static final String ERROR_WHILE_FETCHING_BOUNDARY_DETAILS = "Exception occurred while fetching boundary relationship from boundary service: "; + public static final String ERROR_WHILE_FETCHING_BOUNDARY_HIERARCHY_DETAILS = "Exception occurred while fetching boundary hierarchy details from boundary service: "; + public static final String ERROR_WHILE_FETCHING_DATA_FROM_HRMS = "Exception occurred while fetching employee from hrms: "; public static final String RES_MSG_ID = "uief87324"; diff --git a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index 22287a59be9..eea842b1896 100644 --- a/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java @@ -186,6 +186,7 @@ private PlanRequestDTO convertToPlanReqDTO(PlanRequest planRequest) { .status(plan.getStatus()) .assignee(plan.getAssignee()) .additionalDetails(plan.getAdditionalDetails()) + .jurisdictionMapping(plan.getJurisdictionMapping()) .activities(plan.getActivities()) .resources(plan.getResources()) .targets(plan.getTargets()) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java index 61d1b156d71..7d42339124a 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java @@ -2,6 +2,8 @@ import digit.web.models.Plan; import digit.web.models.PlanRequest; +import digit.web.models.boundary.BoundaryTypeHierarchy; +import digit.web.models.boundary.BoundaryTypeHierarchyDefinition; import digit.web.models.boundary.EnrichedBoundary; import digit.web.models.boundary.HierarchyRelation; import org.egov.common.utils.AuditDetailsEnrichmentUtil; @@ -108,22 +110,120 @@ public void enrichPlanUpdate(PlanRequest body) { } /** - * Enriches the boundary ancestral path for the provided boundary code in the census request. + * Enriches the boundary ancestral path and jurisdiction mapping for the provided boundary code in the plan request. * * @param plan The plan record whose boundary ancestral path has to be enriched. * @param tenantBoundary boundary relationship from the boundary service for the given boundary code. */ public void enrichBoundaryAncestralPath(Plan plan, HierarchyRelation tenantBoundary) { EnrichedBoundary boundary = tenantBoundary.getBoundary().get(0); + Map jurisdictionMapping = new LinkedHashMap<>(); + StringBuilder boundaryAncestralPath = new StringBuilder(boundary.getCode()); + jurisdictionMapping.put(boundary.getBoundaryType(), boundary.getCode()); // Iterate through the child boundary until there are no more while (!CollectionUtils.isEmpty(boundary.getChildren())) { boundary = boundary.getChildren().get(0); boundaryAncestralPath.append("|").append(boundary.getCode()); + jurisdictionMapping.put(boundary.getBoundaryType(), boundary.getCode()); } // Setting the boundary ancestral path for the provided boundary plan.setBoundaryAncestralPath(boundaryAncestralPath.toString()); + + // Setting jurisdiction mapping for the provided boundary + plan.setJurisdictionMapping(jurisdictionMapping); + } + + /** + * Helper method to enrich boundary hierarchy mapping. + * Creates a mapping of parentBoundaryType to childBoundaryType from the boundaryTypeHierarchy search response. + * + * @param boundaryTypeHierarchyDef Search response from boundary hierarchy search. + * @param boundaryHierarchyMapping boundary hierarchy map to be enriched. + * @return returns the highest boundary hierarchy for the given hierarchy type. + */ + private String getBoundaryHierarchyMapping(BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDef, Map boundaryHierarchyMapping) { + String highestBoundaryHierarchy = null; + + for (BoundaryTypeHierarchy boundaryTypeHierarchy : boundaryTypeHierarchyDef.getBoundaryHierarchy()) { + if (ObjectUtils.isEmpty(boundaryTypeHierarchy.getParentBoundaryType())) + highestBoundaryHierarchy = boundaryTypeHierarchy.getBoundaryType(); + else + boundaryHierarchyMapping.put(boundaryTypeHierarchy.getParentBoundaryType(), boundaryTypeHierarchy.getBoundaryType()); + } + + return highestBoundaryHierarchy; + } + + /** + * Enriches jurisdiction mapping in plan for the given boundary ancestral path. + * + * @param plan plan with boundary ancestral path. + * @param boundaryTypeHierarchyDef boundary hierarchy for the given hierarchy type. + */ + public void enrichJurisdictionMapping(Plan plan, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDef) { + Map boundaryHierarchyMapping = new HashMap<>(); + + // Enriches the boundaryHierarchyMapping and returns the highest boundary hierarchy for the given hierarchy type. + String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDef, boundaryHierarchyMapping); + + Map jurisdictionMapping = new LinkedHashMap<>(); + String boundaryHierarchy = highestBoundaryHierarchy; + + // Get the list of boundary codes from pipe separated boundaryAncestralPath. + List boundaryCode = getBoundaryCodeFromAncestralPath(plan.getBoundaryAncestralPath()); + + // Creates the mapping of boundary hierarchy with the corresponding boundary code. + for (String boundary : boundaryCode) { + jurisdictionMapping.put(boundaryHierarchy, boundary); + boundaryHierarchy = boundaryHierarchyMapping.get(boundaryHierarchy); + } + + plan.setJurisdictionMapping(jurisdictionMapping); + } + + /** + * Enriches jurisdiction mapping for the list of plans for the given boundary ancestral path. + * + * @param planList list of plans with boundary ancestral paths. + * @param boundaryTypeHierarchyDef boundary hierarchy for the given hierarchy type. + */ + public void enrichJurisdictionMapping(List planList, BoundaryTypeHierarchyDefinition boundaryTypeHierarchyDef) { + Map boundaryHierarchyMapping = new HashMap<>(); + + // Enriches the boundaryHierarchyMapping and returns the highest boundary hierarchy for the given hierarchy type. + String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDef, boundaryHierarchyMapping); + + for (Plan plan : planList) { + + Map jurisdictionMapping = new LinkedHashMap<>(); + String boundaryHierarchy = highestBoundaryHierarchy; + + // Get the list of boundary codes from pipe separated boundaryAncestralPath. + List boundaryCode = getBoundaryCodeFromAncestralPath(plan.getBoundaryAncestralPath()); + + // Creates the mapping of boundary hierarchy with the corresponding boundary code. + for (String boundary : boundaryCode) { + jurisdictionMapping.put(boundaryHierarchy, boundary); + boundaryHierarchy = boundaryHierarchyMapping.get(boundaryHierarchy); + } + + plan.setJurisdictionMapping(jurisdictionMapping); + } + } + + /** + * Converts the boundaryAncestral path from a pipe separated string to an array of boundary codes. + * + * @param boundaryAncestralPath pipe separated boundaryAncestralPath. + * @return a list of boundary codes. + */ + private List getBoundaryCodeFromAncestralPath(String boundaryAncestralPath) { + if (ObjectUtils.isEmpty(boundaryAncestralPath)) { + return Collections.emptyList(); + } + return Arrays.asList(boundaryAncestralPath.split("\\|")); } } diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index 0d1e47f35dd..d58b40496ff 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -10,6 +10,7 @@ import digit.util.MdmsUtil; import digit.web.models.*; import digit.web.models.boundary.BoundarySearchResponse; +import digit.web.models.boundary.BoundaryTypeHierarchyResponse; import digit.web.models.boundary.HierarchyRelation; import digit.web.models.projectFactory.CampaignResponse; import org.egov.common.utils.MultiStateInstanceUtil; @@ -294,6 +295,8 @@ public void validatePlanUpdate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); + BoundaryTypeHierarchyResponse boundaryTypeHierarchyResponse = boundaryUtil.fetchBoundaryHierarchy(request.getRequestInfo(), request.getPlan().getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType()); //TODO: remove after setting the flag in consumer request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); @@ -337,6 +340,9 @@ public void validatePlanUpdate(PlanRequest request) { // Validate plan-employee assignment and jurisdiction validatePlanEmployeeAssignmentAndJurisdiction(request); + + // Enrich jurisdiction mapping in plan + planEnricher.enrichJurisdictionMapping(request.getPlan(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); } /** @@ -526,7 +532,7 @@ public void validateJurisdiction(Plan plan, List jurisdictions) { } /** - * Validates the boundary code provided in census request against boundary service. + * Validates the boundary code provided in plan request against boundary service. * * @param boundarySearchResponse response from the boundary service. * @param plan Plan record whose loclality is to be validated. @@ -540,7 +546,7 @@ private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, //TODO: change to if(!plan.isRequestFromResourceEstimationConsumer()) after triggering from consumer - // Enrich the boundary ancestral path for the provided boundary code + // Enrich the boundary ancestral path and jurisdiction mapping for the provided boundary code if(plan.isRequestFromResourceEstimationConsumer()) planEnricher.enrichBoundaryAncestralPath(plan, tenantBoundary); } @@ -550,6 +556,9 @@ private void validateBoundaryCode(BoundarySearchResponse boundarySearchResponse, * @param bulkPlanRequest */ public void validateBulkPlanUpdate(BulkPlanRequest bulkPlanRequest) { + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(bulkPlanRequest.getRequestInfo(), bulkPlanRequest.getPlans().get(0).getCampaignId(), bulkPlanRequest.getPlans().get(0).getTenantId()); + BoundaryTypeHierarchyResponse boundaryTypeHierarchyResponse = boundaryUtil.fetchBoundaryHierarchy(bulkPlanRequest.getRequestInfo(), bulkPlanRequest.getPlans().get(0).getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType()); + // Validate attributes across each plan in the bulk request validatePlanAttributes(bulkPlanRequest); @@ -558,6 +567,9 @@ public void validateBulkPlanUpdate(BulkPlanRequest bulkPlanRequest) { // Validate plan employee assignment and jurisdiction validatePlanEmployeeAssignmentAndJurisdiction(bulkPlanRequest); + + // Enrich jurisdiction mapping in plan + planEnricher.enrichJurisdictionMapping(bulkPlanRequest.getPlans(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); } /** diff --git a/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java b/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java index e5513928780..ec43e0f0447 100644 --- a/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java @@ -3,6 +3,9 @@ import digit.config.Configuration; import digit.web.models.RequestInfoWrapper; import digit.web.models.boundary.BoundarySearchResponse; +import digit.web.models.boundary.BoundaryTypeHierarchyResponse; +import digit.web.models.boundary.BoundaryTypeHierarchySearchCriteria; +import digit.web.models.boundary.BoundaryTypeHierarchySearchRequest; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.springframework.stereotype.Component; @@ -11,6 +14,7 @@ import java.util.HashMap; import java.util.Map; import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_BOUNDARY_DETAILS; +import static digit.config.ServiceConstants.ERROR_WHILE_FETCHING_BOUNDARY_HIERARCHY_DETAILS; @Slf4j @@ -79,4 +83,29 @@ private StringBuilder getBoundaryRelationshipSearchUri(Map uriPa return uri; } + + public BoundaryTypeHierarchyResponse fetchBoundaryHierarchy(RequestInfo requestInfo, String tenantId, String hierarchyType) { + + // Create Boundary hierarchy search uri + String uri = getBoundaryHierarchySearchUri(); + + // Create request body + BoundaryTypeHierarchySearchCriteria searchCriteria = BoundaryTypeHierarchySearchCriteria.builder().tenantId(tenantId).hierarchyType(hierarchyType).build(); + BoundaryTypeHierarchySearchRequest searchRequest = BoundaryTypeHierarchySearchRequest.builder().requestInfo(requestInfo).boundaryTypeHierarchySearchCriteria(searchCriteria).build(); + BoundaryTypeHierarchyResponse searchResponse = new BoundaryTypeHierarchyResponse(); + + try { + searchResponse = restTemplate.postForObject(uri, searchRequest, BoundaryTypeHierarchyResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_BOUNDARY_HIERARCHY_DETAILS, e); + } + + return searchResponse; + } + + private String getBoundaryHierarchySearchUri() { + StringBuilder uri = new StringBuilder(); + uri.append(configs.getBoundaryServiceHost()).append(configs.getBoundaryHierarchySearchEndpoint()); + return uri.toString(); + } } diff --git a/health-services/plan-service/src/main/java/digit/web/models/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index b1c989bf1dc..556e7c7962d 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Plan.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Plan.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; +import java.util.Map; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -71,6 +72,9 @@ public class Plan { @JsonProperty("auditDetails") private AuditDetails auditDetails = null; + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + @JsonIgnore private String boundaryAncestralPath = null; diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java index 2cf0aaea4d3..b91868256b2 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java @@ -14,6 +14,7 @@ import org.springframework.validation.annotation.Validated; import java.util.List; +import java.util.Map; /** * Plan @@ -56,6 +57,9 @@ public class PlanDTO { @JsonProperty("additionalDetails") private Object additionalDetails = null; + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + @JsonProperty("activities") @Valid private List activities; diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java new file mode 100644 index 00000000000..45ab5a19141 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java @@ -0,0 +1,30 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +/** + * BoundaryTypeHierarchy + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchy { + + @JsonProperty("boundaryType") + private String boundaryType = null; + + @JsonProperty("parentBoundaryType") + private String parentBoundaryType = null; + + @JsonProperty("active") + private Boolean active = null; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java new file mode 100644 index 00000000000..6faf8ac0b49 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java @@ -0,0 +1,45 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * BoundaryTypeHierarchyDefinition + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchyDefinition { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("tenantId") + private String tenantId = null; + + @JsonProperty("hierarchyType") + private String hierarchyType = null; + + @JsonProperty("boundaryHierarchy") + @Valid + private List boundaryHierarchy = null; + + @JsonProperty("auditDetails") + private AuditDetails auditDetails = null; + + @JsonProperty("boundaryHierarchyJsonNode") + private JsonNode boundaryHierarchyJsonNode = null; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java new file mode 100644 index 00000000000..6372620c43c --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java @@ -0,0 +1,36 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * BoundaryTypeHierarchyResponse + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchyResponse { + + @JsonProperty("ResponseInfo") + @Valid + private ResponseInfo responseInfo = null; + + @JsonProperty("totalCount") + private Integer totalCount = null; + + @JsonProperty("BoundaryHierarchy") + @Valid + private List boundaryHierarchy = null; + +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java new file mode 100644 index 00000000000..ba335f7f037 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java @@ -0,0 +1,39 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +/** + * BoundaryTypeHierarchySearchCriteria + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchySearchCriteria { + + @JsonProperty("tenantId") + @Size(min = 1, max = 100) + @NotNull + private String tenantId = null; + + @JsonProperty("hierarchyType") + @Size(min = 1, max = 100) + private String hierarchyType = null; + + @JsonProperty("offset") + private Integer offset; + + @JsonProperty("limit") + private Integer limit; + +} + diff --git a/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java new file mode 100644 index 00000000000..46cb6eb463a --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java @@ -0,0 +1,31 @@ +package digit.web.models.boundary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * BoundaryTypeHierarchySearchRequest + */ +@Validated +@jakarta.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2023-10-16T17:02:11.361704+05:30[Asia/Kolkata]") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BoundaryTypeHierarchySearchRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("BoundaryTypeHierarchySearchCriteria") + @Valid + private BoundaryTypeHierarchySearchCriteria boundaryTypeHierarchySearchCriteria = null; + +} diff --git a/health-services/plan-service/src/main/resources/application.properties b/health-services/plan-service/src/main/resources/application.properties index 3967ee5ff4f..905c60af9e6 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -80,6 +80,7 @@ egov.user.search.endpoint=/user/_search #Boundary service urls egov.boundary.service.host=https://unified-dev.digit.org egov.boundary.relationship.search.endpoint=/boundary-service/boundary-relationships/_search +egov.boundary.hierarchy.search.endpoint=/boundary-service/boundary-hierarchy-definition/_search # Workflow egov.workflow.host=https://unified-dev.digit.org From 44302a145469ec8a05ca0a42d2239f68c9456404 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 26 Nov 2024 10:55:03 +0530 Subject: [PATCH 346/351] setting assignees separetly for send back actions --- .../main/java/digit/service/PlanEnricher.java | 2 ++ .../digit/service/workflow/WorkflowService.java | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java index 61d1b156d71..0639e88691f 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java @@ -105,6 +105,8 @@ public void enrichPlanUpdate(PlanRequest body) { } }); + // Enriching last modified time for update + body.getPlan().getAuditDetails().setLastModifiedTime(System.currentTimeMillis()); } /** diff --git a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java index 1a45d0ac0d8..24932950df8 100644 --- a/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -157,6 +157,11 @@ public ProcessInstanceRequest createWorkflowRequest(PlanRequest planRequest) { List assignee = getAssigneeForAutoAssignment(plan, planRequest.getRequestInfo()); + // Set assignees for send back actions + if (config.getWfSendBackActions().contains(plan.getWorkflow().getAction())) { + assignee = Collections.singletonList(plan.getAuditDetails().getLastModifiedBy()); + } + // Set Assignee if(!ObjectUtils.isEmpty(assignee)) plan.getWorkflow().setAssignes(assignee); @@ -256,8 +261,6 @@ private List getAssigneeForAutoAssignment(Plan plan, RequestInfo request } } else if (config.getWfIntermediateActions().contains(action)) { assignee = assignToHigherBoundaryLevel(heirarchysBoundaryCodes, plan, jurisdictionToEmployeeMap); - } else if (config.getWfSendBackActions().contains(action)) { - assignee = Collections.singletonList(plan.getAuditDetails().getLastModifiedBy()); } return assignee; @@ -323,7 +326,12 @@ private ProcessInstanceRequest createWorkflowRequest(BulkPlanRequest bulkPlanReq List assignee = getAssigneeForAutoAssignment(bulkPlanRequest.getPlans().get(0), bulkPlanRequest.getRequestInfo()); - bulkPlanRequest.getPlans().forEach(plan -> { + for(Plan plan: bulkPlanRequest.getPlans()) { + + // Setting assignee for send back actions + if (config.getWfSendBackActions().contains(plan.getWorkflow().getAction())) { + assignee = Collections.singletonList(plan.getAuditDetails().getLastModifiedBy()); + } // Set assignee if(!ObjectUtils.isEmpty(assignee)) @@ -347,7 +355,7 @@ private ProcessInstanceRequest createWorkflowRequest(BulkPlanRequest bulkPlanReq // Add entry for bulk transition processInstanceList.add(processInstance); - }); + } return ProcessInstanceRequest.builder() .requestInfo(bulkPlanRequest.getRequestInfo()) From 24e446f8a6be2e3e37f770385334adc0cce536b8 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 26 Nov 2024 12:06:56 +0530 Subject: [PATCH 347/351] Changing assignee column to Text in db --- .../main/V20242110115700__alter_plan_assignee_create_ddl.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242110115700__alter_plan_assignee_create_ddl.sql diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242110115700__alter_plan_assignee_create_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242110115700__alter_plan_assignee_create_ddl.sql new file mode 100644 index 00000000000..584399af592 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242110115700__alter_plan_assignee_create_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE plan ALTER COLUMN assignee TYPE TEXT; From 5acd2558de6f3314b7ee06cbe777ab759353c96b Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 26 Nov 2024 12:08:45 +0530 Subject: [PATCH 348/351] Changing assignee column to Text in db --- .../main/V20241126120700__alter_census_assignee_create_ddl.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql new file mode 100644 index 00000000000..7d271361aae --- /dev/null +++ b/health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE census ALTER COLUMN assignee TYPE TEXT; \ No newline at end of file From 742f4b0c4e7ab6ed2ef42db7af0d1ffe2788585e Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Tue, 26 Nov 2024 19:40:13 +0530 Subject: [PATCH 349/351] enriching jurisdiction mapping --- .../digit/kafka/FacilityCatchmentConsumer.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index 60c731efb33..4440a170263 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -3,10 +3,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import digit.repository.CensusRepository; import digit.service.CensusService; +import digit.service.enrichment.CensusEnrichment; +import digit.util.BoundaryUtil; import digit.util.CommonUtil; import digit.web.models.BulkCensusRequest; import digit.web.models.Census; import digit.web.models.CensusResponse; +import digit.web.models.boundary.BoundaryTypeHierarchyResponse; import digit.web.models.plan.PlanFacilityDTO; import digit.web.models.plan.PlanFacilityRequestDTO; import lombok.extern.slf4j.Slf4j; @@ -35,11 +38,17 @@ public class FacilityCatchmentConsumer { private CommonUtil commonUtil; - public FacilityCatchmentConsumer(ObjectMapper objectMapper, CensusService service, CommonUtil commonUtil, CensusRepository repository) { + private BoundaryUtil boundaryUtil; + + private CensusEnrichment enrichment; + + public FacilityCatchmentConsumer(ObjectMapper objectMapper, CensusService service, CommonUtil commonUtil, CensusRepository repository, BoundaryUtil boundaryUtil, CensusEnrichment enrichment) { this.objectMapper = objectMapper; this.service = service; this.commonUtil = commonUtil; this.repository = repository; + this.boundaryUtil = boundaryUtil; + this.enrichment = enrichment; } @KafkaListener(topics = {"${plan.facility.update.topic}"}) @@ -51,6 +60,7 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE CensusResponse censusResponse = service.search(commonUtil.getCensusSearchRequest(planFacilityDTO.getTenantId(), planFacilityDTO.getPlanConfigurationId(), planFacilityDTO.getServiceBoundaries(), planFacilityDTO.getInitiallySetServiceBoundaries(), planFacilityRequestDTO.getRequestInfo())); List censusFromSearch = censusResponse.getCensus(); + BoundaryTypeHierarchyResponse boundaryTypeHierarchyResponse = boundaryUtil.fetchBoundaryHierarchy(planFacilityRequestDTO.getRequestInfo(), censusFromSearch.get(0).getTenantId(), censusFromSearch.get(0).getHierarchyType()); String facilityId = planFacilityRequestDTO.getPlanFacilityDTO().getFacilityId(); String facilityName = planFacilityRequestDTO.getPlanFacilityDTO().getFacilityName(); @@ -78,6 +88,8 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE } }); + // Enrich jurisdiction mapping in census + enrichment.enrichJurisdictionMapping(censusFromSearch, boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); repository.bulkUpdate(BulkCensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(censusFromSearch).build()); } catch (Exception exception) { From 3d00d074b6abfec2880aa1042f08d823e6dbdddd Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Wed, 27 Nov 2024 10:44:14 +0530 Subject: [PATCH 350/351] enriching jurisdiction mapping --- .../src/main/java/digit/kafka/FacilityCatchmentConsumer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java index 4440a170263..d5be4b7458c 100644 --- a/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -88,7 +88,7 @@ public void listen(Map consumerRecord, @Header(KafkaHeaders.RECE } }); - // Enrich jurisdiction mapping in census + // Enrich jurisdiction mapping in census for indexer enrichment.enrichJurisdictionMapping(censusFromSearch, boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); repository.bulkUpdate(BulkCensusRequest.builder().requestInfo(planFacilityRequestDTO.getRequestInfo()).census(censusFromSearch).build()); From 7e96d3443745b8ed27313c56012e82d447b7b391 Mon Sep 17 00:00:00 2001 From: Tanishi Goyal Date: Thu, 28 Nov 2024 12:36:29 +0530 Subject: [PATCH 351/351] DB migration script cleanup --- ...152700__census_additional_field_create_ddl.sql | 12 ------------ ...26120700__alter_census_assignee_create_ddl.sql | 1 - ...sql => V20241128123000__census_create_ddl.sql} | 15 ++++++++++++++- 3 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql delete mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql rename health-services/census-service/src/main/resources/db/migration/main/{V20240925155908__census_create_ddl.sql => V20241128123000__census_create_ddl.sql} (74%) diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql deleted file mode 100644 index 9887f73656f..00000000000 --- a/health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql +++ /dev/null @@ -1,12 +0,0 @@ --- Table: additional_field -CREATE TABLE additional_field ( - id character varying(64) NOT NULL, - census_id character varying(64) NOT NULL, - "key" character varying(64) NOT NULL, - "value" numeric(12,2) NOT NULL, - show_on_ui boolean DEFAULT true NOT NULL, - editable boolean DEFAULT true NOT NULL, - "order" bigint NOT NULL, - CONSTRAINT uk_additional_field_id PRIMARY KEY (id), - FOREIGN KEY (census_id) REFERENCES census(id) -); diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql deleted file mode 100644 index 7d271361aae..00000000000 --- a/health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE census ALTER COLUMN assignee TYPE TEXT; \ No newline at end of file diff --git a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql b/health-services/census-service/src/main/resources/db/migration/main/V20241128123000__census_create_ddl.sql similarity index 74% rename from health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql rename to health-services/census-service/src/main/resources/db/migration/main/V20241128123000__census_create_ddl.sql index cf80c461292..aabba734ec2 100644 --- a/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql +++ b/health-services/census-service/src/main/resources/db/migration/main/V20241128123000__census_create_ddl.sql @@ -10,7 +10,7 @@ CREATE TABLE census ( effective_to bigint, source character varying(255) NOT NULL, status character varying(255), - assignee character varying(255), + assignee TEXT, facility_assigned boolean, boundary_ancestral_path TEXT NOT NULL, additional_details JSONB, @@ -34,3 +34,16 @@ CREATE TABLE population_by_demographics ( CONSTRAINT uk_population_by_demographics_id PRIMARY KEY (id), FOREIGN KEY (census_id) REFERENCES census(id) ); + +-- Table: additional_field +CREATE TABLE additional_field ( + id character varying(64) NOT NULL, + census_id character varying(64) NOT NULL, + "key" character varying(64) NOT NULL, + "value" numeric(12,2) NOT NULL, + show_on_ui boolean DEFAULT true NOT NULL, + editable boolean DEFAULT true NOT NULL, + "order" bigint NOT NULL, + CONSTRAINT uk_additional_field_id PRIMARY KEY (id), + FOREIGN KEY (census_id) REFERENCES census(id) +); \ No newline at end of file