diff --git a/CODEOWNERS b/CODEOWNERS index 30885762527..7833b872775 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,3 @@ * @kavi-egov @sathishp-eGov -health-services/project-factory/ @jagankumar-egov +health-services/project-factory/ @jagankumar-egov diff --git a/core-services/service-request/pom.xml b/core-services/service-request/pom.xml index 5b5bfe71423..f04bced991b 100644 --- a/core-services/service-request/pom.xml +++ b/core-services/service-request/pom.xml @@ -43,7 +43,7 @@ org.flywaydb flyway-core - 9.22.3 + org.postgresql diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/config/Configuration.java b/core-services/service-request/src/main/java/org/egov/servicerequest/config/Configuration.java index 2d5b8f71444..4aa6a5d519b 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/config/Configuration.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/config/Configuration.java @@ -55,6 +55,9 @@ public MappingJackson2HttpMessageConverter jacksonConverter(ObjectMapper objectM @Value("${egov.service.definition.create.topic}") private String serviceDefinitionCreateTopic; + @Value("${egov.service.definition.update.topic}") + private String serviceDefinitionUpdateTopic; + @Value("${egov.service.create.topic}") private String serviceCreateTopic; diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/error/ErrorCode.java b/core-services/service-request/src/main/java/org/egov/servicerequest/error/ErrorCode.java index 754e55208bb..e1a99338c3c 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/error/ErrorCode.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/error/ErrorCode.java @@ -1,6 +1,7 @@ package org.egov.servicerequest.error; import org.springframework.stereotype.Component; +import org.apache.kafka.common.protocol.types.Field; @Component public class ErrorCode { @@ -30,6 +31,8 @@ public class ErrorCode { public static final String SERVICE_REQUEST_ATTRIBUTE_INVALID_MULTI_VALUE_LIST_VALUE_MSG = "Attribute Value provided against the attribute definition of type multi value list must be an instance of list"; + public static final String SERVICE_REQUEST_ATTRIBUTE_INVALID_BOOLEAN_VALUE_MSG = "Attribute Value provided against the attribute definition of type boolean must be an instance of boolean"; + public static final String INVALID_SIZE_OF_INPUT_CODE = "INVALID_SIZE_OF_INPUT_CODE"; public static final String INVALID_SIZE_OF_TEXT_MSG = "Text value cannot be of length greater than configured length "; @@ -61,4 +64,17 @@ public class ErrorCode { public static final String INVALID_REGEX_ERR_CODE = "INVALID_REGEX_ERR_CODE"; public static final String INVALID_REGEX_ERR_MSG = "The provided regex failed to compile for attribute definition with code - "; + + public static final String SERVICE_DEFINITION_NOT_EXIST_ERR_CODE = "SERVICE_DEFINITION_NOT_EXIST_ERR_CODE"; + + public static final String SERVICE_DEFINITION_NOT_EXIST_ERR_MSG = "Provided tenantId and code unique combination does not exist"; + + public static final String VALID_SERVICE_EXIST_ERR_CODE = "VALID_SERVICE_EXIST_ERR_CODE"; + + public static final String VALID_SERVICE_EXIST_ERR_MSG = "Valid Service exists corresponding to Service Definition"; + + public static final String INACTIVE_SERVICE_DEFINITION_ERR_CODE = "INACTIVE_SERVICE_DEFINITION_ERR_CODE"; + + public static final String INACTIVE_SERVICE_DEFINITION_ERR_MSG = "Inactive Service Definition cannot be updated"; + } diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/repository/querybuilder/ServiceDefinitionQueryBuilder.java b/core-services/service-request/src/main/java/org/egov/servicerequest/repository/querybuilder/ServiceDefinitionQueryBuilder.java index afd7c2ef680..feabdbba147 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/repository/querybuilder/ServiceDefinitionQueryBuilder.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/repository/querybuilder/ServiceDefinitionQueryBuilder.java @@ -56,9 +56,11 @@ public String getServiceDefinitionsIdsQuery(ServiceDefinitionSearchRequest servi } // Fetch service definitions which have NOT been soft deleted - addClauseIfRequired(query, preparedStmtList); - query.append(" sd.isActive = ? "); - preparedStmtList.add(Boolean.TRUE); + if(!serviceDefinitionSearchRequest.isIncludeDeleted()){ + addClauseIfRequired(query, preparedStmtList); + query.append(" sd.isActive = ? "); + preparedStmtList.add(Boolean.TRUE); + } // order service definitions based on their createdtime in latest first manner query.append(ORDERBY_CREATEDTIME); diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceDefinitionRequestService.java b/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceDefinitionRequestService.java index 185274a0eae..64c3c52b6ea 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceDefinitionRequestService.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceDefinitionRequestService.java @@ -68,7 +68,19 @@ public List searchServiceDefinition(ServiceDefinitionSearchRe public ServiceDefinition updateServiceDefinition(ServiceDefinitionRequest serviceDefinitionRequest) { - // TO DO + ServiceDefinition serviceDefinition = serviceDefinitionRequest.getServiceDefinition(); + + //Validate incoming service definition request + ServiceDefinition definitionFromDb = serviceDefinitionRequestValidator.validateUpdateRequest(serviceDefinitionRequest); + + //Enrich incoming service definition request + enrichmentService.enrichServiceDefinitionUpdateRequest(serviceDefinitionRequest, definitionFromDb); + + // Producer statement to emit service definition to kafka for persisting + producer.push(config.getServiceDefinitionUpdateTopic(), serviceDefinitionRequest); + + // Restore attribute values to the type in which it was sent in service definition request + enrichmentService.setAttributeDefinitionValuesBackToNativeState(serviceDefinition); return serviceDefinitionRequest.getServiceDefinition(); } diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceRequestEnrichmentService.java b/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceRequestEnrichmentService.java index 90b9729f864..0864c204d42 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceRequestEnrichmentService.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/service/ServiceRequestEnrichmentService.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; @Component public class ServiceRequestEnrichmentService { @@ -110,4 +111,68 @@ public void setAttributeValuesBackToNativeState(ServiceRequest serviceRequest, M attributeValue.setValue(attributeCodeVsValueMap.get(attributeValue.getAttributeCode())); }); } + + private void updateAttributeDefinition(AttributeDefinition attributeDefinition, AttributeDefinition existingAttributeDefinition, RequestInfo requestInfo){ + + attributeDefinition.setId(existingAttributeDefinition.getId()); + + attributeDefinition.setAuditDetails(existingAttributeDefinition.getAuditDetails()); + + attributeDefinition.setReferenceId(existingAttributeDefinition.getReferenceId()); + + attributeDefinition.getAuditDetails().setLastModifiedTime(System.currentTimeMillis()); + + attributeDefinition.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUuid()); + + } + private void upsertAttributeDefinition(AttributeDefinition attributeDefinition, ServiceDefinitionRequest serviceDefinitionRequest){ + RequestInfo requestInfo = serviceDefinitionRequest.getRequestInfo(); + + attributeDefinition.setId(UUID.randomUUID().toString()); + + attributeDefinition.setAuditDetails( + AuditDetails.builder() + .createdBy(requestInfo.getUserInfo().getUuid()) + .createdTime(System.currentTimeMillis()) + .lastModifiedBy(requestInfo.getUserInfo().getUuid()) + .lastModifiedTime(System.currentTimeMillis()) + .build() + ); + + attributeDefinition.setReferenceId(serviceDefinitionRequest.getServiceDefinition().getId()); + } + public void enrichServiceDefinitionUpdateRequest(ServiceDefinitionRequest serviceDefinitionRequest, ServiceDefinition definitionFromDb) { + List attributeDefinitions = serviceDefinitionRequest.getServiceDefinition().getAttributes(); + + //For quick lookup of Attribute Definition with Code + Map existingAttributeCode = definitionFromDb + .getAttributes() + .stream() + .collect(Collectors.toMap(AttributeDefinition::getCode, a->a)); + + RequestInfo requestInfo = serviceDefinitionRequest.getRequestInfo(); + + ServiceDefinition serviceDefinition = serviceDefinitionRequest.getServiceDefinition(); + + serviceDefinition.setId(definitionFromDb.getId()); + serviceDefinition.setAuditDetails(definitionFromDb.getAuditDetails()); + serviceDefinition.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUuid()); + serviceDefinition.getAuditDetails().setLastModifiedTime(System.currentTimeMillis()); + + attributeDefinitions.forEach(attributeDefinition -> { + if(existingAttributeCode.containsKey(attributeDefinition.getCode())){ + updateAttributeDefinition(attributeDefinition, existingAttributeCode.get(attributeDefinition.getCode()), requestInfo); + } + else{ + upsertAttributeDefinition(attributeDefinition, serviceDefinitionRequest); + } + + if(!(attributeDefinition.getDataType().equals(AttributeDefinition.DataTypeEnum.SINGLEVALUELIST) || attributeDefinition.getDataType().equals(AttributeDefinition.DataTypeEnum.MULTIVALUELIST))){ + List emptyStringList = new ArrayList<>(); + emptyStringList.add(""); + attributeDefinition.setValues(emptyStringList); + } + }); + + } } diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceDefinitionRequestValidator.java b/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceDefinitionRequestValidator.java index 86f8debd558..d8e13c5ea69 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceDefinitionRequestValidator.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceDefinitionRequestValidator.java @@ -1,11 +1,8 @@ package org.egov.servicerequest.validators; import org.egov.servicerequest.repository.ServiceDefinitionRequestRepository; -import org.egov.servicerequest.web.models.AttributeDefinition; -import org.egov.servicerequest.web.models.ServiceDefinition; -import org.egov.servicerequest.web.models.ServiceDefinitionCriteria; -import org.egov.servicerequest.web.models.ServiceDefinitionRequest; -import org.egov.servicerequest.web.models.ServiceDefinitionSearchRequest; +import org.egov.servicerequest.repository.ServiceRequestRepository; +import org.egov.servicerequest.web.models.*; import org.egov.tracer.model.CustomException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -18,14 +15,7 @@ import java.util.Set; import java.util.regex.Pattern; -import static org.egov.servicerequest.error.ErrorCode.ATTRIBUTE_CODE_UNIQUENESS_ERR_CODE; -import static org.egov.servicerequest.error.ErrorCode.ATTRIBUTE_CODE_UNIQUENESS_ERR_MSG; -import static org.egov.servicerequest.error.ErrorCode.INVALID_ATTRIBUTE_DEFINITION_ERR_CODE; -import static org.egov.servicerequest.error.ErrorCode.INVALID_ATTRIBUTE_DEFINITION_ERR_MSG; -import static org.egov.servicerequest.error.ErrorCode.INVALID_REGEX_ERR_CODE; -import static org.egov.servicerequest.error.ErrorCode.INVALID_REGEX_ERR_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_DEFINITION_ALREADY_EXISTS_ERR_CODE; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_DEFINITION_ALREADY_EXISTS_ERR_MSG; +import static org.egov.servicerequest.error.ErrorCode.*; @Component public class ServiceDefinitionRequestValidator { @@ -33,6 +23,10 @@ public class ServiceDefinitionRequestValidator { @Autowired private ServiceDefinitionRequestRepository serviceDefinitionRequestRepository; + @Autowired + private ServiceRequestRepository serviceRequestRepository; + + public void validateServiceDefinitionRequest(ServiceDefinitionRequest serviceDefinitionRequest){ ServiceDefinition serviceDefinition = serviceDefinitionRequest.getServiceDefinition(); @@ -87,16 +81,57 @@ private void validateAttributeDefinitionUniqueness(ServiceDefinition serviceDefi } private void validateServiceDefinitionExistence(ServiceDefinition serviceDefinition) { - List serviceDefinitionList = serviceDefinitionRequestRepository.getServiceDefinitions(ServiceDefinitionSearchRequest.builder().serviceDefinitionCriteria(ServiceDefinitionCriteria.builder().tenantId(serviceDefinition.getTenantId()).code(Collections.singletonList(serviceDefinition.getCode())).build()).build()); + List serviceDefinitionList = serviceDefinitionRequestRepository.getServiceDefinitions(ServiceDefinitionSearchRequest.builder().includeDeleted(true).serviceDefinitionCriteria(ServiceDefinitionCriteria.builder().tenantId(serviceDefinition.getTenantId()).code(Collections.singletonList(serviceDefinition.getCode())).build()).build()); if(!CollectionUtils.isEmpty(serviceDefinitionList)){ throw new CustomException(SERVICE_DEFINITION_ALREADY_EXISTS_ERR_CODE, SERVICE_DEFINITION_ALREADY_EXISTS_ERR_MSG); } } - public void validateUpdateRequest(ServiceDefinitionRequest serviceDefinitionRequest) { + private List validateExistence(ServiceDefinition serviceDefinition) { + List serviceDefinitionList = serviceDefinitionRequestRepository. + getServiceDefinitions(ServiceDefinitionSearchRequest.builder() + .includeDeleted(true) + .serviceDefinitionCriteria(ServiceDefinitionCriteria.builder().tenantId(serviceDefinition.getTenantId()).code(Collections.singletonList(serviceDefinition.getCode())).build()).build()); + + //Check if valid service definition exists + if (CollectionUtils.isEmpty(serviceDefinitionList)) { + throw new CustomException(SERVICE_DEFINITION_NOT_EXIST_ERR_CODE, SERVICE_DEFINITION_NOT_EXIST_ERR_MSG); + } + + return serviceDefinitionList; + } + + private void validateService(List serviceDefinition){ + List service = serviceRequestRepository.getService( + ServiceSearchRequest.builder().serviceCriteria( + ServiceCriteria.builder().serviceDefIds(Collections.singletonList(serviceDefinition.get(0).getId())).build() + ).build() + ); + //already a service exists corresponding to service definition + if(!CollectionUtils.isEmpty(service)){ + throw new CustomException(VALID_SERVICE_EXIST_ERR_CODE, VALID_SERVICE_EXIST_ERR_MSG); + } + } + + public ServiceDefinition validateUpdateRequest(ServiceDefinitionRequest serviceDefinitionRequest) { + ServiceDefinition serviceDefinition = serviceDefinitionRequest.getServiceDefinition(); + + //Validate if a Service Definition exists + List serviceDefinitionList = validateExistence(serviceDefinition); + + //Validate if a Service exists corresponding to this Service Definition + validateService(serviceDefinitionList); + + // Validate if all attribute definitions provided as part of service definitions have unique code + validateAttributeDefinitionUniqueness(serviceDefinition); - // TO DO + // Validate values provided in attribute definitions as per data type + validateAttributeValuesAsPerDataType(serviceDefinition); + + // Validate regex values provided in attribute definitions + validateRegex(serviceDefinition); + return serviceDefinitionList.get(0); } } diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceRequestValidator.java b/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceRequestValidator.java index 66595568bc1..67b2929b36d 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceRequestValidator.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/validators/ServiceRequestValidator.java @@ -21,25 +21,7 @@ import java.util.Map; import java.util.Set; -import static org.egov.servicerequest.error.ErrorCode.INVALID_SIZE_OF_INPUT_CODE; -import static org.egov.servicerequest.error.ErrorCode.INVALID_SIZE_OF_TEXT_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_DATETIME_VALUE_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_MULTI_VALUE_LIST_VALUE_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_NUMBER_VALUE_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_SINGLE_VALUE_LIST_VALUE_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_STRING_VALUE_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_TEXT_VALUE_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_VALUE_CODE; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_VALUE_MULTIVALUELIST_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_INVALID_VALUE_SINGLEVALUELIST_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_VALUES_UNIQUENESS_ERR_CODE; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_ATTRIBUTE_VALUES_UNIQUENESS_ERR_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_INVALID_SERVICE_DEF_ID_CODE; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_INVALID_SERVICE_DEF_ID_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_REQUIRED_ATTRIBUTE_NOT_PROVIDED_ERR_CODE; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_REQUIRED_ATTRIBUTE_NOT_PROVIDED_ERR_MSG; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_UNRECOGNIZED_ATTRIBUTE_CODE; -import static org.egov.servicerequest.error.ErrorCode.SERVICE_REQUEST_UNRECOGNIZED_ATTRIBUTE_MSG; +import static org.egov.servicerequest.error.ErrorCode.*; @Slf4j @Component @@ -133,6 +115,10 @@ private void validateAttributeValuesAgainstServiceDefinition(ServiceDefinition s if(!(attributeValue.getValue() instanceof List)){ throw new CustomException(SERVICE_REQUEST_ATTRIBUTE_INVALID_VALUE_CODE, SERVICE_REQUEST_ATTRIBUTE_INVALID_MULTI_VALUE_LIST_VALUE_MSG); } + }else if(attributeCodeVsDataType.get(attributeValue.getAttributeCode()).equals(AttributeDefinition.DataTypeEnum.BOOLEAN)){ + if(!(attributeValue.getValue() instanceof Boolean)){ + throw new CustomException(SERVICE_REQUEST_ATTRIBUTE_INVALID_VALUE_CODE, SERVICE_REQUEST_ATTRIBUTE_INVALID_BOOLEAN_VALUE_MSG); + } } }); diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeDefinition.java b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeDefinition.java index 59c32cf913b..649421350a1 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeDefinition.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeDefinition.java @@ -41,7 +41,7 @@ public class AttributeDefinition { @JsonProperty("code") @NotNull - @Size(min = 2, max = 64) + @Size(min = 2, max = 256) private String code = null; /** @@ -50,6 +50,8 @@ public class AttributeDefinition { public enum DataTypeEnum { STRING("String"), + BOOLEAN("Boolean"), + NUMBER("Number"), TEXT("Text"), @@ -60,9 +62,7 @@ public enum DataTypeEnum { MULTIVALUELIST("MultiValueList"), - FILE("File"), - - BOOLEAN("Boolean"); + FILE("File"); private String value; @@ -112,7 +112,7 @@ public static DataTypeEnum fromValue(String text) { @Valid private AuditDetails auditDetails = null; - @JsonProperty("additionalDetails") + @JsonProperty("additionalFields") private Object additionalDetails = null; diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeValue.java b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeValue.java index 8aeff4e39f3..98ce105e9b3 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeValue.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/AttributeValue.java @@ -41,7 +41,7 @@ public class AttributeValue { @Valid private AuditDetails auditDetails = null; - @JsonProperty("additionalDetails") + @JsonProperty("additionalFields") private Object additionalDetails = null; diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/Service.java b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/Service.java index b0348458c15..4fc646ca8ea 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/Service.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/Service.java @@ -51,7 +51,7 @@ public class Service { @Valid private AuditDetails auditDetails = null; - @JsonProperty("additionalDetails") + @JsonProperty("additionalFields") private Object additionalDetails = null; @JsonProperty("accountId") diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinition.java b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinition.java index e91eeedf541..01b9b31fac9 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinition.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinition.java @@ -35,7 +35,7 @@ public class ServiceDefinition { @JsonProperty("code") @NotNull - @Size(min = 2, max = 64) + @Size(min = 2, max = 256) private String code = null; @JsonProperty("isActive") @@ -50,7 +50,7 @@ public class ServiceDefinition { @Valid private AuditDetails auditDetails = null; - @JsonProperty("additionalDetails") + @JsonProperty("additionalFields") private Object additionalDetails = null; @JsonProperty("clientId") diff --git a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinitionSearchRequest.java b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinitionSearchRequest.java index 82af972de54..1971656a6c8 100644 --- a/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinitionSearchRequest.java +++ b/core-services/service-request/src/main/java/org/egov/servicerequest/web/models/ServiceDefinitionSearchRequest.java @@ -33,5 +33,6 @@ public class ServiceDefinitionSearchRequest { @Valid private Pagination pagination = null; - + @JsonProperty("includeDeleted") + private boolean includeDeleted = false; } diff --git a/core-services/service-request/src/main/resources/application.properties b/core-services/service-request/src/main/resources/application.properties index b08e73fc128..a3fdc45c3f2 100644 --- a/core-services/service-request/src/main/resources/application.properties +++ b/core-services/service-request/src/main/resources/application.properties @@ -48,6 +48,7 @@ egov.service.request.max.limit=100 # Kafka topics egov.service.definition.create.topic=save-service-definition egov.service.create.topic=save-service +egov.service.definition.update.topic=update-service-definition # String input size configuration egov.max.string.input.size=8192 \ No newline at end of file diff --git a/core-services/service-request/src/main/resources/db/migration/main/V20241115143930__servicedefinition_alter_ddl.sql b/core-services/service-request/src/main/resources/db/migration/main/V20241115143930__servicedefinition_alter_ddl.sql new file mode 100644 index 00000000000..ed8ce4007ca --- /dev/null +++ b/core-services/service-request/src/main/resources/db/migration/main/V20241115143930__servicedefinition_alter_ddl.sql @@ -0,0 +1,9 @@ +-- Migration script to alter the length of 'code' column in both tables to 256 + +-- Update eg_service_definition table +ALTER TABLE eg_service_definition +ALTER COLUMN code TYPE character varying(256); + +-- Update eg_service_attribute_definition table +ALTER TABLE eg_service_attribute_definition +ALTER COLUMN code TYPE character varying(256); diff --git a/core-services/service-request/src/main/resources/service-request-persister.yml b/core-services/service-request/src/main/resources/service-request-persister.yml index 10fc9ce8702..22bcf13539c 100644 --- a/core-services/service-request/src/main/resources/service-request-persister.yml +++ b/core-services/service-request/src/main/resources/service-request-persister.yml @@ -8,72 +8,68 @@ serviceMaps: queryMaps: - query: INSERT INTO eg_service_definition(id, tenantid, code, isactive, createdby, lastmodifiedby, createdtime, lastmodifiedtime, additionaldetails, clientid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?); - basePath: $.serviceDefinition + basePath: $.ServiceDefinition jsonMaps: - - jsonPath: $.serviceDefinition.id + - jsonPath: $.ServiceDefinition.id - - jsonPath: $.serviceDefinition.tenantId + - jsonPath: $.ServiceDefinition.tenantId - - jsonPath: $.serviceDefinition.code + - jsonPath: $.ServiceDefinition.code - - jsonPath: $.serviceDefinition.isActive + - jsonPath: $.ServiceDefinition.isActive - - jsonPath: $.serviceDefinition.auditDetails.createdBy + - jsonPath: $.ServiceDefinition.auditDetails.createdBy - - jsonPath: $.serviceDefinition.auditDetails.lastModifiedBy + - jsonPath: $.ServiceDefinition.auditDetails.lastModifiedBy - - jsonPath: $.serviceDefinition.auditDetails.createdTime + - jsonPath: $.ServiceDefinition.auditDetails.createdTime - - jsonPath: $.serviceDefinition.auditDetails.lastModifiedTime + - jsonPath: $.ServiceDefinition.auditDetails.lastModifiedTime - - jsonPath: $.serviceDefinition.additionalDetails + - jsonPath: $.ServiceDefinition.additionalDetails type: JSON dbType: JSONB - - jsonPath: $.serviceDefinition.clientId + - jsonPath: $.ServiceDefinition.clientId - query: INSERT INTO eg_service_attribute_definition(id, referenceid, tenantid, code, datatype, "values", isactive, required, regex, "order", createdby, lastmodifiedby, createdtime, lastmodifiedtime, additionaldetails) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); - basePath: $.serviceDefinition.attributes.* + basePath: $.ServiceDefinition.attributes.* jsonMaps: - - jsonPath: $.serviceDefinition.attributes.*.id + - jsonPath: $.ServiceDefinition.attributes.*.id - - jsonPath: $.serviceDefinition.attributes.*.referenceId + - jsonPath: $.ServiceDefinition.attributes.*.referenceId - - jsonPath: $.serviceDefinition.attributes.*.tenantId + - jsonPath: $.ServiceDefinition.attributes.*.tenantId - - jsonPath: $.serviceDefinition.attributes.*.code + - jsonPath: $.ServiceDefinition.attributes.*.code - - jsonPath: $.serviceDefinition.attributes.*.dataType + - jsonPath: $.ServiceDefinition.attributes.*.dataType - - jsonPath: $.serviceDefinition.attributes.*.values + - jsonPath: $.ServiceDefinition.attributes.*.values type: ARRAY dbType: STRING - - jsonPath: $.serviceDefinition.attributes.*.isActive + - jsonPath: $.ServiceDefinition.attributes.*.isActive - - jsonPath: $.serviceDefinition.attributes.*.required + - jsonPath: $.ServiceDefinition.attributes.*.required - - jsonPath: $.serviceDefinition.attributes.*.regex + - jsonPath: $.ServiceDefinition.attributes.*.regex - - jsonPath: $.serviceDefinition.attributes.*.order + - jsonPath: $.ServiceDefinition.attributes.*.order - - jsonPath: $.serviceDefinition.attributes.*.auditDetails.createdBy + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.createdBy - - jsonPath: $.serviceDefinition.attributes.*.auditDetails.lastModifiedBy + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.lastModifiedBy - - jsonPath: $.serviceDefinition.attributes.*.auditDetails.createdTime + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.createdTime - - jsonPath: $.serviceDefinition.attributes.*.auditDetails.lastModifiedTime + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.lastModifiedTime - - jsonPath: $.serviceDefinition.attributes.*.additionalDetails + - jsonPath: $.ServiceDefinition.attributes.*.additionalDetails type: JSON dbType: JSONB - - - - - version: 1.0 description: Persists service details in service table fromTopic: save-service @@ -82,54 +78,135 @@ serviceMaps: - query: INSERT INTO eg_service(id, tenantid, servicedefid, referenceid, createdby, lastmodifiedby, createdtime, lastmodifiedtime, additionaldetails, accountid, clientid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); - basePath: $.service + basePath: $.Service jsonMaps: - - jsonPath: $.service.id + - jsonPath: $.Service.id - - jsonPath: $.service.tenantId + - jsonPath: $.Service.tenantId - - jsonPath: $.service.serviceDefId + - jsonPath: $.Service.serviceDefId - - jsonPath: $.service.referenceId + - jsonPath: $.Service.referenceId - - jsonPath: $.service.auditDetails.createdBy + - jsonPath: $.Service.auditDetails.createdBy - - jsonPath: $.service.auditDetails.lastModifiedBy + - jsonPath: $.Service.auditDetails.lastModifiedBy - - jsonPath: $.service.auditDetails.createdTime + - jsonPath: $.Service.auditDetails.createdTime - - jsonPath: $.service.auditDetails.lastModifiedTime + - jsonPath: $.Service.auditDetails.lastModifiedTime - - jsonPath: $.service.additionalDetails + - jsonPath: $.Service.additionalDetails type: JSON dbType: JSONB - - jsonPath: $.service.accountId + - jsonPath: $.Service.accountId - - jsonPath: $.service.clientId + - jsonPath: $.Service.clientId - query: INSERT INTO eg_service_attribute_value(id, referenceid, attributecode, value, createdby, lastmodifiedby, createdtime, lastmodifiedtime, additionaldetails) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); - basePath: $.service.attributes.* + basePath: $.Service.attributes.* + jsonMaps: + - jsonPath: $.Service.attributes.*.id + + - jsonPath: $.Service.attributes.*.referenceId + + - jsonPath: $.Service.attributes.*.attributeCode + + - jsonPath: $.Service.attributes.*.value + type: JSON + dbType: JSONB + + - jsonPath: $.Service.attributes.*.auditDetails.createdBy + + - jsonPath: $.Service.attributes.*.auditDetails.lastModifiedBy + + - jsonPath: $.Service.attributes.*.auditDetails.createdTime + + - jsonPath: $.Service.attributes.*.auditDetails.lastModifiedTime + + - jsonPath: $.Service.attributes.*.additionalDetails + type: JSON + dbType: JSONB + + + - version: 1.0 + description: Update Service Definition + fromTopic: update-service-definition + isTransaction: true + queryMaps: + + - query: UPDATE eg_service_definition SET lastmodifiedby = ?, lastmodifiedtime = ?, isactive = ?, additionaldetails = ? WHERE id = ? + basePath: $.ServiceDefinition + jsonMaps: + - jsonPath: $.ServiceDefinition.auditDetails.lastModifiedBy + + - jsonPath: $.ServiceDefinition.auditDetails.lastModifiedTime + + - jsonPath: $.ServiceDefinition.isActive + + - jsonPath: $.ServiceDefinition.additionalDetails + type: JSON + dbType: JSONB + + - jsonPath: $.ServiceDefinition.id + + - query: INSERT INTO eg_service_attribute_definition(id, referenceid, tenantid, code, datatype, "values", isactive, required, regex, "order", createdby, lastmodifiedby, createdtime, lastmodifiedtime, additionaldetails) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET datatype=?, "values"=?, isactive=?, required=?, regex=?, "order"=?, lastmodifiedby=?, lastmodifiedtime=?, additionaldetails=?; + basePath: $.ServiceDefinition.attributes.* jsonMaps: - - jsonPath: $.service.attributes.*.id + - jsonPath: $.ServiceDefinition.attributes.*.id + + - jsonPath: $.ServiceDefinition.attributes.*.referenceId + + - jsonPath: $.ServiceDefinition.attributes.*.tenantId + + - jsonPath: $.ServiceDefinition.attributes.*.code + + - jsonPath: $.ServiceDefinition.attributes.*.dataType + + - jsonPath: $.ServiceDefinition.attributes.*.values + type: ARRAY + dbType: STRING - - jsonPath: $.service.attributes.*.referenceId + - jsonPath: $.ServiceDefinition.attributes.*.isActive - - jsonPath: $.service.attributes.*.attributeCode + - jsonPath: $.ServiceDefinition.attributes.*.required - - jsonPath: $.service.attributes.*.value + - jsonPath: $.ServiceDefinition.attributes.*.regex + + - jsonPath: $.ServiceDefinition.attributes.*.order + + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.createdBy + + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.lastModifiedBy + + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.createdTime + + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.lastModifiedTime + + - jsonPath: $.ServiceDefinition.attributes.*.additionalDetails type: JSON dbType: JSONB - - jsonPath: $.service.attributes.*.auditDetails.createdBy + - jsonPath: $.ServiceDefinition.attributes.*.dataType + + - jsonPath: $.ServiceDefinition.attributes.*.values + type: ARRAY + dbType: STRING + + - jsonPath: $.ServiceDefinition.attributes.*.isActive + + - jsonPath: $.ServiceDefinition.attributes.*.required + + - jsonPath: $.ServiceDefinition.attributes.*.regex - - jsonPath: $.service.attributes.*.auditDetails.lastModifiedBy + - jsonPath: $.ServiceDefinition.attributes.*.order - - jsonPath: $.service.attributes.*.auditDetails.createdTime + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.lastModifiedBy - - jsonPath: $.service.attributes.*.auditDetails.lastModifiedTime + - jsonPath: $.ServiceDefinition.attributes.*.auditDetails.lastModifiedTime - - jsonPath: $.service.attributes.*.additionalDetails + - jsonPath: $.ServiceDefinition.attributes.*.additionalDetails type: JSON dbType: JSONB \ No newline at end of file diff --git a/health-services/census-service/CHANGELOG.md b/health-services/census-service/CHANGELOG.md new file mode 100644 index 00000000000..38562489c90 --- /dev/null +++ b/health-services/census-service/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog +All notable changes to this module will be documented in this file. + +## 1.0.0 - 2024-11-28 +#### Census Service +The Census Service introduces core functionalities for managing census data: + +1. Validation of Census: Ensures data integrity by validating all census requests before processing. +2. Census Create: Creates new census records after validation and enrichment, publishing request to the designated Kafka topic to handle the creation process asynchronously. +3. Census Update: Updates existing records post-validation and enrichment by sending request to the designated Kafka update topic. +4. Census Bulk Update: Updates multiple census records in one operation after successful validation. +5. Census Search: Enables searching for census records with the provided search criteria. +6. Plan Facility Consumer: Listens to Plan Facility Update topic to assign facility to a boundary in census. \ No newline at end of file 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..7e6f7adc8fb --- /dev/null +++ b/health-services/census-service/pom.xml @@ -0,0 +1,141 @@ + + 4.0.0 + org.egov + census-service + jar + census-service + 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 + + + org.egov.common + health-services-models + 1.0.21-SNAPSHOT + compile + + + 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..8459885357e --- /dev/null +++ b/health-services/census-service/src/main/java/digit/config/Configuration.java @@ -0,0 +1,86 @@ +package digit.config; + +import lombok.*; +import org.egov.tracer.config.TracerConfiguration; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Import; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@Data +@Import({TracerConfiguration.class}) +@NoArgsConstructor +@AllArgsConstructor +@Setter +@Getter +public class Configuration { + + // Allowed roles for census + @Value("#{${allowed.census.roles}}") + private List allowedCensusRoles; + + @Value("#{${workflow.restricted.roles}}") + private List workflowRestrictedRoles; + + // Persister Topic + @Value("${census.create.topic}") + private String censusCreateTopic; + + @Value("${census.update.topic}") + private String censusUpdateTopic; + + @Value("${census.bulk.update.topic}") + private String censusBulkUpdateTopic; + + @Value("${plan.facility.update.topic}") + private String planFcailityUpdateTopic; + + // Boundary Service + @Value("${egov.boundary.service.host}") + private String boundaryServiceHost; + + @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; + + @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("${egov.business.service.search.endpoint}") + private String businessServiceSearchEndpoint; + + @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; + + //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/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..5d944060848 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/config/ServiceConstants.java @@ -0,0 +1,114 @@ +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 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: "; + + 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 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"; + + 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="; + + 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 "; + + 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 : "; + + 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"; + + 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 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 CENSUS_ALREADY_EXISTS_CODE = "CENSUS_ALREADY_EXISTS"; + public static final String CENSUS_ALREADY_EXISTS_MESSAGE = "Census with the given boundary and source already exists."; + + 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 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"; + + 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/kafka/FacilityCatchmentConsumer.java b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java new file mode 100644 index 00000000000..d5be4b7458c --- /dev/null +++ b/health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java @@ -0,0 +1,99 @@ +package digit.kafka; + +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; +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.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static digit.config.ServiceConstants.FACILITY_ID_FIELD; +import static digit.config.ServiceConstants.FACILITY_NAME_FIELD; + +@Component +@Slf4j +public class FacilityCatchmentConsumer { + + private ObjectMapper objectMapper; + + private CensusService service; + + private CensusRepository repository; + + private CommonUtil commonUtil; + + 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}"}) + 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(), 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(); + + Set boundariesWithFacility = new HashSet<>(List.of(planFacilityDTO.getServiceBoundaries().split(","))); + Set boundariesWithNoFacility = new HashSet<>(planFacilityDTO.getInitiallySetServiceBoundaries()); + + 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.setAdditionalDetails(commonUtil.removeFieldFromAdditionalDetails(census.getAdditionalDetails(), FACILITY_NAME_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.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(census.getAdditionalDetails(), FACILITY_NAME_FIELD, facilityName)); + census.setFacilityAssigned(Boolean.TRUE); + census.setPartnerAssignmentValidationEnabled(Boolean.FALSE); + } + }); + + // Enrich jurisdiction mapping in census for indexer + enrichment.enrichJurisdictionMapping(censusFromSearch, boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); + 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/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/kafka/ResourceCensusConsumer.java b/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java new file mode 100644 index 00000000000..e161225b23a --- /dev/null +++ b/health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java @@ -0,0 +1,37 @@ +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); + censusRequest.getCensus().setPartnerAssignmentValidationEnabled(Boolean.FALSE); + 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/repository/CensusRepository.java b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java new file mode 100644 index 00000000000..4a9f159e7e9 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/CensusRepository.java @@ -0,0 +1,21 @@ +package digit.repository; + +import digit.web.models.*; + +import java.util.List; +import java.util.Map; + +public interface CensusRepository { + + public void create(CensusRequest censusRequest); + + public List search(CensusSearchCriteria censusSearchCriteria); + + public void update(CensusRequest censusRequest); + + public void bulkUpdate(BulkCensusRequest request); + + public Integer count(CensusSearchCriteria censusSearchCriteria); + + public Map statusCount(CensusSearchRequest censusSearchRequest); +} 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..d09d230e4fa --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java @@ -0,0 +1,45 @@ +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; + + 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/repository/impl/CensusRepositoryImpl.java b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java new file mode 100644 index 00000000000..c6dec4b4d11 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java @@ -0,0 +1,219 @@ +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.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.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.CENSUS_BUSINESS_SERVICE; + +@Slf4j +@Repository +public class CensusRepositoryImpl implements CensusRepository { + + private Producer producer; + + private Configuration config; + + private CensusQueryBuilder queryBuilder; + + private CensusRowMapper censusRowMapper; + + private JdbcTemplate jdbcTemplate; + + private 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; + } + + /** + * Pushes a new census record to persister kafka topic. + * + * @param censusRequest The request containing the census details + */ + @Override + public void create(CensusRequest censusRequest) { + CensusRequestDTO requestDTO = convertToReqDTO(censusRequest); + producer.push(config.getCensusCreateTopic(), requestDTO); + } + + /** + * 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) { + + if(censusSearchCriteria.getAreaCodes() != null && censusSearchCriteria.getAreaCodes().isEmpty()) + return new ArrayList<>(); + + // 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()); + } + + /** + * Counts the number of census records based on the provided search criteria. + * + * @param censusSearchCriteria The search criteria for filtering census records. + * @return The total count of census matching the search criteria. + */ + @Override + public Integer count(CensusSearchCriteria censusSearchCriteria) { + + if(censusSearchCriteria.getAreaCodes() != null && censusSearchCriteria.getAreaCodes().isEmpty()) + return 0; + + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getCensusCountQuery(censusSearchCriteria, preparedStmtList); + + return jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); + } + + /** + * Counts the census record based on their current status for the provided search criteria. + * + * @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(CensusSearchRequest censusSearchRequest) { + List preparedStmtList = new ArrayList<>(); + 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 statusCountMap; + } + + /** + * 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) { + CensusRequestDTO requestDTO = convertToReqDTO(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 rows for bulk update + List rows = request.getCensus().stream().map(census -> new Object[] { + census.getStatus(), + !CollectionUtils.isEmpty(census.getAssignee()) ? String.join(",", census.getAssignee()) : census.getAssignee(), + census.getAuditDetails().getLastModifiedBy(), + census.getAuditDetails().getLastModifiedTime(), + commonUtil.convertToPgObject(census.getAdditionalDetails()), + census.getFacilityAssigned(), + census.getId() + }).toList(); + + // Perform bulk update + jdbcTemplate.batchUpdate(bulkCensusUpdateQuery, rows); + producer.push(config.getCensusBulkUpdateTopic(), request); + } + + /** + * 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(); + + 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(assignee) + .status(census.getStatus()) + .type(census.getType().toString()) + .totalPopulation(census.getTotalPopulation()) + .populationByDemographics(census.getPopulationByDemographics()) + .jurisdictionMapping(census.getJurisdictionMapping()) + .additionalFields(census.getAdditionalFields()) + .effectiveFrom(census.getEffectiveFrom()) + .effectiveTo(census.getEffectiveTo()) + .source(census.getSource()) + .boundaryAncestralPath(census.getBoundaryAncestralPath().get(0)) + .facilityAssigned(census.getFacilityAssigned()) + .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/querybuilder/CensusQueryBuilder.java b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java new file mode 100644 index 00000000000..7eec3f639ca --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java @@ -0,0 +1,219 @@ +package digit.repository.querybuilder; + +import digit.config.Configuration; +import digit.util.QueryUtil; +import digit.web.models.CensusSearchCriteria; +import org.springframework.stereotype.Component; +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; + +@Component +public class CensusQueryBuilder { + + private QueryUtil queryUtil; + + private Configuration config; + + public CensusQueryBuilder(QueryUtil queryUtil, Configuration config) { + this.config = config; + this.queryUtil = queryUtil; + } + + 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" + + "\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(id) AS total_count FROM ( "; + + 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 = ?"; + + /** + * 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 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(List ids, List preparedStmtList) { + String query = buildCensusQuery(ids, preparedStmtList); + query = queryUtil.addOrderByClause(query, CENSUS_SEARCH_QUERY_ORDER_BY_CLAUSE); + 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, 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; + } + + /** + * 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 buildCensusSearchQuery(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) { + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder().tenantId(searchCriteria.getTenantId()).source(searchCriteria.getSource()).jurisdiction(searchCriteria.getJurisdiction()).build(); + return buildCensusSearchQuery(censusSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); + } + + /** + * Constructs query based on the provided search criteria + * + * @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 ids based on search criteria + */ + 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(" id = ?"); + preparedStmtList.add(criteria.getId()); + } + + if (!CollectionUtils.isEmpty(criteria.getIds())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + 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(" tenant_id = ?"); + preparedStmtList.add(criteria.getTenantId()); + } + + if (!ObjectUtils.isEmpty(criteria.getStatus())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" status = ?"); + preparedStmtList.add(criteria.getStatus()); + } + + if (!ObjectUtils.isEmpty(criteria.getSource())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" source = ?"); + preparedStmtList.add(criteria.getSource()); + } + + if (!ObjectUtils.isEmpty(criteria.getFacilityAssigned())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" facility_assigned = ?"); + preparedStmtList.add(criteria.getFacilityAssigned()); + } + + if (!ObjectUtils.isEmpty(criteria.getEffectiveTo())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + if (criteria.getEffectiveTo() == 0) { + builder.append(" effective_to IS NULL "); + } else { + builder.append(" effective_to = ?"); + preparedStmtList.add(criteria.getEffectiveTo()); + } + } + + if (!CollectionUtils.isEmpty(criteria.getAreaCodes())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" boundary_code IN ( ").append(queryUtil.createQuery(criteria.getAreaCodes().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, 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, 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[] "); + builder.append(" && string_to_array(boundary_ancestral_path, '|') "); + queryUtil.addToPreparedStatement(preparedStmtList, criteria.getJurisdiction()); + } + + StringBuilder countQuery = new StringBuilder(); + if (isCount) { + countQuery.append(CENSUS_SEARCH_QUERY_COUNT_WRAPPER).append(builder); + countQuery.append(") AS subquery"); + + return countQuery.toString(); + } + + if (isStatusCount) { + return CENSUS_STATUS_COUNT_QUERY.replace("{INTERNAL_QUERY}", builder); + } + + return builder.toString(); + } + + 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(); + } +} 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..7edac5005dd --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java @@ -0,0 +1,148 @@ +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; +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 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<>(); + Set populationByDemographicSet = new HashSet<>(); + Set additionalFieldSet = new HashSet<>(); + + while (rs.next()) { + String censusId = rs.getString("census_id"); + Census censusEntry = censusMap.get(censusId); + + if (ObjectUtils.isEmpty(censusEntry)) { + censusEntry = new Census(); + populationByDemographicSet.clear(); + additionalFieldSet.clear(); + + // 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")); + censusEntry.setHierarchyType(rs.getString("census_hierarchy_type")); + censusEntry.setBoundaryCode(rs.getString("census_boundary_code")); + 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")); + censusEntry.setSource(rs.getString("census_source")); + censusEntry.setStatus(rs.getString("census_status")); + 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"))); + censusEntry.setAuditDetails(auditDetails); + } + addPopulationByDemographic(rs, populationByDemographicSet, censusEntry); + addAdditionalField(rs, additionalFieldSet, censusEntry); + + censusMap.put(censusId, censusEntry); + } + + 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 additionalFieldSet A set 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, Set additionalFieldSet, Census censusEntry) throws SQLException { + String additionalFieldId = rs.getString("additional_field_id"); + + if (ObjectUtils.isEmpty(additionalFieldId) || additionalFieldSet.contains(additionalFieldId)) { + return; + } + + AdditionalField additionalField = new AdditionalField(); + additionalField.setId(rs.getString("additional_field_id")); + additionalField.setKey(rs.getString("additional_field_key")); + 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")); + + if (CollectionUtils.isEmpty(censusEntry.getAdditionalFields())) { + List additionalFields = new ArrayList<>(); + additionalFields.add(additionalField); + censusEntry.setAdditionalFields(additionalFields); + } else { + censusEntry.getAdditionalFields().add(additionalField); + } + + additionalFieldSet.add(additionalFieldId); + } + + + /** + * Adds a PopulationByDemographics object to the census entry based on the result set. + * + * @param rs The ResultSet containing the data. + * @param populationByDemographicSet A set 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, Set populationByDemographicSet, Census censusEntry) throws SQLException { + String populationByDemographicId = rs.getString("population_by_demographics_id"); + + if (ObjectUtils.isEmpty(populationByDemographicId) || populationByDemographicSet.contains(populationByDemographicId)) { + return; + } + + PopulationByDemographic populationByDemographic = new PopulationByDemographic(); + populationByDemographic.setId(rs.getString("population_by_demographics_id")); + populationByDemographic.setDemographicVariable(PopulationByDemographic.DemographicVariableEnum.fromValue(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); + } + + populationByDemographicSet.add(populationByDemographicId); + } +} 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 new file mode 100644 index 00000000000..b997f2f933f --- /dev/null +++ b/health-services/census-service/src/main/java/digit/repository/rowmapper/StatusCountRowMapper.java @@ -0,0 +1,30 @@ +package digit.repository.rowmapper; + +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.HashMap; +import java.util.Map; + +@Component +public class StatusCountRowMapper implements ResultSetExtractor> { + + @Override + public Map extractData(ResultSet rs) throws SQLException, DataAccessException { + Map statusCountMap = new HashMap<>(); + + while (rs.next()) { + String status = rs.getString("census_status"); + Integer statusCount = rs.getInt("census_status_count"); + + 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 new file mode 100644 index 00000000000..ec37824bfc1 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/CensusService.java @@ -0,0 +1,127 @@ +package digit.service; + +import digit.repository.CensusRepository; +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.BulkCensusRequest; +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; + + private CensusRepository repository; + + private CensusValidator validator; + + private CensusEnrichment enrichment; + + private 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; + } + + /** + * 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) { + + // Validate census create request + validator.validateCreate(request); + + // Enrich census create request + enrichment.enrichCreate(request); + + // Enrich timeframe for previous census + timeframeEnrichment.enrichPreviousTimeframe(request); + + // Call workflow transition API for status update + workflow.invokeWorkflowForStatusUpdate(request); + + // Delegate creation request to repository + repository.create(request); + + return CensusResponse.builder() + .census(Collections.singletonList(request.getCensus())) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .build(); + } + + /** + * 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) { + + return CensusResponse.builder() + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .census(repository.search(request.getCensusSearchCriteria())) + .totalCount(repository.count(request.getCensusSearchCriteria())) + .statusCount(repository.statusCount(request)) + .build(); + } + + /** + * 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) { + // 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/enrichment/CensusEnrichment.java b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java new file mode 100644 index 00000000000..4754de26c4e --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java @@ -0,0 +1,218 @@ +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.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; +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; + +import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; + +@Component +public class CensusEnrichment { + + private CommonUtil commonUtil; + + public CensusEnrichment(CommonUtil commonUtil) { + this.commonUtil = commonUtil; + } + + /** + * Enriches the CensusRequest for creating a new census record. + * Enriches the given census record with generated IDs for Census and PopulationByDemographics. + * 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. + */ + public void enrichCreate(CensusRequest request) { + Census census = request.getCensus(); + + // Generate id for census record + UUIDEnrichmentUtil.enrichRandomUuid(census, "id"); + + // Generate id for PopulationByDemographics + if (!CollectionUtils.isEmpty(census.getPopulationByDemographics())) { + 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)); + + // 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)); + } + + /** + * 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); + } + + /** + * 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. + * + * @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(); + + // Generate id for populationByDemographics + if (!CollectionUtils.isEmpty(census.getPopulationByDemographics())) { + census.getPopulationByDemographics().forEach(populationByDemographics -> { + if (ObjectUtils.isEmpty(populationByDemographics.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(populationByDemographics, "id"); + } + }); + } + + //Generate id for additionalFields + census.getAdditionalFields().forEach(additionalField -> { + if (ObjectUtils.isEmpty(additionalField.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(additionalField, "id"); + } + }); + + // Set last modified time on update call + census.getAuditDetails().setLastModifiedTime(System.currentTimeMillis()); + + denormalizeAdditionalFields(request.getCensus()); + } + + /** + * 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 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; + + // Get the list of boundary codes from pipe separated boundaryAncestralPath. + List 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); + } + + /** + * 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<>(); + + // Enriches the boundaryHierarchyMapping and returns the highest boundary hierarchy for the given hierarchy type. + String highestBoundaryHierarchy = getBoundaryHierarchyMapping(boundaryTypeHierarchyDef, boundaryHierarchyMapping); + + for (Census census : censusList) { + + Map jurisdictionMapping = new LinkedHashMap<>(); + String boundaryHierarchy = highestBoundaryHierarchy; + + // Get the list of boundary codes from pipe separated boundaryAncestralPath. + List 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/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/service/validator/CensusValidator.java b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java new file mode 100644 index 00000000000..526e2445fb8 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java @@ -0,0 +1,337 @@ +package digit.service.validator; + +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.*; +import digit.web.models.boundary.BoundarySearchResponse; +import digit.web.models.boundary.BoundaryTypeHierarchyResponse; +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.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 java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; + +@Component +public class CensusValidator { + + private BoundaryUtil boundaryUtil; + + private PlanEmployeeAssignmnetUtil employeeAssignmnetUtil; + + private Configuration configs; + + private 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; + } + + /** + * 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); + + // Validate duplicate records for census + validateDuplicateRecords(census); + + // Validate boundary code against boundary service + validateBoundaryCode(boundarySearchResponse, census); + + // Validate partner assignment and jurisdiction against plan service + validatePartnerForCensus(request); + + // Validate keys in additional field + validateAdditionalFields(request); + } + + private void validateDuplicateRecords(Census census) { + List censusResponseFromSearch = repository.search(CensusSearchCriteria.builder().source(census.getSource()).areaCodes(Collections.singletonList(census.getBoundaryCode())).build()); + + if(!CollectionUtils.isEmpty(censusResponseFromSearch)) { + throw new CustomException(CENSUS_ALREADY_EXISTS_CODE, CENSUS_ALREADY_EXISTS_MESSAGE); + } + } + + 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()); + }); + } + + /** + * 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 and jurisdiction mapping for the provided boundary code + enrichment.enrichBoundaryAncestralPath(census, tenantBoundary); + } + + /** + * Validates partner assignment and jurisdiction against plan service + * Also validates the user information within the provided CensusRequest. + * + * @param request the census request + */ + 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 (census.getPartnerAssignmentValidationEnabled()) { + 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(roles.stream().toList()) + .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()); + } + } + + 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(UNAUTHORIZED_WORKFLOW_ACCESS_CODE, UNAUTHORIZED_WORKFLOW_ACCESS_MESSAGE); + } + } + + /** + * Validates partner assignment and jurisdiction for census update request. + * + * @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); + + // Validate partner assignment and jurisdiction against plan service + validatePartnerForCensus(request); + + // Validate keys in additional field + validateAdditionalFields(request); + + // Enrich jurisdiction mapping in census + enrichment.enrichJurisdictionMapping(request.getCensus(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); + } + + /** + * Validates the existence of census record in the repository + * + * @param request The request containing the census to be validated + */ + private void validateCensusExistence(CensusRequest request) { + Census census = request.getCensus(); + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() + .id(census.getId()) + .build(); + + List censusList = repository.search(searchCriteria); + + if (CollectionUtils.isEmpty(censusList)) { + throw new CustomException(INVALID_CENSUS_CODE, INVALID_CENSUS_MESSAGE); + } + + 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) { + 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); + + // Validate if census in request body exists + validateCensusExistence(request); + + // Validate partner assignment and jurisdiction against plan service + validatePartnerForCensus(request); + + // Enrich jurisdiction mapping in census + enrichment.enrichJurisdictionMapping(request.getCensus(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); + } + + /** + * 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 new file mode 100644 index 00000000000..e842c5dae29 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -0,0 +1,331 @@ +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.BulkCensusRequest; +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.RequestInfo; +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)); + + } + + /** + * 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 + List assignee = getAssigneeForAutoAssignment(request.getCensus().get(0), request.getRequestInfo()); + + for (Census census : request.getCensus()) { + if (config.getWfSendBackActions().contains(census.getWorkflow().getAction())) { + assignee = Collections.singletonList(census.getAuditDetails().getLastModifiedBy()); + } + + // Set assignee + if (!ObjectUtils.isEmpty(assignee)) + census.getWorkflow().setAssignes(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. + * + * @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(); + + // 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(); + + // 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); + + census.setAssignee(assignee); + + // Enrich user for process instance + 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()); + } + + /** + * 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. + * For INTERMEDIATE actions (non-ROOT_APPROVER), assigns an employee from a higher-level boundary. + * For SEND_BACK actions, assigns the last modified user. + * + * @param census the census object containing workflow and jurisdiction details + * @param requestInfo the 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); + + PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = + PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(census.getTenantId()) + .jurisdiction(Arrays.stream(hierarchiesBoundaryCodes).toList()) + .planConfigurationId(census.getSource()) + .role(config.getAllowedCensusRoles()) + .build(); + + //search for plan-employee assignments for the ancestral hierarchy codes. + PlanEmployeeAssignmentResponse planEmployeeAssignmentResponse = planEmployeeAssignmnetUtil.fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest.builder() + .planEmployeeAssignmentSearchCriteria(planEmployeeAssignmentSearchCriteria) + .requestInfo(requestInfo).build()); + + // 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(); + return assignment.getJurisdiction().stream() + .filter(jurisdiction -> Arrays.asList(hierarchiesBoundaryCodes).contains(jurisdiction)) + .map(jurisdiction -> new AbstractMap.SimpleEntry<>(jurisdiction, employeeId)); + }) + .collect(Collectors.groupingBy( + Map.Entry::getKey, // jurisdiction as the key + LinkedHashMap::new, // Preserve insertion order + Collectors.mapping( + Map.Entry::getValue, // employee IDs as values + Collectors.toList() // Collect employee IDs into a List + ) + )); + + List assignee = null; //assignee will remain null in case terminate actions are being taken + + String action = census.getWorkflow().getAction(); + if (config.getWfInitiateActions().contains(action)) { + 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(hierarchiesBoundaryCodes, census, jurisdictionToEmployeeMap); + } + + return assignee; + } + + /** + * 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 list of employee IDs from the higher boundary, or null if + */ + public List 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 (census.getAssigneeJurisdiction().contains(boundaryCode)) { + + for (int j = i - 1; j >= 0; j--) { + // Check the next higher level in the hierarchy (one index above the match) + String higherBoundaryCode = heirarchysBoundaryCodes[j]; + + // Fetch the employeeId from the map for the higher boundary code + List 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/BoundaryUtil.java b/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java new file mode 100644 index 00000000000..8e977cf3ccb --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/BoundaryUtil.java @@ -0,0 +1,111 @@ +package digit.util; + +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; +import org.springframework.web.client.RestTemplate; + +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 +@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; + } + + 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/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 new file mode 100644 index 00000000000..bf473f57cac --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/CommonUtil.java @@ -0,0 +1,151 @@ +package digit.util; + +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; +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.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.*; + +@Slf4j +@Component +public class CommonUtil { + + private 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 { + + // Get or create the additionalDetails as an ObjectNode + 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); + + // Convert updated ObjectNode back to a Map and set it in 'additionalDetails' + Map updatedDetails = objectMapper.convertValue(objectNode, Map.class); + return updatedDetails; + + } catch (Exception e) { + throw new CustomException(ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_CODE, ERROR_WHILE_UPDATING_ADDITIONAL_DETAILS_MESSAGE); + } + } + + 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 + * @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 + * @param planConfigId + * @param serviceBoundary + * @return + */ + public CensusSearchRequest getCensusSearchRequest(String tenantId, String planConfigId, String serviceBoundary, List initiallySetServiceBoundaries, RequestInfo requestInfo) { + Set areaCodesForSearch = new HashSet<>(); + + areaCodesForSearch.addAll(Arrays.asList(serviceBoundary.split(","))); + areaCodesForSearch.addAll(initiallySetServiceBoundaries); + + CensusSearchCriteria searchCriteria = CensusSearchCriteria.builder() + .tenantId(tenantId) + .source(planConfigId) + .areaCodes(areaCodesForSearch.stream().toList()) + .offset(0) + .limit(areaCodesForSearch.size()) + .build(); + + return CensusSearchRequest.builder().requestInfo(requestInfo).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(); + } + + 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; + } +} 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..0cb18bdb6db --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java @@ -0,0 +1,59 @@ +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 config; + + public PlanEmployeeAssignmnetUtil(RestTemplate restTemplate, Configuration configs) { + this.restTemplate = restTemplate; + this.config = configs; + } + + /** + * This method fetches plan employee assignment from plan service for provided employeeID. + * @param planEmployeeAssignmentSearchRequest request containint the planEmployeeAssignment search criteria + * @return returns planEmployeeAssignment for provided search criteria. + */ + public PlanEmployeeAssignmentResponse fetchPlanEmployeeAssignment(PlanEmployeeAssignmentSearchRequest planEmployeeAssignmentSearchRequest) { + + // Get plan employee assignment uri + StringBuilder uri = getPlanEmployeeAssignmentUri(); + + PlanEmployeeAssignmentResponse response = new PlanEmployeeAssignmentResponse(); + + try { + response = restTemplate.postForObject(uri.toString(), planEmployeeAssignmentSearchRequest, PlanEmployeeAssignmentResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_EMPLOYEE_ASSIGNMENT_DETAILS, e); + } + + return response; + } + + /** + * 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(config.getPlanServiceHost()).append(config.getPlanEmployeeAssignmentSearchEndpoint()); + } +} 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..3d9354df7a3 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/util/QueryUtil.java @@ -0,0 +1,139 @@ +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 ObjectMapper objectMapper; + + private QueryUtil(Configuration config, ObjectMapper objectMapper) { + this.config = config; + this.objectMapper = objectMapper; + } + + /** + * 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 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()) { + 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 number of placeholders to be added. + * @return a string with provided number of placeholders. + */ + 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 prepared statement list to add Ids. + * @param ids set of Ids to be added. + */ + public void addToPreparedStatement(List preparedStmtList, Set ids) { + ids.forEach(id -> { + preparedStmtList.add(id); + }); + } + + public void addToPreparedStatement(List preparedStmtList, List ids) { + ids.forEach(id -> { + preparedStmtList.add(id); + }); + } + + /** + * This method appends order by clause to the query. + * + * @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. + * + * @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); + + // Append offset + paginatedQuery.append(" OFFSET ? "); + preparedStmtList.add(config.getDefaultOffset()); + + // Append limit + paginatedQuery.append(" LIMIT ? "); + preparedStmtList.add(config.getDefaultLimit()); + + 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/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/web/controllers/CensusController.java b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java new file mode 100644 index 00000000000..8feabf4b455 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/controllers/CensusController.java @@ -0,0 +1,76 @@ +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; +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 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 create(@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 search(@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 update(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody CensusRequest body) { + 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/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java b/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java similarity index 52% rename from health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java rename to health-services/census-service/src/main/java/digit/web/models/AdditionalField.java index b8ed98d54e8..10351283cdb 100644 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java +++ b/health-services/census-service/src/main/java/digit/web/models/AdditionalField.java @@ -1,8 +1,9 @@ -package org.egov.processor.web.models; +package digit.web.models; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; -import jakarta.validation.constraints.*; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,34 +13,36 @@ import java.math.BigDecimal; /** - * Assumption + * AdditionalField */ @Validated @Data @AllArgsConstructor @NoArgsConstructor @Builder -public class Assumption { +public class AdditionalField { + @JsonProperty("id") @Valid @Size(min = 2, max = 64) private String id = null; @JsonProperty("key") + @Valid @NotNull - @Size(min = 1, max = 256) private String key = null; @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") + @NotNull private BigDecimal value = null; - @JsonProperty("active") - @NotNull - private Boolean active = true; + @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/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/Census.java b/health-services/census-service/src/main/java/digit/web/models/Census.java new file mode 100644 index 00000000000..55ed850ff18 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/Census.java @@ -0,0 +1,142 @@ +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.List; +import java.util.Map; + +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 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") + private List assignee = null; + + @JsonProperty("status") + @Size(max = 64) + private String status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("additionalFields") + @Valid + private List additionalFields = 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 + @Builder.Default + private Boolean partnerAssignmentValidationEnabled = Boolean.TRUE; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("workflow") + @Valid + private Workflow workflow; + + @JsonIgnore + private List assigneeJurisdiction; + + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; + + /** + * 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/CensusDTO.java b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java new file mode 100644 index 00000000000..02d3c7d1b2b --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusDTO.java @@ -0,0 +1,104 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; +import java.util.Map; + +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 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") + private String assignee = null; + + @JsonProperty("status") + private String status = null; + + @JsonProperty("type") + @NotNull + private String type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("additionalFields") + @Valid + private List additionalFields = null; + + @JsonProperty("effectiveFrom") + private Long effectiveFrom = null; + + @JsonProperty("effectiveTo") + private Long effectiveTo = null; + + @JsonProperty("source") + @NotNull + private String source = null; + + @JsonProperty("boundaryAncestralPath") + private String boundaryAncestralPath = null; + + @JsonIgnore + private boolean partnerAssignmentValidationEnabled; + + @JsonProperty("facilityAssigned") + private Boolean facilityAssigned = null; + + @JsonProperty("workflow") + @Valid + private Workflow workflow; + + @JsonIgnore + private List assigneeJurisdiction; + + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; +} 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/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/CensusResponse.java b/health-services/census-service/src/main/java/digit/web/models/CensusResponse.java new file mode 100644 index 00000000000..4aace9435f2 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusResponse.java @@ -0,0 +1,42 @@ +package digit.web.models; + +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/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..363da1907ae --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java @@ -0,0 +1,72 @@ +package digit.web.models; + + +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; + } + +} 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..ac595972fe7 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java @@ -0,0 +1,33 @@ +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; +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 + @NotNull + private CensusSearchCriteria censusSearchCriteria = 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 new file mode 100644 index 00000000000..8b984e06d89 --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java @@ -0,0 +1,69 @@ +package digit.web.models; + + +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; + } + } + +} 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/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/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/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..6e38c1dad95 --- /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 List 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; +} 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..ce15f091cec --- /dev/null +++ b/health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java @@ -0,0 +1,72 @@ +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; + +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("planConfigurationName") + private String planConfigurationName = 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("initiallySetServiceBoundaries") + private List initiallySetServiceBoundaries; + + @JsonProperty("facilityName") + private String facilityName = null; + + @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 new file mode 100644 index 00000000000..fcf43df5960 --- /dev/null +++ b/health-services/census-service/src/main/resources/application.properties @@ -0,0 +1,82 @@ +server.contextPath=/census-service +server.servlet.context-path=/census-service +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=false + +# 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 +spring.kafka.producer.properties.max.request.size=3000000 + +# 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 + +#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 + +#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 +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 + + +#Pagination config +census.default.offset=0 +census.default.limit=10 + +resource.config.consumer.census.create.topic=resource-census-create-topic +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'} +workflow.restricted.roles={'ROOT_FACILITY_CATCHMENT_MAPPER','FACILITY_CATCHMENT_MAPPER'} \ 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/resource-estimation-service/src/main/resources/db/migrate.sh b/health-services/census-service/src/main/resources/db/migrate.sh similarity index 67% rename from health-services/resource-estimation-service/src/main/resources/db/migrate.sh rename to health-services/census-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/census-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/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..cf80c461292 --- /dev/null +++ b/health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql @@ -0,0 +1,36 @@ +-- Table: census +CREATE TABLE census ( + 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) 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, + 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), + 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/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..9887f73656f --- /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" 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 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 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/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/facility/pom.xml b/health-services/facility/pom.xml index 1eb0038656a..b0a2d7d2cad 100644 --- a/health-services/facility/pom.xml +++ b/health-services/facility/pom.xml @@ -45,12 +45,12 @@ org.egov.common health-services-common - 1.0.17-SNAPSHOT + 1.0.20-SNAPSHOT org.egov.common health-services-models - 1.0.20-SNAPSHOT + 1.0.23-SNAPSHOT compile diff --git a/health-services/facility/src/main/java/org/egov/facility/repository/FacilityRepository.java b/health-services/facility/src/main/java/org/egov/facility/repository/FacilityRepository.java index 482ac988b98..2d6b0fd9a6a 100644 --- a/health-services/facility/src/main/java/org/egov/facility/repository/FacilityRepository.java +++ b/health-services/facility/src/main/java/org/egov/facility/repository/FacilityRepository.java @@ -5,6 +5,7 @@ import org.egov.common.data.query.builder.SelectQueryBuilder; import org.egov.common.data.query.exception.QueryBuilderException; import org.egov.common.data.repository.GenericRepository; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.facility.Facility; import org.egov.common.models.facility.FacilitySearch; import org.egov.common.producer.Producer; @@ -23,6 +24,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import static org.egov.common.utils.CommonUtils.constructTotalCountCTEAndReturnResult; import static org.egov.common.utils.CommonUtils.getIdMethod; @Repository @@ -35,7 +37,7 @@ public FacilityRepository(Producer producer, NamedParameterJdbcTemplate namedPar facilityRowMapper, Optional.of("facility")); } - public List findById(List ids, String columnName, Boolean includeDeleted) { + public SearchResponse findById(List ids, String columnName, Boolean includeDeleted) { List objFound = findInCache(ids); if (!includeDeleted) { objFound = objFound.stream() @@ -48,7 +50,7 @@ public List findById(List ids, String columnName, Boolean incl .map(obj -> (String) ReflectionUtils.invokeMethod(idMethod, obj)) .collect(Collectors.toList())); if (ids.isEmpty()) { - return objFound; + return SearchResponse.builder().response(objFound).build(); } } @@ -61,10 +63,12 @@ public List findById(List ids, String columnName, Boolean incl objFound.addAll(this.namedParameterJdbcTemplate.query(query, paramMap, this.rowMapper)); putInCache(objFound); - return objFound; + + /*The totalCount is being set automatically through the builder method.*/ + return SearchResponse.builder().response(objFound).build(); } - public List find(FacilitySearch searchObject, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted) throws QueryBuilderException { + public SearchResponse find(FacilitySearch searchObject, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted) throws QueryBuilderException { String query = "SELECT *, a.id as aid,a.tenantid as atenantid, a.clientreferenceid as aclientreferenceid FROM facility f LEFT JOIN address a ON f.addressid = a.id"; Map paramsMap = new HashMap<>(); List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); @@ -83,12 +87,17 @@ public List find(FacilitySearch searchObject, Integer limit, Integer o if (lastChangedSince != null) { query = query + "and lastModifiedTime>=:lastModifiedTime "; } - query = query + "ORDER BY f.id ASC LIMIT :limit OFFSET :offset"; paramsMap.put("tenantId", tenantId); paramsMap.put("isDeleted", includeDeleted); paramsMap.put("lastModifiedTime", lastChangedSince); + + Long totalCount = constructTotalCountCTEAndReturnResult(query, paramsMap, this.namedParameterJdbcTemplate); + + query = query + " LIMIT :limit OFFSET :offset"; paramsMap.put("limit", limit); paramsMap.put("offset", offset); - return this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); + List facilities = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); + + return SearchResponse.builder().response(facilities).totalCount(totalCount).build(); } } diff --git a/health-services/facility/src/main/java/org/egov/facility/repository/rowmapper/FacilityRowMapper.java b/health-services/facility/src/main/java/org/egov/facility/repository/rowmapper/FacilityRowMapper.java index 3517293adcf..73276c91d88 100644 --- a/health-services/facility/src/main/java/org/egov/facility/repository/rowmapper/FacilityRowMapper.java +++ b/health-services/facility/src/main/java/org/egov/facility/repository/rowmapper/FacilityRowMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.facility.Address; import org.egov.common.models.facility.AddressType; diff --git a/health-services/facility/src/main/java/org/egov/facility/service/FacilityService.java b/health-services/facility/src/main/java/org/egov/facility/service/FacilityService.java index 769aae4b725..76ceb67033d 100644 --- a/health-services/facility/src/main/java/org/egov/facility/service/FacilityService.java +++ b/health-services/facility/src/main/java/org/egov/facility/service/FacilityService.java @@ -1,13 +1,16 @@ package org.egov.facility.service; +import io.micrometer.core.instrument.search.Search; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.facility.Facility; import org.egov.common.models.facility.FacilityBulkRequest; import org.egov.common.models.facility.FacilityRequest; import org.egov.common.models.facility.FacilitySearchRequest; +import org.egov.common.models.project.ProjectBeneficiary; import org.egov.common.validator.Validator; import org.egov.facility.config.FacilityConfiguration; import org.egov.facility.repository.FacilityRepository; @@ -173,23 +176,27 @@ public List delete(FacilityBulkRequest request, boolean isBulk) { return validEntities; } - public List search(FacilitySearchRequest facilitySearchRequest, - Integer limit, - Integer offset, - String tenantId, - Long lastChangedSince, - Boolean includeDeleted) throws Exception { + public SearchResponse search(FacilitySearchRequest facilitySearchRequest, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws Exception { log.info("starting search method for facility"); String idFieldName = getIdFieldName(facilitySearchRequest.getFacility()); if (isSearchByIdOnly(facilitySearchRequest.getFacility(), idFieldName)) { List ids = (List) ReflectionUtils.invokeMethod(getIdMethod(Collections .singletonList(facilitySearchRequest.getFacility())), facilitySearchRequest.getFacility()); - return facilityRepository.findById(ids, idFieldName, includeDeleted).stream() + SearchResponse searchResponse = facilityRepository.findById(ids, idFieldName, includeDeleted); + List facilities = searchResponse.getResponse().stream() .filter(lastChangedSince(lastChangedSince)) .filter(havingTenantId(tenantId)) .filter(includeDeleted(includeDeleted)) .collect(Collectors.toList()); + searchResponse.setResponse(facilities); + + return searchResponse; } log.info("completed search method for facility"); diff --git a/health-services/facility/src/main/java/org/egov/facility/validator/FNonExistentValidator.java b/health-services/facility/src/main/java/org/egov/facility/validator/FNonExistentValidator.java index c666d6b3264..2857a038490 100644 --- a/health-services/facility/src/main/java/org/egov/facility/validator/FNonExistentValidator.java +++ b/health-services/facility/src/main/java/org/egov/facility/validator/FNonExistentValidator.java @@ -50,7 +50,7 @@ public Map> validate(FacilityBulkRequest request) { Map eMap = getIdToObjMap(validEntities, idMethod); if (!eMap.isEmpty()) { List entityIds = new ArrayList<>(eMap.keySet()); - List existingEntities = facilityRepository.findById(entityIds, getIdFieldName(idMethod), false); + List existingEntities = facilityRepository.findById(entityIds, getIdFieldName(idMethod), false).getResponse(); List nonExistentEntities = checkNonExistentEntities(eMap, existingEntities, idMethod); nonExistentEntities.forEach(facility -> { diff --git a/health-services/facility/src/main/java/org/egov/facility/validator/FRowVersionValidator.java b/health-services/facility/src/main/java/org/egov/facility/validator/FRowVersionValidator.java index df76ac89fe4..17adda2b3f2 100644 --- a/health-services/facility/src/main/java/org/egov/facility/validator/FRowVersionValidator.java +++ b/health-services/facility/src/main/java/org/egov/facility/validator/FRowVersionValidator.java @@ -47,7 +47,7 @@ public Map> validate(FacilityBulkRequest request) { Map eMap = getIdToObjMap(validEntities, idMethod); if (!eMap.isEmpty()) { List entityIds = new ArrayList<>(eMap.keySet()); - List existingEntities = facilityRepository.findById(entityIds, getIdFieldName(idMethod), false); + List existingEntities = facilityRepository.findById(entityIds, getIdFieldName(idMethod), false).getResponse(); List entitiesWithMismatchedRowVersion = getEntitiesWithMismatchedRowVersion(eMap, existingEntities, idMethod); entitiesWithMismatchedRowVersion.forEach(facility -> { diff --git a/health-services/facility/src/main/java/org/egov/facility/web/controllers/FacilityApiController.java b/health-services/facility/src/main/java/org/egov/facility/web/controllers/FacilityApiController.java index 3ca37071ca8..67de20615b1 100644 --- a/health-services/facility/src/main/java/org/egov/facility/web/controllers/FacilityApiController.java +++ b/health-services/facility/src/main/java/org/egov/facility/web/controllers/FacilityApiController.java @@ -8,6 +8,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import org.egov.common.contract.response.ResponseInfo; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.core.URLParams; import org.egov.common.models.facility.Facility; import org.egov.common.models.facility.FacilityBulkRequest; @@ -111,7 +112,7 @@ public ResponseEntity facilityV1SearchPost( @Valid @ModelAttribute URLParams urlParams, @ApiParam(value = "Details for existing facility.", required = true) @Valid @RequestBody FacilitySearchRequest request ) throws Exception { - List facilities = facilityService.search( + SearchResponse searchResponse = facilityService.search( request, urlParams.getLimit(), urlParams.getOffset(), @@ -119,7 +120,9 @@ public ResponseEntity facilityV1SearchPost( urlParams.getLastChangedSince(), urlParams.getIncludeDeleted()); FacilityBulkResponse response = FacilityBulkResponse.builder().responseInfo(ResponseInfoFactory - .createResponseInfo(request.getRequestInfo(), true)).facilities(facilities).build(); + .createResponseInfo(request.getRequestInfo(), true)) + .facilities(searchResponse.getResponse()) + .totalCount(searchResponse.getTotalCount()).build(); return ResponseEntity.status(HttpStatus.OK).body(response); } diff --git a/health-services/facility/src/test/java/org/egov/facility/validator/NonExistentEntityValidatorTest.java b/health-services/facility/src/test/java/org/egov/facility/validator/NonExistentEntityValidatorTest.java index a6e8c05f7c1..06955011bc0 100644 --- a/health-services/facility/src/test/java/org/egov/facility/validator/NonExistentEntityValidatorTest.java +++ b/health-services/facility/src/test/java/org/egov/facility/validator/NonExistentEntityValidatorTest.java @@ -1,8 +1,10 @@ package org.egov.facility.validator; import org.egov.common.models.Error; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.facility.Facility; import org.egov.common.models.facility.FacilityBulkRequest; +import org.egov.common.models.household.Household; import org.egov.facility.helper.FacilityBulkRequestTestBuilder; import org.egov.facility.helper.FacilityTestBuilder; import org.egov.facility.repository.FacilityRepository; @@ -37,7 +39,7 @@ class NonExistentEntityValidatorTest { void shouldAddToErrorDetailsMapIfEntityNotFound() { FacilityBulkRequest request = FacilityBulkRequestTestBuilder.builder().withFacilityId("some-id").withRequestInfo().build(); when(facilityRepository.findById(anyList(), anyString(), anyBoolean())) - .thenReturn(Collections.emptyList()); + .thenReturn(SearchResponse.builder().build()); Map> errorDetailsMap = fNonExistentValidator.validate(request); @@ -49,7 +51,9 @@ void shouldAddToErrorDetailsMapIfEntityNotFound() { void shouldNotAddToErrorDetailsMapIfEntityFound() { FacilityBulkRequest request = FacilityBulkRequestTestBuilder.builder().withFacilityId("some-id").withRequestInfo().build(); when(facilityRepository.findById(anyList(), anyString(), anyBoolean())) - .thenReturn(Collections.singletonList(FacilityTestBuilder.builder().withFacility().withId("some-id").build())); + .thenReturn(SearchResponse.builder(). + response(Collections.singletonList(FacilityTestBuilder.builder().withFacility().withId("some-id").build())) + .build()); Map> errorDetailsMap = fNonExistentValidator.validate(request); diff --git a/health-services/facility/src/test/java/org/egov/facility/validator/RowVersionValidatorTest.java b/health-services/facility/src/test/java/org/egov/facility/validator/RowVersionValidatorTest.java index 1f44a89f94a..52f92421c49 100644 --- a/health-services/facility/src/test/java/org/egov/facility/validator/RowVersionValidatorTest.java +++ b/health-services/facility/src/test/java/org/egov/facility/validator/RowVersionValidatorTest.java @@ -1,6 +1,7 @@ package org.egov.facility.validator; import org.egov.common.models.Error; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.facility.Facility; import org.egov.common.models.facility.FacilityBulkRequest; import org.egov.facility.helper.FacilityBulkRequestTestBuilder; @@ -39,7 +40,9 @@ void shouldAddToErrorDetailsIfRowVersionMismatchFound() { FacilityBulkRequest request = FacilityBulkRequestTestBuilder.builder().withFacilityId("some-id").withRequestInfo().build(); request.getFacilities().get(0).setRowVersion(2); when(facilityRepository.findById(anyList(), anyString(), anyBoolean())) - .thenReturn(Collections.singletonList(FacilityTestBuilder.builder().withFacility().withId("some-id").build())); + .thenReturn(SearchResponse.builder() + .response(Collections.singletonList(FacilityTestBuilder.builder().withFacility().withId("some-id").build())) + .build()); Map> errorDetailsMap = fRowVersionValidator.validate(request); @@ -51,7 +54,8 @@ void shouldAddToErrorDetailsIfRowVersionMismatchFound() { void shouldNotAddToErrorDetailsIfRowVersionSimilar() { FacilityBulkRequest request = FacilityBulkRequestTestBuilder.builder().withFacilityId("some-id").withRequestInfo().build(); when(facilityRepository.findById(anyList(), anyString(), anyBoolean())) - .thenReturn(Collections.singletonList(FacilityTestBuilder.builder().withFacility().withId("some-id").build())); + .thenReturn(SearchResponse.builder() + .response(Collections.singletonList(FacilityTestBuilder.builder().withFacility().withId("some-id").build())).build()); Map> errorDetailsMap = fRowVersionValidator.validate(request); diff --git a/health-services/individual/pom.xml b/health-services/individual/pom.xml index 84ca10da8d3..d99c514e51b 100644 --- a/health-services/individual/pom.xml +++ b/health-services/individual/pom.xml @@ -53,12 +53,12 @@ org.egov.common health-services-common - 1.0.18-SNAPSHOT + 1.0.19-SNAPSHOT org.egov.common health-services-models - 1.0.20-SNAPSHOT + 1.0.22-SNAPSHOT compile diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index e08aeef5d17..703b5521652 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -264,14 +264,14 @@ private String getQueryForIndividual(IndividualSearch searchObject, Integer limi query = query + "AND lastModifiedTime>=:lastModifiedTime "; } if (searchObject.getRoleCodes() != null && !searchObject.getRoleCodes().isEmpty()) { - query = query + "AND roles @> '["; + query = query + "AND ("; for (int i = 0; i < searchObject.getRoleCodes().size(); i++) { - query = query + "{\"code\": \"" + searchObject.getRoleCodes().get(i) + "\"}"; + query = query + "roles @> '[{\"code\": \"" + searchObject.getRoleCodes().get(i) + "\"}]'"; if (i != searchObject.getRoleCodes().size() - 1) { - query = query + ","; + query = query + " OR "; // Add OR between conditions } } - query = query + "]' "; + query = query + ") "; } if (searchObject.getUsername() != null) { diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/AddressRowMapper.java b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/AddressRowMapper.java index 48396c74988..fe50b9c2d6c 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/AddressRowMapper.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/AddressRowMapper.java @@ -1,14 +1,14 @@ package org.egov.individual.repository.rowmapper; -import digit.models.coremodels.AuditDetails; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.egov.common.contract.models.AuditDetails; +import org.egov.common.models.core.Boundary; import org.egov.common.models.individual.Address; import org.egov.common.models.individual.AddressType; -import org.egov.common.models.core.Boundary; import org.springframework.jdbc.core.RowMapper; -import java.sql.ResultSet; -import java.sql.SQLException; - public class AddressRowMapper implements RowMapper
{ @Override public Address mapRow(ResultSet resultSet, int i) throws SQLException { diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IdentifierRowMapper.java b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IdentifierRowMapper.java index 4cdbc036fa9..89244c90588 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IdentifierRowMapper.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IdentifierRowMapper.java @@ -1,12 +1,12 @@ package org.egov.individual.repository.rowmapper; -import digit.models.coremodels.AuditDetails; -import org.egov.common.models.individual.Identifier; -import org.springframework.jdbc.core.RowMapper; - import java.sql.ResultSet; import java.sql.SQLException; +import org.egov.common.contract.models.AuditDetails; +import org.egov.common.models.individual.Identifier; +import org.springframework.jdbc.core.RowMapper; + public class IdentifierRowMapper implements RowMapper { @Override public Identifier mapRow(ResultSet resultSet, int i) throws SQLException { diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IndividualRowMapper.java b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IndividualRowMapper.java index be0f5387bd4..26ea439cd69 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IndividualRowMapper.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/IndividualRowMapper.java @@ -6,8 +6,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; -import digit.models.coremodels.user.enums.UserType; +import org.egov.common.contract.models.AuditDetails; +import org.egov.common.contract.user.enums.UserType; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.individual.BloodGroup; import org.egov.common.models.individual.Gender; diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/SkillRowMapper.java b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/SkillRowMapper.java index c658d9e98e6..bacdae2e64a 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/SkillRowMapper.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/rowmapper/SkillRowMapper.java @@ -1,12 +1,12 @@ package org.egov.individual.repository.rowmapper; -import digit.models.coremodels.AuditDetails; -import org.egov.common.models.individual.Skill; -import org.springframework.jdbc.core.RowMapper; - import java.sql.ResultSet; import java.sql.SQLException; +import org.egov.common.contract.models.AuditDetails; +import org.egov.common.models.individual.Skill; +import org.springframework.jdbc.core.RowMapper; + public class SkillRowMapper implements RowMapper { @Override public Skill mapRow(ResultSet resultSet, int i) throws SQLException { diff --git a/health-services/individual/src/main/java/org/egov/individual/service/EnrichmentService.java b/health-services/individual/src/main/java/org/egov/individual/service/EnrichmentService.java index 7ea9daff08e..45c972c644e 100644 --- a/health-services/individual/src/main/java/org/egov/individual/service/EnrichmentService.java +++ b/health-services/individual/src/main/java/org/egov/individual/service/EnrichmentService.java @@ -9,8 +9,8 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import digit.models.coremodels.AuditDetails; import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.contract.request.RequestInfo; import org.egov.common.models.individual.Address; import org.egov.common.models.individual.Identifier; diff --git a/health-services/individual/src/main/java/org/egov/individual/service/NotificationService.java b/health-services/individual/src/main/java/org/egov/individual/service/NotificationService.java index 8cb45638e6c..88767bb5bb4 100644 --- a/health-services/individual/src/main/java/org/egov/individual/service/NotificationService.java +++ b/health-services/individual/src/main/java/org/egov/individual/service/NotificationService.java @@ -1,11 +1,15 @@ package org.egov.individual.service; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.jayway.jsonpath.JsonPath; -import digit.models.coremodels.RequestInfoWrapper; -import digit.models.coremodels.SMSRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.models.RequestInfoWrapper; import org.egov.common.contract.request.RequestInfo; +import org.egov.common.models.core.SMSRequest; import org.egov.common.models.individual.IndividualRequest; import org.egov.individual.Constants; import org.egov.individual.config.IndividualProperties; @@ -15,10 +19,6 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static org.egov.individual.Constants.INDIVIDUAL_CREATE_LOCALIZATION_CODE; import static org.egov.individual.Constants.INDIVIDUAL_UPDATE_LOCALIZATION_CODE; diff --git a/health-services/libraries/health-services-common/pom.xml b/health-services/libraries/health-services-common/pom.xml index 8f5e0d4fae9..5bdd15176c3 100644 --- a/health-services/libraries/health-services-common/pom.xml +++ b/health-services/libraries/health-services-common/pom.xml @@ -8,7 +8,7 @@ health-services-common jar health-services-common - 1.0.18-SNAPSHOT + 1.0.20-SNAPSHOT Shared classes among services @@ -85,11 +85,6 @@ org.springframework.boot spring-boot-starter-jdbc - - org.egov.services - digit-models - 1.0.0-SNAPSHOT - org.egov.services tracer @@ -120,7 +115,13 @@ org.egov.common health-services-models - 1.0.20-SNAPSHOT + 1.0.23-dev-SNAPSHOT + compile + + + org.egov + mdms-client + 2.9.0-SNAPSHOT compile diff --git a/health-services/libraries/health-services-common/src/main/java/org/egov/common/data/repository/GenericRepository.java b/health-services/libraries/health-services-common/src/main/java/org/egov/common/data/repository/GenericRepository.java index 537a82400cc..269a15e449d 100644 --- a/health-services/libraries/health-services-common/src/main/java/org/egov/common/data/repository/GenericRepository.java +++ b/health-services/libraries/health-services-common/src/main/java/org/egov/common/data/repository/GenericRepository.java @@ -4,6 +4,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.data.query.builder.SelectQueryBuilder; import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.models.core.SearchResponse; import org.egov.common.producer.Producer; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; @@ -23,6 +24,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static org.egov.common.utils.CommonUtils.constructTotalCountCTEAndReturnResult; import static org.egov.common.utils.CommonUtils.getIdMethod; import static org.egov.common.utils.CommonUtils.getMethod; import static org.egov.common.utils.CommonUtils.getObjClass; @@ -236,6 +238,52 @@ public void putInCache(List objects, String key) { cacheByKey(objects, key); } + /** + * Finds entities based on search criteria, also returns the count of entities found. + * + * @param searchObject The object containing search criteria. + * @param limit The maximum number of entities to return. + * @param offset The offset for pagination. + * @param tenantId The tenant ID to filter entities. + * @param lastChangedSince The timestamp for last modified entities. + * @param includeDeleted Flag to include deleted entities in the search result. + * @return A list of entities found based on the search criteria with total count. + * @throws QueryBuilderException If an error occurs while building the query. + */ + public SearchResponse findWithCount(Object searchObject, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws QueryBuilderException { + String query = selectQueryBuilder.build(searchObject, tableName); + query += " AND tenantId=:tenantId "; + if (query.contains(tableName + " AND")) { + query = query.replace(tableName + " AND", tableName + " WHERE"); + } + if (Boolean.FALSE.equals(includeDeleted)) { + query += "AND isDeleted=:isDeleted "; + } + if (lastChangedSince != null) { + query += "AND lastModifiedTime>=:lastModifiedTime "; + } + query += "ORDER BY id ASC"; + Map paramsMap = selectQueryBuilder.getParamsMap(); + paramsMap.put("tenantId", tenantId); + paramsMap.put("isDeleted", includeDeleted); + paramsMap.put("lastModifiedTime", lastChangedSince); + + Long totalCount = constructTotalCountCTEAndReturnResult(query, paramsMap, namedParameterJdbcTemplate); + + query += " LIMIT :limit OFFSET :offset"; + paramsMap.put("limit", limit); + paramsMap.put("offset", offset); + + List resultantList = namedParameterJdbcTemplate.query(query, paramsMap, rowMapper); + + return SearchResponse.builder().response(resultantList).totalCount(totalCount).build(); + } + /** * Finds entities based on search criteria. * diff --git a/health-services/libraries/health-services-common/src/main/java/org/egov/common/helper/AuditDetailsTestBuilder.java b/health-services/libraries/health-services-common/src/main/java/org/egov/common/helper/AuditDetailsTestBuilder.java index 984882b8310..efce9048d3f 100644 --- a/health-services/libraries/health-services-common/src/main/java/org/egov/common/helper/AuditDetailsTestBuilder.java +++ b/health-services/libraries/health-services-common/src/main/java/org/egov/common/helper/AuditDetailsTestBuilder.java @@ -1,6 +1,6 @@ package org.egov.common.helper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; public class AuditDetailsTestBuilder { private AuditDetails.AuditDetailsBuilder builder; diff --git a/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/IdGenService.java b/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/IdGenService.java index c693e8f6788..25b167a227d 100644 --- a/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/IdGenService.java +++ b/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/IdGenService.java @@ -1,9 +1,9 @@ package org.egov.common.service; -import digit.models.coremodels.IdGenerationRequest; -import digit.models.coremodels.IdGenerationResponse; -import digit.models.coremodels.IdRequest; -import digit.models.coremodels.IdResponse; +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.common.http.client.ServiceRequestClient; import org.egov.tracer.model.CustomException; diff --git a/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/UserService.java b/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/UserService.java index 77be02a6504..204e7fa6fdb 100644 --- a/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/UserService.java +++ b/health-services/libraries/health-services-common/src/main/java/org/egov/common/service/UserService.java @@ -1,7 +1,7 @@ package org.egov.common.service; -import digit.models.coremodels.UserDetailResponse; -import digit.models.coremodels.UserSearchRequest; +import org.egov.common.contract.user.UserDetailResponse; +import org.egov.common.contract.user.UserSearchRequest; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.User; import org.egov.common.http.client.ServiceRequestClient; diff --git a/health-services/libraries/health-services-common/src/main/java/org/egov/common/utils/CommonUtils.java b/health-services/libraries/health-services-common/src/main/java/org/egov/common/utils/CommonUtils.java index 927a05044ca..c72e7a7563c 100644 --- a/health-services/libraries/health-services-common/src/main/java/org/egov/common/utils/CommonUtils.java +++ b/health-services/libraries/health-services-common/src/main/java/org/egov/common/utils/CommonUtils.java @@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.egov.common.ds.Tuple; diff --git a/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObject.java b/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObject.java index 1aa90f6ba01..68cdf3b6981 100644 --- a/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObject.java +++ b/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObject.java @@ -1,6 +1,6 @@ package org.egov.common.helpers; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObjectWithClientRefId.java b/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObjectWithClientRefId.java index 268d32b9cd0..3f54d554a32 100644 --- a/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObjectWithClientRefId.java +++ b/health-services/libraries/health-services-common/src/test/java/org/egov/common/helpers/SomeObjectWithClientRefId.java @@ -1,6 +1,6 @@ package org.egov.common.helpers; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/health-services/libraries/health-services-common/src/test/java/org/egov/common/utils/CommonUtilsTest.java b/health-services/libraries/health-services-common/src/test/java/org/egov/common/utils/CommonUtilsTest.java index b50d359d969..e2f01d42f18 100644 --- a/health-services/libraries/health-services-common/src/test/java/org/egov/common/utils/CommonUtilsTest.java +++ b/health-services/libraries/health-services-common/src/test/java/org/egov/common/utils/CommonUtilsTest.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import lombok.Builder; import lombok.Data; import org.egov.common.contract.request.RequestInfo; diff --git a/health-services/libraries/health-services-models/pom.xml b/health-services/libraries/health-services-models/pom.xml index 6ca95c3fe47..dc4e4c878ca 100644 --- a/health-services/libraries/health-services-models/pom.xml +++ b/health-services/libraries/health-services-models/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.egov.common health-services-models - 1.0.21-SNAPSHOT + 1.0.23-SNAPSHOT 17 ${java.version} @@ -24,11 +24,6 @@ jackson-datatype-jsr310 2.14.2 - - org.egov.services - digit-models - 1.0.0-SNAPSHOT - org.egov.services tracer diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/Boundary.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/Boundary.java index f3632bb819b..434d2c52f9e 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/Boundary.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/Boundary.java @@ -1,10 +1,9 @@ package org.egov.common.models.core; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovModel.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovModel.java index f68ea5cea75..4c47b940b45 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovModel.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovModel.java @@ -1,18 +1,17 @@ package org.egov.common.models.core; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; +import org.egov.common.contract.models.AuditDetails; @Data @NoArgsConstructor diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovOfflineModel.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovOfflineModel.java index e816f6cd3ce..d9a338d5cde 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovOfflineModel.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/EgovOfflineModel.java @@ -1,15 +1,14 @@ package org.egov.common.models.core; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; +import org.egov.common.contract.models.AuditDetails; @Data @NoArgsConstructor diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/SMSRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/SMSRequest.java new file mode 100644 index 00000000000..74371122d5f --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/SMSRequest.java @@ -0,0 +1,18 @@ +package org.egov.common.models.core; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class SMSRequest { + private String mobileNumber; + private String message; +} \ No newline at end of file diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/AdditionalFields.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/AdditionalFields.java index 3ea950184ae..e94f3aeab71 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/AdditionalFields.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/AdditionalFields.java @@ -1,19 +1,19 @@ package org.egov.common.models.facility; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * AdditionalFields */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Facility.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Facility.java index 3c4d8ba3bf9..0a7a92bf03f 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Facility.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Facility.java @@ -1,21 +1,16 @@ package org.egov.common.models.facility; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.egov.common.models.core.EgovOfflineModel; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * Facility */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkRequest.java index 36c96818a5b..e8dd5de95bf 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkRequest.java @@ -1,19 +1,19 @@ package org.egov.common.models.facility; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * FacilityBulkRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkResponse.java index d58d67eba90..e1550174657 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityBulkResponse.java @@ -1,40 +1,55 @@ package org.egov.common.models.facility; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** - * FacilityResponse + * Represents a bulk response for facilities, including response metadata and a list of facilities. */ @Validated - - @Data @NoArgsConstructor @AllArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) public class FacilityBulkResponse { + + /** + * Metadata about the API response, including request details and status. + */ @JsonProperty("ResponseInfo") @NotNull @Valid private org.egov.common.contract.response.ResponseInfo responseInfo = null; + /** + * List of facilities returned in the response. + */ @JsonProperty("Facilities") @Valid private List facilities = null; + /** + * Total number of facilities in the response, defaults to 0. + */ + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + /** + * Adds a single facility to the list and returns the updated response. + */ public FacilityBulkResponse addFacilityItem(Facility facilityItem) { if (this.facilities == null) { this.facilities = new ArrayList<>(); @@ -42,6 +57,4 @@ public FacilityBulkResponse addFacilityItem(Facility facilityItem) { this.facilities.add(facilityItem); return this; } - } - diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityRequest.java index be7a61eb30d..4ad6fd4f358 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * FacilityRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityResponse.java index d0642700db3..c211f19fd5c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilityResponse.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * FacilityResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilitySearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilitySearchRequest.java index 6a6924bea67..e079450fc4a 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilitySearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/FacilitySearchRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * FacilitySearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/TenantRole.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/TenantRole.java index d706a86fcff..9294e57417d 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/TenantRole.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/TenantRole.java @@ -1,19 +1,19 @@ package org.egov.common.models.facility; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/UserInfo.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/UserInfo.java index a534fb37cfb..11deb8cbd48 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/UserInfo.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/UserInfo.java @@ -1,19 +1,19 @@ package org.egov.common.models.facility; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/AdditionalFields.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/AdditionalFields.java index c38b8ef5b97..a04df2e6c06 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/AdditionalFields.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/AdditionalFields.java @@ -1,19 +1,19 @@ package org.egov.common.models.household; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * AdditionalFields */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Field.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Field.java index c948934f9c9..ef02f0c2d95 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Field.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Field.java @@ -1,10 +1,9 @@ package org.egov.common.models.household; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java index 2452054c4f8..63c982ff07f 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java @@ -8,8 +8,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; -import org.hibernate.validator.constraints.Range; import org.egov.common.models.core.EgovOfflineModel; +import org.hibernate.validator.constraints.Range; import org.springframework.validation.annotation.Validated; /** diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkRequest.java index cf1b86cc6d2..77e8498cd3e 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.household; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * HouseholdRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkResponse.java index 3646ac55627..26b8a85f21c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdBulkResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.household; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * HouseholdResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMember.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMember.java index c7e016e117d..6e697513777 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMember.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMember.java @@ -1,22 +1,16 @@ package org.egov.common.models.household; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.egov.common.models.core.EgovOfflineModel; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * A representation of a household member (already registered as an individual) */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkRequest.java index 9e45a1f496c..a16cb00a03b 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkRequest.java @@ -1,19 +1,19 @@ package org.egov.common.models.household; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * HouseholdMemberRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkResponse.java index 529336e2052..df83a9b6221 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberBulkResponse.java @@ -1,18 +1,18 @@ package org.egov.common.models.household; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * HouseholdMemberResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberRequest.java index afe2b3a35a2..636be1ea09b 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * HouseholdMemberRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberResponse.java index 4439b053fa2..c00408c8b1f 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberResponse.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * HouseholdMemberResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberSearchRequest.java index 1827c58c249..97c1f03edf5 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdMemberSearchRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * HouseholdMemberSearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdRequest.java index 2f97fff1203..bbde10101e2 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * HouseholdRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdResponse.java index 8659cc34bbf..ca82278de1d 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdResponse.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * HouseholdResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearchRequest.java index 57e5377b5ca..3a43464d905 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearchRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * HouseholdSearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/TenantRole.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/TenantRole.java index 9a37607d2ca..a75a0cc4173 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/TenantRole.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/TenantRole.java @@ -1,19 +1,19 @@ package org.egov.common.models.household; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/UserInfo.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/UserInfo.java index 648f7640cbe..4b29d02edf4 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/UserInfo.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/UserInfo.java @@ -1,19 +1,19 @@ package org.egov.common.models.household; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/AdditionalFields.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/AdditionalFields.java index 2546f7f417e..f7a4703279c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/AdditionalFields.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/AdditionalFields.java @@ -1,19 +1,19 @@ package org.egov.common.models.individual; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * AdditionalFields */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Address.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Address.java index a6a6a067449..09e5894a88c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Address.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Address.java @@ -2,21 +2,20 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.DecimalMax; +import jakarta.validation.constraints.DecimalMin; +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.models.core.Boundary; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.DecimalMax; -import jakarta.validation.constraints.DecimalMin; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * Representation of a address. Individual APIs may choose to extend from this using allOf if more details needed to be added in their case. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Field.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Field.java index c6b33f09776..86d86e5c4e7 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Field.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Field.java @@ -1,10 +1,9 @@ package org.egov.common.models.individual; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Identifier.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Identifier.java index 213a67a9446..f07b5909530 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Identifier.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Identifier.java @@ -2,17 +2,16 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * Identifier */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Individual.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Individual.java index e045ff1fea5..1fb620908bc 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Individual.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Individual.java @@ -1,26 +1,23 @@ package org.egov.common.models.individual; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +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 lombok.experimental.SuperBuilder; import org.egov.common.models.core.EgovOfflineModel; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - /** * A representation of an Individual. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkRequest.java index 4810780d4e7..59e954bcd5b 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.individual; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * IndividualRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkResponse.java index 5a185cbaf8d..60647504677 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.individual; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,17 +14,11 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** - * IndividualResponse + * IndividualBulkResponse represents the response structure for bulk operations related to individuals. + * It encapsulates the response information, total count of individuals, and a list of individual objects. */ @Validated - - @Data @NoArgsConstructor @AllArgsConstructor @@ -27,20 +26,35 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class IndividualBulkResponse { + /** + * Metadata about the API response, including details like request status and other information. + */ @JsonProperty("ResponseInfo") @NotNull @Valid private ResponseInfo responseInfo = null; + /** + * Total count of individual records in the response, defaults to 0 if not specified. + */ @JsonProperty("TotalCount") @Valid @Builder.Default private Long totalCount = 0L; - + + /** + * List of individual records returned in the response. + */ @JsonProperty("Individual") @Valid private List individual = null; + /** + * Adds a single individual record to the list and returns the updated response. + * + * @param individualItem The individual record to add to the list. + * @return The updated IndividualBulkResponse instance. + */ public IndividualBulkResponse addIndividualItem(Individual individualItem) { if (this.individual == null) { this.individual = new ArrayList<>(); @@ -48,6 +62,4 @@ public IndividualBulkResponse addIndividualItem(Individual individualItem) { this.individual.add(individualItem); return this; } - } - diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualRequest.java index c8b7927e036..74d61e71bcb 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * IndividualRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualResponse.java index e782b4af9a8..20b21747fe1 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualResponse.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * IndividualResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Name.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Name.java index 7a75ea01913..895ed4c19f7 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Name.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Name.java @@ -2,14 +2,13 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.constraints.Size; - /** * Name */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Skill.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Skill.java index 58b905a8522..682ddccdedd 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Skill.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/Skill.java @@ -2,17 +2,16 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * Identifier */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/UserDetails.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/UserDetails.java index ea435d9fac9..07ad2e70c02 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/UserDetails.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/UserDetails.java @@ -1,18 +1,18 @@ package org.egov.common.models.individual; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.user.enums.UserType; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.egov.common.contract.user.enums.UserType; import org.egov.common.models.core.Role; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Size; -import java.util.List; - @Data @AllArgsConstructor @NoArgsConstructor diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/AdditionalFields.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/AdditionalFields.java index 87d1cd3ea63..7ae3f2fcc85 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/AdditionalFields.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/AdditionalFields.java @@ -1,19 +1,19 @@ package org.egov.common.models.product; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * AdditionalFields */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Field.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Field.java index f27a52cf429..8c20a6f160b 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Field.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Field.java @@ -1,10 +1,9 @@ package org.egov.common.models.product; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Product.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Product.java index afa12e20be2..71d61bde9bc 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Product.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/Product.java @@ -2,19 +2,15 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.egov.common.models.core.EgovModel; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * Product */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductRequest.java index 5b209a65ff9..2381054bb30 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.product; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * ProductRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductResponse.java index 52865f39251..871fcecfe3e 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.product; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * ProductResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductSearchRequest.java index 1f32dad0bf8..d42833b05e9 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductSearchRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProductSearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariant.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariant.java index 6f7e34e6b5e..969500ae70b 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariant.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariant.java @@ -1,10 +1,9 @@ package org.egov.common.models.product; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantRequest.java index e9d815128a9..4e5a644fe8e 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.product; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * ProductVariantRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantResponse.java index 5584a534753..9120c1e686a 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.product; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * ProductVariantResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantSearchRequest.java index 880b52f0d1a..58da166d7d1 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProductVariantSearchRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProductVariantSearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProjectProductVariant.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProjectProductVariant.java index 3970c1927d2..b15c8ac157a 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProjectProductVariant.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/ProjectProductVariant.java @@ -2,14 +2,13 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.constraints.NotNull; - /** * ProjectProductVariant */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/TenantRole.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/TenantRole.java index 2b2ed233edc..f58ffb7190d 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/TenantRole.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/TenantRole.java @@ -1,8 +1,13 @@ package org.egov.common.models.product; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,11 +15,6 @@ import org.egov.common.contract.request.Role; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/UserInfo.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/UserInfo.java index 5c89828c693..9876d411fc3 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/UserInfo.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/product/UserInfo.java @@ -1,8 +1,13 @@ package org.egov.common.models.product; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,11 +15,6 @@ import org.egov.common.contract.request.Role; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/AdditionalFields.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/AdditionalFields.java index 819eb9def0c..9dd8ccf7868 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/AdditionalFields.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/AdditionalFields.java @@ -1,19 +1,19 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * AdditionalFields */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Address.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Address.java index a928b1cadbf..97a9dfd4c27 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Address.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Address.java @@ -3,6 +3,11 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +import jakarta.validation.Valid; +import jakarta.validation.constraints.DecimalMax; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,12 +15,6 @@ import org.egov.common.models.core.Boundary; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.DecimalMax; -import jakarta.validation.constraints.DecimalMin; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * Representation of a address. Individual APIs may choose to extend from this using allOf if more details needed to be added in their case. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkRequest.java index a6167611a94..ab1bbb52368 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * BeneficiaryRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkResponse.java index 06c6081b71b..fbd9c84e842 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryBulkResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * BeneficiaryResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryRequest.java index cb1e4462721..a40eba1c47c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * BeneficiaryRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryResponse.java index 0b95acf2dc8..49b341a332b 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryResponse.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * BeneficiaryResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiarySearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiarySearchRequest.java index 9ca9e718d78..112bca6f03d 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiarySearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiarySearchRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * BeneficiarySearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Document.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Document.java index 1eb86b7c89f..388c1f52a66 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Document.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Document.java @@ -3,18 +3,17 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * A Object holds the basic data for a Trade License */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Field.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Field.java index 58360cdaf8e..4bb2c5052b1 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Field.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Field.java @@ -1,10 +1,9 @@ package org.egov.common.models.project; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Project.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Project.java index 586ff410489..b01995957ba 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Project.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Project.java @@ -1,20 +1,20 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +import jakarta.validation.Valid; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.egov.common.contract.models.AuditDetails; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import java.util.ArrayList; -import java.util.List; - /** * The purpose of this object to define the Project for a geography and period */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectBeneficiary.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectBeneficiary.java index 6c899a34765..514c5413422 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectBeneficiary.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectBeneficiary.java @@ -1,23 +1,18 @@ package org.egov.common.models.project; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.egov.common.models.core.EgovOfflineModel; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * A representation of the registration of an entity to a Project. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkRequest.java index cd1af9dfcb0..846ba1dcf38 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkRequest.java @@ -1,8 +1,14 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -10,12 +16,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * ProjectStaffRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkResponse.java index d2481b16298..38d1df9eafa 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkResponse.java @@ -1,6 +1,12 @@ package org.egov.common.models.project; + +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -8,35 +14,47 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** - * ProjectFacilityResponse + * Represents a bulk response for project facilities, including response metadata and a list of facilities. */ @Validated - - @Data @NoArgsConstructor @AllArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) public class ProjectFacilityBulkResponse { + + /** + * Metadata about the API response, including request details and status. + */ @JsonProperty("ResponseInfo") @NotNull @Valid private ResponseInfo responseInfo = null; + /** + * Total number of project facilities in the response, defaults to 0. + */ + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + + /** + * List of project facilities returned in the response. + */ @JsonProperty("ProjectFacilities") @NotNull @Valid private List projectFacilities = new ArrayList<>(); + /** + * Adds a single project facility to the list and returns the updated response. + */ public ProjectFacilityBulkResponse addProjectFacilityItem(ProjectFacility projectFacilityItem) { this.projectFacilities.add(projectFacilityItem); return this; } } + diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityRequest.java index a985decccef..7c556dc1f0c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProjectFacilityRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityResponse.java index ce862b669c6..5424a2a29f2 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityResponse.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProjectFacilityResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectProductVariant.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectProductVariant.java index e8841ba5de9..4e07cede298 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectProductVariant.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectProductVariant.java @@ -2,14 +2,13 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.constraints.NotNull; - /** * ProjectProductVariant */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectRequest.java index da4ae0343e4..f450a99a556 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * ProjectRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResource.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResource.java index 64001b9e278..dbeff61e3f3 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResource.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResource.java @@ -1,22 +1,17 @@ package org.egov.common.models.project; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.egov.common.models.core.EgovModel; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * This object defines the mapping of a resource to a project. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkRequest.java index 26b6c095232..a78ed2a8637 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * ProjectResourceRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkResponse.java index e04eb6abd1b..7aef41e322b 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * ProjectResourceResponse */ @@ -37,6 +37,11 @@ public class ProjectResourceBulkResponse { @Valid private List projectResource = new ArrayList<>(); + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + public ProjectResourceBulkResponse addProjectResourceItem(ProjectResource projectResourceItem) { this.projectResource.add(projectResourceItem); return this; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceRequest.java index d3387b1af96..edfdc4e583d 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProjectResourceRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceResponse.java index cc9a7e5c635..465b5cc3774 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceResponse.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProjectResourceResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResponse.java index 54872c4d5a4..09440ed984f 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * ProjectResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectSearchRequest.java index 3dc85137b83..8489479b0cd 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectSearchRequest.java @@ -9,7 +9,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.egov.common.contract.request.RequestInfo; -import org.egov.common.models.core.ProjectSearchURLParams; import org.springframework.validation.annotation.Validated; /** diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java index 78ecda1fa80..a2775e15997 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaff.java @@ -1,23 +1,16 @@ package org.egov.common.models.project; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - -import lombok.experimental.SuperBuilder; -import org.egov.common.models.core.EgovModel; -import org.springframework.validation.annotation.Validated; - -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.egov.common.models.core.EgovModel; +import org.springframework.validation.annotation.Validated; /** * This object defines the mapping of a system staff user to a project for a certain period. diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkRequest.java index c13dc8fcc4b..baaf7d8ef94 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * ProjectStaffRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkResponse.java index d73daee5c73..49070e25a94 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,17 +14,10 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** -* ProjectStaffResponse -*/ + * Represents a bulk response for project staff, containing response metadata and a list of staff members. + */ @Validated - - @Data @NoArgsConstructor @AllArgsConstructor @@ -27,19 +25,38 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class ProjectStaffBulkResponse { + /** + * Metadata about the API response, including request status and other information. + */ @JsonProperty("ResponseInfo") @NotNull @Valid private ResponseInfo responseInfo = null; + /** + * List of project staff members returned in the response. + */ @JsonProperty("ProjectStaff") @NotNull @Valid private List projectStaff = new ArrayList<>(); + /** + * Total number of project staff members in the response, defaults to 0 if not specified. + */ + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + + /** + * Adds a single project staff member to the list and returns the updated response. + * + * @param projectStaffItem The project staff member to add to the list. + * @return The updated ProjectStaffBulkResponse instance. + */ public ProjectStaffBulkResponse addProjectStaffItem(ProjectStaff projectStaffItem) { this.projectStaff.add(projectStaffItem); return this; } } - diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffRequest.java index ec7042c5ee0..37839657cee 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProjectStaffRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffResponse.java index 49403f8dd95..d862684e27a 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffResponse.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * ProjectStaffResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java index b428843e9d3..78445bed4a9 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java @@ -1,20 +1,20 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import io.swagger.annotations.ApiModel; +import jakarta.validation.Valid; +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.Size; -import java.util.ArrayList; -import java.util.List; - /** * This is the master data to capture the metadata of Project */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Role.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Role.java index fa2e4fee092..49078973f0c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Role.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Role.java @@ -3,15 +3,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * 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 */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java index 5fe7f7dbf7e..e7152211048 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java @@ -3,12 +3,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.egov.common.contract.models.AuditDetails; import org.springframework.validation.annotation.Validated; /** diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkRequest.java index 87b257e312c..94b89a69685 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * TaskRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkResponse.java index c0bbfb8e5f5..673bb8c6d97 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskBulkResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * TaskResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskRequest.java index a1d61ed85c1..438ec662d70 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * TaskRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResource.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResource.java index 8c798d1ef34..042dee89976 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResource.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResource.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -10,6 +9,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.springframework.validation.annotation.Validated; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceRequest.java index 8baedb1acfa..1ff055ae364 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceRequest.java @@ -1,7 +1,13 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; @@ -9,12 +15,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * TaskRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceResponse.java index 4d8c13db362..c63d797d91e 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResourceResponse.java @@ -1,7 +1,12 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,11 +14,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * TaskResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResponse.java index 64274a157ea..c24964729db 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskResponse.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.response.ResponseInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * TaskResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskSearchRequest.java index dea1ee10e02..bb52da94578 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskSearchRequest.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,9 +11,6 @@ import org.egov.common.contract.request.RequestInfo; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * TaskSearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TenantRole.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TenantRole.java index 1feb9f2518f..9a1aa439694 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TenantRole.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TenantRole.java @@ -1,19 +1,19 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserInfo.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserInfo.java index 57afb18c30f..aa727b72fe9 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserInfo.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserInfo.java @@ -1,19 +1,19 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserServiceResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserServiceResponse.java index a14f952ab02..d4448feec31 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserServiceResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserServiceResponse.java @@ -1,5 +1,8 @@ package org.egov.common.models.project; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -8,9 +11,6 @@ import lombok.NoArgsConstructor; import org.egov.common.contract.request.User; -import java.util.ArrayList; -import java.util.List; - @Data @NoArgsConstructor @AllArgsConstructor diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/Referral.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/Referral.java index 9cdc553bb92..72d8930d21f 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/Referral.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/Referral.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferral.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferral.java index 2c68467c843..50cd5a9b2ea 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferral.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferral.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkResponse.java index a561ef4f8a4..d8791d66979 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkResponse.java @@ -13,21 +13,39 @@ import lombok.NoArgsConstructor; import org.egov.common.contract.response.ResponseInfo; +/** + * Represents a bulk response for HF (Health Facility) referrals, containing response metadata and a list of referrals. + */ @Data @NoArgsConstructor @AllArgsConstructor @Builder public class HFReferralBulkResponse { + + /** + * Metadata about the API response, including details such as request status and information. + */ @JsonProperty("ResponseInfo") @NotNull @Valid private ResponseInfo responseInfo; + /** + * List of health facility referrals returned in the response. + */ @JsonProperty("HFReferrals") @NotNull @Valid private List hfReferrals; + /** + * Total number of HF referrals in the response, defaults to 0 if not specified. + */ + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + /** * Add a HfReferral item to the list of HfReferrals in the bulk response. * diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffect.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffect.java index f9f3041aeb5..cd41a108d8d 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffect.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/sideeffect/SideEffect.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/AdditionalFields.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/AdditionalFields.java index ef65681acc2..275d45de86c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/AdditionalFields.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/AdditionalFields.java @@ -1,19 +1,19 @@ package org.egov.common.models.stock; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * AdditionalFields */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Field.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Field.java index f040c0d8a28..39cc0e6f3b1 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Field.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Field.java @@ -1,10 +1,9 @@ package org.egov.common.models.stock; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java index 1ec63f96c54..fb9ed990e54 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/Stock.java @@ -1,17 +1,13 @@ package org.egov.common.models.stock; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.Valid; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Builder.Default; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkRequest.java index 696a7b9e41e..24080a26365 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkRequest.java @@ -1,19 +1,19 @@ package org.egov.common.models.stock; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * StockRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkResponse.java index cea7c46b8e5..3ad45bc8ed7 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkResponse.java @@ -1,24 +1,22 @@ package org.egov.common.models.stock; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** - * StockResponse + * Represents a bulk response for stock items, containing response metadata and a list of stock entries. */ @Validated - - @Data @NoArgsConstructor @AllArgsConstructor @@ -26,20 +24,40 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class StockBulkResponse { + /** + * Metadata about the API response, including details such as request status and information. + */ @JsonProperty("ResponseInfo") @NotNull @Valid private org.egov.common.contract.response.ResponseInfo responseInfo = null; + /** + * List of stock items returned in the response. + */ @JsonProperty("Stock") @NotNull @Valid private List stock = new ArrayList<>(); - + /** + * Total number of stock items in the response, defaults to 0 if not specified. + */ + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + + /** + * Adds a single stock item to the list of stock and returns the updated response. + * + * @param stockItem The stock item to add to the list. + * @return The updated StockBulkResponse instance. + */ public StockBulkResponse addStockItem(Stock stockItem) { this.stock.add(stockItem); return this; } } + diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliation.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliation.java index b8fc052ce68..b1db836bf5d 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliation.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliation.java @@ -1,21 +1,16 @@ package org.egov.common.models.stock; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import digit.models.coremodels.AuditDetails; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.egov.common.models.core.EgovOfflineModel; import org.springframework.validation.annotation.Validated; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; - /** * StockReconciliation */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkRequest.java index b9f01d68f98..17eeac712c9 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkRequest.java @@ -1,19 +1,19 @@ package org.egov.common.models.stock; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.ArrayList; -import java.util.List; - /** * StockReconciliationRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkResponse.java index caea2ead604..bae326d2dd8 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkResponse.java @@ -1,24 +1,22 @@ package org.egov.common.models.stock; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** - * StockReconciliationResponse + * Represents a bulk response for stock reconciliation, containing response metadata and a list of stock reconciliation entries. */ @Validated - - @Data @NoArgsConstructor @AllArgsConstructor @@ -26,19 +24,38 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class StockReconciliationBulkResponse { + /** + * Metadata about the API response, including details such as request status and information. + */ @JsonProperty("ResponseInfo") @NotNull @Valid private org.egov.common.contract.response.ResponseInfo responseInfo = null; + /** + * List of stock reconciliation items returned in the response. + */ @JsonProperty("StockReconciliation") @NotNull @Valid private List stockReconciliation = new ArrayList<>(); + /** + * Total number of stock reconciliation items in the response, defaults to 0 if not specified. + */ + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + + /** + * Adds a single stock reconciliation item to the list and returns the updated response. + * + * @param stockReconciliationItem The stock reconciliation item to add to the list. + * @return The updated StockReconciliationBulkResponse instance. + */ public StockReconciliationBulkResponse addStockReconciliationItem(StockReconciliation stockReconciliationItem) { this.stockReconciliation.add(stockReconciliationItem); return this; } } - diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationRequest.java index 58845227bf2..2475b989848 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * StockReconciliationRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationResponse.java index 409223db9ca..3046c8697c9 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationResponse.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * StockReconciliationResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationSearchRequest.java index 6b307ce2d11..d768a5a306e 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationSearchRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * StockReconciliationSearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockRequest.java index 10b7f7fde07..b716902e5a6 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * StockRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockResponse.java index 1cea9fc0185..55dadd4834c 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockResponse.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockResponse.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * StockResponse */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockSearchRequest.java index 9f73cb1e00e..8664fc1837f 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockSearchRequest.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockSearchRequest.java @@ -2,15 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; - /** * StockSearchRequest */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/TenantRole.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/TenantRole.java index 261bcb9d725..6c582bf37af 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/TenantRole.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/TenantRole.java @@ -1,19 +1,19 @@ package org.egov.common.models.stock; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/UserInfo.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/UserInfo.java index 85edeeef0aa..1c67558b4e3 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/UserInfo.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/UserInfo.java @@ -1,19 +1,19 @@ package org.egov.common.models.stock; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; +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 jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; - /** * 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. */ diff --git a/health-services/plan-service/CHANGELOG.md b/health-services/plan-service/CHANGELOG.md index 650d79eae57..a73439d7658 100644 --- a/health-services/plan-service/CHANGELOG.md +++ b/health-services/plan-service/CHANGELOG.md @@ -1,10 +1,38 @@ # Changelog All notable changes to this module will be documented in this file. -## 1.0.0 - 2024-06-24 -#### Plan Service - 1. Plan Service manages: validation of plans, plan search, plan create, plan update. - 2. Validation of plan: Plan service validates plan request before it takes action on it like update or create. - 3. Plan Create: Plan service creates a plan after successful validation is done. It sends create request on topic to create plan. - 4. Plan Update : Plan service creates a plan after successful validation is done. It sends update request on topic to resource estimation service to further process. - 5. Plan Search: This enables to search plan based on provided search string. \ No newline at end of file +## 1.0.0 - 2024-12-03 +### Plan Service + +##### Plan Configuration + +1. Validation of Plan Configuration: Validates all plan configuration requests against MDMS and Project Factory before processing the requests. +2. Plan Configuration Create: Validates and enriches new plan configurations before publishing them to the Kafka topic for asynchronous processing. +3. Plan Configuration Update: Updates existing plan configurations post-validation and enrichment by pushing requests to the Kafka update topic. +4. Plan Configuration Search: Facilitates searching for plan configurations using the provided search criteria. +5. Resource Generator Consumer: Listens to resource generator plan configuration update topic to update plan configuration. + +#### Plan + +1. Plan manages: validation of plans, plan search, plan create, plan update. +2. Validation of plan: Plan service validates plan request before it takes action on it like update or create. +3. Plan Create: Plan service creates a plan after successful validation is done. It sends create request on topic to create plan. +4. Plan Update : Plan service creates a plan after successful validation is done. It sends update request on topic to resource estimation service to further process. +5. Plan Search: This enables to search plan based on provided search string. +6. Plan Bulk Update: Allows updating multiple plans in a single operation after validation. +7. Resource Generator Consumer: Listens to resource plan create topic to trigger the creation of new plans. + +#### Plan Facility + +1. Validation: Validates plan facility requests against MDMS, Facility Service and Project Factory before processing the requests. +2. Plan Facility Create: Creates a plan facility after validation and enrichment, pushing the create request to the designated kafka topic. +3. Plan Facility Update: Updates existing facilities post-validation by pushing update requests to the Kafka topic. Also sends the update request to Census service for facility mapping. +4. Plan Facility Search: Searches Plan Facility for the provided search criteria. +5. Project Factory Consumer: Listens to project factory consumer to enrich and create new plan facility. + +#### Plan Employee Assignment + +1. Validation: Validates plan employee assignment requests against MDMS, User service and Project Factory before processing the requests. +2. Plan Employee Assignment Create: Assigns employees to plans post-validation and enrichment, considering roles and jurisdictions by pushing request to create kafka topic. +3. Plan Employee Assignment Update: Updates existing assignments after validation, publishing the changes to the designated Kafka update topic. +4. Plan Employee Assignment Search: Enables searching for employee assignments using provided search criteria. \ No newline at end of file diff --git a/health-services/plan-service/pom.xml b/health-services/plan-service/pom.xml index ce6a2dff717..c41f44a9f05 100644 --- a/health-services/plan-service/pom.xml +++ b/health-services/plan-service/pom.xml @@ -89,6 +89,17 @@ junit test + + org.egov.services + services-common + 2.9.0-SNAPSHOT + compile + + + org.apache.commons + commons-text + 1.10.0 + diff --git a/health-services/plan-service/src/main/java/digit/Main.java b/health-services/plan-service/src/main/java/digit/Main.java index 9ccda08d54e..4c49611bebd 100644 --- a/health-services/plan-service/src/main/java/digit/Main.java +++ b/health-services/plan-service/src/main/java/digit/Main.java @@ -9,7 +9,7 @@ @Import({ TracerConfiguration.class }) @SpringBootApplication -@ComponentScan(basePackages = { "digit", "digit.web.controllers" , "digit.config"}) +@ComponentScan(basePackages = { "digit", "digit.web.controllers" , "digit.config", "org.egov.common.utils"}) public class Main { public static void main(String[] args) throws Exception { 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..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 @@ -1,16 +1,13 @@ 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; +import java.util.List; +import java.util.Map; @Component @Data @@ -21,6 +18,13 @@ @Getter public class Configuration { + //Role Map + @Value("#{${role.map}}") + public Map roleMap; + + @Value("${plan.estimation.approver.roles}") + public List planEstimationApproverRoles; + //MDMS @Value("${egov.mdms.host}") private String mdmsHost; @@ -28,6 +32,32 @@ public class Configuration { @Value("${egov.mdms.search.endpoint}") private String mdmsEndPoint; + @Value("${egov.mdms.search.v2.endpoint}") + private String mdmsV2EndPoint; + + //Project Factory + @Value("${egov.project.factory.host}") + private String projectFactoryHost; + + @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; + + // Boundary Service + @Value("${egov.boundary.service.host}") + private String boundaryServiceHost; + + @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}") @@ -36,16 +66,64 @@ 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; @Value("${plan.update.topic}") private String planUpdateTopic; + @Value("${plan.bulk.update.topic}") + private String planBulkUpdateTopic; + + @Value("${plan.facility.create.topic}") + private String planFacilityCreateTopic; + + @Value("${plan.facility.update.topic}") + private String planFacilityUpdateTopic; + @Value("${plan.default.offset}") private Integer defaultOffset; @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; + + @Value("${egov.facility.search.endpoint}") + private String facilitySearchEndPoint; + + //Workflow + @Value("${egov.workflow.host}") + private String wfHost; + + @Value("${egov.workflow.transition.path}") + private String wfTransitionPath; + + @Value("${egov.business.service.search.endpoint}") + private String businessServiceSearchEndpoint; + + @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/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 2266c82de93..a2b9696b482 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,55 +12,118 @@ 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_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_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"; public static final String SUCCESSFUL = "successful"; public static final String FAILED = "failed"; + 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 "; 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"; + 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"; + + 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"; + public static final String TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE = "Template Identifier is not present in MDMS "; public static final String REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE = "REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND"; - public static final String REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE = "Required Template Identifier is not present in Files"; + public static final String REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE = "Required Template Identifier is not present in Files "; public static final String ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_CODE = "ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER"; - 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 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"; + 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."; + 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 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."; + + 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_ROOT_EMPLOYEE_JURISDICTION_CODE = "INVALID_ROOT_EMPLOYEE_JURISDICTION"; + public static final String INVALID_ROOT_EMPLOYEE_JURISDICTION_MESSAGE = "The root employee's jurisdiction should be at highest hierarchy"; + + public static final String INVALID_EMPLOYEE_JURISDICTION_CODE = "INVALID_EMPLOYEE_JURISDICTION"; + public static final String INVALID_EMPLOYEE_JURISDICTION_MESSAGE = "The employee's jurisdiction can't be at highest or lowest hierarchy"; + + public static final String INVALID_JURISDICTION_CODE = "INVALID_JURISDICTION"; + public static final String INVALID_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"; + 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 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_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_CONFIGURATION_ALREADY_EXISTS_CODE = "PLAN_CONFIGURATION_ALREADY_EXISTS"; + public static final String PLAN_CONFIGURATION_ALREADY_EXISTS_MESSAGE = "Plan Configuration for the provided name and campaign id 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_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"; + + 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 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"; @@ -73,26 +136,119 @@ 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"; + + public static final String NAME_VALIDATION_FAILED_CODE = "NAME_VALIDATION_FAILED"; + public static final String NAME_VALIDATION_FAILED_MESSAGE = "Name Validation failed"; + + public static final String INVALID_PLAN_ID_CODE = "INVALID_PLAN_ID"; + public static final String INVALID_PLAN_ID_MESSAGE = "Plan id provided is invalid"; + + public static final String CYCLIC_ACTIVITY_DEPENDENCY_CODE = "CYCLIC_ACTIVITY_DEPENDENCY"; + public static final String CYCLIC_ACTIVITY_DEPENDENCY_MESSAGE = "Cyclic activity dependency found"; + + public static final String INVALID_ACTIVITY_DEPENDENCY_CODE = "INVALID_ACTIVITY_DEPENDENCY"; + public static final String INVALID_ACTIVITY_DEPENDENCY_MESSAGE = "Activity dependency is invalid"; + + public static final String ACTIVITIES_CANNOT_BE_NULL_CODE = "ACTIVITIES_CANNOT_BE_NULL"; + public static final String ACTIVITIES_CANNOT_BE_NULL_MESSAGE = "Activities list in Plan cannot be null"; + + public static final String DUPLICATE_ACTIVITY_CODES = "DUPLICATE_ACTIVITY_CODES"; + public static final String DUPLICATE_ACTIVITY_CODES_MESSAGE = "Activity codes within the plan should be unique"; + + public static final String PLAN_ACTIVITIES_MANDATORY_CODE = "PLAN_ACTIVITIES_MANDATORY"; + public static final String PLAN_ACTIVITIES_MANDATORY_MESSAGE = "Activities are mandatory if execution plan id is not provided"; + + public static final String PLAN_ACTIVITIES_NOT_ALLOWED_CODE = "PLAN_ACTIVITIES_NOT_ALLOWED"; + public static final String PLAN_ACTIVITIES_NOT_ALLOWED_MESSAGE = "Activities are not allowed if execution plan id is provided"; + + public static final String INVALID_ACTIVITY_DATES_CODE = "INVALID_ACTIVITY_DATES"; + public static final String INVALID_ACTIVITY_DATES_MESSAGE = "Planned end date cannot be before planned start date"; + + 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 INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE = "INVALID_RESOURCE_ACTIVITY_LINKAGE"; + public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE = "Resource-Activity linkage is invalid"; + + public static final String INVALID_TARGET_ACTIVITY_LINKAGE_CODE = "INVALID_TARGET_ACTIVITY_LINKAGE"; + public static final String INVALID_TARGET_ACTIVITY_LINKAGE_MESSAGE = "Target-Activity linkage is invalid"; + + public static final String DUPLICATE_TARGET_UUIDS_CODE = "DUPLICATE_TARGET_UUIDS"; + public static final String DUPLICATE_TARGET_UUIDS_MESSAGE = "Target UUIDs should be unique"; + + public static final String DUPLICATE_RESOURCE_UUIDS_CODE = "DUPLICATE_RESOURCE_UUIDS"; + public static final String DUPLICATE_RESOURCE_UUIDS_MESSAGE = "Resource UUIDs should be unique"; + + 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 - "; + + 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 : "; + + 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 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 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."; + + 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"; + public static final String MDMS_MASTER_HIERARCHY_CONFIG = "hierarchyConfig"; + public static final String MDMS_MASTER_HIERARCHY_SCHEMA = "HierarchySchema"; 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"; public static final String MDMS_MASTER_METRIC = "Metric"; public static final String MDMS_MASTER_UOM = "Uom"; + public static final String MDMS_MASTER_NAME_VALIDATION= "MicroplanNamingRegex"; + public static final String MDMS_SCHEMA_ADMIN_SCHEMA = "adminSchema"; + public static final String BOUNDARY = "boundary"; + public static final String HIERARCHY_TYPE = "hierarchyType"; + + //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 = "$."; public static final String DOT_SEPARATOR = "."; 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"; + public static final String FILTER_TO_GET_ALL_IDS = "*.id"; + public static final String FILTER_DATA = "$.*.data"; public static final String LOCALITY_CODE = "Locality"; @@ -108,6 +264,114 @@ 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 MDMS_SCHEMA_VEHICLE_DETAILS = "VehicleDetails"; + public static final String BOUNDARY_CODE = "boundaryCode"; + public static final String FILTER_ALL_ASSUMPTIONS = ".assumptionCategories[*].assumptions[*]"; + + public static final String HIERARCHY_CONFIG_FOR_MICROPLAN = "[?(@.type == 'microplan')]"; + + 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 + public static final String AND = " && "; + public static final String EQUALS = " == "; + public static final String SINGLE_QUOTE = "'"; + + // 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 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"; + 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"; + + // 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"; + + public static final String SETUP_COMPLETED_ACTION = "INITIATE"; + + 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}"; + + 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 = "%"; + + public static final String MDMS_MASTER_HIERARCHY= "hierarchy"; + + 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"; + + 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 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"; + + public static final String FAILED_MESSAGE = "Failed to push message to topic"; + + public static final String FACILITY_NAME_SEARCH_PARAMETER_KEY = "facilityName"; + + public static final String FACILITY_STATUS_SEARCH_PARAMETER_KEY = "facilityStatus"; + + public static final String FACILITY_TYPE_SEARCH_PARAMETER_KEY = "facilityType"; + + public static final String COMMA_DELIMITER = ","; + + 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/kafka/ProjectFactoryCreatePlanFacilityConsumer.java b/health-services/plan-service/src/main/java/digit/kafka/ProjectFactoryCreatePlanFacilityConsumer.java new file mode 100644 index 00000000000..f01da2db239 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/kafka/ProjectFactoryCreatePlanFacilityConsumer.java @@ -0,0 +1,57 @@ +package digit.kafka; + +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.repository.PlanFacilityRepository; +import digit.service.enrichment.PlanFacilityEnricher; +import digit.util.CommonUtil; +import digit.web.models.PlanFacilityRequest; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +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 org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.Map; + +import static digit.config.ServiceConstants.HIERARCHY_TYPE; + +@Slf4j +@Component +public class ProjectFactoryCreatePlanFacilityConsumer { + + private ObjectMapper objectMapper; + + private PlanFacilityEnricher enrichment; + + private CommonUtil commonUtil; + + private PlanFacilityRepository repository; + + public ProjectFactoryCreatePlanFacilityConsumer(ObjectMapper objectMapper, PlanFacilityEnricher enrichment, CommonUtil commonUtil, PlanFacilityRepository repository) { + this.objectMapper = objectMapper; + this.enrichment = enrichment; + this.commonUtil = commonUtil; + this.repository = repository; + } + + @KafkaListener(topics = {"${project.factory.save.plan.facility.consumer.topic}"}) + public void listen(Map consumerRecord, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + PlanFacilityRequest planFacilityRequest = objectMapper.convertValue(consumerRecord, PlanFacilityRequest.class); + String hierarchyType = commonUtil.extractFieldsFromJsonObject(planFacilityRequest.getPlanFacility().getAdditionalDetails(), HIERARCHY_TYPE).toString(); + + if(!StringUtils.isEmpty(hierarchyType)) + enrichment.enrichJurisdictionMapping(planFacilityRequest, hierarchyType); + + if(CollectionUtils.isEmpty(planFacilityRequest.getPlanFacility().getServiceBoundaries())) + planFacilityRequest.getPlanFacility().setServiceBoundaries(new ArrayList<>()); + + repository.create(planFacilityRequest); + } catch (Exception exception) { + log.error("Error in census consumer", exception); + } + } +} \ No newline at end of file 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/plan-service/src/main/java/digit/repository/PlanConfigurationRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanConfigurationRepository.java index 49efc1d89f4..62af2daaac4 100644 --- a/health-services/plan-service/src/main/java/digit/repository/PlanConfigurationRepository.java +++ b/health-services/plan-service/src/main/java/digit/repository/PlanConfigurationRepository.java @@ -16,5 +16,6 @@ public interface PlanConfigurationRepository { public void update(PlanConfigurationRequest planConfigurationRequest); + public Integer count(PlanConfigurationSearchCriteria planConfigurationSearchCriteria); } 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..370141a8697 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java @@ -0,0 +1,16 @@ +package digit.repository; + +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); + + public Integer count(PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria); +} 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..ce94f569086 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java @@ -0,0 +1,15 @@ +package digit.repository; + +import digit.web.models.*; + +import java.util.List; + +public interface PlanFacilityRepository { + public void create(PlanFacilityRequest planFacilityRequest); + + 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/PlanRepository.java b/health-services/plan-service/src/main/java/digit/repository/PlanRepository.java index eb76b357701..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,10 +1,9 @@ package digit.repository; -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; public interface PlanRepository { public void create(PlanRequest planRequest); @@ -13,4 +12,9 @@ public interface PlanRepository { public void update(PlanRequest planRequest); + public Integer count(PlanSearchCriteria planSearchCriteria); + + public Map statusCount(PlanSearchRequest planSearchRequest); + + public void bulkUpdate(BulkPlanRequest body); } 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..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 @@ -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; @@ -35,9 +35,10 @@ 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()); } return response; 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..bba32818812 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java @@ -0,0 +1,121 @@ +package digit.repository.impl; + +import digit.config.Configuration; +import digit.kafka.Producer; +import digit.repository.PlanEmployeeAssignmentRepository; +import digit.repository.querybuilder.PlanEmployeeAssignmentQueryBuilder; +import digit.repository.rowmapper.PlanEmployeeAssignmentRowMapper; +import digit.web.models.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Repository +public class PlanEmployeeAssignmentImpl implements PlanEmployeeAssignmentRepository { + + private Producer producer; + + private Configuration config; + + private PlanEmployeeAssignmentQueryBuilder queryBuilder; + + private JdbcTemplate jdbcTemplate; + + private PlanEmployeeAssignmentRowMapper rowMapper; + + 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; + } + + /** + * 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) { + PlanEmployeeAssignmentRequestDTO requestDTO = 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); + log.info("Plan Employee Assignment search query : " + searchQuery); + + List planEmployeeAssignments = jdbcTemplate.query(searchQuery, rowMapper, preparedStmtList.toArray()); + 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) { + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getPlanEmployeeAssignmentCountQuery(searchCriteria, preparedStmtList); + Integer count = jdbcTemplate.queryForObject(query, preparedStmtList.toArray(), Integer.class); + + return count; + } + + /** + * 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) { + PlanEmployeeAssignmentRequestDTO requestDTO = convertToReqDTO(planEmployeeAssignmentRequest); + producer.push(config.getPlanEmployeeAssignmentUpdateTopic(), requestDTO); + } + + /** + * 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()) + .planConfigurationName(planEmployeeAssignment.getPlanConfigurationName()) + .hierarchyLevel(planEmployeeAssignment.getHierarchyLevel()) + .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/impl/PlanFacilityRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java new file mode 100644 index 00000000000..2d3c2304bae --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java @@ -0,0 +1,150 @@ +package digit.repository.impl; + +import digit.config.Configuration; +import digit.kafka.Producer; +import digit.repository.PlanFacilityRepository; +import digit.repository.querybuilder.PlanFacilityQueryBuilder; +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.springframework.stereotype.Repository; +import java.util.ArrayList; +import java.util.List; +import static digit.config.ServiceConstants.*; + +@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; + } + + /** + * 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) { + // 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()) + .planConfigurationName(planFacility.getPlanConfigurationName()) + .facilityId(planFacility.getFacilityId()) + .facilityName(planFacility.getFacilityName()) + .jurisdictionMapping(planFacility.getJurisdictionMapping()) + .boundaryAncestralPath(planFacility.getBoundaryAncestralPath()) + .residingBoundary(planFacility.getResidingBoundary()) + .serviceBoundaries(convertArrayToString(planFacility.getServiceBoundaries())) + .initiallySetServiceBoundaries(planFacility.getInitiallySetServiceBoundaries()) + .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(COMMA_DELIMITER, stringList); + } + + + + /** + * This method searches for plans based on the search criteria. + * + * @param planFacilitySearchCriteria + * @return List + */ + @Override + public List search(PlanFacilitySearchCriteria planFacilitySearchCriteria) { + // Fetch plan facility from database + return queryDatabaseForPlanFacilities(planFacilitySearchCriteria); + } + + /** + * This method emits an event to the persister for it to update the plan facility in the database. + * + * @param planFacilityRequest + */ + @Override + public void update(PlanFacilityRequest planFacilityRequest) { + try { + 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()); + } + } + + /** + * 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. + * + * @param planFacilitySearchCriteria + * @return List + */ + private List queryDatabaseForPlanFacilities(PlanFacilitySearchCriteria planFacilitySearchCriteria) { + List preparedStmtList = new ArrayList<>(); + String query = planFacilityQueryBuilder.getPlanFacilitySearchQuery(planFacilitySearchCriteria, preparedStmtList); + 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/impl/PlanRepositoryImpl.java b/health-services/plan-service/src/main/java/digit/repository/impl/PlanRepositoryImpl.java index c6acbb55221..99e4b9487de 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,17 +5,21 @@ 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.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 @@ -31,13 +35,19 @@ public class PlanRepositoryImpl implements PlanRepository { private Configuration config; + private PlanStatusCountRowMapper statusCountRowMapper; + + private WorkflowService workflowService; + public PlanRepositoryImpl(Producer producer, PlanQueryBuilder planQueryBuilder, PlanRowMapper planRowMapper, - JdbcTemplate jdbcTemplate, Configuration config) { + 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; } /** @@ -46,11 +56,8 @@ public PlanRepositoryImpl(Producer producer, PlanQueryBuilder planQueryBuilder, */ @Override public void create(PlanRequest planRequest) { - try { - producer.push(config.getPlanCreateTopic(), planRequest); - } catch (Exception e) { - log.info("Pushing message to topic " + config.getPlanCreateTopic() + " failed.", e); - } + PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); + producer.push(config.getPlanCreateTopic(), planRequestDTO); } /** @@ -70,9 +77,29 @@ public List search(PlanSearchCriteria planSearchCriteria) { } // Fetch plans from database based on the acquired ids - List plans = searchPlanByIds(planIds); + return searchPlanByIds(planIds); + } - return plans; + /** + * Counts the plan based on their current status for the provided search criteria. + * + * @param planSearchRequest The search criteria for filtering plans. + * @return The status count of plans for the given search criteria. + */ + @Override + public Map statusCount(PlanSearchRequest planSearchRequest) { + List preparedStmtList = new ArrayList<>(); + 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 statusCountMap; } /** @@ -81,13 +108,41 @@ public List search(PlanSearchCriteria planSearchCriteria) { */ @Override public void update(PlanRequest planRequest) { - try { - producer.push(config.getPlanUpdateTopic(), planRequest); - } catch (Exception e) { - log.info("Pushing message to topic " + config.getPlanUpdateTopic() + " failed.", e); - } + PlanRequestDTO planRequestDTO = convertToPlanReqDTO(planRequest); + producer.push(config.getPlanUpdateTopic(), planRequestDTO); } + @Override + public void bulkUpdate(BulkPlanRequest body) { + // Get bulk plan update query + String bulkPlanUpdateQuery = planQueryBuilder.getBulkPlanQuery(); + + // Prepare rows for bulk update + List rows = body.getPlans().stream().map(plan -> new Object[] { + plan.getStatus(), + !CollectionUtils.isEmpty(plan.getAssignee()) ? String.join(",", plan.getAssignee()) : plan.getAssignee(), + plan.getAuditDetails().getLastModifiedBy(), + plan.getAuditDetails().getLastModifiedTime(), + plan.getId() + }).toList(); + + // Perform batch update + jdbcTemplate.batchUpdate(bulkPlanUpdateQuery, rows); + producer.push(config.getPlanBulkUpdateTopic(), body); + } + + /** + * 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 @@ -112,4 +167,41 @@ 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(); + + 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()) + .tenantId(plan.getTenantId()) + .locality(plan.getLocality()) + .campaignId(plan.getCampaignId()) + .planConfigurationId(plan.getPlanConfigurationId()) + .status(plan.getStatus()) + .assignee(assignee) + .additionalDetails(plan.getAdditionalDetails()) + .jurisdictionMapping(plan.getJurisdictionMapping()) + .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/repository/querybuilder/PlanConfigQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanConfigQueryBuilder.java index 6dc4449b55f..e8caef51d94 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,30 +1,35 @@ package digit.repository.querybuilder; import digit.config.Configuration; - 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; +import java.util.LinkedHashSet; +import java.util.List; + +import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; + @Component 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 "; - 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.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.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.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" + @@ -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, 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; @@ -97,22 +102,28 @@ private String buildPlanConfigSearchQuery(PlanConfigurationSearchCriteria criter preparedStmtList.add(criteria.getId()); } - if (criteria.getExecutionPlanId() != null) { + if (!CollectionUtils.isEmpty(criteria.getIds())) { + addClauseIfRequired(preparedStmtList, builder); + builder.append(" pc.id IN ( ").append(queryUtil.createQuery(criteria.getIds().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, criteria.getIds()); + } + + 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) { addClauseIfRequired(preparedStmtList, builder); - builder.append(" pc.name = ?"); - preparedStmtList.add(criteria.getName()); + builder.append(" pc.name ILIKE ?"); + preparedStmtList.add(PERCENTAGE_WILDCARD + 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, criteria.getStatus()); } if (criteria.getUserUuid() != null) { @@ -162,22 +173,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); } 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..b63f790f806 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java @@ -0,0 +1,170 @@ +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; +import java.util.List; + +import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; + +@Component +public class PlanEmployeeAssignmentQueryBuilder { + + private 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 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 PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_QUERY_ORDER_BY_CLAUSE = " ORDER BY 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 ( "; + + /** + * 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, 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 = getPaginatedQuery(query, searchCriteria, 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, Boolean isCount) { + StringBuilder builder = Boolean.TRUE.equals(searchCriteria.getFilterUniqueByPlanConfig()) ? + new StringBuilder(UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_RANKED_QUERY) : new StringBuilder(PLAN_EMPLOYEE_ASSIGNMENT_SEARCH_BASE_QUERY); + + if (searchCriteria.getId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pa.id = ?"); + preparedStmtList.add(searchCriteria.getId()); + } + + if (searchCriteria.getTenantId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pa.tenant_id = ?"); + preparedStmtList.add(searchCriteria.getTenantId()); + } + + if (searchCriteria.getPlanConfigurationId() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pa.plan_configuration_id = ?"); + preparedStmtList.add(searchCriteria.getPlanConfigurationId()); + } + + if (searchCriteria.getPlanConfigurationName() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + 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(" pa.employee_id IN ( ").append(queryUtil.createQuery(searchCriteria.getEmployeeId().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, 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, searchCriteria.getPlanConfigurationStatus()); + } + + if (!CollectionUtils.isEmpty(searchCriteria.getRole())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pa.role IN ( ").append(queryUtil.createQuery(searchCriteria.getRole().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, searchCriteria.getRole()); + } + + if(searchCriteria.getHierarchyLevel() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pa.hierarchy_level = ?"); + preparedStmtList.add(searchCriteria.getHierarchyLevel()); + } + + if (searchCriteria.getActive() != null) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" pa.active = ?"); + 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, searchCriteria.getJurisdiction()); + } + + if(searchCriteria.getFilterUniqueByPlanConfig()) { + builder.append(" )").append(UNIQUE_PLAN_EMPLOYEE_ASSIGNMENT_MAIN_SEARCH_QUERY); + } + + 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(); + } + + 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 new file mode 100644 index 00000000000..0d475c4e577 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java @@ -0,0 +1,154 @@ +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; +import java.util.Set; + +import static digit.config.ServiceConstants.PERCENTAGE_WILDCARD; + +@Component +public class PlanFacilityQueryBuilder { + + private Configuration config; + + private QueryUtil queryUtil; + + public PlanFacilityQueryBuilder(Configuration config, QueryUtil queryUtil) { + this.config = config; + this.queryUtil = queryUtil; + } + + 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.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.boundary_ancestral_path as plan_facility_boundary_ancestral_path, " + + "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 "; + + 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, Boolean.FALSE); + query = queryUtil.addOrderByClause(query, PLAN_FACILITY_SEARCH_QUERY_ORDER_BY_CLAUSE); + query = getPaginatedQuery(query, planFacilitySearchCriteria, preparedStmtList); + return query; + } + + /** + * 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())) { + Set ids = planFacilitySearchCriteria.getIds(); + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" id IN ( ").append(queryUtil.createQuery(ids.size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, ids); + } + + 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.getPlanConfigurationName())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" plan_configuration_name ILIKE ? "); + preparedStmtList.add(PERCENTAGE_WILDCARD + planFacilitySearchCriteria.getPlanConfigurationName() + PERCENTAGE_WILDCARD); + } + + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityId())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" facility_id = ? "); + preparedStmtList.add(planFacilitySearchCriteria.getFacilityId()); + } + + if (!ObjectUtils.isEmpty(planFacilitySearchCriteria.getFacilityName())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" facility_name ILIKE ? "); + preparedStmtList.add(PERCENTAGE_WILDCARD + planFacilitySearchCriteria.getFacilityName() + PERCENTAGE_WILDCARD); + } + + 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, residingBoundaries); + } + + if (!CollectionUtils.isEmpty(planFacilitySearchCriteria.getJurisdiction())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ").append(queryUtil.createQuery(planFacilitySearchCriteria.getJurisdiction().size())).append(" ]::text[] "); + builder.append(" && string_to_array(boundary_ancestral_path, '|') "); + queryUtil.addToPreparedStatement(preparedStmtList, planFacilitySearchCriteria.getJurisdiction()); + } + + 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); + } + + 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(); + } + + 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/querybuilder/PlanQueryBuilder.java b/health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanQueryBuilder.java index 1b0adb59213..5c8bc91097b 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,9 @@ import org.springframework.stereotype.Component; 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; @@ -14,13 +17,16 @@ 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 "; - 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.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" + @@ -31,8 +37,14 @@ public PlanQueryBuilder(Configuration config) { "\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 "; + 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"; + public String getPlanQuery(List ids, List preparedStmtList) { return buildPlanQuery(ids, preparedStmtList); } @@ -41,60 +53,137 @@ 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, ids); } - return builder.toString(); + return queryUtil.addOrderByClause(builder.toString(), PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE); } public String getPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList) { - String query = buildPlanSearchQuery(planSearchCriteria, preparedStmtList); - query = QueryUtil.addOrderByClause(query, PLAN_SEARCH_QUERY_ORDER_BY_CLAUSE); + 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; } + /** + * 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, 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) { + PlanSearchCriteria planSearchCriteria = PlanSearchCriteria.builder() + .tenantId(searchCriteria.getTenantId()) + .planConfigurationId(searchCriteria.getPlanConfigurationId()) + .campaignId(searchCriteria.getCampaignId()) + .jurisdiction(searchCriteria.getJurisdiction()) + .build(); + return buildPlanSearchQuery(planSearchCriteria, preparedStmtList, Boolean.FALSE, Boolean.TRUE); + } + /** * Method to build query dynamically based on the criteria passed to the method + * * @param planSearchCriteria * @param preparedStmtList * @return */ - private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, List preparedStmtList) { + private String buildPlanSearchQuery(PlanSearchCriteria planSearchCriteria, 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); + 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); - builder.append(" locality = ? "); - preparedStmtList.add(planSearchCriteria.getLocality()); + if (!CollectionUtils.isEmpty(planSearchCriteria.getLocality())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" locality IN ( ").append(queryUtil.createQuery(planSearchCriteria.getLocality().size())).append(" )"); + queryUtil.addToPreparedStatement(preparedStmtList, planSearchCriteria.getLocality()); } - if (!ObjectUtils.isEmpty(planSearchCriteria.getExecutionPlanId())) { - QueryUtil.addClauseIfRequired(builder, preparedStmtList); - builder.append(" execution_plan_id = ? "); - preparedStmtList.add(planSearchCriteria.getExecutionPlanId()); + if (!ObjectUtils.isEmpty(planSearchCriteria.getCampaignId())) { + 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()); } + 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 (!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, Collections.singleton(planSearchCriteria.getAssignee())); + } + + if (!CollectionUtils.isEmpty(planSearchCriteria.getJurisdiction())) { + queryUtil.addClauseIfRequired(builder, preparedStmtList); + builder.append(" ARRAY [ ") + .append(queryUtil.createQuery(planSearchCriteria.getJurisdiction().size())) + .append(" ]::text[] "); + + builder.append(" && string_to_array(boundary_ancestral_path, '|') "); + queryUtil.addToPreparedStatement(preparedStmtList, planSearchCriteria.getJurisdiction()); + } + + + StringBuilder countQuery = new StringBuilder(); + if (isCount) { + + countQuery.append(PLAN_SEARCH_QUERY_COUNT_WRAPPER).append(builder); + countQuery.append(") AS subquery"); + + return countQuery.toString(); + } + + if (isStatusCount) { + return PLAN_STATUS_COUNT_QUERY.replace("{INTERNAL_QUERY}", builder); + } + return builder.toString(); } @@ -112,4 +201,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/repository/rowmapper/PlanConfigRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanConfigRowMapper.java index f8aebd12a9a..4645ce10b5e 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,33 +1,35 @@ package digit.repository.rowmapper; -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 java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import digit.util.QueryUtil; +import digit.web.models.*; 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 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<>(); - Map fileMap = new LinkedHashMap<>(); - Map operationMap = new LinkedHashMap<>(); - Map assumptionMap = new LinkedHashMap<>(); - Map resourceMappingMap = new LinkedHashMap<>(); + Set fileSet = new HashSet<>(); + Set operationSet = new HashSet<>(); + Set assumptionSet = new HashSet<>(); + Set resourceMappingSet = new HashSet<>(); while (rs.next()) { @@ -37,6 +39,10 @@ public List extractData(ResultSet rs) throws SQLException, Da if (ObjectUtils.isEmpty(planConfigEntry)) { planConfigEntry = new PlanConfiguration(); + fileSet.clear(); + operationSet.clear(); + assumptionSet.clear(); + resourceMappingSet.clear(); // Prepare audit details AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("plan_configuration_created_by")).createdTime(rs.getLong("plan_configuration_created_time")).lastModifiedBy(rs.getString("plan_configuration_last_modified_by")).lastModifiedTime(rs.getLong("plan_configuration_last_modified_time")).build(); @@ -45,15 +51,16 @@ 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.setStatus(PlanConfiguration.StatusEnum.valueOf(rs.getString("plan_configuration_status").toUpperCase())); + planConfigEntry.setCampaignId(rs.getString("plan_configuration_campaign_id")); + planConfigEntry.setStatus(rs.getString("plan_configuration_status")); + planConfigEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_configuration_additional_details"))); planConfigEntry.setAuditDetails(auditDetails); } - addFiles(rs, planConfigEntry, fileMap); - addAssumptions(rs, planConfigEntry, assumptionMap); - addOperations(rs, planConfigEntry, operationMap); - addResourceMappings(rs, planConfigEntry, resourceMappingMap); + addFiles(rs, planConfigEntry, fileSet); + addAssumptions(rs, planConfigEntry, assumptionSet); + addOperations(rs, planConfigEntry, operationSet); + addResourceMappings(rs, planConfigEntry, resourceMappingSet); planConfigurationMap.put(planConfigId, planConfigEntry); } @@ -65,13 +72,13 @@ public List extractData(ResultSet rs) throws SQLException, Da * * @param rs The ResultSet containing the data. * @param planConfigEntry The PlanConfiguration entry to which the File object will be added. - * @param fileMap A map to keep track of added File objects. + * @param fileSet A set to keep track of added File objects. * @throws SQLException If an SQL error occurs. */ - private void addFiles(ResultSet rs, PlanConfiguration planConfigEntry, Map fileMap) throws SQLException { + private void addFiles(ResultSet rs, PlanConfiguration planConfigEntry, Set fileSet) throws SQLException { String fileId = rs.getString("plan_configuration_files_id"); - if (ObjectUtils.isEmpty(fileId) || fileMap.containsKey(fileId)) { + if (ObjectUtils.isEmpty(fileId) || fileSet.contains(fileId)) { return; } @@ -89,7 +96,7 @@ private void addFiles(ResultSet rs, PlanConfiguration planConfigEntry, Map assumptionMap) throws SQLException { + private void addAssumptions(ResultSet rs, PlanConfiguration planConfigEntry, Set assumptionSet) throws SQLException { String assumptionId = rs.getString("plan_configuration_assumptions_id"); - if (ObjectUtils.isEmpty(assumptionId) || assumptionMap.containsKey(assumptionId)) { + if (ObjectUtils.isEmpty(assumptionId) || assumptionSet.contains(assumptionId)) { return; } @@ -113,6 +120,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<>(); @@ -122,7 +131,7 @@ private void addAssumptions(ResultSet rs, PlanConfiguration planConfigEntry, Map planConfigEntry.getAssumptions().add(assumption); } - assumptionMap.put(assumptionId, assumption); + assumptionSet.add(assumptionId); } /** @@ -130,13 +139,13 @@ private void addAssumptions(ResultSet rs, PlanConfiguration planConfigEntry, Map * * @param rs The ResultSet containing the data. * @param planConfigEntry The PlanConfiguration entry to which the Operation object will be added. - * @param operationMap A map to keep track of added Operation objects. + * @param operationSet A set to keep track of added Operation objects. * @throws SQLException If an SQL error occurs. */ - private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Map operationMap) throws SQLException { + private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Set operationSet) throws SQLException { String operationId = rs.getString("plan_configuration_operations_id"); - if (ObjectUtils.isEmpty(operationId) || operationMap.containsKey(operationId)) { + if (ObjectUtils.isEmpty(operationId) || operationSet.contains(operationId)) { return; } @@ -147,6 +156,10 @@ 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")); + 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<>(); @@ -156,7 +169,7 @@ private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Map< planConfigEntry.getOperations().add(operation); } - operationMap.put(operationId, operation); + operationSet.add(operationId); } /** @@ -164,13 +177,13 @@ private void addOperations(ResultSet rs, PlanConfiguration planConfigEntry, Map< * * @param rs The ResultSet containing the data. * @param planConfigEntry The PlanConfiguration entry to which the ResourceMapping object will be added. - * @param mappingMap A map to keep track of added ResourceMapping objects. + * @param resourceMappingSet A set to keep track of added ResourceMapping objects. * @throws SQLException If an SQL error occurs. */ - private void addResourceMappings(ResultSet rs, PlanConfiguration planConfigEntry, Map mappingMap) throws SQLException { + private void addResourceMappings(ResultSet rs, PlanConfiguration planConfigEntry, Set resourceMappingSet) throws SQLException { String mappingId = rs.getString("plan_configuration_mapping_id"); - if (ObjectUtils.isEmpty(mappingId) || mappingMap.containsKey(mappingId)) { + if (ObjectUtils.isEmpty(mappingId) || resourceMappingSet.contains(mappingId)) { return; } @@ -189,7 +202,7 @@ private void addResourceMappings(ResultSet rs, PlanConfiguration planConfigEntry planConfigEntry.getResourceMapping().add(mapping); } - mappingMap.put(mappingId, mapping); + resourceMappingSet.add(mappingId); } } 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..edf79b72c02 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java @@ -0,0 +1,66 @@ +package digit.repository.rowmapper; + +import digit.util.QueryUtil; +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.*; +import java.util.stream.Collectors; + +@Slf4j +@Component +public class PlanEmployeeAssignmentRowMapper implements ResultSetExtractor> { + + private QueryUtil queryUtil; + + public PlanEmployeeAssignmentRowMapper(QueryUtil queryUtil) { + this.queryUtil = queryUtil; + } + + @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"); + Set jurisdictionList = Arrays.stream(jurisdiction.split(",")).collect(Collectors.toSet()); + + // Prepare PlanEmployeeAssignment object + 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")); + planEmployeeAssignment.setJurisdiction(jurisdictionList); + planEmployeeAssignment.setActive(rs.getBoolean("active")); + planEmployeeAssignment.setAdditionalDetails(queryUtil.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/PlanFacilityRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java new file mode 100644 index 00000000000..c7ea2667ef1 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java @@ -0,0 +1,79 @@ +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 final 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 (planFacilityEntry == null || 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.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")); + planFacilityEntry.setBoundaryAncestralPath(rs.getString("plan_facility_boundary_ancestral_path")); + String serviceBoundaries = rs.getString("plan_facility_service_boundaries"); + 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")); + } + + 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/repository/rowmapper/PlanRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanRowMapper.java index a82919fed46..aa00207a741 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.QueryUtil; 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,28 +17,32 @@ @Component public class PlanRowMapper implements ResultSetExtractor> { - private ObjectMapper objectMapper; + private QueryUtil queryUtil; - public PlanRowMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; + public PlanRowMapper(QueryUtil queryUtil) { + this.queryUtil = queryUtil; } @Override public List extractData(ResultSet rs) throws SQLException, DataAccessException { Map planMap = new LinkedHashMap<>(); Map activityMap = new LinkedHashMap<>(); - Map conditionMap = new LinkedHashMap<>(); - Map resourceMap = new LinkedHashMap<>(); - Map targetMap = new LinkedHashMap<>(); + Set conditionSet = new HashSet<>(); + Set resourceSet = new HashSet<>(); + Set targetSet = new HashSet<>(); // 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(); + activityMap.clear(); + conditionSet.clear(); + resourceSet.clear(); + targetSet.clear(); // Prepare audit details AuditDetails auditDetails = AuditDetails.builder() @@ -51,20 +52,26 @@ 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.setExecutionPlanId(rs.getString("plan_execution_plan_id")); + planEntry.setCampaignId(rs.getString("plan_campaign_id")); + planEntry.setStatus(rs.getString("plan_status")); + planEntry.setAssignee(assignee); planEntry.setPlanConfigurationId(rs.getString("plan_plan_configuration_id")); - planEntry.setAdditionalDetails(getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); + planEntry.setBoundaryAncestralPath(rs.getString("plan_boundary_ancestral_path")); + planEntry.setAdditionalDetails(queryUtil.getAdditionalDetail((PGobject) rs.getObject("plan_additional_details"))); planEntry.setAuditDetails(auditDetails); } - addActivities(rs, planEntry, activityMap, conditionMap); - addResources(rs, planEntry, resourceMap); - addTargets(rs, planEntry, targetMap); + addActivities(rs, planEntry, activityMap, conditionSet); + addResources(rs, planEntry, resourceSet); + addTargets(rs, planEntry, targetSet); planMap.put(planId, planEntry); } @@ -72,15 +79,14 @@ public List extractData(ResultSet rs) throws SQLException, DataAccessExcep } private void addActivities(ResultSet rs, Plan plan, - Map activityMap, Map conditionMap) throws SQLException, DataAccessException { + Map activityMap, Set conditionSet) throws SQLException, DataAccessException { String activityId = rs.getString("plan_activity_id"); - if(!ObjectUtils.isEmpty(activityId) && activityMap.containsKey(activityId)) { - addActivityConditions(rs, activityMap.get(activityId), conditionMap); + if (!ObjectUtils.isEmpty(activityId) && activityMap.containsKey(activityId)) { + addActivityConditions(rs, activityMap.get(activityId), conditionSet); 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; @@ -103,7 +109,7 @@ else if (ObjectUtils.isEmpty(activityId)) { .dependencies(ObjectUtils.isEmpty(dependencies) ? new ArrayList<>() : Arrays.asList(rs.getString("plan_activity_dependencies").split(","))) .build(); - addActivityConditions(rs, activity, conditionMap); + addActivityConditions(rs, activity, conditionSet); if (CollectionUtils.isEmpty(plan.getActivities())) { List activityList = new ArrayList<>(); @@ -117,10 +123,10 @@ else if (ObjectUtils.isEmpty(activityId)) { } - private void addActivityConditions(ResultSet rs, Activity activity, Map conditionMap) throws SQLException, DataAccessException { + private void addActivityConditions(ResultSet rs, Activity activity, Set conditionSet) throws SQLException, DataAccessException { String conditionId = rs.getString("plan_activity_condition_id"); - if(ObjectUtils.isEmpty(conditionId) || conditionMap.containsKey(conditionId)) { + if (ObjectUtils.isEmpty(conditionId) || conditionSet.contains(conditionId)) { List conditionList = new ArrayList<>(); activity.setConditions(conditionList); return; @@ -140,7 +146,7 @@ private void addActivityConditions(ResultSet rs, Activity activity, Map conditionList = new ArrayList<>(); conditionList.add(condition); activity.setConditions(conditionList); @@ -148,15 +154,15 @@ private void addActivityConditions(ResultSet rs, Activity activity, Map resourceMap) throws SQLException, DataAccessException { + private void addResources(ResultSet rs, Plan planEntry, Set resourceSet) throws SQLException, DataAccessException { String resourceId = rs.getString("plan_resource_id"); - if(ObjectUtils.isEmpty(resourceId) || resourceMap.containsKey(resourceId)) { + if (ObjectUtils.isEmpty(resourceId) || resourceSet.contains(resourceId)) { List resourceList = new ArrayList<>(); planEntry.setResources(resourceList); return; @@ -184,14 +190,14 @@ private void addResources(ResultSet rs, Plan planEntry, Map re planEntry.getResources().add(resource); } - resourceMap.put(resource.getId(), resource); + resourceSet.add(resource.getId()); } - private void addTargets(ResultSet rs, Plan planEntry, Map targetMap) throws SQLException, DataAccessException { + private void addTargets(ResultSet rs, Plan planEntry, Set targetSet) throws SQLException, DataAccessException { String targetId = rs.getString("plan_target_id"); - if(ObjectUtils.isEmpty(targetId) || targetMap.containsKey(targetId)) { + if (ObjectUtils.isEmpty(targetId) || targetSet.contains(targetId)) { List targetList = new ArrayList<>(); planEntry.setTargets(targetList); return; @@ -225,23 +231,7 @@ private void addTargets(ResultSet rs, Plan planEntry, Map target planEntry.getTargets().add(target); } - targetMap.put(target.getId(), target); - - } - - private JsonNode getAdditionalDetail(PGobject pGobject){ - JsonNode additionalDetail = null; + targetSet.add(target.getId()); - 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/repository/rowmapper/PlanStatusCountRowMapper.java b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java new file mode 100644 index 00000000000..11e14d37763 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java @@ -0,0 +1,31 @@ +package digit.repository.rowmapper; + +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.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("status"); + Integer statusCount = rs.getInt("plan_status_count"); + + if(!ObjectUtils.isEmpty(status)) + statusCountMap.put(status, statusCount); + } + + return statusCountMap; + } +} 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 303d9477e70..c9602b1a543 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,85 +1,99 @@ package digit.service; -import digit.config.Configuration; -import digit.kafka.Producer; -import digit.repository.impl.PlanConfigurationRepositoryImpl; +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.CommonUtil; import digit.util.ResponseInfoFactory; +import digit.web.models.PlanConfiguration; import digit.web.models.PlanConfigurationRequest; import digit.web.models.PlanConfigurationResponse; import digit.web.models.PlanConfigurationSearchRequest; -import java.util.Collections; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.ResponseInfoUtil; import org.springframework.stereotype.Service; +import java.util.Collections; +import java.util.List; + @Service @Slf4j public class PlanConfigurationService { - private Producer producer; - private EnrichmentService enrichmentService; - private Configuration config; - private PlanConfigurationValidator validator; - private PlanConfigurationRepositoryImpl repository; + private PlanConfigurationRepository repository; private ResponseInfoFactory responseInfoFactory; - public PlanConfigurationService(Producer producer, EnrichmentService enrichmentService, Configuration config - , PlanConfigurationValidator validator, PlanConfigurationRepositoryImpl repository, ResponseInfoFactory responseInfoFactory) { - this.producer = producer; + private WorkflowValidator workflowValidator; + + private WorkflowService workflowService; + + private CommonUtil commonUtil; + + public PlanConfigurationService(EnrichmentService enrichmentService, PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory, WorkflowService workflowService, WorkflowValidator workflowValidator, CommonUtil commonUtil) { this.enrichmentService = enrichmentService; - this.config = config; this.validator = validator; this.repository = repository; this.responseInfoFactory = responseInfoFactory; + this.workflowService = workflowService; + this.workflowValidator = workflowValidator; + this.commonUtil = commonUtil; } /** * Creates a new plan configuration based on the provided request. + * * @param request The request containing the plan configuration details. * @return The created plan configuration request. */ - public PlanConfigurationRequest create(PlanConfigurationRequest request) { + public PlanConfigurationResponse create(PlanConfigurationRequest request) { enrichmentService.enrichPlanConfigurationBeforeValidation(request); validator.validateCreate(request); enrichmentService.enrichCreate(request); repository.create(request); - return request; + + return PlanConfigurationResponse.builder() + .planConfiguration(Collections.singletonList(request.getPlanConfiguration())) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .build(); } /** * Searches for plan configurations based on the provided search criteria. + * * @param request The search request containing the criteria. * @return A list of plan configurations that match the search criteria. */ public PlanConfigurationResponse search(PlanConfigurationSearchRequest request) { validator.validateSearchRequest(request); - PlanConfigurationResponse response = PlanConfigurationResponse.builder(). + List planConfigurations = repository.search(request.getPlanConfigurationSearchCriteria()); + commonUtil.sortOperationsByExecutionOrder(planConfigurations); + return PlanConfigurationResponse.builder(). responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) - .planConfiguration(repository.search(request.getPlanConfigurationSearchCriteria())) + .planConfiguration(planConfigurations) .totalCount(repository.count(request.getPlanConfigurationSearchCriteria())) .build(); - - return response; } /** * Updates an existing plan configuration based on the provided request. + * * @param request The request containing the updated plan configuration details. * @return The response containing the updated plan configuration. */ public PlanConfigurationResponse update(PlanConfigurationRequest request) { validator.validateUpdateRequest(request); enrichmentService.enrichUpdate(request); + workflowValidator.validateWorkflow(request); + workflowService.invokeWorkflowForStatusUpdate(request); repository.update(request); - // Build and return response back to controller return PlanConfigurationResponse.builder() .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(request.getRequestInfo(), Boolean.TRUE)) .planConfiguration(Collections.singletonList(request.getPlanConfiguration())) 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..afa9ee46f38 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java @@ -0,0 +1,91 @@ +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; +import java.util.List; + +@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) { + // 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(planEmployeeAssignmentList) + .totalCount(repository.count(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); + + 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/PlanEnricher.java b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java deleted file mode 100644 index 75d79c840a3..00000000000 --- a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java +++ /dev/null @@ -1,109 +0,0 @@ -package digit.service; - -import digit.web.models.PlanRequest; -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; - -@Component -public class PlanEnricher { - - /** - * Enriches the plan create request - * @param body - */ - public void enrichPlanCreate(PlanRequest body) { - if (body.getPlan() == null) { - throw new IllegalArgumentException("Plan details are missing in the request."); - } - // Generate id for plan - UUIDEnrichmentUtil.enrichRandomUuid(body.getPlan(), "id"); - - // Generate id for activities - body.getPlan().getActivities().forEach(activity -> UUIDEnrichmentUtil.enrichRandomUuid(activity, "id")); - - // Generate id for activity conditions - body.getPlan().getActivities().forEach(activity -> { - if(!CollectionUtils.isEmpty(activity.getConditions())) { - UUIDEnrichmentUtil.enrichRandomUuid(activity.getConditions(), "id"); - } - }); - - // Set empty value in dependencies list when it is empty or null - body.getPlan().getActivities().forEach(activity -> { - if(CollectionUtils.isEmpty(activity.getDependencies())) { - List emptyStringList = new ArrayList<>(); - emptyStringList.add(""); - activity.setDependencies(emptyStringList); - } - }); - - // Generate id for resources - body.getPlan().getResources().forEach(resource -> UUIDEnrichmentUtil.enrichRandomUuid(resource, "id")); - - // Generate id for targets - body.getPlan().getTargets().forEach(target -> UUIDEnrichmentUtil.enrichRandomUuid(target, "id")); - - // Enrich audit details - body.getPlan().setAuditDetails(AuditDetailsEnrichmentUtil - .prepareAuditDetails(body.getPlan().getAuditDetails(), body.getRequestInfo(), Boolean.TRUE)); - - } - - /** - * Enriches the plan update request - * @param body - */ - public void enrichPlanUpdate(PlanRequest body) { - // Generate uuid for new activities - Set newActivityUuids = new HashSet<>(); - body.getPlan().getActivities().forEach(activity -> { - if(ObjectUtils.isEmpty(activity.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(activity, "id"); - newActivityUuids.add(activity.getId()); - } - }); - - // Generate uuid for new activity conditions - body.getPlan().getActivities().forEach(activity -> { - if(!CollectionUtils.isEmpty(activity.getConditions()) && newActivityUuids.contains(activity.getId())) { - activity.getConditions().forEach(condition -> { - if(ObjectUtils.isEmpty(condition.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(condition, "id"); - } - }); - } - }); - - // Set empty value in dependencies list when it is empty or null - body.getPlan().getActivities().forEach(activity -> { - if(CollectionUtils.isEmpty(activity.getDependencies())) { - List emptyStringList = new ArrayList<>(); - emptyStringList.add(""); - activity.setDependencies(emptyStringList); - } - }); - - // Generate uuid for new resources - body.getPlan().getResources().forEach(resource -> { - if(ObjectUtils.isEmpty(resource.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(resource, "id"); - } - }); - - // Generate uuid for new targets - body.getPlan().getTargets().forEach(target -> { - if(ObjectUtils.isEmpty(target.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(target, "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 new file mode 100644 index 00000000000..8282a0fea74 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java @@ -0,0 +1,98 @@ +package digit.service; + +import digit.repository.PlanFacilityRepository; +import digit.service.enrichment.PlanFacilityEnricher; +import digit.service.validator.PlanFacilityValidator; +import digit.util.ResponseInfoFactory; +import digit.web.models.PlanFacility; +import digit.web.models.PlanFacilityRequest; +import digit.web.models.PlanFacilityResponse; +import org.egov.common.utils.ResponseInfoUtil; +import digit.web.models.PlanFacilitySearchRequest; +import org.springframework.stereotype.Service; +import java.util.Collections; +import java.util.List; + +@Service +public class PlanFacilityService { + + 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; + this.responseInfoFactory = responseInfoFactory; + this.planFacilityEnricher = planFacilityEnricher; + this.planFacilityRepository = planFacilityRepository; + } + + /** + * This method processes the requests that come for creating plan facilities. + * + * @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 + 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 + return PlanFacilityResponse.builder() + .planFacility(Collections.singletonList(planFacilityRequest.getPlanFacility())) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(planFacilityRequest.getRequestInfo(), Boolean.TRUE)) + .build(); + } + + /** + * 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 planFacilitySearchRequest) { + // Enrich search request + planFacilityEnricher.enrichSearchRequest(planFacilitySearchRequest); + + // Delegate request to repository + List planFacilityList = planFacilityRepository.search(planFacilitySearchRequest.getPlanFacilitySearchCriteria()); + + // Build and return response back to controller + return PlanFacilityResponse.builder() + .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(planFacilitySearchRequest.getRequestInfo(), Boolean.TRUE)) + .planFacility(planFacilityList) + .totalCount(planFacilityRepository.count(planFacilitySearchRequest.getPlanFacilitySearchCriteria())) + .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 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(); + } + +} 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..dad7e8b7d83 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,16 +1,16 @@ package digit.service; import digit.repository.PlanRepository; -import digit.web.models.Plan; -import digit.web.models.PlanRequest; -import digit.web.models.PlanResponse; -import digit.web.models.PlanSearchRequest; +import digit.service.enrichment.PlanEnricher; +import digit.service.validator.PlanValidator; +import digit.service.workflow.WorkflowService; +import digit.web.models.*; import org.egov.common.utils.ResponseInfoUtil; import org.springframework.stereotype.Service; -import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; @Service public class PlanService { @@ -21,10 +21,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 +42,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); @@ -58,10 +64,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); + // Build and return response back to controller return PlanResponse.builder() .responseInfo(ResponseInfoUtil.createResponseInfoFromRequestInfo(body.getRequestInfo(), Boolean.TRUE)) .plan(planList) + .totalCount(count) + .statusCount(statusCountMap) .build(); } @@ -77,6 +91,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); @@ -86,4 +103,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 deleted file mode 100644 index b52c3450c6d..00000000000 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ /dev/null @@ -1,383 +0,0 @@ -package digit.service; - -import com.jayway.jsonpath.JsonPath; -import digit.repository.PlanConfigurationRepository; -import digit.repository.PlanRepository; -import digit.util.MdmsUtil; -import digit.web.models.*; -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 java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_CODE; -import static digit.config.ServiceConstants.INVALID_PLAN_CONFIG_ID_MESSAGE; -import static digit.config.ServiceConstants.JSONPATH_ERROR_CODE; -import static digit.config.ServiceConstants.JSONPATH_ERROR_MESSAGE; -import static digit.config.ServiceConstants.MDMS_MASTER_METRIC; -import static digit.config.ServiceConstants.MDMS_MASTER_UOM; -import static digit.config.ServiceConstants.MDMS_PLAN_MODULE_NAME; -import static digit.config.ServiceConstants.METRIC_NOT_FOUND_IN_MDMS_CODE; -import static digit.config.ServiceConstants.METRIC_NOT_FOUND_IN_MDMS_MESSAGE; -import static digit.config.ServiceConstants.METRIC_UNIT_NOT_FOUND_IN_MDMS_CODE; -import static digit.config.ServiceConstants.METRIC_UNIT_NOT_FOUND_IN_MDMS_MESSAGE; - -@Component -public class PlanValidator { - - private PlanRepository planRepository; - - private PlanConfigurationRepository planConfigurationRepository; - - private MdmsUtil mdmsUtil; - - public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil) { - this.planRepository = planRepository; - this.planConfigurationRepository = planConfigurationRepository; - this.mdmsUtil = mdmsUtil; - } - - /** - * This method performs business validations on plan create requests - * @param request - */ - public void validatePlanCreate(PlanRequest request) { - String rootTenantId = request.getPlan().getTenantId().split("\\.")[0]; - Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - - // Validate activities - validateActivities(request); - - // Validate plan configuration existence - validatePlanConfigurationExistence(request); - - // Validate resources - validateResources(request); - - // Validate resource-activity linkage - validateResourceActivityLinkage(request); - - // Validate target-activity linkage - validateTargetActivityLinkage(request); - - // Validate dependencies - validateActivityDependencies(request); - - // Validate Target's Metrics against MDMS - validateTargetMetrics(request, mdmsData); - - // Validate Metric Detail's Unit against MDMS - validateMetricDetailUnit(request, mdmsData); - } - - /** - * This validation method validates if the dependent activities are valid and if they form a cycle - * @param request - */ - private void validateActivityDependencies(PlanRequest request) { - // Check if dependent activity codes are valid - validateDependentActivityCodes(request); - - // Check if dependent activities form a cycle - checkForCycleInActivityDependencies(request); - } - - /** - * This method checks if the activity dependencies form a cycle - * @param request - */ - private void checkForCycleInActivityDependencies(PlanRequest request) { - Map> activityCodeVsDependenciesMap = request.getPlan().getActivities().stream() - .collect(Collectors.toMap(Activity::getCode, - activity -> CollectionUtils.isEmpty(activity.getDependencies()) ? List.of() : activity.getDependencies())); - - activityCodeVsDependenciesMap.keySet().forEach(activityCode -> { - activityCodeVsDependenciesMap.get(activityCode).forEach(dependency -> { - if(activityCodeVsDependenciesMap.get(dependency).contains(activityCode)) - throw new CustomException("CYCLIC_ACTIVITY_DEPENDENCY", "Cyclic activity dependency found"); - }); - }); - } - - /** - * This method validates if the dependent activity codes are valid - * @param request - */ - private void validateDependentActivityCodes(PlanRequest request) { - // Collect all activity codes - Set activityCodes = request.getPlan().getActivities().stream() - .map(Activity::getCode) - .collect(Collectors.toSet()); - - // Check if the dependent activity codes are valid - request.getPlan().getActivities().forEach(activity -> { - if(!CollectionUtils.isEmpty(activity.getDependencies())) { - activity.getDependencies().forEach(dependency -> { - if(!activityCodes.contains(dependency)) - throw new CustomException("INVALID_ACTIVITY_DEPENDENCY", "Activity dependency is invalid"); - }); - } - }); - } - - - /** - * 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) - throw new CustomException("ACTIVITIES_CANNOT_BE_NULL","Activities list in Plan cannot be null"); - - Set activityCodes = request.getPlan().getActivities().stream() - .map(Activity::getCode) - .collect(Collectors.toSet()); - - // If activity codes are not unique, throw an exception - if(activityCodes.size() != request.getPlan().getActivities().size()) { - throw new CustomException("DUPLICATE_ACTIVITY_CODES", "Activity codes within the plan should be unique"); - } - - // If execution plan id is not provided, providing activities is mandatory - if(ObjectUtils.isEmpty(request.getPlan().getExecutionPlanId()) - && CollectionUtils.isEmpty(request.getPlan().getActivities())) { - throw new CustomException("PLAN_ACTIVITIES_MANDATORY", "Activities are mandatory if execution plan id is not provided"); - } - - // If execution plan id is provided, providing activities is not allowed - if(!ObjectUtils.isEmpty(request.getPlan().getExecutionPlanId()) - && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { - throw new CustomException("PLAN_ACTIVITIES_NOT_ALLOWED", "Activities are not allowed if execution plan id is provided"); - } - - // Validate activity dates - if(!CollectionUtils.isEmpty(request.getPlan().getActivities())) { - request.getPlan().getActivities().forEach(activity -> { - if(activity.getPlannedEndDate() < activity.getPlannedStartDate()) - throw new CustomException("INVALID_ACTIVITY_DATES", "Planned end date cannot be before planned start date"); - }); - } - } - - /** - * 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(planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() - .id(request.getPlan().getPlanConfigurationId()) - .tenantId(request.getPlan().getTenantId()) - .build()))) { - 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()) - && CollectionUtils.isEmpty(request.getPlan().getResources())) { - throw new CustomException("PLAN_RESOURCES_MANDATORY", "Resources are mandatory if plan configuration id is not provided"); - } - - // 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", "Resources are not allowed if plan configuration id is provided"); - } - - // 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 - * @param request - */ - private void validateResourceActivityLinkage(PlanRequest request) { - if(ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) - && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { - // Collect all activity codes - Set activityCodes = request.getPlan().getActivities().stream() - .map(Activity::getCode) - .collect(Collectors.toSet()); - - // Validate resource-activity linkage - request.getPlan().getResources().forEach(resource -> { - if(!activityCodes.contains(resource.getActivityCode())) - throw new CustomException("INVALID_RESOURCE_ACTIVITY_LINKAGE", "Resource-Activity linkage is invalid"); - }); - } - } - - /** - * This method validates the linkage between targets and activities - * @param request - */ - private void validateTargetActivityLinkage(PlanRequest request) { - if(!CollectionUtils.isEmpty(request.getPlan().getActivities())) { - // Collect all activity codes - Set activityCodes = request.getPlan().getActivities().stream() - .map(Activity::getCode) - .collect(Collectors.toSet()); - - // Validate target-activity linkage - request.getPlan().getTargets().forEach(target -> { - if(!activityCodes.contains(target.getActivityCode())) - throw new CustomException("INVALID_TARGET_ACTIVITY_LINKAGE", "Target-Activity linkage is invalid"); - }); - } - } - - /** - * This method performs business validations on plan update requests - * @param request - */ - public void validatePlanUpdate(PlanRequest request) { - // Validate plan existence - validatePlanExistence(request); - - String rootTenantId = request.getPlan().getTenantId().split("\\.")[0]; - Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); - - // Validate activities - validateActivities(request); - - // Validate activities uuid uniqueness - validateActivitiesUuidUniqueness(request); - - // Validate plan configuration existence - validatePlanConfigurationExistence(request); - - // Validate resources - validateResources(request); - - // Validate resource uuid uniqueness - validateResourceUuidUniqueness(request); - - // Validate target uuid uniqueness - validateTargetUuidUniqueness(request); - - // Validate resource-activity linkage - validateResourceActivityLinkage(request); - - // Validate target-activity linkage - validateTargetActivityLinkage(request); - - // Validate dependencies - validateActivityDependencies(request); - - // Validate Target's Metrics against MDMS - validateTargetMetrics(request, mdmsData); - - // Validate Metric Detail's Unit against MDMS - validateMetricDetailUnit(request, mdmsData); - - } - - private void validateTargetUuidUniqueness(PlanRequest request) { - // Collect all target uuids - Set targetUuids = request.getPlan().getTargets().stream() - .map(Target::getId) - .collect(Collectors.toSet()); - - // If target uuids are not unique, throw an exception - if(targetUuids.size() != request.getPlan().getTargets().size()) { - throw new CustomException("DUPLICATE_TARGET_UUIDS", "Target uuids should be unique"); - } - } - - private void validateResourceUuidUniqueness(PlanRequest request) { - // Collect all resource uuids - Set resourceUuids = request.getPlan().getResources().stream() - .map(Resource::getId) - .collect(Collectors.toSet()); - - // If resource uuids are not unique, throw an exception - if(resourceUuids.size() != request.getPlan().getResources().size()) { - throw new CustomException("DUPLICATE_RESOURCE_UUIDS", "Resource uuids should be unique"); - } - } - - private void validateActivitiesUuidUniqueness(PlanRequest request) { - // Collect all activity uuids - Set activityUuids = request.getPlan().getActivities().stream() - .map(Activity::getId) - .collect(Collectors.toSet()); - - // If activity uuids are not unique, throw an exception - if(activityUuids.size() != request.getPlan().getActivities().size()) { - throw new CustomException("DUPLICATE_ACTIVITY_UUIDS", "Activity uuids should be unique"); - } - } - - /** - * 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() - .ids(Collections.singleton(request.getPlan().getId())) - .build()))) { - throw new CustomException("INVALID_PLAN_ID", "Plan id provided is invalid"); - } - } - - public void validateTargetMetrics(PlanRequest request, Object mdmsData) { - Plan plan = request.getPlan(); - final String jsonPathForMetric = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_METRIC + ".*.code"; - - List metricListFromMDMS = null; - System.out.println("Jsonpath -> " + jsonPathForMetric); - try { - metricListFromMDMS = JsonPath.read(mdmsData, jsonPathForMetric); - } catch (Exception e) { - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - for (Target target : plan.getTargets()) { - if (!metricListFromMDMS.contains(target.getMetric())) { - throw new CustomException(METRIC_NOT_FOUND_IN_MDMS_CODE, METRIC_NOT_FOUND_IN_MDMS_MESSAGE); - } - } - } - - public void validateMetricDetailUnit(PlanRequest request, Object mdmsData) { - Plan plan = request.getPlan(); - - List metricDetails = plan.getTargets().stream() - .map(Target::getMetricDetail) - .toList(); - - List metricUnitListFromMDMS = null; - final String jsonPathForMetricUnit = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UOM + ".*.code"; - try { - metricUnitListFromMDMS = JsonPath.read(mdmsData, jsonPathForMetricUnit); - } catch (Exception e) { - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - for (MetricDetail metricDetail : metricDetails) { - if (!metricUnitListFromMDMS.contains(metricDetail.getMetricUnit())) { - throw new CustomException(METRIC_UNIT_NOT_FOUND_IN_MDMS_CODE, METRIC_UNIT_NOT_FOUND_IN_MDMS_MESSAGE); - } - } - } - -} 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..7dfb66f4a64 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,148 +1,144 @@ 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.AuditDetailsEnrichmentUtil; 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.USERINFO_MISSING_CODE; -import static digit.config.ServiceConstants.USERINFO_MISSING_MESSAGE; -import org.springframework.util.ObjectUtils; + +import static digit.config.ServiceConstants.DRAFT_STATUS; +import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; @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; } /** * Enriches the PlanConfigurationRequest for creating a new plan configuration. - * This method enriches the plan configuration with generated IDs, validates user information, and enriches audit details for create operation. + * 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. */ public void enrichCreate(PlanConfigurationRequest request) { - enrichPlanConfiguration(request.getPlanConfiguration()); - if(ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) - throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); - - enrichAuditDetails(request, Boolean.TRUE); - } - - /** - * Enriches the given plan configuration with generated IDs for plan, files, assumptions, operations, and resource mappings. - * @param planConfiguration The PlanConfiguration to be enriched. - */ - public void enrichPlanConfiguration(PlanConfiguration planConfiguration) { + 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"); // 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")); + } - /** - * Enriches the audit details for the PlanConfigurationRequest based on the operation type (create or update). - * @param request The PlanConfigurationRequest for which audit details are to be enriched. - * @param isCreate A boolean indicating whether the operation is a create or update operation. - */ - public void enrichAuditDetails(PlanConfigurationRequest request, Boolean isCreate) { - PlanConfiguration planConfiguration = request.getPlanConfiguration(); - planConfiguration.setAuditDetails(AuditDetailsEnrichmentUtil - .prepareAuditDetails(planConfiguration.getAuditDetails(), request.getRequestInfo(), isCreate)); + planConfiguration.setAuditDetails(prepareAuditDetails(planConfiguration.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); } /** * 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. */ public void enrichUpdate(PlanConfigurationRequest request) { - enrichPlanConfigurationForUpdate(request); - if (request.getRequestInfo().getUserInfo() == null) - throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); + PlanConfiguration planConfiguration = request.getPlanConfiguration(); - enrichAuditDetails(request, Boolean.FALSE); - } + // Generate id for Files + if (!CollectionUtils.isEmpty(planConfiguration.getFiles())) { + planConfiguration.getFiles().forEach(file -> { + if (ObjectUtils.isEmpty(file.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); + } + enrichActiveForResourceMapping(file, request.getPlanConfiguration().getResourceMapping()); + }); + } - /** - * Enriches the plan configuration for update by generating IDs for files, assumptions, operations, and resource mappings if they are empty. - * @param request The PlanConfigurationRequest to be enriched for update operation. - */ - public void enrichPlanConfigurationForUpdate(PlanConfigurationRequest request) { - PlanConfiguration planConfiguration = request.getPlanConfiguration(); + // Generate id for Assumptions + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { + planConfiguration.getAssumptions().forEach(assumption -> { + if (ObjectUtils.isEmpty(assumption.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id"); + } + }); + } - // For Files - 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"); - } - }); - - // For Operations - 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"); - } - }); + // Generate id for Operations + if (!CollectionUtils.isEmpty(planConfiguration.getOperations())) { + planConfiguration.getOperations().forEach(operation -> { + if (ObjectUtils.isEmpty(operation.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(operation, "id"); + } + }); + } + // Generate id for ResourceMappings + if (!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { + planConfiguration.getResourceMapping().forEach(resourceMapping -> { + if (ObjectUtils.isEmpty(resourceMapping.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); + } + }); + } + + planConfiguration.setAuditDetails(prepareAuditDetails(request.getPlanConfiguration().getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); + + //enrich execution order for operations on setup complete + if (commonUtil.checkForEmptyOperationsOrAssumptions(planConfiguration)) { + enrichExecutionOrderForOperations(planConfiguration); + } } /** * 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) { if (!file.getActive()) { // Set all corresponding resource mappings to inactive - for (ResourceMapping mapping : resourceMappings) { - if (mapping.getFilestoreId().equals(file.getFilestoreId())) { - mapping.setActive(false); - } - } + resourceMappings.stream() + .filter(mapping -> mapping.getFilestoreId().equals(file.getFilestoreId())) + .forEach(mapping -> mapping.setActive(false)); } } @@ -153,34 +149,55 @@ 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 - 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); - } - }); - - 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.getFiles())) { + planConfiguration.getFiles().forEach(file -> { + if (ObjectUtils.isEmpty(file.getId())) { + file.setActive(Boolean.TRUE); + } + }); + } + + if (!CollectionUtils.isEmpty(planConfiguration.getOperations())) { + planConfiguration.getOperations().forEach(operation -> { + if (ObjectUtils.isEmpty(operation.getId())) { + operation.setActive(Boolean.TRUE); + } + }); + } + + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { + planConfiguration.getAssumptions().forEach(assumption -> { + if (ObjectUtils.isEmpty(assumption.getId())) { + assumption.setActive(Boolean.TRUE); + } + }); + } + + if (!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { + planConfiguration.getResourceMapping().forEach(resourceMapping -> { + if (ObjectUtils.isEmpty(resourceMapping.getId())) { + resourceMapping.setActive(Boolean.TRUE); + } + }); + } + } + + /** + * 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()) { + if(operation.getActive()) + 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 new file mode 100644 index 00000000000..c4072ca637e --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java @@ -0,0 +1,71 @@ +package digit.service.enrichment; + +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. + * + * @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 active true + planEmployeeAssignment.setActive(Boolean.TRUE); + + // Set Audit Details for Plan employee assignment + planEmployeeAssignment.setAuditDetails(prepareAuditDetails(planEmployeeAssignment.getAuditDetails(), + request.getRequestInfo(), + Boolean.TRUE)); + + // Add plan config name to which the employee is mapped + planEmployeeAssignment.setPlanConfigurationName(commonUtil.getPlanConfigName(planEmployeeAssignment.getTenantId(), planEmployeeAssignment.getPlanConfigurationId())); + } + + /** + * 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/service/enrichment/PlanEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEnricher.java new file mode 100644 index 00000000000..17364bfdb6d --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanEnricher.java @@ -0,0 +1,231 @@ +package digit.service.enrichment; + +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; +import org.egov.common.utils.UUIDEnrichmentUtil; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import java.util.*; + +@Component +public class PlanEnricher { + + /** + * Enriches the plan create request + * @param body + */ + public void enrichPlanCreate(PlanRequest body) { + if (body.getPlan() == null) { + throw new IllegalArgumentException("Plan details are missing in the request."); + } + // Generate id for plan + UUIDEnrichmentUtil.enrichRandomUuid(body.getPlan(), "id"); + + // Generate id for activities + body.getPlan().getActivities().forEach(activity -> UUIDEnrichmentUtil.enrichRandomUuid(activity, "id")); + + // Generate id for activity conditions + body.getPlan().getActivities().forEach(activity -> { + if(!CollectionUtils.isEmpty(activity.getConditions())) { + UUIDEnrichmentUtil.enrichRandomUuid(activity.getConditions(), "id"); + } + }); + + // Set empty value in dependencies list when it is empty or null + body.getPlan().getActivities().forEach(activity -> { + if(CollectionUtils.isEmpty(activity.getDependencies())) { + List emptyStringList = new ArrayList<>(); + emptyStringList.add(""); + activity.setDependencies(emptyStringList); + } + }); + + // Generate id for resources + body.getPlan().getResources().forEach(resource -> UUIDEnrichmentUtil.enrichRandomUuid(resource, "id")); + + // Generate id for targets + body.getPlan().getTargets().forEach(target -> UUIDEnrichmentUtil.enrichRandomUuid(target, "id")); + + // Enrich audit details + body.getPlan().setAuditDetails(AuditDetailsEnrichmentUtil + .prepareAuditDetails(body.getPlan().getAuditDetails(), body.getRequestInfo(), Boolean.TRUE)); + + } + + /** + * Enriches the plan update request + * @param body + */ + public void enrichPlanUpdate(PlanRequest body) { + // Generate uuid for new activities + Set newActivityUuids = new HashSet<>(); + body.getPlan().getActivities().forEach(activity -> { + if(ObjectUtils.isEmpty(activity.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(activity, "id"); + newActivityUuids.add(activity.getId()); + } + }); + + // Generate uuid for new activity conditions + body.getPlan().getActivities().forEach(activity -> { + if(!CollectionUtils.isEmpty(activity.getConditions()) && newActivityUuids.contains(activity.getId())) { + activity.getConditions().forEach(condition -> { + if(ObjectUtils.isEmpty(condition.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(condition, "id"); + } + }); + } + }); + + // Set empty value in dependencies list when it is empty or null + body.getPlan().getActivities().forEach(activity -> { + if(CollectionUtils.isEmpty(activity.getDependencies())) { + List emptyStringList = new ArrayList<>(); + emptyStringList.add(""); + activity.setDependencies(emptyStringList); + } + }); + + // Generate uuid for new resources + body.getPlan().getResources().forEach(resource -> { + if(ObjectUtils.isEmpty(resource.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(resource, "id"); + } + }); + + // Generate uuid for new targets + body.getPlan().getTargets().forEach(target -> { + if(ObjectUtils.isEmpty(target.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(target, "id"); + } + }); + + // Enriching last modified time for update + body.getPlan().getAuditDetails().setLastModifiedTime(System.currentTimeMillis()); + } + + /** + * 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/enrichment/PlanFacilityEnricher.java b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java new file mode 100644 index 00000000000..a07530dbfd2 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java @@ -0,0 +1,213 @@ +package digit.service.enrichment; + +import digit.util.BoundaryUtil; +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.boundary.BoundarySearchResponse; +import digit.web.models.boundary.EnrichedBoundary; +import digit.web.models.census.*; +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.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; +import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; + +@Component +@Slf4j +public class PlanFacilityEnricher { + + private CommonUtil commonUtil; + + private CensusUtil censusUtil; + + private BoundaryUtil boundaryUtil; + + public PlanFacilityEnricher(CommonUtil commonUtil, CensusUtil censusUtil, BoundaryUtil boundaryUtil) { + this.commonUtil = commonUtil; + this.censusUtil = censusUtil; + this.boundaryUtil = boundaryUtil; + } + + /** + * Enriches the plan facility create request + * + * @param planFacilityRequest + */ + public void enrichPlanFacilityCreate(@Valid PlanFacilityRequest planFacilityRequest) { + // 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(Boolean.TRUE); + + // Add plan config name to which the facility is mapped + planFacilityRequest.getPlanFacility().setPlanConfigurationName(commonUtil.getPlanConfigName(planFacilityRequest.getPlanFacility().getTenantId(), planFacilityRequest.getPlanFacility().getPlanConfigurationId())); + } + + public void enrichJurisdictionMapping(PlanFacilityRequest request, String hierarchyType) { + BoundarySearchResponse boundarySearchResponse = boundaryUtil.fetchBoundaryData(request.getRequestInfo(), request.getPlanFacility().getResidingBoundary(), request.getPlanFacility().getTenantId(), hierarchyType, Boolean.TRUE, Boolean.FALSE); + + EnrichedBoundary boundary = boundarySearchResponse.getTenantBoundary().get(0).getBoundary().get(0); + Map jurisdictionMapping = new LinkedHashMap<>(); + + jurisdictionMapping.put(boundary.getBoundaryType(), boundary.getCode()); + 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()); + jurisdictionMapping.put(boundary.getBoundaryType(), boundary.getCode()); + } + + // Setting the boundary ancestral path for the provided boundary + request.getPlanFacility().setBoundaryAncestralPath(boundaryAncestralPath.toString()); + + // Setting jurisdiction mapping for the provided boundary + request.getPlanFacility().setJurisdictionMapping(jurisdictionMapping); + } + + /** + * Enriches the plan facility update request + * + * @param planFacilityRequest The PlanFacilityRequest object contains the plan facility to be enriched. + */ + public void enrichPlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { + PlanFacility planFacility = planFacilityRequest.getPlanFacility(); + + //enrich audit details + planFacility.setAuditDetails(prepareAuditDetails(planFacilityRequest.getPlanFacility().getAuditDetails(), planFacilityRequest.getRequestInfo(), Boolean.FALSE)); + + // enrich serving population + 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()); + + 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()); + + // 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); + + updateServingPopulation(boundariesToBeSearched, planFacility, boundaryToPopMap, servingPopulation); + } + } + + /** + * 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()); + + for(String boundary : boundariesToBeSearched) { + Long totalPopulation = boundaryToPopMap.get(boundary); + + if (!currentServiceBoundaries.contains(boundary)) { + servingPopulation = servingPopulation.subtract(BigDecimal.valueOf(totalPopulation)); + } else if (!initialServiceBoundaries.contains(boundary)) { + servingPopulation = servingPopulation.add(BigDecimal.valueOf(totalPopulation)); + } + } + Map fieldToUpdate = new HashMap<>(); + fieldToUpdate.put(SERVING_POPULATION_CODE, servingPopulation); + + planFacility.setAdditionalDetails(commonUtil.updateFieldInAdditionalDetails(planFacility.getAdditionalDetails(), fieldToUpdate)); + } + + /** + * 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 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/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index 115c19855d8..58041c3324d 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,262 +1,281 @@ 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.CommonUtil; import digit.util.MdmsUtil; +import digit.util.MdmsV2Util; import digit.web.models.*; - -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - +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; 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.*; @Component @Slf4j public class PlanConfigurationValidator { - private MdmsUtil mdmsUtil; + private MdmsV2Util mdmsV2Util; + private PlanConfigurationRepository planConfigRepository; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository) { + private CommonUtil commonUtil; + + private 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; } /** * Validates the create request for plan configuration, including assumptions against MDMS data. + * * @param request The create request for plan configuration. */ public void validateCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; + 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, null); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); + + // Validate if the plan configuration for the provided name and campaign id already exists + validateDuplicateRecord(planConfiguration); + + // 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); - validateAssumptionValue(planConfiguration); - validateFilestoreId(planConfiguration); + + // Validate that the assumption keys in the request are unique + validateAssumptionUniqueness(planConfiguration); + + // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); - validateOperationsInputAgainstMDMS(request, mdmsData); - validateResourceMappingAgainstMDMS(request, mdmsData); - validateMappedToUniqueness(planConfiguration.getResourceMapping()); + + //Validating operation's input and assumptionValue fields + validateOperations(request, campaignResponse); + + //Validating plan config name against MDMS data + validatePlanConfigName(request, mdmsData); + + // Validate the user information in the request + commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validates the vehicle id from additional details object against the data from mdms v2 + validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); + } /** - * Validates the assumption values against the assumption keys in the plan configuration. - * If an operation uses an inactive assumption, throws an exception. + * Validates if plan configuration for the provided name and campaign id already exists * - * @param planConfiguration The plan configuration to validate. + * @param planConfiguration the plan configuration from the create request */ - public void validateAssumptionValue(PlanConfiguration planConfiguration) { - // Collect all active assumption keys - Set activeAssumptionKeys = planConfiguration.getAssumptions().stream() - .filter(Assumption::getActive) - .map(Assumption::getKey) - .collect(Collectors.toSet()); + private void validateDuplicateRecord(PlanConfiguration planConfiguration) { + List planConfigurationsFromSearch = planConfigRepository.search(PlanConfigurationSearchCriteria.builder() + .tenantId(planConfiguration.getTenantId()) + .campaignId(planConfiguration.getCampaignId()) + .name(planConfiguration.getName()) + .build()); - 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 (!CollectionUtils.isEmpty(planConfigurationsFromSearch)) { + throw new CustomException(PLAN_CONFIGURATION_ALREADY_EXISTS_CODE, PLAN_CONFIGURATION_ALREADY_EXISTS_MESSAGE); } } + /** + * 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); + } + } /** - * Validates the assumption keys against MDMS data. - * @param request The request containing the plan configuration and the MDMS data. - * @param mdmsData The MDMS data. + * Validates the name of the plan configuration against a regex pattern retrieved from MDMS data. + * + * @param request the plan configuration request containing the plan configuration details + * @param mdmsData the MDMS data containing the name validation regex patterns + * @throws CustomException if the JSONPath evaluation fails, the name validation list from MDMS is empty, + * or the plan configuration name validation fails. */ - public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { + public void validatePlanConfigName(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; - List assumptionListFromMDMS = null; + final String jsonPathForNameValidation = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_NAME_VALIDATION + "[*].data"; + List nameValidationListFromMDMS = null; try { - log.info(jsonPathForAssumption); - assumptionListFromMDMS = JsonPath.read(mdmsData, jsonPathForAssumption); + nameValidationListFromMDMS = JsonPath.read(mdmsData, jsonPathForNameValidation); } catch (Exception e) { - log.error(e.getMessage()); + log.error(jsonPathForNameValidation); throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - for(Assumption assumption : planConfiguration.getAssumptions()) - { - 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); - } + if (CollectionUtils.isEmpty(nameValidationListFromMDMS)) { + throw new CustomException(NAME_VALIDATION_LIST_EMPTY_CODE, NAME_VALIDATION_LIST_EMPTY_MESSAGE); + } + + String regexPattern = (String) nameValidationListFromMDMS.get(0); + if (!commonUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) { + throw new CustomException(NAME_VALIDATION_FAILED_CODE, NAME_VALIDATION_FAILED_MESSAGE); } } + /** - * Validates the file store IDs in the provided PlanConfiguration's Resource Mapping list. - * @param planConfiguration The PlanConfiguration to validate. + * Validates the assumption values against the assumption keys in the plan configuration. + * If an operation uses an inactive assumption, throws an exception. + * + * @param planConfiguration The plan configuration 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); - } - } - } /** - * Validates the template identifiers of files in the PlanConfigurationRequest against the list of template identifiers - * obtained from MDMS (Master Data Management System) data. + * Validates the assumption keys against MDMS data. * - * @param request The PlanConfigurationRequest containing the PlanConfiguration to validate. - * @param mdmsData The MDMS data containing template identifiers to validate against. + * @param request The request containing the plan configuration and the MDMS data. + * @param mdmsData The MDMS data. */ - public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { + public void validateAssumptionKeyAgainstMDMS(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); - } + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { - 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); + Object additionalDetails = request.getPlanConfiguration().getAdditionalDetails(); + if (additionalDetails == null) { + throw new CustomException(ADDITIONAL_DETAILS_MISSING_CODE, ADDITIONAL_DETAILS_MISSING_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); - } - } + 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); + assumptionListFromMDMS = JsonPath.read(mdmsData, jsonPathForAssumption); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_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); - } + Set assumptionSetFromMDMS = new HashSet<>(assumptionListFromMDMS); + 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 + assumption.getKey() + " at JSONPath: " + jsonPathForAssumption); + } + }); } - } - /** - * Validates the operations input against the Master Data Management System (MDMS) data. + * Validates the uniqueness of assumption keys in the provided PlanConfiguration. + * If any duplicate keys are found, a CustomException is thrown. * - * @param request The PlanConfigurationRequest containing the plan configuration and other details. - * @param mdmsData The MDMS data containing the master rule configure inputs. + * @param planConfig the PlanConfiguration object containing a list of Assumptions to validate + * @throws CustomException if a duplicate assumption key is found */ - 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); - } - } - } + public void validateAssumptionUniqueness(PlanConfiguration planConfig) { + Set assumptionKeys = new HashSet<>(); - // helper function - public static List getRuleConfigInputsFromSchema(List schemas, List templateIds, List inputFileTypes) { - if (schemas == null) { - return new ArrayList<>(); - } - Set 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 ArrayList<>(); - for(Map.Entry column : columns.entrySet()){ - LinkedHashMap data = column.getValue(); - if(data.get(MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT)){ - finalData.add(column.getKey()); + for (Assumption assumption : planConfig.getAssumptions()) { + if (assumption.getActive() != Boolean.FALSE) { + if (assumptionKeys.contains(assumption.getKey())) { + throw new CustomException(DUPLICATE_ASSUMPTION_KEY_CODE, DUPLICATE_ASSUMPTION_KEY_MESSAGE + assumption.getKey()); } + assumptionKeys.add(assumption.getKey()); } } - return new ArrayList<>(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. + * Validates the template identifiers of files in the PlanConfigurationRequest against the list of template identifiers + * obtained from MDMS (Master Data Management System) data. * - * @param resourceMappings The list of 'ResourceMapping' objects to validate. - * @throws CustomException If a duplicate 'mappedTo' value is found. + * @param request The PlanConfigurationRequest containing the PlanConfiguration to validate. + * @param mdmsData The MDMS data containing template identifiers to validate against. */ - 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()); + public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { + PlanConfiguration planConfiguration = request.getPlanConfiguration(); + if (!CollectionUtils.isEmpty(planConfiguration.getFiles())) { + final String jsonPathForTemplateIdentifier = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_UPLOAD_CONFIGURATION + ".*.id"; + final String jsonPathForTemplateIdentifierIsRequired = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + 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); } + + HashSet templateIdentifierSetFromMDMS = new HashSet<>(templateIdentifierListFromMDMS); + HashSet requiredTemplateIdentifierSetFromMDMS = new HashSet<>(requiredTemplateIdentifierFromMDMS); + + for (File file : planConfiguration.getFiles()) { + if (!templateIdentifierSetFromMDMS.contains(file.getTemplateIdentifier())) { + log.error(TEMPLATE_IDENTIFIER_NOT_FOUND_IN_MDMS_MESSAGE + file.getTemplateIdentifier()); + 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 (requiredTemplateIdentifierSetFromMDMS.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_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE + 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 + if(commonUtil.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); + } + }); + } + } } - /** * Validates the search request for plan configurations. + * * @param planConfigurationSearchRequest The search request for plan configurations. */ public void validateSearchRequest(PlanConfigurationSearchRequest planConfigurationSearchRequest) { @@ -276,43 +295,60 @@ private void validateSearchCriteria(PlanConfigurationSearchRequest planConfigura /** * Validates the update request for plan configuration, including assumptions against MDMS data. + * * @param request The update request for plan configuration. */ public void validateUpdateRequest(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - String rootTenantId = planConfiguration.getTenantId().split("\\.")[0]; + 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, null); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlanConfiguration().getCampaignId(), rootTenantId); + + // Validate the existence of the plan configuration in the request + validatePlanConfigExistence(request); - // Validate plan existence - PlanConfiguration planConfigurationFromDB = 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); - validateAssumptionValue(planConfiguration); - validateFilestoreId(planConfiguration); -// validateFilesActive(planConfigurationFromDB, planConfiguration); + + // Validate that the assumption keys in the request are unique + validateAssumptionUniqueness(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); - validateOperationsInputAgainstMDMS(request, mdmsData); - validateOperationDependencies(planConfiguration); - validateResourceMappingAgainstMDMS(request, mdmsData); - validateMappedToUniqueness(planConfiguration.getResourceMapping()); + + //Validating plan config name against MDMS data + validatePlanConfigName(request, mdmsData); + + // Validate the user information in the request + commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validates the vehicle id from additional details object against the data from mdms v2 + validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); } /** * Validates the existence of the plan configuration in the repository. + * * @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()) .build()); - if(CollectionUtils.isEmpty(planConfigurationList)) { + if (CollectionUtils.isEmpty(planConfigurationList)) { throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); } - return planConfigurationList.get(0); } /** @@ -323,102 +359,231 @@ 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()); + 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 + 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()); + } + }); + } + } - // 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()); - } + + /** + * 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, List mdmsV2Data) { + List vehicleIdsfromAdditionalDetails = commonUtil.extractFieldsFromJsonObject(request.getPlanConfiguration().getAdditionalDetails(), JSON_FIELD_VEHICLE_ID, List.class); + if (!CollectionUtils.isEmpty(vehicleIdsfromAdditionalDetails)) { + List vehicleIdsFromMdms = mdmsV2Data.stream() + .map(Mdms::getId) + .toList(); + + 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); + } + }); } } - /** - * 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(); - 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); + /** + * 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); + throw new CustomException(FILES_NOT_FOUND_CODE, FILES_NOT_FOUND_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)); + /** + * 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); + throw new CustomException(ASSUMPTIONS_NOT_FOUND_CODE, ASSUMPTIONS_NOT_FOUND_MESSAGE); + } + } - if (!exists) { - throw new CustomException(BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE, BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE); - } + /** + * 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); + throw new CustomException(OPERATIONS_NOT_FOUND_CODE, OPERATIONS_NOT_FOUND_MESSAGE); } + } + + /** + * 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 (commonUtil.isSetupCompleted(planConfiguration)) { + performEmptyChecks(planConfiguration); + + // Get shared data upfront + HashSet allowedColumns = getAllowedColumnsFromMDMS( + request, campaignResponse.getCampaignDetails().get(0).getProjectType() + ); + Set activeAssumptionKeys = getActiveAssumptionKeys(planConfiguration); + validateOperationInputs(planConfiguration, allowedColumns, activeAssumptionKeys); + validateOperationAssumptionValues(planConfiguration, allowedColumns, activeAssumptionKeys); } + } /** - * Return all properties that has isTrue flag as a true. - * @param schemas schema object. - * @param templateIds template ids list. - * @param inputFileTypes list of file type. - * @return + * 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. */ - public static List getIsTruePropertyFromSchema(List schemas, List templateIds, List inputFileTypes) { - if (schemas == null) { - return new ArrayList<>(); + 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); + } + } } - Set 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 ArrayList<>(); - for(Map.Entry column : columns.entrySet()){ - LinkedHashMap data = column.getValue(); - if(data.get(MDMS_SCHEMA_PROPERTIES_IS_REQUIRED)){ - finalData.add(column.getKey()); + + // 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 new ArrayList<>(finalData); + + 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 activeAssumptionKeys) { + // Set to keep track of previous outputs + Set previousOutputs = new HashSet<>(); + + for (Operation operation : planConfiguration.getOperations()) { + // Validate input + if (operation.getActive() && !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()); + } + + // Add current operation's output to previousOutputs if it's active + if (operation.getActive()) { + previousOutputs.add(operation.getOutput()); + } + } } - public void validateFilesActive(PlanConfiguration planConfigurationFromDB, PlanConfiguration planConfiguration) - { - // Create a map of files from planConfigurationFromDB using the file ID as the key - Map filesFromDBMap = planConfigurationFromDB.getFiles().stream() - .collect(Collectors.toMap(File::getId, file -> file)); - - // Iterate over the files in planConfiguration - for (File file : planConfiguration.getFiles()) { - File dbFile = filesFromDBMap.get(file.getId()); - // If the file exists in planConfigurationFromDB and has been made active after being inactive - if (dbFile == null) { - throw new CustomException("FILES_ACTIVE_STATUS_CHANGE_NOT_ALLOWED", "Files cannot be made active after being inactive, please upload new file"); + /** + * 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 (operation.getActive() && !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() && operation.getSource() == Source.MDMS) { + previousOutputs.add(operation.getOutput()); } } } + } 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..772ec6dd133 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java @@ -0,0 +1,349 @@ +package digit.service.validator; + +import digit.config.Configuration; +import digit.repository.PlanEmployeeAssignmentRepository; +import digit.util.*; +import digit.web.models.*; +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; +import org.springframework.util.*; + +import java.util.*; +import java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; + +@Slf4j +@Component +public class PlanEmployeeAssignmentValidator { + + private MultiStateInstanceUtil centralInstanceUtil; + + private MdmsUtil mdmsUtil; + + private UserUtil userUtil; + + private CommonUtil commonUtil; + + private CampaignUtil campaignUtil; + + private PlanEmployeeAssignmentRepository repository; + + private 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.userUtil = userUtil; + this.commonUtil = commonUtil; + this.campaignUtil = campaignUtil; + this.repository = repository; + this.config = config; + } + + /** + * 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 = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); + UserDetailResponse userDetailResponse = userUtil.fetchUserDetail(userUtil.getUserSearchReq(request.getRequestInfo(), planEmployeeAssignment.getEmployeeId(), planEmployeeAssignment.getTenantId())); + + // Validate if a same assignment already exists + validateDuplicateRecord(request); + + // Validate if plan config id exists + validatePlanConfigId(planConfigurations); + + // Validate role of employee against User Service + validateRoleAgainstUserService(planEmployeeAssignment, userDetailResponse); + + // Validate if role of employee is a conflicting role + validateRoleConflict(planEmployeeAssignment); + + // Validate campaign id, employee jurisdiction and highest root jurisdiction in case of Root role + validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, 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) { + + // 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(); + + if (!userRolesFromUserService.contains(planEmployeeAssignment.getRole())) { + throw new CustomException(INVALID_EMPLOYEE_ROLE_CODE, INVALID_EMPLOYEE_ROLE_MESSAGE); + } + } + + /** + * Validates if the plan employee assignment for the provided details already exists + * + * @param request the employee assignment create request + */ + private void validateDuplicateRecord(PlanEmployeeAssignmentRequest request) { + PlanEmployeeAssignment employeeAssignment = request.getPlanEmployeeAssignment(); + + List planEmployeeAssignmentsFromSearch = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(employeeAssignment.getTenantId()) + .planConfigurationId(employeeAssignment.getPlanConfigurationId()) + .employeeId(Collections.singletonList(employeeAssignment.getEmployeeId())) + .role(Collections.singletonList(employeeAssignment.getRole())) + .build()); + + if (!CollectionUtils.isEmpty(planEmployeeAssignmentsFromSearch)) { + throw new CustomException(PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_CODE, PLAN_EMPLOYEE_ASSIGNMENT_ALREADY_EXISTS_MESSAGE); + } + } + + /** + * 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 validateRootEmployeeJurisdiction(PlanEmployeeAssignment planEmployeeAssignment, Object mdmsData, CampaignDetail campaignDetail) { + if (planEmployeeAssignment.getRole().contains(ROOT_PREFIX)) { + Set jurisdiction = planEmployeeAssignment.getJurisdiction(); + + // Validate that National role employee should not have more than one jurisdiction assigned + if (jurisdiction.size() > 1) { + throw new CustomException(INVALID_ROOT_EMPLOYEE_JURISDICTION_CODE, INVALID_ROOT_EMPLOYEE_JURISDICTION_MESSAGE); + } + + String rootLevelJurisdiction = jurisdiction.stream().findFirst().orElse(null); + + // Fetch the highest hierarchy for Microplan from MDMS + 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 + campaignDetail.getBoundaries().stream() + .filter(boundary -> boundary.getCode().equals(rootLevelJurisdiction)) + .forEach(boundary -> { + if (!boundary.getType().toLowerCase().equals(highestHierarchy)) { + throw new CustomException(INVALID_ROOT_EMPLOYEE_JURISDICTION_CODE, INVALID_ROOT_EMPLOYEE_JURISDICTION_MESSAGE); + } + }); + } + } + + /** + * 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(Collections.singletonList(planEmployeeAssignment.getEmployeeId())) + .role(Collections.singletonList(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 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 + * @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); + Object mdmsData = mdmsUtil.fetchMdmsData(planEmployeeAssignmentRequest.getRequestInfo(), tenantId); + + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + + // 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 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_PREFIX)) { + Set jurisdiction = planEmployeeAssignment.getJurisdiction(); + + // Fetch the highest and lowest hierarchy for Microplan from MDMS + 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 + campaignDetail.getBoundaries().stream() + .filter(boundary -> jurisdiction.contains(boundary.getCode())) + .forEach(boundary -> { + if (boundary.getType().toLowerCase().equals(lowestHierarchy) || + boundary.getType().toLowerCase().equals(highestHierarchy)) { + throw new CustomException(INVALID_EMPLOYEE_JURISDICTION_CODE, INVALID_EMPLOYEE_JURISDICTION_MESSAGE); + } + }); + } + } + + /** + * 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 validateEmployeeAssignmentJurisdiction(CampaignDetail campaignDetail, PlanEmployeeAssignment planEmployeeAssignment) { + + // 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)) { + throw new CustomException(INVALID_JURISDICTION_CODE, INVALID_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 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); + } + } + + /** + * 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); + } + + if (StringUtils.isEmpty(searchCriteria.getPlanConfigurationId())) { + throw new CustomException(PLAN_CONFIG_ID_EMPTY_CODE, PLAN_CONFIG_ID_EMPTY_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 = commonUtil.searchPlanConfigId(planEmployeeAssignment.getPlanConfigurationId(), rootTenantId); + + // Validate if Plan employee assignment exists + validatePlanEmployeeAssignmentExistance(planEmployeeAssignment); + + // Validate campaign id and employee jurisdiction + validateCampaignDetails(planConfigurations.get(0).getCampaignId(), rootTenantId, request); + + } + + /** + * This method validates if the plan employee assignment provided in the update request exists + * + * @param planEmployeeAssignment The plan employee assignment details from the request + */ + 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); + } + + // Validates the existence of plan employee assignment + List planEmployeeAssignments = repository.search(PlanEmployeeAssignmentSearchCriteria.builder() + .tenantId(planEmployeeAssignment.getTenantId()) + .id(planEmployeeAssignment.getId()) + .role(Collections.singletonList(planEmployeeAssignment.getRole())) + .planConfigurationId(planEmployeeAssignment.getPlanConfigurationId()) + .employeeId(Collections.singletonList(planEmployeeAssignment.getEmployeeId())) + .build()); + + if (CollectionUtils.isEmpty(planEmployeeAssignments)) { + throw new CustomException(INVALID_PLAN_EMPLOYEE_ASSIGNMENT_CODE, INVALID_PLAN_EMPLOYEE_ASSIGNMENT_MESSAGE); + } + } + +} 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..dd7b251eaf1 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java @@ -0,0 +1,301 @@ +package digit.service.validator; + +import com.jayway.jsonpath.JsonPath; +import digit.repository.PlanConfigurationRepository; +import digit.repository.PlanFacilityRepository; +import digit.service.enrichment.PlanFacilityEnricher; +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; +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.*; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +import digit.web.models.projectFactory.Boundary; + +@Component +@Slf4j +public class PlanFacilityValidator { + private PlanFacilityRepository planFacilityRepository; + private PlanConfigurationRepository planConfigurationRepository; + private CampaignUtil campaignUtil; + private MultiStateInstanceUtil centralInstanceUtil; + private MdmsUtil mdmsUtil; + private FacilityUtil facilityUtil; + private CommonUtil commonUtil; + private PlanFacilityEnricher enrichment; + + public PlanFacilityValidator(PlanFacilityRepository planFacilityRepository, PlanConfigurationRepository planConfigurationRepository, CampaignUtil campaignUtil, MultiStateInstanceUtil centralInstanceUtil, MdmsUtil mdmsUtil, FacilityUtil facilityUtil, CommonUtil commonUtil, PlanFacilityEnricher enrichment) { + this.planFacilityRepository = planFacilityRepository; + this.planConfigurationRepository = planConfigurationRepository; + this.campaignUtil = campaignUtil; + this.centralInstanceUtil = centralInstanceUtil; + this.mdmsUtil = mdmsUtil; + this.facilityUtil = facilityUtil; + this.commonUtil = commonUtil; + this.enrichment = enrichment; + } + + /** + * 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) { + // 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); + + // Validate facility existence + validateFacilityExistence(planFacilityRequest); + + // Validate service boundaries and residing boundaries with campaign id + 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 + * and campaign-related validations. + * + * @param planFacilityRequest + */ + public void validatePlanFacilityUpdate(PlanFacilityRequest planFacilityRequest) { + String rootTenantId = centralInstanceUtil.getStateLevelTenant(planFacilityRequest.getPlanFacility().getTenantId()); + + //validate plan facility existence + validatePlanFacilityExistence(planFacilityRequest); + + List planConfigurations = fetchPlanConfigurationById(planFacilityRequest.getPlanFacility().getPlanConfigurationId(), rootTenantId); + + //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 hierarchy type for campaign + Map hierarchyMap = commonUtil.getMicroplanHierarchy(mdmsData); + String lowestHierarchy = hierarchyMap.get(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN); + + // Collect all boundary code for the campaign + Set boundaryCodes = fetchBoundaryCodes(campaignResponse.getCampaignDetails().get(0), lowestHierarchy); + + // Validate residing boundaries + validateResidingBoundaries(boundaryCodes, planFacility); + + // Validate service boundaries + validateServiceBoundaries(boundaryCodes, planFacility); + + //Enrich jurisdiction mapping and boundary ancestral path + enrichment.enrichJurisdictionMapping(planFacilityRequest, campaignResponse.getCampaignDetails().get(0).getHierarchyType()); + } + + /** + * 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().toLowerCase())) + .map(Boundary::getCode) + .collect(Collectors.toSet()); + + return boundaryCodes; + } + + /** + * 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) { + 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); + } + }); + } + + /** + * This method validates if the hierarchy type provided in the request exists + * + * @param campaignResponse + * @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_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_HIERARCHY_CONFIG + "[*]"; + + List> hierarchyConfigList = null; + 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(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN); + } + } + // 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 plan facility id provided in the update request exists + * + * @param planFacilityRequest + */ + private void validatePlanFacilityExistence(PlanFacilityRequest planFacilityRequest) { + List planFacilityListFromSearch = planFacilityRepository.search(PlanFacilitySearchCriteria.builder() + .ids(Collections.singleton(planFacilityRequest.getPlanFacility().getId())) + .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); + } + + /** + * Searches the plan config based on the plan config id provided + * + * @param planConfigurationId + * @param tenantId + * @return + */ + 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); + } + + return planConfigurations; + } + + /** + * Validates if the facility with the provided ID exists in the system. + * + * @param planFacilityRequest + */ + private void validateFacilityExistence(PlanFacilityRequest planFacilityRequest) { + 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 " + 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); + BigDecimal initialServingPop = BigDecimal.ZERO; + + Map fieldsToBeAdded = new HashMap<>(); + fieldsToBeAdded.put("facilityUsage", facility.getUsage()); + 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); + + planFacilityRequest.getPlanFacility().setAdditionalDetails( + commonUtil.updateFieldInAdditionalDetails(planFacilityRequest.getPlanFacility().getAdditionalDetails(), fieldsToBeAdded)); + } + +} diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanValidator.java new file mode 100644 index 00000000000..1fd98c823b7 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanValidator.java @@ -0,0 +1,676 @@ +package digit.service.validator; + +import com.jayway.jsonpath.JsonPath; +import digit.config.Configuration; +import digit.repository.PlanConfigurationRepository; +import digit.repository.PlanRepository; +import digit.service.PlanEmployeeService; +import digit.service.enrichment.PlanEnricher; +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.BoundaryTypeHierarchyResponse; +import digit.web.models.boundary.HierarchyRelation; +import digit.web.models.projectFactory.CampaignResponse; +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 java.util.*; +import java.util.stream.Collectors; + +import static digit.config.ServiceConstants.*; + +@Component +public class PlanValidator { + + private PlanRepository planRepository; + + private PlanConfigurationRepository planConfigurationRepository; + + private MdmsUtil mdmsUtil; + + private MultiStateInstanceUtil centralInstanceUtil; + + private CommonUtil commonUtil; + + private CampaignUtil campaignUtil; + + private PlanEmployeeService planEmployeeService; + + private 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; + this.centralInstanceUtil = centralInstanceUtil; + this.commonUtil = commonUtil; + this.campaignUtil = campaignUtil; + this.planEmployeeService = planEmployeeService; + this.config = config; + this.planEnricher = planEnricher; + this.boundaryUtil = boundaryUtil; + } + + /** + * This method performs business validations on plan create requests + * + * @param request + */ + 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); + + //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); + + // Validate plan configuration existence + validatePlanConfigurationExistence(request); + + // Validate resources + validateResources(request); + + // Validate resource-activity linkage + validateResourceActivityLinkage(request); + + // Validate target-activity linkage + validateTargetActivityLinkage(request); + + // Validate dependencies + validateActivityDependencies(request); + + // Validate Target's Metrics against MDMS + validateTargetMetrics(request, mdmsData); + + // 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()); + + // Validate plan-employee assignment and jurisdiction is request is from Resource Estimation Consumer + if(!request.getPlan().isRequestFromResourceEstimationConsumer()) + validatePlanEmployeeAssignmentAndJurisdiction(request); + } + + /** + * 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); + } + } + + /** + * This validation method validates if the dependent activities are valid and if they form a cycle + * + * @param request + */ + private void validateActivityDependencies(PlanRequest request) { + // Check if dependent activity codes are valid + validateDependentActivityCodes(request); + + // Check if dependent activities form a cycle + checkForCycleInActivityDependencies(request); + } + + /** + * This method checks if the activity dependencies form a cycle + * + * @param request + */ + private void checkForCycleInActivityDependencies(PlanRequest request) { + Map> activityCodeVsDependenciesMap = request.getPlan().getActivities().stream() + .collect(Collectors.toMap(Activity::getCode, + activity -> CollectionUtils.isEmpty(activity.getDependencies()) ? List.of() : activity.getDependencies())); + + activityCodeVsDependenciesMap.keySet().forEach(activityCode -> { + activityCodeVsDependenciesMap.get(activityCode).forEach(dependency -> { + if (activityCodeVsDependenciesMap.get(dependency).contains(activityCode)) + throw new CustomException(CYCLIC_ACTIVITY_DEPENDENCY_CODE, CYCLIC_ACTIVITY_DEPENDENCY_MESSAGE); + }); + }); + } + + /** + * This method validates if the dependent activity codes are valid + * + * @param request + */ + private void validateDependentActivityCodes(PlanRequest request) { + // Collect all activity codes + Set activityCodes = request.getPlan().getActivities().stream() + .map(Activity::getCode) + .collect(Collectors.toSet()); + + // Check if the dependent activity codes are valid + request.getPlan().getActivities().forEach(activity -> { + if (!CollectionUtils.isEmpty(activity.getDependencies())) { + activity.getDependencies().forEach(dependency -> { + if (!activityCodes.contains(dependency)) + throw new CustomException(INVALID_ACTIVITY_DEPENDENCY_CODE, INVALID_ACTIVITY_DEPENDENCY_MESSAGE); + }); + } + }); + } + + + /** + * 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) + throw new CustomException(ACTIVITIES_CANNOT_BE_NULL_CODE, ACTIVITIES_CANNOT_BE_NULL_MESSAGE); + + Set activityCodes = request.getPlan().getActivities().stream() + .map(Activity::getCode) + .collect(Collectors.toSet()); + + // If activity codes are not unique, throw an exception + 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()) + && 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()) + && !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())) { + request.getPlan().getActivities().forEach(activity -> { + if (activity.getPlannedEndDate() < activity.getPlannedStartDate()) + throw new CustomException(INVALID_ACTIVITY_DATES_CODE, INVALID_ACTIVITY_DATES_MESSAGE); + }); + } + } + + /** + * 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()))) { + 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()) + && 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 + * + * @param request + */ + private void validateResourceActivityLinkage(PlanRequest request) { + if (ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) + && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { + // Collect all activity codes + Set activityCodes = request.getPlan().getActivities().stream() + .map(Activity::getCode) + .collect(Collectors.toSet()); + + // Validate resource-activity linkage + request.getPlan().getResources().forEach(resource -> { + if (!activityCodes.contains(resource.getActivityCode())) + throw new CustomException(INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE, INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE); + }); + } + } + + /** + * This method validates the linkage between targets and activities + * + * @param request + */ + private void validateTargetActivityLinkage(PlanRequest request) { + if (!CollectionUtils.isEmpty(request.getPlan().getActivities())) { + // Collect all activity codes + Set activityCodes = request.getPlan().getActivities().stream() + .map(Activity::getCode) + .collect(Collectors.toSet()); + + // Validate target-activity linkage + request.getPlan().getTargets().forEach(target -> { + if (!activityCodes.contains(target.getActivityCode())) + throw new CustomException(INVALID_TARGET_ACTIVITY_LINKAGE_CODE, INVALID_TARGET_ACTIVITY_LINKAGE_MESSAGE); + }); + } + } + + /** + * This method performs business validations on plan update requests + * + * @param request + */ + public void validatePlanUpdate(PlanRequest request) { + // Validate plan existence + validatePlanExistence(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); + + + // Validate activities + validateActivities(request); + + // Validate activities uuid uniqueness + validateActivitiesUuidUniqueness(request); + + // Validate plan configuration existence + validatePlanConfigurationExistence(request); + + // Validate resources + validateResources(request); + + // Validate resource uuid uniqueness + validateResourceUuidUniqueness(request); + + // Validate target uuid uniqueness + validateTargetUuidUniqueness(request); + + // Validate resource-activity linkage + validateResourceActivityLinkage(request); + + // Validate target-activity linkage + validateTargetActivityLinkage(request); + + // Validate dependencies + validateActivityDependencies(request); + + // Validate Target's Metrics against MDMS + validateTargetMetrics(request, mdmsData); + + // Validate Metric Detail's Unit against MDMS + validateMetricDetailUnit(request, mdmsData); + + // Validate the user information in the request + commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validate plan-employee assignment and jurisdiction + validatePlanEmployeeAssignmentAndJurisdiction(request); + + // Enrich jurisdiction mapping in plan + planEnricher.enrichJurisdictionMapping(request.getPlan(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); + } + + /** + * Validates that all target UUIDs within the provided PlanRequest are unique. + * + * @param request the PlanRequest containing the targets to be validated + * @throws CustomException if any target UUIDs are not unique + */ + private void validateTargetUuidUniqueness(PlanRequest request) { + // Collect all target UUIDs + Set targetUuids = request.getPlan().getTargets().stream() + .map(Target::getId) + .collect(Collectors.toSet()); + + // If target UUIDs are not unique, throw an exception + if (targetUuids.size() != request.getPlan().getTargets().size()) { + throw new CustomException(DUPLICATE_TARGET_UUIDS_CODE, DUPLICATE_TARGET_UUIDS_MESSAGE); + } + } + + /** + * Validates that all resource UUIDs within the provided PlanRequest are unique. + * + * @param request the PlanRequest containing the resources to be validated + * @throws CustomException if any resource UUIDs are not unique + */ + private void validateResourceUuidUniqueness(PlanRequest request) { + // Collect all resource UUIDs + Set resourceUuids = request.getPlan().getResources().stream() + .map(Resource::getId) + .collect(Collectors.toSet()); + + // If resource UUIDs are not unique, throw an exception + if (resourceUuids.size() != request.getPlan().getResources().size()) { + throw new CustomException(DUPLICATE_RESOURCE_UUIDS_CODE, DUPLICATE_RESOURCE_UUIDS_MESSAGE); + } + } + + /** + * Validates that all activity UUIDs within the provided PlanRequest are unique. + * + * @param request the PlanRequest containing the activities to be validated + * @throws CustomException if any activity UUIDs are not unique + */ + private void validateActivitiesUuidUniqueness(PlanRequest request) { + // Collect all activity UUIDs + Set activityUuids = request.getPlan().getActivities().stream() + .map(Activity::getId) + .collect(Collectors.toSet()); + + // If activity UUIDs are not unique, throw an exception + if (activityUuids.size() != request.getPlan().getActivities().size()) { + throw new CustomException(DUPLICATE_ACTIVITY_UUIDS_CODE, DUPLICATE_ACTIVITY_UUIDS_MESSAGE); + } + } + + + /** + * This method validates if the plan id provided in the update request exists + * + * @param request the PlanRequest containing the plan + */ + private void validatePlanExistence(PlanRequest request) { + // If plan id provided is invalid, throw an exception + List planFromDatabase = planRepository.search(PlanSearchCriteria.builder() + .ids(Collections.singleton(request.getPlan().getId())) + .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()); + } + + /** + * Validates the target metrics within the provided PlanRequest against MDMS data. + * + * 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 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 + */ + public void validateTargetMetrics(PlanRequest request, Object mdmsData) { + Plan plan = request.getPlan(); + final String jsonPathForMetric = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_METRIC + ".*.code"; + + List metricListFromMDMS = null; + System.out.println("Jsonpath -> " + jsonPathForMetric); + try { + metricListFromMDMS = JsonPath.read(mdmsData, jsonPathForMetric); + } catch (Exception e) { + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + HashSet metricSetFromMDMS = new HashSet<>(metricListFromMDMS); + plan.getTargets().stream().forEach(target -> { + if (!metricSetFromMDMS.contains(target.getMetric())) { + throw new CustomException(METRIC_NOT_FOUND_IN_MDMS_CODE, METRIC_NOT_FOUND_IN_MDMS_MESSAGE); + } + }); + + } + + /** + * Validates the metric unit details within the provided PlanRequest against MDMS data. + * + * 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 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 + */ + public void validateMetricDetailUnit(PlanRequest request, Object mdmsData) { + Plan plan = request.getPlan(); + + List metricDetails = plan.getTargets().stream() + .map(Target::getMetricDetail) + .toList(); + + List metricUnitListFromMDMS; + final String jsonPathForMetricUnit = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UOM + ".*.uomCode"; + try { + metricUnitListFromMDMS = JsonPath.read(mdmsData, jsonPathForMetricUnit); + } catch (Exception e) { + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + HashSet metricUnitSetFromMDMS = new HashSet<>(metricUnitListFromMDMS); + metricDetails.stream().forEach(metricDetail -> { + if (!metricUnitSetFromMDMS.contains(metricDetail.getMetricUnit())) { + throw new CustomException(METRIC_UNIT_NOT_FOUND_IN_MDMS_CODE, METRIC_UNIT_NOT_FOUND_IN_MDMS_MESSAGE); + } + }); + + } + + /** + * 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() + .tenantId(planRequest.getPlan().getTenantId()) + .employeeId(Collections.singletonList(planRequest.getRequestInfo().getUserInfo().getUuid())) + .planConfigurationId(planRequest.getPlan().getPlanConfigurationId()) + .role(config.getPlanEstimationApproverRoles()) + .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()); + + 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 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 validateJurisdiction(Plan plan, Set 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(new ArrayList<>(jurisdictions)); + + } + + /** + * 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. + */ + 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 and jurisdiction mapping for the provided boundary code + if(plan.isRequestFromResourceEstimationConsumer()) + planEnricher.enrichBoundaryAncestralPath(plan, tenantBoundary); + } + + /** + * @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); + + // Validate if plans provided in the request body exist + validatePlanExistence(bulkPlanRequest); + + // Validate plan employee assignment and jurisdiction + validatePlanEmployeeAssignmentAndJurisdiction(bulkPlanRequest); + + // Enrich jurisdiction mapping in plan + planEnricher.enrichJurisdictionMapping(bulkPlanRequest.getPlans(), boundaryTypeHierarchyResponse.getBoundaryHierarchy().get(0)); + } + + /** + * + * @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())) + ); + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..24932950df8 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java @@ -0,0 +1,432 @@ +package digit.service.workflow; + +import com.fasterxml.jackson.databind.ObjectMapper; +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; +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; +import org.egov.tracer.model.CustomException; +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 +public class WorkflowService { + + private ServiceRequestRepository serviceRequestRepository; + + private Configuration config; + + private ObjectMapper mapper; + + private CommonUtil commonUtil; + + private PlanEmployeeService planEmployeeService; + + private PlanConfigurationValidator planConfigurationValidator; + + private 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; + } + + /** + * 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); + + // 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. + * If the action is null, it does not proceed with integration. + * + * @param planRequest The request containing the plan estimate 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()); + + // Enrich audit details after auto assignment is complete + planRequest.getPlan().setAuditDetails(AuditDetailsEnrichmentUtil + .prepareAuditDetails( planRequest.getPlan().getAuditDetails(), planRequest.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 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(); + + enrichAssignesInProcessInstance(processInstance, planConfig.getWorkflow()); + + return ProcessInstanceRequest.builder() + .requestInfo(planConfigurationRequest.getRequestInfo()) + .processInstances(Collections.singletonList(processInstance)) + .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(); + + 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); + + plan.setAssignee(assignee); + + enrichAssignesInProcessInstance(processInstance, plan.getWorkflow()); + + log.info("Process Instance assignes - " + processInstance.getAssignes()); + 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 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. + * 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 requestInfo auth details for making internal calls + * @param plan the plan object containing workflow and jurisdiction details + */ + private List 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(plan.getTenantId()) + .jurisdiction(Arrays.stream(heirarchysBoundaryCodes).toList()) + .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(requestInfo).build()); + + // 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(); + return assignment.getJurisdiction().stream() + .filter(jurisdiction -> Arrays.asList(heirarchysBoundaryCodes).contains(jurisdiction)) + .map(jurisdiction -> new AbstractMap.SimpleEntry<>(jurisdiction, employeeId)); + }) + .collect(Collectors.groupingBy( + Map.Entry::getKey, // jurisdiction as the key + LinkedHashMap::new, // Preserve insertion order + Collectors.mapping( + Map.Entry::getValue, // employee IDs as values + Collectors.toList() // Collect employee IDs into a List + ) + )); + + List assignee = null; //assignee will remain null in case terminate actions are being taken + + String action = plan.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, plan, jurisdictionToEmployeeMap); + } + + return assignee; + } + + /** + * 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 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 List 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 (plan.getAssigneeJurisdiction().contains(boundaryCode)) { + + for (int j = i - 1; j >= 0; j--) { + // Check the next higher level in the hierarchy (one index above the match) + String higherBoundaryCode = heirarchysBoundaryCodes[j]; + + // Fetch the employeeId from the map for the higher boundary code + List 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; + } + + 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 + List assignee = getAssigneeForAutoAssignment(bulkPlanRequest.getPlans().get(0), + bulkPlanRequest.getRequestInfo()); + + 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)) + plan.getWorkflow().setAssignes(assignee); + + plan.setAssignee(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(); + } + + /** + * 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(URI_BUSINESS_SERVICE_QUERY_TEMPLATE); + + uriParameters.put(URI_TENANT_ID_PARAM, tenantId); + uriParameters.put(URI_BUSINESS_SERVICE_PARAM, businessService); + + return uri.toString(); + } + +} \ No newline at end of file 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..ec43e0f0447 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java @@ -0,0 +1,111 @@ +package digit.util; + +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; +import org.springframework.web.client.RestTemplate; + +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 +@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; + } + + 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/util/CampaignUtil.java b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java new file mode 100644 index 00000000000..5f1632e6366 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/CampaignUtil.java @@ -0,0 +1,91 @@ +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.egov.tracer.model.CustomException; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +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; + } + + /** + * This method fetches data from project factory for provided campaignId and service boundaries + * + * @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) { + + // Build the URI for calling the Project Factory service + StringBuilder uri = buildCampaignSearchUri(); + + // 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); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_PROJECT_FACTORY, e); + } + + // 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); + } + + return campaignResponse; + } + + /** + * This method create the uri for project factory to fetch campaign data. + * + * @return The complete URI. + */ + private StringBuilder buildCampaignSearchUri() { + return new StringBuilder().append(configs.getProjectFactoryHost()).append(configs.getProjectFactorySearchEndPoint()); + } + + /** + * 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 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)) + .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/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 new file mode 100644 index 00000000000..6635294fd87 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/CommonUtil.java @@ -0,0 +1,275 @@ +package digit.util; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +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.Operation; +import digit.web.models.PlanConfiguration; +import digit.web.models.PlanConfigurationSearchCriteria; +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.math.BigDecimal; +import java.util.*; +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(PlanConfigurationRepository planConfigurationRepository, ObjectMapper objectMapper) { + this.planConfigurationRepository = planConfigurationRepository; + this.objectMapper = objectMapper; + } + + /** + * 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(); + } + + + /** + * Extracts provided field from the additional details object + * + * @param additionalDetails the additionalDetails object from PlanConfigurationRequest + * @param fieldToExtract the name of the field to be extracted from the additional details + * @return the value of the specified field as a string + * @throws CustomException if the field does not exist + */ + public Object extractFieldsFromJsonObject(Object additionalDetails, String fieldToExtract) { + try { + String jsonString = objectMapper.writeValueAsString(additionalDetails); + JsonNode rootNode = objectMapper.readTree(jsonString); + + JsonNode node = rootNode.get(fieldToExtract); + if (node != null && !node.isNull()) { + + // Check for different types of JSON nodes + if (node.isDouble() || node.isFloat()) { + return BigDecimal.valueOf(node.asDouble()); // Convert Double to BigDecimal + } else if (node.isLong() || node.isInt()) { + return BigDecimal.valueOf(node.asLong()); // Convert Long to BigDecimal + } else if (node.isBoolean()) { + return node.asBoolean(); + } else if (node.isTextual()) { + return node.asText(); + } + } + return null; + } catch (Exception e) { + log.error(e.getMessage() + fieldToExtract); + throw new CustomException(PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_CODE, PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_MESSAGE + fieldToExtract); + } + } + + /** + * 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() + 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; + } + + /** + * 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. + * + * @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 + * + * @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_SCHEMA + 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); + } + + Map hierarchyMap = new HashMap<>(); + hierarchyMap.put(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN, hierarchyForMicroplan.get(0).get(LOWEST_HIERARCHY_FIELD_FOR_MICROPLAN).toString().toLowerCase()); + hierarchyMap.put(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN, hierarchyForMicroplan.get(0).get(HIGHEST_HIERARCHY_FIELD_FOR_MICROPLAN).toString().toLowerCase()); + + 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; + } + + /** + * 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 checkForEmptyOperationsOrAssumptions(PlanConfiguration planConfiguration) { + return !ObjectUtils.isEmpty(planConfiguration.getOperations()) && !ObjectUtils.isEmpty(planConfiguration.getAssumptions()); + } + + + /** + * 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 + 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); + } + } + + public void sortOperationsByExecutionOrder(List planConfigurations) { + for (PlanConfiguration planConfiguration : planConfigurations) { + List operations = planConfiguration.getOperations(); + if (!ObjectUtils.isEmpty(operations)) { + operations.sort(Comparator.comparing(Operation::getExecutionOrder)); + } + } + } + +} 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..025d4ea6bb6 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/FacilityUtil.java @@ -0,0 +1,84 @@ +package digit.util; + +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; +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; + private ObjectMapper mapper; + + public FacilityUtil(RestTemplate restTemplate, Configuration configs, ObjectMapper mapper) { + this.restTemplate = restTemplate; + this.configs = configs; + this.mapper = mapper; + } + + 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(); + + // 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 = getFacilitySearchRequest(planFacilityRequest); + 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 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(); + + return FacilitySearchRequest.builder() + .requestInfo(requestInfo) + .facilitySearchCriteria(searchCriteria) + .build(); + } + + + +} 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 4e301a3e5f5..a4979c5da52 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,42 @@ 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(); } + private ModuleDetail getAdminConsoleModuleDetail() { + List adminConsoleMasters = new ArrayList<>(); + + MasterDetail hierarchyConfigMaster = MasterDetail.builder().name(MDMS_MASTER_HIERARCHY_SCHEMA).build(); + + adminConsoleMasters.add(hierarchyConfigMaster); + + return ModuleDetail.builder().masterDetails(adminConsoleMasters).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<>(); @@ -75,14 +101,16 @@ private ModuleDetail getPlanModuleDetail() { MasterDetail ruleConfigureInputsMasterDetail = MasterDetail.builder().name(MDMS_MASTER_RULE_CONFIGURE_INPUTS).filter(FILTER_DATA).build(); MasterDetail schemaDetails = MasterDetail.builder().name(MDMS_MASTER_SCHEMAS).build(); MasterDetail metricDetails = MasterDetail.builder().name(MDMS_MASTER_METRIC).build(); - MasterDetail UnitDetails = MasterDetail.builder().name(MDMS_MASTER_UOM).build(); + MasterDetail unitDetails = MasterDetail.builder().name(MDMS_MASTER_UOM).build(); + MasterDetail namingRegexDetails = MasterDetail.builder().name(MDMS_MASTER_NAME_VALIDATION).build(); assumptionMasterDetails.add(assumptionMasterDetail); assumptionMasterDetails.add(uploadConfigMasterDetail); assumptionMasterDetails.add(ruleConfigureInputsMasterDetail); assumptionMasterDetails.add(schemaDetails); assumptionMasterDetails.add(metricDetails); - assumptionMasterDetails.add(UnitDetails); + assumptionMasterDetails.add(unitDetails); + assumptionMasterDetails.add(namingRegexDetails); return ModuleDetail.builder().masterDetails(assumptionMasterDetails).moduleName(MDMS_PLAN_MODULE_NAME).build(); } 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..dad22d39d35 --- /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.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; + + public MdmsV2Util(RestTemplate restTemplate, ObjectMapper objectMapper, Configuration configs) + { + this.restTemplate = restTemplate; + this.objectMapper = objectMapper; + this.configs = configs; + } + + 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(configs.getMdmsHost()).append(configs.getMdmsV2EndPoint()); + } + + private MdmsCriteriaReqV2 getMdmsV2Request(RequestInfo requestInfo, String tenantId, String schemaCode, String uniqueIdentifier) + { + MdmsCriteriaV2 mdmsCriteriaV2 = MdmsCriteriaV2.builder() + .tenantId(tenantId) + .schemaCode(schemaCode) + .limit(configs.getDefaultLimit()) + .offset(configs.getDefaultOffset()).build(); + + if(!ObjectUtils.isEmpty(uniqueIdentifier)) + mdmsCriteriaV2.setUniqueIdentifiers(Collections.singletonList(uniqueIdentifier)); + + return MdmsCriteriaReqV2.builder() + .requestInfo(requestInfo) + .mdmsCriteriaV2(mdmsCriteriaV2).build(); + } + +} 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..070f442a897 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,7 +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; @@ -11,10 +19,17 @@ import static digit.config.ServiceConstants.DOT_REGEX; import static digit.config.ServiceConstants.DOT_SEPARATOR; - +@Component public class QueryUtil { - private QueryUtil(){} + private Configuration config; + + private ObjectMapper objectMapper; + + private QueryUtil(Configuration config, ObjectMapper objectMapper) { + this.config = config; + this.objectMapper = objectMapper; + } private static final Gson gson = new Gson(); @@ -22,13 +37,14 @@ private QueryUtil(){} * 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 "); } } @@ -36,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 -> { @@ -53,40 +70,48 @@ 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); }); } + public void addToPreparedStatement(List preparedStmtList, List ids) { + ids.forEach(id -> { + preparedStmtList.add(id); + }); + } /** * This method appends order by clause to the query + * * @param query * @param orderByClause * @return */ - public static String addOrderByClause(String query, String orderByClause){ + public String addOrderByClause(String query, String orderByClause) { return query + orderByClause; } /** * This method prepares partial json string from the filter map to query on jsonb column + * * @param filterMap * @return */ - public static String preparePartialJsonStringFromFilterMap(Map 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)); } }); @@ -100,14 +125,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. @@ -123,4 +149,43 @@ 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(); + } + + /** + * 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/util/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java new file mode 100644 index 00000000000..19c7bebeea7 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java @@ -0,0 +1,12 @@ +package digit.util; + +import org.springframework.stereotype.Component; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Component +public class ServiceUtil { + + +} 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..0e60073313e --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/UserUtil.java @@ -0,0 +1,73 @@ +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 config; + + private RestTemplate restTemplate; + + public UserUtil(RestTemplate restTemplate, Configuration config) { + this.restTemplate = restTemplate; + this.config = config; + } + + /** + * This method fetches user details from User Service for the provided search request + * + * @param userSearchReq Search request to search for user detail response + */ + public UserDetailResponse fetchUserDetail(UserSearchRequest userSearchReq) { + + UserDetailResponse userDetailResponse = new UserDetailResponse(); + + try { + userDetailResponse = restTemplate.postForObject(getUserServiceUri().toString(), userSearchReq, UserDetailResponse.class); + } catch (Exception e) { + log.error(ERROR_WHILE_FETCHING_FROM_USER_SERVICE, e); + } + + return userDetailResponse; + } + + /** + * 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; + } +} 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 1577ce3dbb1..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; @@ -45,13 +44,7 @@ public PlanConfigController(ObjectMapper objectMapper, PlanConfigurationService @RequestMapping(value = "/config/_create", method = RequestMethod.POST) public ResponseEntity configCreatePost(@Parameter(in = ParameterIn.DEFAULT, description = "", schema = @Schema()) @Valid @RequestBody PlanConfigurationRequest body) { - PlanConfigurationRequest planConfigurationRequest = planConfigurationService.create(body); - PlanConfigurationResponse response = PlanConfigurationResponse.builder() - .planConfiguration(Collections.singletonList(planConfigurationRequest.getPlanConfiguration())) - .responseInfo(responseInfoFactory - .createResponseInfoFromRequestInfo(body.getRequestInfo(), true)) - .build(); - + PlanConfigurationResponse response = planConfigurationService.create(body); return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); } 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/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/controllers/PlanFacilityController.java b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java new file mode 100644 index 00000000000..bca90f5c544 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java @@ -0,0 +1,61 @@ +package digit.web.controllers; + +import digit.service.PlanFacilityService; +import digit.web.models.*; +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") +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 = "/facility/_create", method = RequestMethod.POST) + public ResponseEntity createPlanFacility(@Valid @RequestBody PlanFacilityRequest planFacilityRequest) { + PlanFacilityResponse planFacilityResponse = planFacilityService.createPlanFacility(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 searchPlanFacility(@Valid @RequestBody PlanFacilitySearchRequest planFacilityRequest) { + PlanFacilityResponse planFacilityResponse = planFacilityService.searchPlanFacility(planFacilityRequest); + 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 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/Assumption.java b/health-services/plan-service/src/main/java/digit/web/models/Assumption.java index a4b7e3ad01f..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,10 +38,19 @@ 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") + @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/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 diff --git a/health-services/plan-service/src/main/java/digit/web/models/File.java b/health-services/plan-service/src/main/java/digit/web/models/File.java index 68cf28cd46b..3b232a60aeb 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/File.java +++ b/health-services/plan-service/src/main/java/digit/web/models/File.java @@ -14,6 +14,8 @@ import lombok.Data; import lombok.Builder; +import java.util.Arrays; + /** * File */ @@ -72,12 +74,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/plan-service/src/main/java/digit/web/models/MetricDetail.java b/health-services/plan-service/src/main/java/digit/web/models/MetricDetail.java index 40452bb02d1..d2a4bcc2f64 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/MetricDetail.java +++ b/health-services/plan-service/src/main/java/digit/web/models/MetricDetail.java @@ -15,6 +15,7 @@ import org.springframework.validation.annotation.Validated; import java.math.BigDecimal; +import java.util.Arrays; @Validated @Data @@ -64,12 +65,10 @@ public String toString() { @JsonCreator public static MetricComparatorEnum fromValue(String text) { - for (MetricComparatorEnum b : MetricComparatorEnum.values()) { - if (String.valueOf(b.symbol).equals(text)) { - return b; - } - } - return null; + 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/plan-service/src/main/java/digit/web/models/Operation.java b/health-services/plan-service/src/main/java/digit/web/models/Operation.java index 0569dc9a536..b12c44341fb 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 @@ -13,6 +13,8 @@ import lombok.Data; import lombok.Builder; +import java.util.Arrays; + /** * Operation */ @@ -38,14 +40,30 @@ public class Operation { @JsonProperty("assumptionValue") @NotNull - @Size(min = 2, max = 256) + @Size(min = 1, max = 256) private String assumptionValue = null; @JsonProperty("output") @NotNull - @Size(min = 1, max = 64) + @Size(min = 1, max = 256) 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("executionOrder") + private Integer executionOrder = null; + @JsonProperty("active") @NotNull private Boolean active = true; @@ -80,12 +98,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; - } - } - throw new IllegalArgumentException("Unexpected value '" + text + "'"); + 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/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/Plan.java b/health-services/plan-service/src/main/java/digit/web/models/Plan.java index f1fb59a400e..3ff0e8ce87d 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,12 +1,15 @@ package digit.web.models; +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; 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; @@ -35,14 +38,21 @@ 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) private String planConfigurationId = null; + @JsonProperty("status") + @Size(max = 64) + private String status = null; + + @JsonProperty("assignee") + private List assignee = null; + @JsonProperty("additionalDetails") private Object additionalDetails = null; @@ -61,4 +71,20 @@ public class Plan { @JsonProperty("auditDetails") private AuditDetails auditDetails = null; + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + + @JsonIgnore + private String boundaryAncestralPath = null; + + @JsonIgnore + private boolean isRequestFromResourceEstimationConsumer; + + @JsonIgnore + private List assigneeJurisdiction; + + @JsonProperty("workflow") + @Valid + private Workflow workflow; + } 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..50c43741d48 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; @@ -11,6 +8,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; @@ -38,54 +36,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/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..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 @@ -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; @@ -12,6 +11,8 @@ import lombok.Data; import lombok.Builder; +import java.util.List; + /** * PlanConfigurationSearchCriteria */ @@ -30,14 +31,17 @@ public class PlanConfigurationSearchCriteria { @JsonProperty("id") private String id = null; + @JsonProperty("ids") + private List ids = null; + @JsonProperty("name") private String name = null; - @JsonProperty("executionPlanId") - private String executionPlanId = null; + @JsonProperty("campaignId") + private String campaignId = null; @JsonProperty("status") - private String status = null; + private List status = null; @JsonProperty("userUuid") private String userUuid = null; @@ -50,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/PlanDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java new file mode 100644 index 00000000000..f56569c1349 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java @@ -0,0 +1,90 @@ +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; +import java.util.Map; + +/** + * 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") + private String assignee = null; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + + @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/PlanEmployeeAssignment.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java new file mode 100644 index 00000000000..c27b1e1eb1b --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java @@ -0,0 +1,71 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Set; + +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; +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("planConfigurationName") + private String planConfigurationName = 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("hierarchyLevel") + @Size(min = 2, max = 64) + private String hierarchyLevel = null; + + @JsonProperty("jurisdiction") + @Valid + @NotEmpty + private Set 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/PlanEmployeeAssignmentDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java new file mode 100644 index 00000000000..555d916c1ff --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java @@ -0,0 +1,69 @@ +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 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("planConfigurationName") + private String planConfigurationName = 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("hierarchyLevel") + @Size(min = 2, max = 64) + private String hierarchyLevel = null; + + @JsonProperty("jurisdiction") + @Valid + @NotEmpty + 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/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/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; +} 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..6c6ecdc516c --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java @@ -0,0 +1,36 @@ +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; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = 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..22008b64135 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java @@ -0,0 +1,72 @@ +package digit.web.models; + +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; +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("id") + private String id = null; + + @JsonProperty("tenantId") + @Size(min = 2, max = 100) + @NotNull + private String tenantId = null; + + @JsonProperty("employeeId") + private List employeeId = null; + + @JsonProperty("planConfigurationId") + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("planConfigurationName") + private String planConfigurationName = null; + + @JsonProperty("planConfigurationStatus") + private Set planConfigurationStatus = null; + + @JsonProperty("role") + @Valid + private List role = null; + + @JsonProperty("hierarchyLevel") + private String hierarchyLevel = null; + + @JsonProperty("jurisdiction") + @Valid + private List jurisdiction = null; + + @JsonProperty("active") + @Builder.Default + private Boolean active = Boolean.TRUE; + + @JsonProperty("filterUniqueByPlanConfig") + @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/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; +} 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..87c024324ac --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java @@ -0,0 +1,92 @@ +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.springframework.validation.annotation.Validated; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 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") + @NotNull + @Size(max = 64) + private String planConfigurationId = null; + + @JsonProperty("planConfigurationName") + private String planConfigurationName = null; + + @JsonProperty("boundaryAncestralPath") + private String boundaryAncestralPath = null; + + @JsonProperty("facilityId") + @NotNull + @Size(max = 64) + private String facilityId = null; + + @JsonProperty("facilityName") + private String facilityName = null; + + @JsonProperty("residingBoundary") + @NotNull + @Size(min = 1, max = 64) + private String residingBoundary = null; + + @JsonProperty("serviceBoundaries") + @NotNull + @Valid + private List serviceBoundaries; + + @JsonIgnore + private List initiallySetServiceBoundaries; + + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("active") + @NotNull + 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/PlanFacilityDTO.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java new file mode 100644 index 00000000000..771c602f760 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java @@ -0,0 +1,79 @@ +package digit.web.models; + +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; + +import java.util.List; +import java.util.Map; + +/** + * 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("planConfigurationName") + private String planConfigurationName = null; + + @JsonProperty("boundaryAncestralPath") + private String boundaryAncestralPath = 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("initiallySetServiceBoundaries") + private List initiallySetServiceBoundaries; + + @JsonProperty("facilityName") + private String facilityName = null; + + @JsonProperty("jurisdictionMapping") + private Map jurisdictionMapping; + + @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/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..9eb2652d0a7 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.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; + +/** + * PlanFacilityRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +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/PlanFacilityResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java new file mode 100644 index 00000000000..1ac3db052c6 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.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.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; +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; + + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; +} 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..a5a4e49c42c --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java @@ -0,0 +1,64 @@ +package digit.web.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +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.Map; +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") + @NotNull + private String planConfigurationId = null; + + @JsonProperty("planConfigurationName") + private String planConfigurationName = 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; + + @JsonProperty("jurisdiction") + private List jurisdiction = null; + + @JsonProperty("facilityId") + private String facilityId = null; + + @JsonProperty("offset") + private Integer offset = null; + + @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 new file mode 100644 index 00000000000..65517af3d18 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java @@ -0,0 +1,34 @@ +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 javax.validation.constraints.NotNull; + +/** + * PlanFacilitySearchRequest + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class PlanFacilitySearchRequest { + + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("PlanFacilitySearchCriteria") + @NotNull + @Valid + private PlanFacilitySearchCriteria planFacilitySearchCriteria = null; + +} 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/PlanResponse.java b/health-services/plan-service/src/main/java/digit/web/models/PlanResponse.java index bf08ba0059c..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; @@ -28,4 +30,12 @@ public class PlanResponse { @Valid private List plan = null; + @JsonProperty("TotalCount") + @Valid + private Integer totalCount = null; + + @JsonProperty("StatusCount") + @Valid + private Map statusCount = 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..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,15 +1,16 @@ package digit.web.models; -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 @@ -29,14 +30,24 @@ public class PlanSearchCriteria { private String tenantId = null; @JsonProperty("locality") - private String locality = null; + private List locality = null; - @JsonProperty("executionPlanId") - private String executionPlanId = 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; 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/Resource.java b/health-services/plan-service/src/main/java/digit/web/models/Resource.java index 0b64b3108c1..d0d8ce2500b 100644 --- a/health-services/plan-service/src/main/java/digit/web/models/Resource.java +++ b/health-services/plan-service/src/main/java/digit/web/models/Resource.java @@ -25,7 +25,7 @@ public class Resource { @JsonProperty("resourceType") @NotNull - @Size(min = 2, max = 256) + @Size(min = 1, max = 256) private String resourceType = null; @JsonProperty("estimatedNumber") 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/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/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/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/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 new file mode 100644 index 00000000000..e8f384d1e98 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/census/Census.java @@ -0,0 +1,139 @@ +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.egov.common.contract.models.Workflow; +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") + @Size(max = 64) + private String assignee = null; + + @JsonProperty("status") + @Size(max = 64) + private String status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private Long totalPopulation = null; + + @JsonProperty("populationByDemographics") + @Valid + private List populationByDemographics = null; + + @JsonProperty("additionalFields") + @Valid + private List additionalFields = 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 + @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; + + /** + * 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/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 new file mode 100644 index 00000000000..fcfec9b1ee9 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java @@ -0,0 +1,64 @@ +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; + +import java.util.Map; + +@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 AdditionalFields 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 Address 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/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/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..be5e324cd5f --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java @@ -0,0 +1,55 @@ +package digit.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/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaReqV2.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaReqV2.java new file mode 100644 index 00000000000..f6af90e1b82 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaReqV2.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 MdmsCriteriaReqV2 { + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo; + + @JsonProperty("MdmsCriteria") + @Valid + private MdmsCriteriaV2 mdmsCriteriaV2; +} \ No newline at end of file diff --git a/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaV2.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaV2.java new file mode 100644 index 00000000000..88e8a715810 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaV2.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 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/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsResponseV2.java b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsResponseV2.java new file mode 100644 index 00000000000..090b41f90da --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsResponseV2.java @@ -0,0 +1,25 @@ +package digit.web.models.mdmsV2; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +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/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..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..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 03ee3da916d..cb941721390 100644 --- a/health-services/plan-service/src/main/resources/application.properties +++ b/health-services/plan-service/src/main/resources/application.properties @@ -30,6 +30,7 @@ spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.Strin 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 +spring.kafka.producer.properties.max.request.size=3000000 # KAFKA CONSUMER CONFIGURATIONS kafka.consumer.config.auto_commit=true @@ -48,14 +49,57 @@ 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 -#mdms urls +plan.facility.update.topic=update-plan-facility +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 + +# 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 + +# Project factory urls +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 + +#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 +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 # Pagination config plan.default.offset=0 plan.default.limit=10 +# CONSUMER TOPICS 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.save.plan.facility.consumer.topic=project-factory-save-plan-facility + +# 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'} diff --git a/health-services/plan-service/src/main/resources/db/Dockerfile b/health-services/plan-service/src/main/resources/db/Dockerfile index 60fc07ce69f..f38638a269f 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 @@ -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"] 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..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 -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 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..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 @@ -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,12 @@ 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, + source character varying(64), + category character varying(64), 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 +52,15 @@ 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(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, @@ -62,8 +74,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/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..0f037765d8f --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql @@ -0,0 +1,19 @@ +-- 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 TEXT, + additional_details JSONB, + plan_configuration_name character varying(128), + facility_name character varying(64), + 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 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/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..1e28950ca6f --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql @@ -0,0 +1,19 @@ +-- 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), + 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), + 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) +); 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; diff --git a/health-services/plan-service/src/main/resources/db/migration/main/V20242112141500__alter plan_facility_add_boundary_ancestral_path_ddl.sql b/health-services/plan-service/src/main/resources/db/migration/main/V20242112141500__alter plan_facility_add_boundary_ancestral_path_ddl.sql new file mode 100644 index 00000000000..0bf373ddcd7 --- /dev/null +++ b/health-services/plan-service/src/main/resources/db/migration/main/V20242112141500__alter plan_facility_add_boundary_ancestral_path_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE plan_facility_linkage ADD boundary_ancestral_path TEXT; \ No newline at end of file diff --git a/health-services/project-factory/src/server/config/index.ts b/health-services/project-factory/src/server/config/index.ts index 1f1c5a27292..b4e94c3a49a 100644 --- a/health-services/project-factory/src/server/config/index.ts +++ b/health-services/project-factory/src/server/config/index.ts @@ -153,6 +153,7 @@ const config = { hrmsEmployeeSearch: process.env.EGOV_HRMS_EMPLOYEE_SEARCH_PATH || "health-hrms/employees/_search", localizationSearch: process.env.EGOV_LOCALIZATION_SEARCH || "localization/messages/v1/_search", localizationCreate: "localization/messages/v1/_upsert", + projectTypeSearch: "project-factory/v1/project-type/search", cacheBurst: process.env.CACHE_BURST || "localization/messages/cache-bust", boundaryRelationshipCreate: "boundary-service/boundary-relationships/_create", healthIndividualSearch: process.env.EGOV_HEALTH_INDIVIDUAL_SEARCH || "health-individual/v1/_search", diff --git a/health-services/project-factory/src/server/utils/excelUtils.ts b/health-services/project-factory/src/server/utils/excelUtils.ts index 44adb5d93d6..a4b21ac5ae0 100644 --- a/health-services/project-factory/src/server/utils/excelUtils.ts +++ b/health-services/project-factory/src/server/utils/excelUtils.ts @@ -198,7 +198,7 @@ function performUnfreezeCells(sheet: any, localizationMap?: any, fileUrl?: any) } } } - sheet.protect('passwordhere', { selectLockedCells: true, selectUnlockedCells: true }); + // sheet.protect('passwordhere', { selectLockedCells: true, selectUnlockedCells: true }); } @@ -392,5 +392,12 @@ export function enrichUsageColumnForFacility(worksheet: any, localizationMap: an } } +function protectSheet(sheet: any) { + sheet.protect('passwordhere', { + selectLockedCells: true, + selectUnlockedCells: true, + }); +} + -export { getNewExcelWorkbook, getExcelWorkbookFromFileURL, formatWorksheet, addDataToSheet, lockTargetFields, updateFontNameToRoboto, formatFirstRow, formatOtherRows, finalizeSheet }; +export { getNewExcelWorkbook, getExcelWorkbookFromFileURL, formatWorksheet, addDataToSheet, lockTargetFields, updateFontNameToRoboto, formatFirstRow, formatOtherRows, finalizeSheet, protectSheet }; diff --git a/health-services/project-factory/src/server/utils/genericUtils.ts b/health-services/project-factory/src/server/utils/genericUtils.ts index faa8095a9fd..7ab4def31fd 100644 --- a/health-services/project-factory/src/server/utils/genericUtils.ts +++ b/health-services/project-factory/src/server/utils/genericUtils.ts @@ -14,11 +14,12 @@ import { generatedResourceStatuses, headingMapping, resourceDataStatuses } from import { getLocaleFromRequest, getLocaleFromRequestInfo, getLocalisationModuleName } from "./localisationUtils"; import { getBoundaryColumnName, getBoundaryTabName, getLatLongMapForBoundaryCodes } from "./boundaryUtils"; import { getBoundaryDataService, searchDataService } from "../service/dataManageService"; -import { addDataToSheet, enrichUsageColumnForFacility, formatWorksheet, getNewExcelWorkbook, updateFontNameToRoboto } from "./excelUtils"; +import { addDataToSheet, enrichUsageColumnForFacility, formatWorksheet, getNewExcelWorkbook, protectSheet, updateFontNameToRoboto } from "./excelUtils"; import createAndSearch from "../config/createAndSearch"; import { generateDynamicTargetHeaders } from "./targetUtils"; import { buildSearchCriteria, checkAndGiveIfParentCampaignAvailable, fetchFileUrls, getCreatedResourceIds, modifyProcessedSheetData } from "./onGoingCampaignUpdateUtils"; import { getReadMeConfigForMicroplan, getRolesForMicroplan, getUserDataFromMicroplanSheet, isMicroplanRequest } from "./microplanUtils"; +import _ from "lodash"; const NodeCache = require("node-cache"); const updateGeneratedResourceTopic = config?.kafka?.KAFKA_UPDATE_GENERATED_RESOURCE_DETAILS_TOPIC; @@ -74,12 +75,11 @@ const throwError = (module = "COMMON", status = 500, code = "UNKNOWN_ERROR", des throw error; }; - const replicateRequest = (originalRequest: Request, requestBody: any, requestQuery?: any) => { const newRequest = { ...originalRequest, - body: requestBody, - query: requestQuery || originalRequest.query + body: _.cloneDeep(requestBody), // Deep clone using lodash + query: requestQuery ? _.cloneDeep(requestQuery) : _.cloneDeep(originalRequest.query) }; return newRequest; }; @@ -461,19 +461,19 @@ function correctParentValues(campaignDetails: any) { return campaignDetails; } -function setDropdownFromSchema(request: any, schema: any, localizationMap?: { [key: string]: string }) { - const dropdowns = Object.entries(schema.properties) - .filter(([key, value]: any) => Array.isArray(value.enum) && value.enum.length > 0) - .reduce((result: any, [key, value]: any) => { - // Transform the key using localisedValue function - const newKey: any = getLocalizedName(key, localizationMap); - result[newKey] = value.enum; - return result; - }, {}); - logger.info(`dropdowns to set ${JSON.stringify(dropdowns)}`) - request.body.dropdowns = dropdowns; - return dropdowns; -} +// function setDropdownFromSchema(request: any, schema: any, localizationMap?: { [key: string]: string }) { +// const dropdowns = Object.entries(schema.properties) +// .filter(([key, value]: any) => Array.isArray(value.enum) && value.enum.length > 0) +// .reduce((result: any, [key, value]: any) => { +// // Transform the key using localisedValue function +// const newKey: any = getLocalizedName(key, localizationMap); +// result[newKey] = value.enum; +// return result; +// }, {}); +// logger.info(`dropdowns to set ${JSON.stringify(dropdowns)}`) +// request.body.dropdowns = dropdowns; +// return dropdowns; +// } function setHiddenColumns(request: any, schema: any, localizationMap?: { [key: string]: string }) { // from schema.properties find the key whose value have value.hideColumn == true @@ -525,7 +525,7 @@ async function createFacilitySheet(request: any, allFacilities: any[], localizat request.body.isSourceMicroplan = isSourceMicroplan; let schema: any = await getSchemaBasedOnSource(request, isSourceMicroplan, responseFromCampaignSearch?.CampaignDetails?.[0]?.additionalDetails?.resourceDistributionStrategy); const keys = schema?.columns; - setDropdownFromSchema(request, schema, localizationMap); + // setDropdownFromSchema(request, schema, localizationMap); setHiddenColumns(request, schema, localizationMap); const headers = ["HCM_ADMIN_CONSOLE_FACILITY_CODE", ...keys] let localizedHeaders; @@ -549,7 +549,7 @@ async function createFacilitySheet(request: any, allFacilities: any[], localizat logger.info("facilities generation done "); logger.debug(`facility response ${JSON.stringify(facilities)}`) const facilitySheetData: any = await createExcelSheet(facilities, localizedHeaders); - return facilitySheetData; + return { schema, facilitySheetData }; } @@ -727,15 +727,15 @@ async function createFacilityAndBoundaryFile(facilitySheetData: any, boundaryShe hideUniqueIdentifierColumn(facilitySheet, createAndSearch?.["facility"]?.uniqueIdentifierColumn); changeFirstRowColumnColour(facilitySheet, 'E06666'); - let receivedDropdowns = request.body?.dropdowns; - logger.info("started adding dropdowns in facility", JSON.stringify(receivedDropdowns)) + // let receivedDropdowns = request.body?.dropdowns; - if (!receivedDropdowns || Object.keys(receivedDropdowns)?.length == 0) { - logger.info("No dropdowns found"); - receivedDropdowns = setDropdownFromSchema(request, schema, localizationMap); - logger.info("refetched drodowns", JSON.stringify(receivedDropdowns)) - } - await handledropdownthings(facilitySheet, receivedDropdowns); + // if (!receivedDropdowns || Object.keys(receivedDropdowns)?.length == 0) { + // logger.info("No dropdowns found"); + // receivedDropdowns = setDropdownFromSchema(request, schema, localizationMap); + // logger.info("refetched drodowns", JSON.stringify(receivedDropdowns)) + // } + await handledropdownthings(facilitySheet, schema, localizationMap); + protectSheet(facilitySheet); await handleHiddenColumns(facilitySheet, request.body?.hiddenColumns); // Add boundary sheet to the workbook @@ -748,11 +748,20 @@ async function createFacilityAndBoundaryFile(facilitySheetData: any, boundaryShe request.body.fileDetails = fileDetails; } -async function handledropdownthings(sheet: any, dropdowns: any) { - let dropdownColumnIndex = -1; +async function handledropdownthings(sheet: any, schema: any, localizationMap: any) { + logger.info(sheet.rowCount) + const dropdowns = Object.entries(schema.properties) + .filter(([key, value]: any) => Array.isArray(value.enum) && value.enum.length > 0) + .reduce((result: any, [key, value]: any) => { + // Transform the key using localisedValue function + const newKey: any = getLocalizedName(key, localizationMap); + result[newKey] = value.enum; + return result; + }, {}); if (dropdowns) { logger.info("Dropdowns provided:", dropdowns); for (const key of Object.keys(dropdowns)) { + let dropdownColumnIndex = -1; if (dropdowns[key]) { logger.info(`Processing dropdown key: ${key} with values: ${dropdowns[key]}`); const firstRow = sheet.getRow(1); @@ -768,16 +777,32 @@ async function handledropdownthings(sheet: any, dropdowns: any) { logger.info(`Setting dropdown for column index: ${dropdownColumnIndex}`); sheet.getColumn(dropdownColumnIndex).eachCell({ includeEmpty: true }, (cell: any, rowNumber: any) => { if (rowNumber > 1) { - // Set dropdown list with no typing allowed - cell.dataValidation = { - type: 'list', - formulae: [`"${dropdowns[key].join(',')}"`], - showDropDown: true, - error: 'Please select a value from the dropdown list.', - errorStyle: 'stop', - showErrorMessage: true, - errorTitle: 'Invalid Entry' - }; + if (cell.protection?.locked) { // Check if the cell is locked + cell.protection = { locked: false }; + // Set dropdown list with no typing allowed + cell.dataValidation = { + type: 'list', + formulae: [`"${dropdowns[key].join(',')}"`], + showDropDown: true, + error: 'Please select a value from the dropdown list.', + errorStyle: 'stop', + showErrorMessage: true, + errorTitle: 'Invalid Entry' + }; + cell.protection = { locked: true }; // Lock the cell again after adding dropdown + } + else { + cell.dataValidation = { + type: 'list', + formulae: [`"${dropdowns[key].join(',')}"`], + showDropDown: true, + error: 'Please select a value from the dropdown list.', + errorStyle: 'stop', + showErrorMessage: true, + errorTitle: 'Invalid Entry', + allowBlank: true // Allow blank entries + }; + } } }); } else { @@ -829,12 +854,13 @@ async function createUserAndBoundaryFile(userSheetData: any, boundarySheetData: let receivedDropdowns = request.body?.dropdowns; logger.info("started adding dropdowns in user", JSON.stringify(receivedDropdowns)) - if (!receivedDropdowns || Object.keys(receivedDropdowns)?.length == 0) { - logger.info("No dropdowns found"); - receivedDropdowns = setDropdownFromSchema(request, schema, localizationMap); - logger.info("refetched drodowns", JSON.stringify(receivedDropdowns)) - } - await handledropdownthings(userSheet, receivedDropdowns); + // if (!receivedDropdowns || Object.keys(receivedDropdowns)?.length == 0) { + // logger.info("No dropdowns found"); + // receivedDropdowns = setDropdownFromSchema(request, schema, localizationMap); + // logger.info("refetched drodowns", JSON.stringify(receivedDropdowns)) + // } + await handledropdownthings(userSheet, schema, localizationMap); + protectSheet(userSheet); await handleHiddenColumns(userSheet, request.body?.hiddenColumns); // Add boundary sheet to the workbook const localizedBoundaryTab = getLocalizedName(getBoundaryTabName(), localizationMap) @@ -854,29 +880,31 @@ async function generateFacilityAndBoundarySheet(tenantId: string, request: any, const allFacilities = await getAllFacilities(tenantId, request.body); request.body.generatedResourceCount = allFacilities?.length; logger.info(`Facilities generation completed and found ${allFacilities?.length} facilities`); - let facilitySheetData: any; + let facilitySheetDataFinal: any; const localizedFacilityTab = getLocalizedName(config?.facility?.facilityTab, localizationMap); - let schema: any; + let schemaFinal: any; if (fileUrl) { /* fetch facility from processed file and generate facility sheet data */ - schema = await callMdmsTypeSchema(request, tenantId, true, typeWithoutWith, "all"); + schemaFinal = await callMdmsTypeSchema(request, tenantId, true, typeWithoutWith, "all"); const processedFacilitySheetData = await getSheetData(fileUrl, localizedFacilityTab, false, undefined, localizationMap); - const modifiedProcessedFacilitySheetData = modifyProcessedSheetData(typeWithoutWith, processedFacilitySheetData, schema, localizationMap); - facilitySheetData = modifiedProcessedFacilitySheetData; - setDropdownFromSchema(request, schema, localizationMap); + const modifiedProcessedFacilitySheetData = modifyProcessedSheetData(typeWithoutWith, processedFacilitySheetData, schemaFinal, localizationMap); + facilitySheetDataFinal = modifiedProcessedFacilitySheetData; + // setDropdownFromSchema(request, schema, localizationMap); } else { - facilitySheetData = await createFacilitySheet(request, allFacilities, localizationMap); + const { schema, facilitySheetData }: any = await createFacilitySheet(request, allFacilities, localizationMap); + facilitySheetDataFinal = facilitySheetData; + schemaFinal = schema; } // request.body.Filters = { tenantId: tenantId, hierarchyType: request?.query?.hierarchyType, includeChildren: true } if (filteredBoundary && filteredBoundary.length > 0) { logger.info("proceed with the filtered boundary data") - await createFacilityAndBoundaryFile(facilitySheetData, filteredBoundary, request, localizationMap, fileUrl, schema); + await createFacilityAndBoundaryFile(facilitySheetDataFinal, filteredBoundary, request, localizationMap, fileUrl, schemaFinal); } else { const boundarySheetData: any = await getBoundarySheetData(request, localizationMap); - await createFacilityAndBoundaryFile(facilitySheetData, boundarySheetData, request, localizationMap, fileUrl, schema); + await createFacilityAndBoundaryFile(facilitySheetDataFinal, boundarySheetData, request, localizationMap, fileUrl, schemaFinal); } } @@ -887,7 +915,7 @@ async function generateUserSheet(request: any, localizationMap?: { [key: string] let schema: any; const isUpdate = fileUrl ? true : false; schema = await callMdmsTypeSchema(request, tenantId, isUpdate, typeWithoutWith); - setDropdownFromSchema(request, schema, localizationMap); + // setDropdownFromSchema(request, schema, localizationMap); const headers = schema?.columns; const localizedHeaders = getLocalizedHeaders(headers, localizationMap); const localizedUserTab = getLocalizedName(config?.user?.userTab, localizationMap); @@ -983,7 +1011,7 @@ async function generateUserSheetForMicroPlan( ) { const { tenantId, type } = request?.query; const schema = await callMdmsTypeSchema(request, tenantId, false, "user", "microplan"); - setDropdownFromSchema(request, schema, localizationMap); + // setDropdownFromSchema(request, schema, localizationMap); const headers = schema?.columns; const localizedHeaders = getLocalizedHeaders(headers, localizationMap); @@ -1005,7 +1033,8 @@ async function generateUserSheetForMicroPlan( // Create a sheet for each role, using the role name as the sheet name const userSheet: any = workbook.addWorksheet(role); addDataToSheet(request, userSheet, userSheetData, undefined, undefined, true, false, localizationMap, fileUrl, schema); - await handledropdownthings(userSheet, request.body?.dropdowns); + await handledropdownthings(userSheet, schema, localizationMap); + protectSheet(userSheet); await handleHiddenColumns(userSheet, request.body?.hiddenColumns); } diff --git a/health-services/project-factory/src/server/validators/microplanValidators.ts b/health-services/project-factory/src/server/validators/microplanValidators.ts index a837e8b3d43..e73eef94892 100644 --- a/health-services/project-factory/src/server/validators/microplanValidators.ts +++ b/health-services/project-factory/src/server/validators/microplanValidators.ts @@ -5,8 +5,6 @@ import { resourceDataStatuses, usageColumnStatus } from "../config/constants"; import config from "../config"; import { isMicroplanRequest } from "../utils/microplanUtils"; import { throwError } from "../utils/genericUtils"; -import { logger } from "../utils/logger"; - export function validatePhoneNumberSheetWise(datas: any[], localizationMap: any, rowMapping: any) { for (const data of datas) { const phoneColumn = getLocalizedName("HCM_ADMIN_CONSOLE_USER_PHONE_NUMBER_MICROPLAN", localizationMap); @@ -277,7 +275,7 @@ function enrichErrorForFcailityMicroplan(request: any, item: any, errors: any = } const facilityCapacityColumn = getLocalizedName(`HCM_ADMIN_CONSOLE_FACILITY_CAPACITY_MICROPLAN_${projectType}`, localizationMap); if (!item?.[facilityCapacityColumn]) { - logger.info(`Data in ${facilityCapacityColumn} column is empty, it will be ignored for microplan validation.`) + errors.push({ status: "INVALID", rowNumber: item?.["!row#number!"], errorDetails: `Data in ${facilityCapacityColumn} column can’t be empty or zero, please update the data and re-upload` }) } else if (typeof (item?.[facilityCapacityColumn]) != "number") { errors.push({ status: "INVALID", rowNumber: item?.["!row#number!"], errorDetails: `Data in ${facilityCapacityColumn} column must be a number from 0 to 100000000` }) @@ -295,6 +293,20 @@ function enrichErrorForFcailityMicroplan(request: any, item: any, errors: any = } } +export function validateFacilityBoundaryForLowestLevel(request: any, boundaries: any, rowData: any, errors: any = [], localizationMap?: { [key: string]: string }) { + if (request?.body?.ResourceDetails?.type == "facility" && request?.body?.ResourceDetails?.additionalDetails?.source == "microplan") { + const hierarchy = request?.body?.hierarchyType?.boundaryHierarchy + const lastLevel = hierarchy?.[hierarchy.length - 1]?.boundaryType + for (const data of rowData?.boundaryCodes) { + const boundaryFromBoundariesType = boundaries.find((boundary: any) => boundary.code == data)?.type + if (boundaryFromBoundariesType != lastLevel) { + errors.push({ status: "INVALID", rowNumber: rowData?.rowNumber, errorDetails: `${data} is not a ${lastLevel} level boundary` }) + } + } + } +} + + export async function validateExtraBoundariesForMicroplan(request: any, dataFromSheet: any, localizationMap: any) { if (await isMicroplanRequest(request)) { diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml index fd0b688dcc3..9cb321d57d0 100644 --- a/health-services/project/pom.xml +++ b/health-services/project/pom.xml @@ -45,12 +45,12 @@ org.egov.common health-services-common - 1.0.18-SNAPSHOT + 1.0.20-dev-SNAPSHOT org.egov.common health-services-models - 1.0.21-SNAPSHOT + 1.0.23-dev-SNAPSHOT compile 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/repository/ProjectFacilityRepository.java b/health-services/project/src/main/java/org/egov/project/repository/ProjectFacilityRepository.java index d602f809b15..219a38458ec 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/ProjectFacilityRepository.java +++ b/health-services/project/src/main/java/org/egov/project/repository/ProjectFacilityRepository.java @@ -1,9 +1,13 @@ package org.egov.project.repository; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import org.egov.common.data.query.builder.SelectQueryBuilder; +import org.egov.common.data.query.exception.QueryBuilderException; import org.egov.common.data.repository.GenericRepository; import org.egov.common.models.project.ProjectFacility; +import org.egov.common.models.project.ProjectFacilitySearch; import org.egov.common.producer.Producer; import org.egov.project.repository.rowmapper.ProjectFacilityRowMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -11,15 +15,16 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository @Slf4j public class ProjectFacilityRepository extends GenericRepository { @Autowired public ProjectFacilityRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, - RedisTemplate redisTemplate, - SelectQueryBuilder selectQueryBuilder, ProjectFacilityRowMapper projectFacilityRowMapper) { + RedisTemplate redisTemplate, + SelectQueryBuilder selectQueryBuilder, ProjectFacilityRowMapper projectFacilityRowMapper) { super(producer, namedParameterJdbcTemplate, redisTemplate, selectQueryBuilder, projectFacilityRowMapper, Optional.of("project_facility")); } -} +} \ No newline at end of file diff --git a/health-services/project/src/main/java/org/egov/project/repository/querybuilder/ProjectAddressQueryBuilder.java b/health-services/project/src/main/java/org/egov/project/repository/querybuilder/ProjectAddressQueryBuilder.java index 466c3549af4..4b3aeda7bac 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/querybuilder/ProjectAddressQueryBuilder.java +++ b/health-services/project/src/main/java/org/egov/project/repository/querybuilder/ProjectAddressQueryBuilder.java @@ -93,6 +93,18 @@ public String getProjectSearchQuery(List projects, Integer limit, Integ preparedStmtList.add(project.getProjectType()); } + if (StringUtils.isNotBlank(project.getReferenceID())) { + addClauseIfRequired(preparedStmtList, queryBuilder); + queryBuilder.append(" prj.referenceId =? "); + preparedStmtList.add(project.getReferenceID()); + } + + if (StringUtils.isNotBlank(project.getParent())) { + addClauseIfRequired(preparedStmtList, queryBuilder); + queryBuilder.append(" prj.parent =? "); + preparedStmtList.add(project.getParent()); + } + if (project.getAddress() != null && StringUtils.isNotBlank(project.getAddress().getBoundary())) { addClauseIfRequired(preparedStmtList, queryBuilder); queryBuilder.append(" addr.boundary=? "); diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/DocumentRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/DocumentRowMapper.java index b9d3f814d7c..b2fcfb5672a 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/DocumentRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/DocumentRowMapper.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.project.Document; import org.egov.tracer.model.CustomException; import org.postgresql.util.PGobject; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/LocationCaptureRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/LocationCaptureRowMapper.java index b9ea8babec8..a5a8da51b09 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/LocationCaptureRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/LocationCaptureRowMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import lombok.extern.slf4j.Slf4j; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.project.UserActionEnum; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectAddressRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectAddressRowMapper.java index fa5d72c5dc7..b4cd46201b3 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectAddressRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectAddressRowMapper.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.project.Address; import org.egov.common.models.project.AddressType; import org.egov.common.models.project.Project; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectBeneficiaryRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectBeneficiaryRowMapper.java index c79c91ed161..663ada6310f 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectBeneficiaryRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectBeneficiaryRowMapper.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.project.ProjectBeneficiary; import org.springframework.jdbc.core.RowMapper; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectFacilityRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectFacilityRowMapper.java index d6433f36db6..3d622db4a42 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectFacilityRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectFacilityRowMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.project.ProjectFacility; import org.springframework.jdbc.core.RowMapper; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectResourceRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectResourceRowMapper.java index 34deb79333a..bd6aa793bb6 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectResourceRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectResourceRowMapper.java @@ -1,7 +1,7 @@ package org.egov.project.repository.rowmapper; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.project.ProjectProductVariant; import org.egov.common.models.project.ProjectResource; import org.springframework.beans.factory.annotation.Autowired; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectRowMapper.java index b8625274dfc..a4e1193eed2 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectRowMapper.java @@ -1,6 +1,6 @@ package org.egov.project.repository.rowmapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.project.Project; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Component; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectStaffRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectStaffRowMapper.java index a0ff3d24bcf..169bdc99d40 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectStaffRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectStaffRowMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.project.ProjectStaff; import org.springframework.jdbc.core.RowMapper; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectTaskRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectTaskRowMapper.java index ccff648bd41..406a7419c54 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectTaskRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/ProjectTaskRowMapper.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.project.Address; import org.egov.common.models.project.AddressType; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TargetRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TargetRowMapper.java index f9b352a69b4..59477283fec 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TargetRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TargetRowMapper.java @@ -1,6 +1,6 @@ package org.egov.project.repository.rowmapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.project.Target; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ResultSetExtractor; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TaskResourceRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TaskResourceRowMapper.java index 87cab062d9c..1187e1692e6 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TaskResourceRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/TaskResourceRowMapper.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.project.TaskResource; import org.springframework.jdbc.core.RowMapper; diff --git a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/UserActionRowMapper.java b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/UserActionRowMapper.java index 8a63f0f3c99..57c992ae154 100644 --- a/health-services/project/src/main/java/org/egov/project/repository/rowmapper/UserActionRowMapper.java +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/UserActionRowMapper.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import lombok.extern.slf4j.Slf4j; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.project.UserActionEnum; diff --git a/health-services/project/src/main/java/org/egov/project/service/ProjectFacilityService.java b/health-services/project/src/main/java/org/egov/project/service/ProjectFacilityService.java index f7628318789..9e5e47675bb 100644 --- a/health-services/project/src/main/java/org/egov/project/service/ProjectFacilityService.java +++ b/health-services/project/src/main/java/org/egov/project/service/ProjectFacilityService.java @@ -1,9 +1,16 @@ package org.egov.project.service; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.project.ProjectFacility; import org.egov.common.models.project.ProjectFacilityBulkRequest; import org.egov.common.models.project.ProjectFacilityRequest; @@ -27,12 +34,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.function.Predicate; -import java.util.stream.Collectors; - import static org.egov.common.utils.CommonUtils.handleErrors; import static org.egov.common.utils.CommonUtils.havingTenantId; import static org.egov.common.utils.CommonUtils.includeDeleted; @@ -214,27 +215,27 @@ private Tuple, Map> validat return new Tuple<>(validEntities, errorDetailsMap); } - public List search(ProjectFacilitySearchRequest projectFacilitySearchRequest, - Integer limit, - Integer offset, - String tenantId, - Long lastChangedSince, - Boolean includeDeleted) throws Exception { + public SearchResponse search(ProjectFacilitySearchRequest projectFacilitySearchRequest, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws Exception { log.info("received request to search project facility"); if (isSearchByIdOnly(projectFacilitySearchRequest.getProjectFacility())) { log.info("searching project facility by id"); List ids = projectFacilitySearchRequest.getProjectFacility().getId(); log.info("fetching project facility with ids: {}", ids); - return projectFacilityRepository.findById(ids, includeDeleted).stream() + List projectfacilities = projectFacilityRepository.findById(ids, includeDeleted).stream() .filter(lastChangedSince(lastChangedSince)) .filter(havingTenantId(tenantId)) .filter(includeDeleted(includeDeleted)) .collect(Collectors.toList()); + return SearchResponse.builder().response(projectfacilities).build(); } log.info("searching project facility using criteria"); - return projectFacilityRepository.find(projectFacilitySearchRequest.getProjectFacility(), + return projectFacilityRepository.findWithCount(projectFacilitySearchRequest.getProjectFacility(), limit, offset, tenantId, lastChangedSince, includeDeleted); } - } diff --git a/health-services/project/src/main/java/org/egov/project/service/ProjectResourceService.java b/health-services/project/src/main/java/org/egov/project/service/ProjectResourceService.java index 660efbd4814..8f8c2555947 100644 --- a/health-services/project/src/main/java/org/egov/project/service/ProjectResourceService.java +++ b/health-services/project/src/main/java/org/egov/project/service/ProjectResourceService.java @@ -5,6 +5,7 @@ import org.egov.common.data.query.exception.QueryBuilderException; import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.project.ProjectResource; import org.egov.common.models.project.ProjectResourceBulkRequest; import org.egov.common.models.project.ProjectResourceRequest; @@ -182,27 +183,28 @@ public List delete(ProjectResourceBulkRequest request, boolean } - public List search(ProjectResourceSearchRequest request, - Integer limit, - Integer offset, - String tenantId, - Long lastChangedSince, - Boolean includeDeleted) throws QueryBuilderException { + public SearchResponse search(ProjectResourceSearchRequest request, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws QueryBuilderException { String idFieldName = getIdFieldName(request.getProjectResource()); if (isSearchByIdOnly(request.getProjectResource(), idFieldName)) { List ids = (List) ReflectionUtils.invokeMethod(getIdMethod((Collections .singletonList(request.getProjectResource()))), request.getProjectResource()); - return projectResourceRepository.findById(ids, includeDeleted, idFieldName).stream() + List projectResources = projectResourceRepository.findById(ids, includeDeleted, idFieldName).stream() .filter(lastChangedSince(lastChangedSince)) .filter(havingTenantId(tenantId)) .filter(includeDeleted(includeDeleted)) .collect(Collectors.toList()); + return SearchResponse.builder().response(projectResources).build(); } log.info("completed search method for project resource"); - return projectResourceRepository.find(request.getProjectResource(), + return projectResourceRepository.findWithCount(request.getProjectResource(), limit, offset, tenantId, lastChangedSince, includeDeleted); } } diff --git a/health-services/project/src/main/java/org/egov/project/service/ProjectService.java b/health-services/project/src/main/java/org/egov/project/service/ProjectService.java index 56e2665792a..e27c827ce29 100644 --- a/health-services/project/src/main/java/org/egov/project/service/ProjectService.java +++ b/health-services/project/src/main/java/org/egov/project/service/ProjectService.java @@ -1,7 +1,7 @@ package org.egov.project.service; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import jakarta.validation.Valid; import java.util.Map; import lombok.extern.slf4j.Slf4j; diff --git a/health-services/project/src/main/java/org/egov/project/service/ProjectStaffService.java b/health-services/project/src/main/java/org/egov/project/service/ProjectStaffService.java index c600537a74e..d172b96263f 100644 --- a/health-services/project/src/main/java/org/egov/project/service/ProjectStaffService.java +++ b/health-services/project/src/main/java/org/egov/project/service/ProjectStaffService.java @@ -4,6 +4,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.project.ProjectStaff; import org.egov.common.models.project.ProjectStaffBulkRequest; import org.egov.common.models.project.ProjectStaffRequest; @@ -28,9 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.lang.reflect.Type; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Predicate; @@ -224,26 +223,27 @@ private Tuple, Map> validate(List return new Tuple<>(validEntities, errorDetailsMap); } - public List search(ProjectStaffSearchRequest projectStaffSearchRequest, - Integer limit, - Integer offset, - String tenantId, - Long lastChangedSince, - Boolean includeDeleted) throws Exception { + public SearchResponse search(ProjectStaffSearchRequest projectStaffSearchRequest, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws Exception { log.info("received request to search project staff"); if (isSearchByIdOnly(projectStaffSearchRequest.getProjectStaff())) { log.info("searching project staff by id"); List ids = projectStaffSearchRequest.getProjectStaff().getId(); log.info("fetching project staff with ids: {}", ids); - return projectStaffRepository.findById(ids, includeDeleted).stream() + List projectStaffs = projectStaffRepository.findById(ids, includeDeleted).stream() .filter(lastChangedSince(lastChangedSince)) .filter(havingTenantId(tenantId)) .filter(includeDeleted(includeDeleted)) .collect(Collectors.toList()); + return SearchResponse.builder().response(projectStaffs).build(); } log.info("searching project staff using criteria"); - return projectStaffRepository.find(projectStaffSearchRequest.getProjectStaff(), + return projectStaffRepository.findWithCount(projectStaffSearchRequest.getProjectStaff(), limit, offset, tenantId, lastChangedSince, includeDeleted); } diff --git a/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectEnrichment.java b/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectEnrichment.java index 2bd670f589f..6497beb4d53 100644 --- a/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectEnrichment.java +++ b/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectEnrichment.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import java.util.Map; import java.util.ArrayList; import lombok.extern.slf4j.Slf4j; diff --git a/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java b/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java index db974db9be9..97bdaecc500 100644 --- a/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java +++ b/health-services/project/src/main/java/org/egov/project/service/enrichment/ProjectTaskEnrichmentService.java @@ -4,7 +4,7 @@ import java.util.Map; import java.util.stream.Collectors; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import lombok.extern.slf4j.Slf4j; import org.egov.common.models.project.Address; import org.egov.common.models.project.Task; diff --git a/health-services/project/src/main/java/org/egov/project/util/BoundaryUtil.java b/health-services/project/src/main/java/org/egov/project/util/BoundaryUtil.java index 3a0a08d31ea..2ac778f4891 100644 --- a/health-services/project/src/main/java/org/egov/project/util/BoundaryUtil.java +++ b/health-services/project/src/main/java/org/egov/project/util/BoundaryUtil.java @@ -1,26 +1,26 @@ package org.egov.project.util; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; -import digit.models.coremodels.RequestInfoWrapper; import lombok.extern.slf4j.Slf4j; -import net.minidev.json.JSONObject; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.egov.common.contract.models.RequestInfoWrapper; import org.egov.common.contract.request.RequestInfo; import org.egov.common.http.client.ServiceRequestClient; import org.egov.tracer.model.CustomException; +import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - @Component @Slf4j diff --git a/health-services/project/src/main/java/org/egov/project/util/MDMSUtils.java b/health-services/project/src/main/java/org/egov/project/util/MDMSUtils.java index 4de61e5ab79..be006ad385d 100644 --- a/health-services/project/src/main/java/org/egov/project/util/MDMSUtils.java +++ b/health-services/project/src/main/java/org/egov/project/util/MDMSUtils.java @@ -5,10 +5,10 @@ import java.util.LinkedList; import java.util.List; -import digit.models.coremodels.mdms.MasterDetail; -import digit.models.coremodels.mdms.MdmsCriteria; -import digit.models.coremodels.mdms.MdmsCriteriaReq; -import digit.models.coremodels.mdms.ModuleDetail; +import org.egov.mdms.model.MasterDetail; +import org.egov.mdms.model.MdmsCriteria; +import org.egov.mdms.model.MdmsCriteriaReq; +import org.egov.mdms.model.ModuleDetail; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.contract.request.RequestInfo; diff --git a/health-services/project/src/main/java/org/egov/project/util/ProjectServiceUtil.java b/health-services/project/src/main/java/org/egov/project/util/ProjectServiceUtil.java index 7d750e8d984..8c9b810eecc 100644 --- a/health-services/project/src/main/java/org/egov/project/util/ProjectServiceUtil.java +++ b/health-services/project/src/main/java/org/egov/project/util/ProjectServiceUtil.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import java.util.Iterator; import java.util.List; import java.util.Map; diff --git a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/BeneficiaryValidator.java b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/BeneficiaryValidator.java index 19c8454d63a..c0be5cfcb64 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/BeneficiaryValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/BeneficiaryValidator.java @@ -3,10 +3,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.mdms.MasterDetail; -import digit.models.coremodels.mdms.MdmsCriteria; -import digit.models.coremodels.mdms.MdmsCriteriaReq; -import digit.models.coremodels.mdms.ModuleDetail; +import org.egov.mdms.model.MasterDetail; +import org.egov.mdms.model.MdmsCriteria; +import org.egov.mdms.model.MdmsCriteriaReq; +import org.egov.mdms.model.ModuleDetail; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.contract.request.RequestInfo; 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/java/org/egov/project/validator/staff/PsUserIdValidator.java b/health-services/project/src/main/java/org/egov/project/validator/staff/PsUserIdValidator.java index 7491e024ec3..a33408b813c 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/staff/PsUserIdValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/staff/PsUserIdValidator.java @@ -1,9 +1,15 @@ package org.egov.project.validator.staff; -import digit.models.coremodels.UserSearchRequest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.contract.request.User; +import org.egov.common.contract.user.UserSearchRequest; import org.egov.common.http.client.ServiceRequestClient; import org.egov.common.models.Error; import org.egov.common.models.individual.Individual; @@ -18,12 +24,6 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -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.common.utils.CommonUtils.getIdToObjMap; import static org.egov.common.utils.CommonUtils.getMethod; import static org.egov.common.utils.CommonUtils.getObjClass; diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtResourceQuantityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtResourceQuantityValidator.java index e3be161fabb..0a4a68bd917 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtResourceQuantityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtResourceQuantityValidator.java @@ -8,10 +8,6 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.mdms.MasterDetail; -import digit.models.coremodels.mdms.MdmsCriteria; -import digit.models.coremodels.mdms.MdmsCriteriaReq; -import digit.models.coremodels.mdms.ModuleDetail; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.egov.common.models.Error; @@ -22,6 +18,10 @@ import org.egov.common.service.MdmsService; import org.egov.common.utils.CommonUtils; import org.egov.common.validator.Validator; +import org.egov.mdms.model.MasterDetail; +import org.egov.mdms.model.MdmsCriteria; +import org.egov.mdms.model.MdmsCriteriaReq; +import org.egov.mdms.model.ModuleDetail; import org.egov.project.config.ProjectConfiguration; import org.egov.tracer.model.CustomException; import org.springframework.core.annotation.Order; diff --git a/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectApiController.java b/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectApiController.java index 1b74b7ab1d7..2ec0adc34d3 100644 --- a/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectApiController.java +++ b/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectApiController.java @@ -220,7 +220,7 @@ public ResponseEntity projectFacilityV2SearchPost( @Valid @ModelAttribute URLParams urlParams, @ApiParam(value = "Capture details of Project facility.", required = true) @Valid @RequestBody ProjectFacilitySearchRequest projectFacilitySearchRequest ) throws Exception { - List projectFacilities = projectFacilityService.search( + SearchResponse searchResponse = projectFacilityService.search( projectFacilitySearchRequest, urlParams.getLimit(), urlParams.getOffset(), @@ -229,7 +229,8 @@ public ResponseEntity projectFacilityV2SearchPost( urlParams.getIncludeDeleted() ); ProjectFacilityBulkResponse response = ProjectFacilityBulkResponse.builder() - .projectFacilities(projectFacilities) + .projectFacilities(searchResponse.getResponse()) + .totalCount(searchResponse.getTotalCount()) .responseInfo(ResponseInfoFactory .createResponseInfo(projectFacilitySearchRequest.getRequestInfo(), true)) .build(); @@ -310,7 +311,7 @@ public ResponseEntity projectStaffV1SearchPost( @Valid @ModelAttribute URLParams urlParams, @ApiParam(value = "Capture details of Project staff.", required = true) @Valid @RequestBody ProjectStaffSearchRequest projectStaffSearchRequest ) throws Exception { - List projectStaffList = projectStaffService.search( + SearchResponse searchResponse = projectStaffService.search( projectStaffSearchRequest, urlParams.getLimit(), urlParams.getOffset(), @@ -319,7 +320,8 @@ public ResponseEntity projectStaffV1SearchPost( urlParams.getIncludeDeleted() ); ProjectStaffBulkResponse response = ProjectStaffBulkResponse.builder() - .projectStaff(projectStaffList) + .projectStaff(searchResponse.getResponse()) + .totalCount(searchResponse.getTotalCount()) .responseInfo(ResponseInfoFactory .createResponseInfo(projectStaffSearchRequest.getRequestInfo(), true)) .build(); diff --git a/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectResourceApiController.java b/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectResourceApiController.java index 6f71ea7ef93..ef0522cfbf0 100644 --- a/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectResourceApiController.java +++ b/health-services/project/src/main/java/org/egov/project/web/controllers/ProjectResourceApiController.java @@ -7,6 +7,7 @@ import jakarta.validation.Valid; import org.egov.common.contract.response.ResponseInfo; import org.egov.common.data.query.exception.QueryBuilderException; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.core.URLParams; import org.egov.common.models.project.ProjectResource; import org.egov.common.models.project.ProjectResourceBulkRequest; @@ -75,7 +76,7 @@ public ResponseEntity resourceV1SearchPost( @ApiParam(value = "Search linkage of Project and resource.", required = true) @Valid @RequestBody ProjectResourceSearchRequest projectResourceSearchRequest ) throws QueryBuilderException { - List projectResource = projectResourceService.search( + SearchResponse searchResponse = projectResourceService.search( projectResourceSearchRequest, urlParams.getLimit(), urlParams.getOffset(), @@ -84,7 +85,10 @@ public ResponseEntity resourceV1SearchPost( urlParams.getIncludeDeleted() ); ProjectResourceBulkResponse response = ProjectResourceBulkResponse.builder().responseInfo(ResponseInfoFactory - .createResponseInfo(projectResourceSearchRequest.getRequestInfo(), true)).projectResource(projectResource).build(); + .createResponseInfo(projectResourceSearchRequest.getRequestInfo(), true)) + .projectResource(searchResponse.getResponse()) + .totalCount(searchResponse.getTotalCount()) + .build(); return ResponseEntity.status(HttpStatus.OK).body(response); } diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index 93f601466a9..e27c6d18403 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -180,4 +180,8 @@ 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/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceCreateTest.java b/health-services/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceCreateTest.java index 93740830a51..fccdb5d0d1d 100644 --- a/health-services/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceCreateTest.java +++ b/health-services/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceCreateTest.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.mdms.MdmsCriteriaReq; +import org.egov.mdms.model.MdmsCriteriaReq; import org.apache.commons.io.IOUtils; import org.egov.common.contract.request.RequestInfo; import org.egov.common.http.client.ServiceRequestClient; diff --git a/health-services/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceUpdateTest.java b/health-services/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceUpdateTest.java index 805fba5c474..e4675e45bc2 100644 --- a/health-services/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceUpdateTest.java +++ b/health-services/project/src/test/java/org/egov/project/service/ProjectBeneficiaryServiceUpdateTest.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.mdms.MdmsCriteriaReq; +import org.egov.mdms.model.MdmsCriteriaReq; import org.apache.commons.io.IOUtils; import org.egov.common.http.client.ServiceRequestClient; import org.egov.common.models.core.SearchResponse; diff --git a/health-services/project/src/test/java/org/egov/project/service/ProjectFacilityServiceSearchTest.java b/health-services/project/src/test/java/org/egov/project/service/ProjectFacilityServiceSearchTest.java index 6eed8465ca5..85fd9f4e71b 100644 --- a/health-services/project/src/test/java/org/egov/project/service/ProjectFacilityServiceSearchTest.java +++ b/health-services/project/src/test/java/org/egov/project/service/ProjectFacilityServiceSearchTest.java @@ -1,6 +1,7 @@ package org.egov.project.service; import org.egov.common.helper.RequestInfoTestBuilder; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.project.ProjectFacility; import org.egov.project.helper.ProjectFacilityTestBuilder; import org.egov.project.repository.ProjectFacilityRepository; @@ -46,9 +47,9 @@ void setUp() { @Test @DisplayName("should not raise exception if no search results are found") void shouldNotRaiseExceptionIfNoProjectFacilityFound() throws Exception { - when(projectFacilityRepository.find(any(ProjectFacilitySearch.class), any(Integer.class), + when(projectFacilityRepository.findWithCount(any(ProjectFacilitySearch.class), any(Integer.class), any(Integer.class), any(String.class), eq(null), any(Boolean.class))) - .thenReturn(Collections.emptyList()); + .thenReturn(SearchResponse.builder().response(Collections.emptyList()).build()); ProjectFacilitySearch projectFacilitySearch = ProjectFacilitySearch.builder() .id(Collections.singletonList("ID101")).facilityId(Collections.singletonList("some-facility-id")).build(); ProjectFacilitySearchRequest projectFacilitySearchRequest = ProjectFacilitySearchRequest.builder() @@ -77,8 +78,9 @@ void shouldNotRaiseExceptionIfNoProjectFacilityFoundForSearchById() { @Test @DisplayName("should return project facility if search criteria is matched") void shouldReturnProjectFacilityIfSearchCriteriaIsMatched() throws Exception { - when(projectFacilityRepository.find(any(ProjectFacilitySearch.class), any(Integer.class), - any(Integer.class), any(String.class), eq(null), any(Boolean.class))).thenReturn(projectFacilities); + when(projectFacilityRepository.findWithCount(any(ProjectFacilitySearch.class), any(Integer.class), + any(Integer.class), any(String.class), eq(null), any(Boolean.class))).thenReturn(SearchResponse.builder() + .response(projectFacilities).build()); projectFacilities.add(ProjectFacilityTestBuilder.builder().withId().withId().withAuditDetails().build()); ProjectFacilitySearch projectFacilitySearch = ProjectFacilitySearch.builder() .id(Collections.singletonList("ID101")).projectId(Collections.singletonList("some-projectId")).build(); @@ -87,7 +89,7 @@ void shouldReturnProjectFacilityIfSearchCriteriaIsMatched() throws Exception { .withCompleteRequestInfo().build()).build(); List projectFacilities = projectFacilityService.search(projectFacilitySearchRequest, - 10, 0, "default", null, false); + 10, 0, "default", null, false).getResponse(); assertEquals(1, projectFacilities.size()); } @@ -104,7 +106,7 @@ void shouldReturnFromCacheIfSearchCriteriaHasIdOnly() throws Exception { when(projectFacilityRepository.findById(anyList(), anyBoolean())).thenReturn(projectFacilities); List projectFacilities = projectFacilityService.search(projectFacilitySearchRequest, - 10, 0, null, null, true); + 10, 0, null, null, true).getResponse(); assertEquals(1, projectFacilities.size()); } diff --git a/health-services/project/src/test/java/org/egov/project/service/ProjectStaffServiceSearchTest.java b/health-services/project/src/test/java/org/egov/project/service/ProjectStaffServiceSearchTest.java index 36aa7100f8d..f14fa8f9a9e 100644 --- a/health-services/project/src/test/java/org/egov/project/service/ProjectStaffServiceSearchTest.java +++ b/health-services/project/src/test/java/org/egov/project/service/ProjectStaffServiceSearchTest.java @@ -1,6 +1,7 @@ package org.egov.project.service; import org.egov.common.helper.RequestInfoTestBuilder; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.project.ProjectStaff; import org.egov.project.helper.ProjectStaffTestBuilder; import org.egov.project.repository.ProjectStaffRepository; @@ -46,9 +47,9 @@ void setUp() { @Test @DisplayName("should not raise exception if no search results are found") void shouldNotRaiseExceptionIfNoProjectStaffFound() throws Exception { - when(projectStaffRepository.find(any(ProjectStaffSearch.class), any(Integer.class), + when(projectStaffRepository.findWithCount(any(ProjectStaffSearch.class), any(Integer.class), any(Integer.class), any(String.class), eq(null), any(Boolean.class))) - .thenReturn(Collections.emptyList()); + .thenReturn(SearchResponse.builder().response(Collections.emptyList()).build()); ProjectStaffSearch projectStaffSearch = ProjectStaffSearch.builder() .id(Collections.singletonList("ID101")).staffId(Collections.singletonList("some-user-id")).build(); ProjectStaffSearchRequest projectStaffSearchRequest = ProjectStaffSearchRequest.builder() @@ -75,15 +76,15 @@ void shouldNotRaiseExceptionIfNoProjectStaffFoundForSearchById() { @Test @DisplayName("should return project staff if search criteria is matched") void shouldReturnProjectStaffIfSearchCriteriaIsMatched() throws Exception { - when(projectStaffRepository.find(any(ProjectStaffSearch.class), any(Integer.class), - any(Integer.class), any(String.class), eq(null), any(Boolean.class))).thenReturn(projectStaffs); + when(projectStaffRepository.findWithCount(any(ProjectStaffSearch.class), any(Integer.class), + any(Integer.class), any(String.class), eq(null), any(Boolean.class))).thenReturn(SearchResponse.builder().response(projectStaffs).build()); projectStaffs.add(ProjectStaffTestBuilder.builder().withId().withId().withAuditDetails().build()); ProjectStaffSearch projectStaffSearch = ProjectStaffSearch.builder().id(Collections.singletonList("ID101")).projectId(Collections.singletonList("some-projectId")).build(); ProjectStaffSearchRequest projectStaffSearchRequest = ProjectStaffSearchRequest.builder() .projectStaff(projectStaffSearch).requestInfo(RequestInfoTestBuilder.builder() .withCompleteRequestInfo().build()).build(); - List projectStaffs = projectStaffService.search(projectStaffSearchRequest, 10, 0, "default", null, false); + List projectStaffs = projectStaffService.search(projectStaffSearchRequest, 10, 0, "default", null, false).getResponse(); assertEquals(1, projectStaffs.size()); } @@ -100,7 +101,7 @@ void shouldReturnFromCacheIfSearchCriteriaHasIdOnly() throws Exception { when(projectStaffRepository.findById(anyList(), anyBoolean())).thenReturn(projectStaffs); List projectStaffs = projectStaffService.search(projectStaffSearchRequest, - 10, 0, null, null, true); + 10, 0, null, null, true).getResponse(); assertEquals(1, projectStaffs.size()); } diff --git a/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectFacilityApiControllerTest.java b/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectFacilityApiControllerTest.java index e6a97cf70c8..fe6a8e402db 100644 --- a/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectFacilityApiControllerTest.java +++ b/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectFacilityApiControllerTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.egov.common.helper.RequestInfoTestBuilder; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.project.ProjectFacility; import org.egov.common.models.project.ProjectFacilityBulkRequest; import org.egov.common.models.project.ProjectFacilityBulkResponse; @@ -193,8 +194,9 @@ void shouldAcceptSearchRequestAndReturnProjectFacility() throws Exception { any(Integer.class), any(String.class), any(Long.class), - any(Boolean.class))).thenReturn(Arrays.asList(ProjectFacilityTestBuilder.builder() - .withId().withAuditDetails().build())); + any(Boolean.class))).thenReturn(SearchResponse.builder() + .response(Arrays.asList(ProjectFacilityTestBuilder.builder() + .withId().withAuditDetails().build())).build()); final MvcResult result = mockMvc.perform(post( "/facility/v1/_search?limit=10&offset=100&tenantId=default&lastChangedSince=1234322&includeDeleted=false") diff --git a/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectStaffApiControllerTest.java b/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectStaffApiControllerTest.java index 1e1b5409485..2147e98e460 100644 --- a/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectStaffApiControllerTest.java +++ b/health-services/project/src/test/java/org/egov/project/web/controllers/ProjectStaffApiControllerTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.egov.common.helper.RequestInfoTestBuilder; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.project.ProjectStaff; import org.egov.common.models.project.ProjectStaffBulkResponse; import org.egov.common.models.project.ProjectStaffRequest; @@ -175,7 +176,7 @@ void shouldAcceptSearchRequestAndReturnProjectStaff() throws Exception { any(Integer.class), any(String.class), any(Long.class), - any(Boolean.class))).thenReturn(Arrays.asList(ProjectStaffTestBuilder.builder().withId().withAuditDetails().build())); + any(Boolean.class))).thenReturn(SearchResponse.builder().response(Arrays.asList(ProjectStaffTestBuilder.builder().withId().withAuditDetails().build())).build()); final MvcResult result = mockMvc.perform(post( "/staff/v1/_search?limit=10&offset=100&tenantId=default&lastChangedSince=1234322&includeDeleted=false") diff --git a/health-services/referralmanagement/pom.xml b/health-services/referralmanagement/pom.xml index b9d85ad8269..4bf32a9765a 100644 --- a/health-services/referralmanagement/pom.xml +++ b/health-services/referralmanagement/pom.xml @@ -46,12 +46,12 @@ org.egov.common health-services-common - 1.0.18-SNAPSHOT + 1.0.20-dev-SNAPSHOT org.egov.common health-services-models - 1.0.20-SNAPSHOT + 1.0.23-dev-SNAPSHOT compile diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/HFReferralRepository.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/HFReferralRepository.java index d2d43634030..0fee8b9d853 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/HFReferralRepository.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/HFReferralRepository.java @@ -12,6 +12,7 @@ import org.egov.common.data.query.builder.QueryFieldChecker; import org.egov.common.data.query.builder.SelectQueryBuilder; import org.egov.common.data.repository.GenericRepository; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.referralmanagement.hfreferral.HFReferral; import org.egov.common.models.referralmanagement.hfreferral.HFReferralSearch; import org.egov.common.producer.Producer; @@ -23,6 +24,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; +import static org.egov.common.utils.CommonUtils.constructTotalCountCTEAndReturnResult; import static org.egov.common.utils.CommonUtils.getIdMethod; /** @@ -66,7 +68,7 @@ protected HFReferralRepository(Producer producer, NamedParameterJdbcTemplate nam * @param includeDeleted Flag indicating whether to include deleted records. * @return A list of HFReferral entities matching the search criteria. */ - public List find(HFReferralSearch searchObject, Integer limit, Integer offset, String tenantId, + public SearchResponse find(HFReferralSearch searchObject, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted) { // Initial query to select HFReferral fields from the table. String query = "SELECT hf.id, hf.clientreferenceid, hf.tenantid, hf.projectid, hf.projectfacilityid, hf.symptom, hf.symptomsurveyid, hf.beneficiaryid, hf.referralcode, hf.nationallevelid, hf.createdby, hf.createdtime, hf.lastmodifiedby, hf.lastmodifiedtime, hf.clientcreatedby, hf.clientcreatedtime, hf.clientlastmodifiedby, hf.clientlastmodifiedtime, hf.rowversion, hf.isdeleted, hf.additionaldetails from hf_referral hf"; @@ -96,16 +98,21 @@ public List find(HFReferralSearch searchObject, Integer limit, Integ } // Add ORDER BY, LIMIT, and OFFSET clauses to the query. - query = query + "ORDER BY hf.createdtime DESC LIMIT :limit OFFSET :offset"; + query = query + "ORDER BY hf.createdtime DESC"; paramsMap.put("tenantId", tenantId); paramsMap.put("isDeleted", includeDeleted); paramsMap.put("lastModifiedTime", lastChangedSince); + + Long totalCount = constructTotalCountCTEAndReturnResult(query, paramsMap, this.namedParameterJdbcTemplate); + + query += " LIMIT :limit OFFSET :offset"; paramsMap.put("limit", limit); paramsMap.put("offset", offset); // Execute the query and retrieve the list of HFReferral entities. List hfReferralList = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); - return hfReferralList; + + return SearchResponse.builder().response(hfReferralList).totalCount(totalCount).build(); } /** @@ -116,7 +123,7 @@ public List find(HFReferralSearch searchObject, Integer limit, Integ * @param columnName The column name to search for IDs. * @return A list of HFReferral entities matching the provided IDs. */ - public List findById(List ids, Boolean includeDeleted, String columnName) { + public SearchResponse findById(List ids, String columnName, Boolean includeDeleted) { // Find objects in the cache based on the provided IDs. List objFound = findInCache(ids); if (!includeDeleted) { @@ -134,7 +141,7 @@ public List findById(List ids, Boolean includeDeleted, Strin // If no IDs are remaining, return the objects found in the cache. if (ids.isEmpty()) { - return objFound; + return SearchResponse.builder().response(objFound).build(); } } @@ -154,6 +161,6 @@ public List findById(List ids, Boolean includeDeleted, Strin // Add the retrieved entities to the cache. objFound.addAll(hfReferralList); putInCache(objFound); - return objFound; + return SearchResponse.builder().response(objFound).build(); } } diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/HFReferralRowMapper.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/HFReferralRowMapper.java index 5456cd9179c..7994e3d192f 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/HFReferralRowMapper.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/HFReferralRowMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.referralmanagement.hfreferral.HFReferral; import org.springframework.beans.factory.annotation.Autowired; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/ReferralRowMapper.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/ReferralRowMapper.java index 181aa1b6a55..83971874a2f 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/ReferralRowMapper.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/ReferralRowMapper.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.referralmanagement.Referral; import org.egov.common.models.referralmanagement.sideeffect.SideEffect; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/SideEffectRowMapper.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/SideEffectRowMapper.java index 3832d8bd7e3..4b4d961b1f2 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/SideEffectRowMapper.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/SideEffectRowMapper.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.referralmanagement.sideeffect.SideEffect; import org.springframework.beans.factory.annotation.Autowired; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/HFReferralService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/HFReferralService.java index c3c287bcff3..bc6aa52dc33 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/HFReferralService.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/HFReferralService.java @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.referralmanagement.hfreferral.HFReferral; import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; import org.egov.common.models.referralmanagement.hfreferral.HFReferralRequest; @@ -169,12 +170,12 @@ public List update(HFReferralBulkRequest hfReferralRequest, boolean } // Method to search for HFReferrals based on certain criteria - public List search(HFReferralSearchRequest referralSearchRequest, - Integer limit, - Integer offset, - String tenantId, - Long lastChangedSince, - Boolean includeDeleted) { + public SearchResponse search(HFReferralSearchRequest referralSearchRequest, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) { log.info("Received request to search referrals"); String idFieldName = getIdFieldName(referralSearchRequest.getHfReferral()); @@ -186,11 +187,12 @@ public List search(HFReferralSearchRequest referralSearchRequest, referralSearchRequest.getHfReferral()); log.info("Fetching referrals with IDs: {}", ids); - return hfReferralRepository.findById(ids, includeDeleted, idFieldName).stream() + List hfReferrals = hfReferralRepository.findById(ids, idFieldName, includeDeleted).getResponse().stream() .filter(lastChangedSince(lastChangedSince)) .filter(havingTenantId(tenantId)) .filter(includeDeleted(includeDeleted)) .collect(Collectors.toList()); + return SearchResponse.builder().response(hfReferrals).build(); } log.info("Searching referrals using criteria"); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java index 3c09df3edde..c812f7c5021 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java @@ -1,19 +1,18 @@ package org.egov.referralmanagement.service; + import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; + + +import com.jayway.jsonpath.JsonPath; import java.util.function.Function; import java.util.stream.Collectors; -import com.jayway.jsonpath.JsonPath; -import digit.models.coremodels.mdms.MasterDetail; -import digit.models.coremodels.mdms.MdmsCriteria; -import digit.models.coremodels.mdms.MdmsCriteriaReq; -import digit.models.coremodels.mdms.ModuleDetail; import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.egov.common.http.client.ServiceRequestClient; @@ -22,6 +21,11 @@ import org.egov.common.models.project.ProjectResponse; import org.egov.common.models.referralmanagement.beneficiarydownsync.DownsyncCriteria; import org.egov.common.models.referralmanagement.beneficiarydownsync.DownsyncRequest; +import org.egov.mdms.model.MasterDetail; +import org.egov.mdms.model.MdmsCriteria; +import org.egov.mdms.model.MdmsCriteriaReq; +import org.egov.mdms.model.ModuleDetail; + import org.egov.referralmanagement.config.ReferralManagementConfiguration; import org.egov.tracer.model.CustomException; import org.springframework.beans.factory.annotation.Autowired; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/util/ValidatorUtil.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/util/ValidatorUtil.java index 043c7d6a1b5..3541cb2d4dc 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/util/ValidatorUtil.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/util/ValidatorUtil.java @@ -1,7 +1,7 @@ package org.egov.referralmanagement.util; -import digit.models.coremodels.UserSearchRequest; import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.user.UserSearchRequest; import org.egov.common.service.UserService; import org.springframework.util.CollectionUtils; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNonExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNonExistentEntityValidator.java index 3011cef48ce..d7e81c7e9a4 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNonExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNonExistentEntityValidator.java @@ -82,7 +82,8 @@ public Map> validate(HFReferralBulkRequest request) { try { // Query the repository to find existing entities existingReferrals = hfReferralRepository.find(hfReferralSearch, hfReferrals.size(), 0, - hfReferrals.get(0).getTenantId(), null, false); + hfReferrals.get(0).getTenantId(), null, false).getResponse() + ; } catch (Exception e) { // Handle query builder exception log.error("Search failed for HFReferral with error: {}", e.getMessage(), e); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrRowVersionValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrRowVersionValidator.java index e5d62bfee0a..83011aceec9 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrRowVersionValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrRowVersionValidator.java @@ -61,7 +61,7 @@ public Map> validate(HFReferralBulkRequest request) { if (!iMap.isEmpty()) { List hfReferralIds = new ArrayList<>(iMap.keySet()); List existingHfReferrals = hfReferralRepository.findById(hfReferralIds, - false, getIdFieldName(idMethod)); + getIdFieldName(idMethod), false).getResponse(); List entitiesWithMismatchedRowVersion = getEntitiesWithMismatchedRowVersion(iMap, existingHfReferrals, idMethod); entitiesWithMismatchedRowVersion.forEach(hfReferral -> { diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/HFReferralApiController.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/HFReferralApiController.java index f09a4c578e8..c09a02bebfa 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/HFReferralApiController.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/HFReferralApiController.java @@ -6,6 +6,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import org.egov.common.contract.response.ResponseInfo; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.core.URLParams; import org.egov.common.models.referralmanagement.hfreferral.HFReferral; import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; @@ -107,7 +108,7 @@ public ResponseEntity referralV1SearchPost( @ApiParam(value = "HFReferral Search.", required = true) @Valid @RequestBody HFReferralSearchRequest request ) throws Exception { - List hfReferrals = hfReferralService.search( + SearchResponse searchResponse = hfReferralService.search( request, urlParams.getLimit(), urlParams.getOffset(), @@ -115,7 +116,10 @@ public ResponseEntity referralV1SearchPost( urlParams.getLastChangedSince(), urlParams.getIncludeDeleted()); HFReferralBulkResponse response = HFReferralBulkResponse.builder().responseInfo(ResponseInfoFactory - .createResponseInfo(request.getRequestInfo(), true)).hfReferrals(hfReferrals).build(); + .createResponseInfo(request.getRequestInfo(), true)) + .hfReferrals(searchResponse.getResponse()) + .totalCount(searchResponse.getTotalCount()) + .build(); return ResponseEntity.status(HttpStatus.OK).body(response); } diff --git a/health-services/resource-estimation-service/CHANGELOG.md b/health-services/resource-estimation-service/CHANGELOG.md deleted file mode 100644 index e5ce4491284..00000000000 --- a/health-services/resource-estimation-service/CHANGELOG.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changelog -## 1.0.0 - 2024-06-24 -#### Base Resource Estimation 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. - 4. Integrate with Campaign Manager: After processing calculations, it also integrates resources and boundary with the Campaign Manager. - 5. Boundary and Data Validation: Validates boundaries and excel data during calculations. \ No newline at end of file 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 deleted file mode 100644 index 797c9a894c3..00000000000 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.egov.processor.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 ERROR_WHILE_FETCHING_FROM_MDMS = "Exception occurred while fetching category lists from mdms: "; - - public static final String TENANTID_REPLACER = "{tenantId}"; - - public static final String TENANTID = "tenantId"; - - public static final String FILESTORE_ID_REPLACER = "{fileStoreId}"; - - public static final String FILES = "files"; - - public static final String FILESTORE_ID = "fileStoreId"; - - public static final String MODULE = "module"; - - 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."; - - public static final String ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE = "Exception occurred while fetching plan configuration from plan service "; - - 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 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_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"; - public static final String INPUT_IS_NOT_VALID = "File does not contain valid input for row "; - - public static final String MDMS_SCHEMA_TYPE = "type"; - public static final String MDMS_SCHEMA_SECTION = "section"; - 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 ERROR_WHILE_UPDATING_PLAN_CONFIG = "Exception occurred while updating plan configuration."; - - 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)$"; - - public static final String FILE_TEMPLATE = "Facilities"; - public static final String HIERARCHYTYPE_REPLACER = "{hierarchyType}"; - public static final String FILE_EXTENSION = "excel"; - - public static final String SCIENTIFIC_NOTATION_INDICATOR = "E"; - 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 ERROR_WHILE_SEARCHING_LOCALE = "Exception occurred while searching locale. "; - public static final String MDMS_MASTER_COMMON_CONSTANTS = "CommonConstants"; - -} 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 deleted file mode 100644 index 32a5c0b4ccc..00000000000 --- a/health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.egov.processor.web.models; - -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; - -@Validated -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class MetricDetail { - - @JsonProperty("value") - @NotNull - private BigDecimal metricValue = null; - - @JsonProperty("comparator") - @NotNull - @Size(min = 1, max = 64) - private String metricComparator = null; - - @JsonProperty("unit") - @NotNull - @Size(min = 1, max = 128) - private String metricUnit = null; - -} diff --git a/health-services/resource-generator/CHANGELOG.md b/health-services/resource-generator/CHANGELOG.md new file mode 100644 index 00000000000..f56811de913 --- /dev/null +++ b/health-services/resource-generator/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +## 1.0.0 - 2024-12-03 +#### Resource Generator Service +The Resource Generator Service introduces comprehensive functionalities for microplanning resource estimation and campaign integration: + +1. File Processing: Supports Excel, Shapefiles, and GeoJSON for resource estimation and validates input data against the plan configuration. +2. Resource Estimation: Calculates resources using predefined formulas and updates plans by publishing data to relevant topics. +3. Boundary Validation: Ensures boundary integrity and validates data during resource calculations. +4. Process Triggers: Automates Plan-Facility creation, Census data creation, and Plan generation based on file uploads and validations. +5. Campaign Integration: Integrates estimated resources and boundaries with the Campaign Manager for streamlined planning. +6. Result Upload: Automates the upload of approved resource sheets to the filestore and updates plan configurations. +7. HCM Integration: Updates project factory with resource estimates for accurate campaign planning. \ No newline at end of file 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 95% rename from health-services/resource-estimation-service/pom.xml rename to health-services/resource-generator/pom.xml index c73dd06629d..33ac3c4c7d6 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 @@ -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-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 54% 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 index 12ce0667abd..c652337ba28 100644 --- 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 @@ -11,6 +11,8 @@ import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.List; + @Component @Data @Import({ TracerConfiguration.class }) @@ -27,12 +29,18 @@ 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; @Value("${egov.plan.config.endpoint}") private String planConfigEndPoint; + @Value("${egov.plan.search.endpoint}") + private String planSearchEndPoint; + // Filestore @Value("${egov.filestore.service.host}") @@ -53,18 +61,18 @@ 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.fetch.from.microplan.endpoint}") + private String campaignIntegrationFetchFromMicroplanEndPoint; + @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; @@ -77,4 +85,51 @@ 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; + + @Value("${plan.config.update.plan.estimates.into.output.file.status}") + private String planConfigUpdatePlanEstimatesIntoOutputFileStatus; + + @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; + + @Value("${resource.update.plan.config.consumer.topic}") + private String resourceUpdatePlanConfigConsumerTopic; + + @Value("${resource.census.create.topic}") + private String resourceCensusCreateTopic; + + //Default + @Value("${resource.default.offset}") + private Integer defaultOffset; + + @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; + + @Value("${census.additional.field.show.on.ui.false.keys}") + public List censusAdditionalFieldShowOnUIFalseKeys; + + //census host + @Value("${egov.census.host}") + private String censusHost; + + @Value("${egov.census.search.endpoint}") + private String censusSearchEndPoint; + } 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-generator/src/main/java/org/egov/processor/config/ServiceConstants.java b/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java new file mode 100644 index 00000000000..7200f29cecc --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java @@ -0,0 +1,123 @@ +package org.egov.processor.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 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"; + + public static final String FILESTORE_ID_REPLACER = "{fileStoreId}"; + + public static final String FILES = "files"; + + public static final String FILESTORE_ID = "fileStoreId"; + + public static final String MODULE = "module"; + + public static final String MICROPLANNING_MODULE = "microplan"; + + 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 ERROR_WHILE_FETCHING_FROM_PLAN_SERVICE = "Exception occurred while fetching plan configuration from plan service "; + + 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 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"; + + 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 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"; + 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"; + public static final String MDMS_SCHEMA_SECTION = "section"; + 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 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)$"; + + public static final String FILE_TEMPLATE = "Facilities"; + public static final String HIERARCHYTYPE_REPLACER = "{hierarchyType}"; + public static final String FILE_EXTENSION = "excel"; + + public static final String SCIENTIFIC_NOTATION_INDICATOR = "E"; + 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,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"; + + //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"; + + //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"; + + //Census additional field constants + public static final String UPLOADED_KEY = "UPLOADED_"; + public static final String CONFIRMED_KEY = "CONFIRMED_"; +} 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 66% 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 index 2aa31907413..8b0c54a4010 100644 --- 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 @@ -1,11 +1,9 @@ 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; @@ -13,6 +11,9 @@ 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; @Component @Slf4j @@ -22,16 +23,22 @@ 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(PlanConfiguration.StatusEnum.GENERATED)) { + 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.getPlanConfigUpdatePlanEstimatesIntoOutputFileStatus()))) { resourceEstimationService.estimateResources(planConfigurationRequest); log.info("Successfully estimated resources for plan."); } 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 74% 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 index ee005cd81c8..6f2326d628a 100644 --- 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 @@ -1,36 +1,19 @@ 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.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.*; 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.PlanConfiguration.StatusEnum; -import org.egov.processor.web.models.PlanConfigurationRequest; -import org.egov.processor.web.models.ResourceMapping; import org.egov.processor.web.models.boundary.BoundarySearchResponse; import org.egov.processor.web.models.boundary.EnrichedBoundary; import org.egov.processor.web.models.campaignManager.Boundary; @@ -40,13 +23,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 java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; -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 @@ -72,9 +58,15 @@ public class ExcelParser implements FileParser { private LocaleUtil localeUtil; + private CensusUtil censusUtil; + + 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) { + CalculationUtil calculationUtil, PlanUtil planUtil, CampaignIntegrationUtil campaignIntegrationUtil, + Configuration config, MdmsUtil mdmsUtil, BoundaryUtil boundaryUtil, LocaleUtil localeUtil, CensusUtil censusUtil, EnrichmentUtil enrichmentUtil, PlanConfigurationUtil planConfigurationUtil) { this.objectMapper = objectMapper; this.parsingUtil = parsingUtil; this.filestoreUtil = filestoreUtil; @@ -85,7 +77,10 @@ public ExcelParser(ObjectMapper objectMapper, ParsingUtil parsingUtil, Filestore this.mdmsUtil = mdmsUtil; this.boundaryUtil = boundaryUtil; this.localeUtil = localeUtil; - } + this.censusUtil = censusUtil; + this.enrichmentUtil = enrichmentUtil; + this.planConfigurationUtil = planConfigurationUtil; + } /** * Parses file data, extracts information from the file, and processes it. @@ -99,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); @@ -108,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; } /** @@ -122,20 +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, planConfig, workbook, - campaignBoundaryList, campaignResourcesList, dataFormatter); - String uploadedFileStoreId = uploadFileAndIntegrateCampaign(planConfigurationRequest, campaignResponse, - planConfig, workbook, campaignBoundaryList, campaignResourcesList); - return uploadedFileStoreId; + processSheets(planConfigurationRequest, fileStoreId, campaignResponse, workbook, + campaignBoundaryList, dataFormatter); + 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."); @@ -154,28 +147,26 @@ private String processExcelFile(PlanConfigurationRequest planConfigurationReques * * @param planConfigurationRequest The request containing configuration details including tenant ID. * @param campaignResponse The response object containing campaign details. - * @param planConfig The configuration details specific to the plan. * @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 (config.isIntegrateWithAdminConsole()) { - campaignIntegrationUtil.updateCampaignResources(uploadedFileStoreId, campaignResourcesList, - fileToUpload.getName()); - - campaignIntegrationUtil.updateCampaignDetails(planConfigurationRequest, campaignResponse, - campaignBoundaryList, campaignResourcesList); + if (planConfig.getStatus().equals(config.getPlanConfigTriggerPlanEstimatesStatus())) { + String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); + planUtil.setFileStoreIdForPopulationTemplate(planConfigurationRequest, uploadedFileStoreId); + planUtil.update(planConfigurationRequest); } - return uploadedFileStoreId; + if (planConfig.getStatus().equals(config.getPlanConfigUpdatePlanEstimatesIntoOutputFileStatus()) && config.isIntegrateWithAdminConsole()) { + String uploadedFileStoreId = uploadConvertedFile(fileToUpload, planConfig.getTenantId()); + campaignIntegrationUtil.updateResourcesInProjectFactory(planConfigurationRequest, uploadedFileStoreId); + } } finally { try { if (fileToUpload != null && !fileToUpload.delete()) { @@ -191,32 +182,48 @@ 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 campaignResourcesList List of campaign resources to be integrated. * @param dataFormatter The data formatter for formatting cell values. */ - private void processSheets(PlanConfigurationRequest planConfigurationRequest, String fileStoreId, - Object campaignResponse, PlanConfiguration planConfig, Workbook excelWorkbook, - List campaignBoundaryList, List campaignResourcesList, - DataFormatter dataFormatter) { - LocaleResponse localeResponse = localeUtil.searchLocale(planConfigurationRequest); - CampaignResponse campaign = parseCampaignResponse(campaignResponse); - Map attributeNameVsDataTypeMap = prepareAttributeVsIndexMap(planConfigurationRequest, - fileStoreId, campaign, planConfig); - List boundaryCodeList = getBoundaryCodeList(planConfigurationRequest, campaign, planConfig); + private void processSheets(PlanConfigurationRequest request, String fileStoreId, + Object campaignResponse, Workbook excelWorkbook, + List campaignBoundaryList, + DataFormatter dataFormatter) { + CampaignResponse campaign = campaignIntegrationUtil.parseCampaignResponse(campaignResponse); + 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); + + 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 (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, - campaignBoundaryList, attributeNameVsDataTypeMap, boundaryCodeList); + 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())) { + 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); + } } }); } @@ -241,8 +248,41 @@ 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(); + 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, + (existing, replacement) -> existing, + LinkedHashMap::new + )); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); Row firstRow = null; - performRowLevelCalculations(planConfigurationRequest, sheet, dataFormatter, fileStoreId, campaignBoundaryList, planConfig, attributeNameVsDataTypeMap, boundaryCodeList, firstRow); + + for (Row row : sheet) { + if (parsingUtil.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); + } } /** @@ -250,12 +290,11 @@ private void processRows(PlanConfigurationRequest planConfigurationRequest, Shee * * @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( @@ -272,29 +311,17 @@ 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(), - 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()); } - - /** - * 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. @@ -309,14 +336,23 @@ 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; + 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 = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + for (Row row : sheet) { - if(isRowEmpty(row)) + if(parsingUtil.isRowEmpty(row)) continue; if (row.getRowNum() == 0) { @@ -325,49 +361,20 @@ 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); - // TODO: remove after testing - 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. * Calculates results based on plan configuration operations, updates result map, and sets cell values. @@ -407,7 +414,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) { @@ -458,12 +465,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"); @@ -474,47 +479,51 @@ 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); - - // Add the columnName and cellValue to the propertiesNode - propertiesNode.put(columnName, cellValue); - } -// System.out.println("Feature Node ---- > " + featureNode); - return featureNode; - } + if (cell == null) { + // Handle null cells if needed + propertiesNode.putNull(columnName); + continue; + } - 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; + 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; + 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; } } - System.out.println(); // Move to the next line after printing the row + + return featureNode; } /** @@ -543,13 +552,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,13 +727,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 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()); - 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/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 82% 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 index c1b1ab07b7a..978633933b9 100644 --- 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 @@ -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,12 @@ 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.springframework.stereotype.Service; -import lombok.extern.slf4j.Slf4j; +import java.util.HashMap; +import java.util.Map; @Service @Slf4j @@ -48,7 +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); } /** @@ -108,5 +109,21 @@ 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) { + 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-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 74% 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 index d6b53891a8b..551206d9b94 100644 --- 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 @@ -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; @@ -16,6 +9,13 @@ import org.egov.processor.web.models.PlanConfigurationRequest; import org.egov.tracer.model.CustomException; 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; @@ -86,21 +86,23 @@ 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(Map resultMap, JsonNode feature, String input, String columnName) { - if (resultMap.containsKey(input)) { - return resultMap.get(input); - } else { - if (feature.get(PROPERTIES).get(columnName) != null) { + 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 inputValue = resultMap.getOrDefault(input, assumptionValueMap.get(input)); + + // Try to fetch the value from the feature (if it exists) + if(ObjectUtils.isEmpty(inputValue)) { + if (feature.has(PROPERTIES) && feature.get(PROPERTIES).has(columnName)) { 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 { @@ -109,12 +111,12 @@ public BigDecimal getInputValueFromJsonFeature(Map resultMap } return value; } catch (NumberFormatException | NullPointerException e) { - return BigDecimal.ZERO; - } - } else { - throw new CustomException("INPUT_VALUE_NOT_FOUND", "Input value not found: " + input); + // Handle potential parsing issues + throw new CustomException("INPUT_VALUE_NOT_FOUND", "Input value not found: " + input); } } } + + return inputValue; } /** @@ -127,12 +129,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 = getInputValueFromFeatureOrMap(feature, resultMap, assumptionValueMap, 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); } 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 61% 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 index d14b3512aef..9bfbe7cb62c 100644 --- 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 @@ -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 @@ -51,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) { @@ -58,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(); + } /** @@ -83,7 +105,28 @@ 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()); + } + } + + /** + * 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()); } } @@ -123,6 +166,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. * @@ -143,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. @@ -219,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. @@ -279,9 +327,35 @@ 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(); } + + /** + * 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/CensusUtil.java b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java new file mode 100644 index 00000000000..2e79ff60af5 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java @@ -0,0 +1,191 @@ +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.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.ArrayList; +import java.util.List; +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; + + 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; + } + + /** + * 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).build()) + .source(planConfig.getId()) + .additionalFields(enrichAdditionalField(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 List enrichAdditionalField(JsonNode feature, Map mappedValues) { + // Initialize orderCounter inside the function + List additionalFieldList = new ArrayList<>(); + int orderCounter = 1; + + 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 + if (!ObjectUtils.isEmpty(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) + .order(orderCounter++) // Use and increment the local orderCounter + .build(); + if(config.getCensusAdditionalFieldShowOnUIFalseKeys().contains(key)) { + additionalField.setShowOnUi(Boolean.FALSE); + additionalField.setEditable(Boolean.FALSE); + } else { + additionalField.setShowOnUi(Boolean.TRUE); + additionalField.setEditable(Boolean.TRUE); + } + additionalFieldList.add(additionalField); + } + } + } + + 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 new file mode 100644 index 00000000000..89f0a89511b --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java @@ -0,0 +1,297 @@ +package org.egov.processor.util; + +import lombok.extern.slf4j.Slf4j; +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.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; +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.*; + +@Component +@Slf4j +public class EnrichmentUtil { + + private MdmsV2Util mdmsV2Util; + + private LocaleUtil localeUtil; + + private ParsingUtil parsingUtil; + + private CensusUtil censusUtil; + + private PlanUtil planUtil; + + private Configuration config; +// private MultiStateInstanceUtil centralInstanceUtil; + + 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; + } + + /** + * 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); + + } + + 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); + // 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(); + + 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() + .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) + .limit(boundaryCodes.size()) + .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); + } + + 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) { + // 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(); + + 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()); + } + } + } + } + + 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) + .limit(boundaryCodes.size()) + .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-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 89% 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 index 1ecb725308f..12fefec0405 100644 --- 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 @@ -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-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 99% 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 index 229dbf57f45..e3019ded61b 100644 --- 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 @@ -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/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-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 59% 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 index b1902b49afb..ba10327e4c8 100644 --- 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 @@ -1,38 +1,30 @@ 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.Collections; -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 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.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 static org.egov.processor.config.ServiceConstants.PROPERTIES; @Slf4j @Component @@ -63,6 +55,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)) @@ -99,12 +93,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; } /** @@ -246,4 +268,128 @@ 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; + } + + + /** + * 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-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 85% 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 index 26a11dcf976..55a8651ec56 100644 --- 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 @@ -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-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 70% 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 index d44aaa2a59f..97c9810e0c5 100644 --- 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 @@ -1,33 +1,26 @@ 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 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.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.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 com.fasterxml.jackson.databind.ObjectMapper; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Map; +import java.util.stream.Collectors; -import lombok.extern.slf4j.Slf4j; +import static org.egov.processor.config.ServiceConstants.*; @Component @Slf4j @@ -38,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. @@ -55,7 +51,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,7 +76,8 @@ private PlanRequest buildPlanRequest(PlanConfigurationRequest planConfigurationR .requestInfo(planConfigurationRequest.getRequestInfo()) .plan(Plan.builder() .tenantId(planConfig.getTenantId()) - .executionPlanId(planConfig.getExecutionPlanId()) + .planConfigurationId(planConfig.getId()) + .campaignId(planConfig.getCampaignId()) .locality(getBoundaryCodeValue(ServiceConstants.BOUNDARY_CODE, feature, mappedValues)) .resources(resultMap.entrySet().stream().map(result -> { @@ -91,6 +88,8 @@ private PlanRequest buildPlanRequest(PlanConfigurationRequest planConfigurationR }).collect(Collectors.toList())) .activities(new ArrayList()) .targets(new ArrayList()) + .workflow(Workflow.builder().action(WORKFLOW_ACTION_INITIATE).build()) + .isRequestFromResourceEstimationConsumer(true) .build()) .build(); @@ -124,9 +123,42 @@ 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); } } + + + 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)); + + planConfigurationRequest.getPlanConfiguration().setWorkflow(null); + } + + } 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; + + +} 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 99% 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 index fa9e1193e90..6c093ba63a2 100644 --- 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 @@ -1,15 +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 java.util.List; + import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.validation.annotation.Validated; +import lombok.Data; +import lombok.Builder; /** * Activity diff --git a/health-services/resource-generator/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 new file mode 100644 index 00000000000..5f1d262fea7 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/Assumption.java @@ -0,0 +1,58 @@ +package org.egov.processor.web.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import jakarta.validation.Valid; +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.NoArgsConstructor; +import lombok.Data; +import lombok.Builder; + +/** + * Assumption + */ +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Assumption { + @JsonProperty("id") + @Valid + @Size(min = 2, max = 64) + private String id = null; + + @JsonProperty("key") + @NotNull + @Size(min = 1, max = 256) + private String key = null; + + @JsonProperty("value") + @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") + 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/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 index 51d3511c068..c63749d5bab 100644 --- 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 @@ -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-generator/src/main/java/org/egov/processor/web/models/File.java similarity index 81% 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 index fe6b6c1abab..25a62e8ac83 100644 --- 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 @@ -1,17 +1,20 @@ 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; /** * File @@ -30,7 +33,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 +43,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 +74,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/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-generator/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 new file mode 100644 index 00000000000..b21b1a62560 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/MetricDetail.java @@ -0,0 +1,75 @@ +package org.egov.processor.web.models; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +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; +import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; + +import java.math.BigDecimal; +import java.util.Arrays; + +@Validated +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +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 + 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-generator/src/main/java/org/egov/processor/web/models/Operation.java similarity index 70% 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 index 25b5b189fa0..5194da66b18 100644 --- 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 @@ -1,17 +1,19 @@ 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; /** * Operation @@ -46,6 +48,22 @@ 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("executionOrder") + private Integer executionOrder = null; + @JsonProperty("active") @NotNull private Boolean active = true; @@ -80,12 +98,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-generator/src/main/java/org/egov/processor/web/models/Plan.java similarity index 63% 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 index a9d4f3139b5..8b2f1803f57 100644 --- 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 @@ -1,17 +1,20 @@ package org.egov.processor.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 java.util.List; 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 */ @@ -34,30 +37,51 @@ 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) 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 = 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; + @JsonIgnore + private String boundaryAncestralPath = null; + + @JsonIgnore + private boolean isRequestFromResourceEstimationConsumer; + + @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-generator/src/main/java/org/egov/processor/web/models/PlanConfiguration.java similarity index 68% 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 index e02d7e49b70..218dbaecbea 100644 --- 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 @@ -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/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 index 5fea454bd5d..693ba12ef32 100644 --- 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 @@ -1,14 +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 java.math.BigDecimal; +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; /** * Resource 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 99% 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 index c53868d1033..ee9e1869c0c 100644 --- 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 @@ -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-generator/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 new file mode 100644 index 00000000000..3d726b35f9f --- /dev/null +++ b/health-services/resource-generator/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; +} 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 index 8d7298939f6..6855fccb123 100644 --- 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 @@ -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 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 94% 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 index 352b29b693b..51c390a2af5 100644 --- 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 @@ -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; 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-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-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-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..b35c0343469 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java @@ -0,0 +1,48 @@ +package org.egov.processor.web.models.campaignManager; + +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; + +@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("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; + +} 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 new file mode 100644 index 00000000000..f895f6c75f1 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java @@ -0,0 +1,138 @@ +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.JsonValue; +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.math.BigDecimal; +import java.util.List; + + +/** + * 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") + @Size(max = 64) + private String assignee = null; + + @JsonProperty("status") + @Size(max = 64) + private String status = null; + + @JsonProperty("type") + @NotNull + private TypeEnum type = null; + + @JsonProperty("totalPopulation") + @NotNull + private BigDecimal 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("workflow") + @Valid + private Workflow workflow; + + @JsonIgnore + private List assigneeJurisdiction; + + @JsonProperty("additionalDetails") + private Object additionalDetails = null; + + @JsonProperty("additionalFields") + @Valid + private List additionalFields = null; + + @JsonProperty("auditDetails") + private @Valid AuditDetails auditDetails; + + /** + * 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-generator/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 new file mode 100644 index 00000000000..08a9c3bdbce --- /dev/null +++ b/health-services/resource-generator/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 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 CensusRequest { + + @JsonProperty("RequestInfo") + @Valid + private RequestInfo requestInfo = null; + + @JsonProperty("Census") + @Valid + private Census census = null; + + +} diff --git a/health-services/resource-generator/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 new file mode 100644 index 00000000000..7e6c0b77440 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusResponse.java @@ -0,0 +1,41 @@ +package org.egov.processor.web.models.census; + +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; +import java.util.Map; + +/** + * 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-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 new file mode 100644 index 00000000000..9ed59d11d63 --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java @@ -0,0 +1,71 @@ +package org.egov.processor.web.models.census; + + +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 java.util.Set; + +/** + * 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; + } + +} diff --git a/health-services/resource-generator/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 new file mode 100644 index 00000000000..ef7439bc368 --- /dev/null +++ b/health-services/resource-generator/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 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; + +/** + * 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-generator/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 new file mode 100644 index 00000000000..52ab230781b --- /dev/null +++ b/health-services/resource-generator/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; + } + } + +} 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-estimation-service/src/main/resources/application.properties b/health-services/resource-generator/src/main/resources/application.properties similarity index 68% rename from health-services/resource-estimation-service/src/main/resources/application.properties rename to health-services/resource-generator/src/main/resources/application.properties index 7cdfe225f6d..45e36a74e5c 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 @@ -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 @@ -65,19 +66,43 @@ 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 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 + +#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 +plan.config.trigger.plan.facility.mappings.status=EXECUTION_TO_BE_DONE +plan.config.update.plan.estimates.into.output.file.status=RESOURCE_ESTIMATIONS_APPROVED + +# Pagination config +resource.default.offset=0 +resource.default.limit=10 + +# 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 +census.additional.field.show.on.ui.false.keys=HCM_ADMIN_CONSOLE_TARGET_LAT_OPT,HCM_ADMIN_CONSOLE_TARGET_LONG_OPT \ No newline at end of file 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 83% rename from health-services/resource-estimation-service/src/main/resources/db/Dockerfile rename to health-services/resource-generator/src/main/resources/db/Dockerfile index 60fc07ce69f..f5241a8f861 100644 --- a/health-services/resource-estimation-service/src/main/resources/db/Dockerfile +++ b/health-services/resource-generator/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-generator/src/main/resources/db/migrate.sh b/health-services/resource-generator/src/main/resources/db/migrate.sh new file mode 100644 index 00000000000..c58d6f91e3f --- /dev/null +++ b/health-services/resource-generator/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 diff --git a/health-services/stock/pom.xml b/health-services/stock/pom.xml index d204ba58903..5cb0c17da56 100644 --- a/health-services/stock/pom.xml +++ b/health-services/stock/pom.xml @@ -45,12 +45,12 @@ org.egov.common health-services-common - 1.0.18-SNAPSHOT + 1.0.20-dev-SNAPSHOT org.egov.common health-services-models - 1.0.20-SNAPSHOT + 1.0.23-dev-SNAPSHOT diff --git a/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockReconciliationRowMapper.java b/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockReconciliationRowMapper.java index 813246f8a2b..d05bca6fdd1 100644 --- a/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockReconciliationRowMapper.java +++ b/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockReconciliationRowMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.stock.StockReconciliation; import org.springframework.jdbc.core.RowMapper; diff --git a/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java b/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java index e413a3052ac..ea57dbad66d 100644 --- a/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java +++ b/health-services/stock/src/main/java/org/egov/stock/repository/rowmapper/StockRowMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import digit.models.coremodels.AuditDetails; +import org.egov.common.contract.models.AuditDetails; import org.egov.common.models.core.AdditionalFields; import org.egov.common.models.stock.ReferenceIdType; import org.egov.common.models.stock.SenderReceiverType; diff --git a/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java b/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java index 2951b21e031..e0e3b10b468 100644 --- a/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java +++ b/health-services/stock/src/main/java/org/egov/stock/service/FacilityService.java @@ -21,6 +21,7 @@ import org.egov.common.models.stock.SenderReceiverType; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockReconciliation; +import org.egov.common.models.stock.TransactionType; import org.egov.stock.config.StockConfiguration; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -83,36 +84,46 @@ public Map> validateProjectFacilityMappings(List ent Map> errorDetailsMap, RequestInfo requestInfo) { - + // Get a list of project reference IDs from the entities using reflection List projectIds = getIdList(entities, getMethod(GET_REFERENCE_ID, entities.get(0).getClass())); List facilityIds = null; + // Check the type of entities being processed (either StockReconciliation or Stock) if (entities.get(0) instanceof StockReconciliation) { + + // If the entity is StockReconciliation, extract facility IDs directly facilityIds = getIdList(entities, getMethod(GET_FACILITY_ID, entities.get(0).getClass())); } else if (entities.get(0) instanceof Stock) { + // If the entity is Stock, manually gather facility IDs based on sender/receiver type and transaction type facilityIds = new ArrayList<>(); for (T entity : entities) { Stock stock = (Stock) entity; - if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType())) { + // Add the sender ID if the sender is a warehouse and the transaction type is DISPATCHED + if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) && TransactionType.DISPATCHED.equals(stock.getTransactionType())) { facilityIds.add(stock.getSenderId()); } - if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType())) { - facilityIds.add(stock.getReceiverId()); - } + + // Add the receiver ID if the receiver is a warehouse and the transaction type is RECEIVED + else if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) && TransactionType.RECEIVED.equals(stock.getTransactionType())) { + facilityIds.add(stock.getReceiverId()); + } } } + // Calculate the search limit based on the number of project and facility IDs Integer searchLimit = projectIds.size() * facilityIds.size(); + // Build a request object to search for project-facility mappings ProjectFacilitySearchRequest projectFacilitySearchRequest = ProjectFacilitySearchRequest.builder() .projectFacility(ProjectFacilitySearch.builder().projectId(projectIds).facilityId(facilityIds).build()) .requestInfo(requestInfo) .build(); try { + // Call an external service to fetch project-facility mappings using the constructed request ProjectFacilityBulkResponse response = serviceRequestClient.fetchResult( new StringBuilder(stockConfiguration.getProjectFacilityServiceHost() + stockConfiguration.getProjectFacilityServiceSearchUrl() @@ -121,11 +132,13 @@ public Map> validateProjectFacilityMappings(List ent projectFacilitySearchRequest, ProjectFacilityBulkResponse.class); + // Group the response by project ID and collect facility IDs associated with each project return response.getProjectFacilities().stream() .collect(Collectors.groupingBy(projectFacility -> projectFacility.getProjectId(), Collectors.mapping(projectFacility -> projectFacility.getFacilityId(), Collectors.toList()))); } catch (Exception e) { + // If an exception occurs, log the error and add network error details to each entity in the errorDetailsMap log.error("error while fetching project facility list: {}", ExceptionUtils.getStackTrace(e)); entities.forEach(b -> { Error error = getErrorForEntityWithNetworkError(); diff --git a/health-services/stock/src/main/java/org/egov/stock/service/StockReconciliationService.java b/health-services/stock/src/main/java/org/egov/stock/service/StockReconciliationService.java index 6c6801a5922..69340c5efca 100644 --- a/health-services/stock/src/main/java/org/egov/stock/service/StockReconciliationService.java +++ b/health-services/stock/src/main/java/org/egov/stock/service/StockReconciliationService.java @@ -10,6 +10,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.stock.StockReconciliation; import org.egov.common.models.stock.StockReconciliationBulkRequest; import org.egov.common.models.stock.StockReconciliationRequest; @@ -182,26 +183,27 @@ public List delete(StockReconciliationBulkRequest request, return validEntities; } - public List search(StockReconciliationSearchRequest request, - Integer limit, - Integer offset, - String tenantId, - Long lastChangedSince, - Boolean includeDeleted) throws Exception { + public SearchResponse search(StockReconciliationSearchRequest request, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws Exception { log.info("starting search method for stock reconciliation"); String idFieldName = getIdFieldName(request.getStockReconciliation()); if (isSearchByIdOnly(request.getStockReconciliation(), idFieldName)) { List ids = (List) ReflectionUtils.invokeMethod(getIdMethod(Collections .singletonList(request.getStockReconciliation())), request.getStockReconciliation()); - return stockRepository.findById(ids, includeDeleted, idFieldName).stream() + List stockReconciliations = stockRepository.findById(ids, includeDeleted, idFieldName).stream() .filter(lastChangedSince(lastChangedSince)) .filter(havingTenantId(tenantId)) .filter(includeDeleted(includeDeleted)) .collect(Collectors.toList()); + return SearchResponse.builder().response(stockReconciliations).build(); } log.info("completed search method for stock reconciliation"); - return stockRepository.find(request.getStockReconciliation(), + return stockRepository.findWithCount(request.getStockReconciliation(), limit, offset, tenantId, lastChangedSince, includeDeleted); } } diff --git a/health-services/stock/src/main/java/org/egov/stock/service/StockService.java b/health-services/stock/src/main/java/org/egov/stock/service/StockService.java index 6a26da44ced..c6b60278be7 100644 --- a/health-services/stock/src/main/java/org/egov/stock/service/StockService.java +++ b/health-services/stock/src/main/java/org/egov/stock/service/StockService.java @@ -10,6 +10,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.egov.common.ds.Tuple; import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockBulkRequest; import org.egov.common.models.stock.StockRequest; @@ -177,27 +178,28 @@ public List delete(StockBulkRequest request, boolean isBulk) { return validEntities; } - public List search(StockSearchRequest stockSearchRequest, - Integer limit, - Integer offset, - String tenantId, - Long lastChangedSince, - Boolean includeDeleted) throws Exception { + public SearchResponse search(StockSearchRequest stockSearchRequest, + Integer limit, + Integer offset, + String tenantId, + Long lastChangedSince, + Boolean includeDeleted) throws Exception { log.info("starting search method for stock"); String idFieldName = getIdFieldName(stockSearchRequest.getStock()); if (isSearchByIdOnly(stockSearchRequest.getStock(), idFieldName)) { List ids = (List) ReflectionUtils.invokeMethod(getIdMethod(Collections .singletonList(stockSearchRequest.getStock())), stockSearchRequest.getStock()); - return stockRepository.findById(ids, includeDeleted, idFieldName).stream() + List stocks = stockRepository.findById(ids, includeDeleted, idFieldName).stream() .filter(lastChangedSince(lastChangedSince)) .filter(havingTenantId(tenantId)) .filter(includeDeleted(includeDeleted)) .collect(Collectors.toList()); + return SearchResponse.builder().response(stocks).build(); } log.info("completed search method for stock"); - return stockRepository.find(stockSearchRequest.getStock(), + return stockRepository.findWithCount(stockSearchRequest.getStock(), limit, offset, tenantId, lastChangedSince, includeDeleted); } } diff --git a/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java b/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java index d71f92cda2d..5c436e37811 100644 --- a/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java +++ b/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java @@ -6,13 +6,14 @@ import java.util.Map; import java.util.stream.Collectors; -import digit.models.coremodels.UserSearchRequest; import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.user.UserSearchRequest; import org.egov.common.ds.Tuple; import org.egov.common.models.Error; import org.egov.common.models.stock.SenderReceiverType; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockReconciliation; +import org.egov.common.models.stock.TransactionType; import org.egov.common.service.UserService; import org.egov.stock.service.FacilityService; import org.egov.tracer.model.CustomException; @@ -265,20 +266,44 @@ private static void enrichErrorForStock(List validEntities, for (Stock stock : validEntities) { + // Get the sender and receiver IDs from the stock object String senderId = stock.getSenderId(); String receiverId = stock.getReceiverId(); + // Get the list of facility IDs mapped to the reference ID of the stock List facilityIds = ProjectFacilityMappingOfIds.get(stock.getReferenceId()); - if (!CollectionUtils.isEmpty(facilityIds)) { - if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) && !facilityIds.contains(senderId)) { - populateErrorForStock(stock, senderId, errorDetailsMap); - } + // Check if the stock involves a warehouse and a valid transaction type (DISPATCHED or RECEIVED) + if ((SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) && TransactionType.DISPATCHED.equals(stock.getTransactionType())) + || (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) && TransactionType.RECEIVED.equals(stock.getTransactionType()))) { + + // If facilityIds are not empty, validate the sender and receiver IDs based on TransactionType + if (!CollectionUtils.isEmpty(facilityIds)) { + + // Check if the sender is a warehouse and the transaction is DISPATCHED + // Validate that the sender ID is in the facility IDs, otherwise log an error + if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) + && !facilityIds.contains(senderId) + && TransactionType.DISPATCHED.equals(stock.getTransactionType())) { + + // Log an error for the invalid sender + populateErrorForStock(stock, senderId, errorDetailsMap); + } - if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) && !facilityIds.contains(receiverId)) - populateErrorForStock(stock, receiverId, errorDetailsMap); - } else { - populateErrorForStock(stock, senderId + " and " + receiverId, errorDetailsMap); + // Check if the receiver is a warehouse and the transaction is RECEIVED + // Validate that the receiver ID is in the facility IDs, otherwise log an error + if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) + && !facilityIds.contains(receiverId) + && TransactionType.RECEIVED.equals(stock.getTransactionType())) { + + // Log an error for the invalid receiver + populateErrorForStock(stock, receiverId, errorDetailsMap); + } + } else { + + // If facilityIds are empty, log an error for both sender and receiver + populateErrorForStock(stock, senderId + " and " + receiverId, errorDetailsMap); + } } } } diff --git a/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockApiController.java b/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockApiController.java index 913213dd191..7033f50a14a 100644 --- a/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockApiController.java +++ b/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockApiController.java @@ -8,6 +8,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import org.egov.common.contract.response.ResponseInfo; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.core.URLParams; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockBulkRequest; @@ -80,7 +81,7 @@ public ResponseEntity stockV1SearchPost( @ApiParam(value = "Capture details of Stock Transfer.", required = true) @Valid @RequestBody StockSearchRequest stockSearchRequest ) throws Exception { - List stock = stockService.search( + SearchResponse searchResponse = stockService.search( stockSearchRequest, urlParams.getLimit(), urlParams.getOffset(), @@ -89,7 +90,7 @@ public ResponseEntity stockV1SearchPost( urlParams.getIncludeDeleted() ); StockBulkResponse response = StockBulkResponse.builder().responseInfo(ResponseInfoFactory - .createResponseInfo(stockSearchRequest.getRequestInfo(), true)).stock(stock).build(); + .createResponseInfo(stockSearchRequest.getRequestInfo(), true)).stock(searchResponse.getResponse()).totalCount(searchResponse.getTotalCount()).build(); return ResponseEntity.status(HttpStatus.OK).body(response); } diff --git a/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockReconciliationApiController.java b/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockReconciliationApiController.java index e612c3b692f..41fc33437e9 100644 --- a/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockReconciliationApiController.java +++ b/health-services/stock/src/main/java/org/egov/stock/web/controllers/StockReconciliationApiController.java @@ -7,6 +7,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import org.egov.common.contract.response.ResponseInfo; +import org.egov.common.models.core.SearchResponse; import org.egov.common.models.core.URLParams; import org.egov.common.models.stock.StockReconciliation; import org.egov.common.models.stock.StockReconciliationBulkRequest; @@ -77,7 +78,7 @@ public ResponseEntity stockReconciliationV1Sear @ApiParam(value = "Capture details of Stock Reconciliation.", required = true) @Valid @RequestBody StockReconciliationSearchRequest stockReconciliationSearchRequest ) throws Exception { - List stock = stockReconciliationService.search( + SearchResponse searchResponse = stockReconciliationService.search( stockReconciliationSearchRequest, urlParams.getLimit(), urlParams.getOffset(), @@ -86,7 +87,10 @@ public ResponseEntity stockReconciliationV1Sear urlParams.getIncludeDeleted() ); StockReconciliationBulkResponse response = StockReconciliationBulkResponse.builder().responseInfo(ResponseInfoFactory - .createResponseInfo(stockReconciliationSearchRequest.getRequestInfo(), true)).stockReconciliation(stock).build(); + .createResponseInfo(stockReconciliationSearchRequest.getRequestInfo(), true)) + .stockReconciliation(searchResponse.getResponse()) + .totalCount(searchResponse.getTotalCount()) + .build(); return ResponseEntity.status(HttpStatus.OK).body(response); }