From 0e1092f9a82496f6d5a139843456d609df33a8d5 Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Mon, 5 Aug 2024 18:04:15 +0530 Subject: [PATCH 01/20] Hlm 6385 irs changes (#841) * HLM-6385: added changes for IRS activity track and closed household concepts * HLM-6385: added changes for IRS activity track and closed household concepts, added db migration script, validations for closed household * HLM-6385: added changes for location tracking * HLM-6385: added changes for location points * HLM-6385: added clientReferenceId and tenantId in LocationPoint, updated Location_capture model * HLM-6385, HCMPRE-46: Updated changes as per design review * HLM-6385, HCMPRE-46: Added Location capture changes * HLM-6385, HCMPRE-46: Added UserAction changes * HLM-6385, HCMPRE-46: updated common models, replaced digit models with service-common * Revert "HLM-6385, HCMPRE-46: updated common models, replaced digit models with service-common" This reverts commit 6abdea41edc35ce8fe9efe298438c559a664136e. * HLM-6385, HCMPRE-46: updated table informations and columns for migration scripts * reverting BoundaryUtil change * reverting BoundaryUtil changes * HLM-6385, HCMPRE-46: updated validators and IRSConsumer * HLM-6385, HCMPRE-46: updated validators * HLM-6385, HCMPRE-46: updated project configuration * HLM-6385, HCMPRE-49: updated models to have isDeleted as it is required in common utils enrichment code * HLM-6385, HCMPRE-46: updated the projectid field, added notnull annotation * HLM-6385, HCMPRE-46: updated all the changes related to enrichment * HLM-6385, HCMPRE-46: made action field notnull * HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields * HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields, HCMPRE-116, HCMPRE-117 * HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields, HCMPRE-116, HCMPRE-117, added in services * HLM-6385, HCMPRE-46: removed outdated changes from Task.java * removed all user location models * Refactored from LocationCapture model to UserAction and packges from irs to useraction * HLM-6385 - lat/long irs name changes * HLM Downsync Incremental product changes pull from impel (#831) * HLM Downsync Incremental product changes pull from impel * HLM removed impel specific changes * renamed Project type filter code constant * HLM updated beneficiary based search * HLM updated downsync search, cycles is required only when it is smc based campaign * HCM - removed project task resource quantity validator * HLM updated downsync logic as per review comments * HCMPRE-216 : Added Administration failed status for validation when task resource is empty or when status is ADMINISTRATION_FAILED * HCMPRE-216: updated task status * HCMPRE-216: changed to ADMINISTRATION_FAILED * HLM-6385: updated with code review comments * HLM-6385: added changes as per review comments, and added correct logs wherever required. * HLM-6385: code review comments addressed. * HLM-6385: review comment added for error handling on LocationCaptureRepository * HLM-6385: another batch of coderabbitai code review comments addressed. * HLM-6385: added more logs in repository for useraction and location capture * HLM-6385: updated the code as per code review comments from @kavi-egov --------- Co-authored-by: kavi_elrey <25226238+kavi-egov@users.noreply.github.com> Co-authored-by: Holash Chand --- .../java/org/egov/household/Constants.java | 2 +- health-services/libraries/docker-compose.yml | 67 ---- .../libraries/health-services-models/pom.xml | 2 +- .../common/models/project/UserActionEnum.java | 33 ++ .../models/project/useraction/UserAction.java | 109 ++++++ .../useraction/UserActionBulkRequest.java | 64 ++++ .../useraction/UserActionBulkResponse.java | 70 ++++ .../project/useraction/UserActionSearch.java | 55 +++ .../useraction/UserActionSearchRequest.java | 44 +++ health-services/project/pom.xml | 2 +- .../main/java/org/egov/project/Constants.java | 8 + .../project/config/ProjectConfiguration.java | 25 ++ .../project/consumer/UserActionConsumer.java | 106 ++++++ .../repository/LocationCaptureRepository.java | 135 ++++++++ .../repository/UserActionRepository.java | 139 ++++++++ .../rowmapper/LocationCaptureRowMapper.java | 91 +++++ .../rowmapper/UserActionRowMapper.java | 95 ++++++ .../service/LocationCaptureService.java | 222 ++++++++++++ .../project/service/ProjectTaskService.java | 8 +- .../project/service/UserActionService.java | 215 ++++++++++++ .../UserActionEnrichmentService.java | 67 ++++ .../org/egov/project/util/BoundaryUtil.java | 2 +- .../egov/project/util/ProjectConstants.java | 10 +- .../task/PtIsResouceEmptyValidator.java | 19 +- .../useraction/UaBoundaryValidator.java | 125 +++++++ .../useraction/UaExistentEntityValidator.java | 76 +++++ .../UaNonExistentEntityValidator.java | 96 ++++++ .../useraction/UaNullIdValidator.java | 27 ++ .../useraction/UaProjectIdValidator.java | 96 ++++++ .../useraction/UaRowVersionValidator.java | 69 ++++ .../useraction/UaStatusValidator.java | 99 ++++++ .../LocationCaptureController.java | 130 +++++++ .../web/controllers/UserActionController.java | 162 +++++++++ .../src/main/resources/application.properties | 9 + .../V20240711175300__user_location_ddl.sql | 23 ++ .../main/V20240711175500__user_action_ddl.sql | 28 ++ .../egov/referralmanagement/Constants.java | 6 + .../ReferralManagementConfiguration.java | 6 + .../service/DownsyncService.java | 323 +++++++++++------- .../service/MasterDataService.java | 129 +++++++ 40 files changed, 2788 insertions(+), 206 deletions(-) delete mode 100644 health-services/libraries/docker-compose.yml create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserActionEnum.java create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkRequest.java create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkResponse.java create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearch.java create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearchRequest.java create mode 100644 health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java create mode 100644 health-services/project/src/main/java/org/egov/project/repository/LocationCaptureRepository.java create mode 100644 health-services/project/src/main/java/org/egov/project/repository/UserActionRepository.java create mode 100644 health-services/project/src/main/java/org/egov/project/repository/rowmapper/LocationCaptureRowMapper.java create mode 100644 health-services/project/src/main/java/org/egov/project/repository/rowmapper/UserActionRowMapper.java create mode 100644 health-services/project/src/main/java/org/egov/project/service/LocationCaptureService.java create mode 100644 health-services/project/src/main/java/org/egov/project/service/UserActionService.java create mode 100644 health-services/project/src/main/java/org/egov/project/service/enrichment/UserActionEnrichmentService.java create mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaBoundaryValidator.java create mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java create mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaNonExistentEntityValidator.java create mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaNullIdValidator.java create mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaProjectIdValidator.java create mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaRowVersionValidator.java create mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java create mode 100644 health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java create mode 100644 health-services/project/src/main/java/org/egov/project/web/controllers/UserActionController.java create mode 100644 health-services/project/src/main/resources/db/migration/main/V20240711175300__user_location_ddl.sql create mode 100644 health-services/project/src/main/resources/db/migration/main/V20240711175500__user_action_ddl.sql create mode 100644 health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java diff --git a/health-services/household/src/main/java/org/egov/household/Constants.java b/health-services/household/src/main/java/org/egov/household/Constants.java index da512e39234..0ce22b8bb8d 100644 --- a/health-services/household/src/main/java/org/egov/household/Constants.java +++ b/health-services/household/src/main/java/org/egov/household/Constants.java @@ -23,7 +23,7 @@ public interface Constants { String INDIVIDUAL_ALREADY_MEMBER_OF_HOUSEHOLD = "INDIVIDUAL_ALREADY_MEMBER_OF_HOUSEHOLD"; - String INDIVIDUAL_ALREADY_MEMBER_OF_HOUSEHOLD_MESSAGE = "individual is already member od household"; + String INDIVIDUAL_ALREADY_MEMBER_OF_HOUSEHOLD_MESSAGE = "individual is already member of household"; String INDIVIDUAL_NOT_FOUND = "INDIVIDUAL_NOT_FOUND"; diff --git a/health-services/libraries/docker-compose.yml b/health-services/libraries/docker-compose.yml deleted file mode 100644 index fea4de2e4ca..00000000000 --- a/health-services/libraries/docker-compose.yml +++ /dev/null @@ -1,67 +0,0 @@ -version: '2' -services: - zookeeper: - image: 'confluentinc/cp-zookeeper:latest' - container_name: zookeeper - environment: - ZOOKEEPER_CLIENT_PORT: 2181 - ZOOKEEPER_TICK_TIME: 2000 - ports: - - '2181:2181' - kafka: - image: 'confluentinc/cp-kafka:latest' - container_name: kafka - depends_on: - - zookeeper - ports: - - '9092:9092' - environment: - KAFKA_BROKER_ID: 1 - KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://127.0.0.1:9092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT - KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 - schema-registry: - image: confluentinc/cp-schema-registry:4.1.1 - hostname: schema-registry - ports: - - "38081:38081" - depends_on: - - kafka - environment: - SCHEMA_REGISTRY_KAFKASTORE_CONNECTION_URL: zookeeper:2181 - SCHEMA_REGISTRY_HOST_NAME: schema-registry - SCHEMA_REGISTRY_LISTENERS: http://schema-registry:38081 - SCHEMA_REGISTRY_DEBUG: "true" - - kafka-rest: - image: confluentinc/cp-kafka-rest:4.1.1 - hostname: kafka-rest - ports: - - "38082:38082" - depends_on: - - schema-registry - environment: - KAFKA_REST_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_REST_SCHEMA_REGISTRY_URL: schema-registry:38081 - KAFKA_REST_HOST_NAME: kafka-rest - KAFKA_REST_LISTENERS: http://kafka-rest:38082 - postgres: - image: postgres:10-bullseye - environment: - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres - ports: - - 5432:5432 - magic: - image: digitsy/kafka-magic - ports: - - "9999:80" - environment: - KMAGIC_ALLOW_TOPIC_DELETE: "true" - KMAGIC_ALLOW_SCHEMA_DELETE: "true" - redis: - image: redis:3.2 - ports: - - 6379:6379 diff --git a/health-services/libraries/health-services-models/pom.xml b/health-services/libraries/health-services-models/pom.xml index ccbf98bc824..f0bef369759 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.20-SNAPSHOT + 1.0.20-dev-SNAPSHOT 17 ${java.version} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserActionEnum.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserActionEnum.java new file mode 100644 index 00000000000..1271584b583 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/UserActionEnum.java @@ -0,0 +1,33 @@ +package org.egov.common.models.project; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum UserActionEnum { + CLOSED_HOUSEHOLD("CLOSED_HOUSEHOLD"), + LOCATION_CAPTURE("LOCATION_CAPTURE"), + OTHER("OTHER"); + + private String value; + + UserActionEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static UserActionEnum fromValue(String text) { + for (UserActionEnum status : UserActionEnum.values()) { + if (String.valueOf(status.value).equals(text)) { + return status; + } + } + return null; + } + +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java new file mode 100644 index 00000000000..ac20f32e157 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java @@ -0,0 +1,109 @@ +package org.egov.common.models.project.useraction; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +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 lombok.experimental.SuperBuilder; +import org.egov.common.models.core.EgovOfflineModel; +import org.egov.common.models.project.UserActionEnum; +import org.springframework.validation.annotation.Validated; + +/** + * The UserAction class represents an action performed by the logged in user related to a project with + * or without in relation to a beneficiary + * It extends the EgovOfflineModel to inherit common properties. + */ +@Validated +@Data +@NoArgsConstructor +@AllArgsConstructor +@SuperBuilder +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserAction extends EgovOfflineModel { + + /** + * The ID of the project associated with the user action. + * It must be between 2 and 64 characters long and cannot be null. + */ + @JsonProperty("projectId") + @Size(min = 2, max = 64) + @NotNull + private String projectId; + + /** + * The latitude coordinate of the user action's location. + * It must be between -90 and 90 degrees and cannot be null. + */ + @JsonProperty("latitude") + @DecimalMin("-90") + @DecimalMax("90") + @NotNull + private Double latitude; + + /** + * The longitude coordinate of the user action's location. + * It must be between -180 and 180 degrees and cannot be null. + */ + @JsonProperty("longitude") + @DecimalMin("-180") + @DecimalMax("180") + @NotNull + private Double longitude; + + /** + * The accuracy of the location measurement in meters. + * It must be a positive number and cannot be null. + */ + @JsonProperty("locationAccuracy") + @DecimalMin("0") + @NotNull + private Double locationAccuracy; + + /** + * The code of the boundary where the user action took place. + * It cannot be null. + */ + @JsonProperty("boundaryCode") + @NotNull + private String boundaryCode; + + /** + * The action performed by the user, represented as a UserActionEnum object. + * It cannot be null. + */ + @JsonProperty("action") + @NotNull + private UserActionEnum action; + + /** + * An optional tag if there is a beneficiary associated with the user action + * It must be between 2 and 64 characters long. + */ + @JsonProperty("beneficiaryTag") + @Size(min = 2, max = 64) + private String beneficiaryTag; + + /** + * An optional tag for the resource associated with the user action. + * It must be between 2 and 64 characters long. + */ + @JsonProperty("resourceTag") + @Size(min = 2, max = 64) + private String resourceTag; + + /** + * A flag indicating whether the user action has been deleted. + * The default value is false. + */ + @JsonProperty("isDeleted") + @Builder.Default + private Boolean isDeleted = false; + +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkRequest.java new file mode 100644 index 00000000000..b2bcb8b4f11 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkRequest.java @@ -0,0 +1,64 @@ +package org.egov.common.models.project.useraction; + +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.egov.common.contract.request.RequestInfo; +import org.springframework.validation.annotation.Validated; + +/** + * The UserActionBulkRequest class is used for handling bulk requests of user actions. + * It contains a RequestInfo object and a list of UserAction objects. + */ +@Validated + + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserActionBulkRequest { + + /** + * The RequestInfo object containing metadata about the request. + * This field is mandatory and must be valid. + */ + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo = null; + + /** + * A list of UserAction objects that are part of the bulk request. + * This field is mandatory, must contain at least one item, and must be valid. + * It is initialized to an empty list by default. + */ + @JsonProperty("UserActions") + @NotNull + @Valid + @Size(min = 1) + @Builder.Default + private List userActions = new ArrayList<>(); + + /** + * Adds a UserAction item to the list of user actions in the bulk request. + * This method is useful for incrementally building the list of user actions. + * + * @param userAction The UserAction object to be added to the list. + * @return The current instance of UserActionBulkRequest with the new UserAction added. + */ + public UserActionBulkRequest addTaskItem(UserAction userAction) { + this.userActions.add(userAction); + return this; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkResponse.java new file mode 100644 index 00000000000..f8698b676bd --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionBulkResponse.java @@ -0,0 +1,70 @@ +package org.egov.common.models.project.useraction; + +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.egov.common.contract.response.ResponseInfo; +import org.springframework.validation.annotation.Validated; + +/** + * The UserActionBulkResponse class is used for handling bulk responses of user actions. + * It contains a ResponseInfo object, a total count of user actions, and a list of UserAction objects. + */ +@Validated +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserActionBulkResponse { + + /** + * The ResponseInfo object containing metadata about the response. + * This field is mandatory and must be valid. + */ + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo = null; + + /** + * The total count of user actions in the response. + * It is initialized to 0 by default. + */ + @JsonProperty("TotalCount") + @Valid + @Builder.Default + private Long totalCount = 0L; + + /** + * A list of UserAction objects that are part of the bulk response. + * This field is mandatory and must be valid. + */ + @JsonProperty("UserActions") + @NotNull + @Valid + private List userActions = null; + + /** + * Adds a UserAction item to the list of user actions in the bulk response. + * This method is useful for incrementally building the list of user actions. + * + * @param userActionItem The UserAction object to be added to the list. + * @return The current instance of UserActionBulkResponse with the new UserAction added. + */ + public UserActionBulkResponse addUserAction(UserAction userActionItem) { + if (this.userActions == null) { + this.userActions = new ArrayList<>(); + } + this.userActions.add(userActionItem); + return this; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearch.java new file mode 100644 index 00000000000..0e2051b6be6 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearch.java @@ -0,0 +1,55 @@ +package org.egov.common.models.project.useraction; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.egov.common.models.core.EgovOfflineSearchModel; +import org.springframework.validation.annotation.Validated; + +/** + * The UserActionSearch class is used for searching user actions based on various criteria. + * It extends the EgovOfflineSearchModel to inherit common search properties. + */ +@Validated +@Data +@NoArgsConstructor +@AllArgsConstructor +@SuperBuilder +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserActionSearch extends EgovOfflineSearchModel { + + /** + * A userId to filter the user actions. + */ + @JsonProperty("createdBy") + private String createdBy; + + /** + * A project ID to filter the user actions. + */ + @JsonProperty("projectId") + private String projectId; + + /** + * A beneficiary tag to filter the user actions. + */ + @JsonProperty("beneficiaryTag") + private String beneficiaryTag; + + /** + * A resource tag to filter the user actions. + */ + @JsonProperty("resourceTag") + private String resourceTag; + + /** + * A boundary code to filter the user actions. + */ + @JsonProperty("boundaryCode") + private String boundaryCode; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearchRequest.java new file mode 100644 index 00000000000..1bf43eb8ced --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearchRequest.java @@ -0,0 +1,44 @@ +package org.egov.common.models.project.useraction; + +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.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.validation.annotation.Validated; + +/** + * The UserActionSearchRequest class is used to encapsulate the request information + * for searching user actions. It includes the request metadata and the search criteria. + */ +@Validated +@Data +@NoArgsConstructor +@AllArgsConstructor +@SuperBuilder +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserActionSearchRequest { + + /** + * The RequestInfo object contains metadata about the request, such as the + * API version, request timestamp, and user details. This field is mandatory + * and must be valid. + */ + @JsonProperty("RequestInfo") + @NotNull + @Valid + private org.egov.common.contract.request.RequestInfo requestInfo; + + /** + * The UserAction object contains the search criteria for filtering user actions. + * This includes various filters such as project IDs, beneficiary tags, resource tags, + * and boundary codes. This field is mandatory and must be valid. + */ + @JsonProperty("UserAction") + @NotNull + @Valid + private UserActionSearch userAction; +} \ No newline at end of file diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml index 54bd4fd9c91..157705fbe73 100644 --- a/health-services/project/pom.xml +++ b/health-services/project/pom.xml @@ -50,7 +50,7 @@ org.egov.common health-services-models - 1.0.20-SNAPSHOT + 1.0.20-dev-SNAPSHOT compile diff --git a/health-services/project/src/main/java/org/egov/project/Constants.java b/health-services/project/src/main/java/org/egov/project/Constants.java index 91e1f824ae8..66333c64989 100644 --- a/health-services/project/src/main/java/org/egov/project/Constants.java +++ b/health-services/project/src/main/java/org/egov/project/Constants.java @@ -56,4 +56,12 @@ public interface Constants { String TASK_QUANTITY = "taskQuantity"; + String HOUSEHOLD_ID = "HouseholdId"; + + String SET_USER_ACTION = "setUserActions"; + + String GET_USER_ACTION = "getUserActions"; + + String PROJECT_USER_ACTION_ENRICHMENT_ERROR = "PROJECT_USER_ACTION_ENRICHMENT_ERROR"; + } 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 32c76154f2b..a3854075dab 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 @@ -189,4 +189,29 @@ public class ProjectConfiguration { @Value("${project.staff.attendance.topic}") private String projectStaffAttendanceTopic; + + // closed household task + @Value("${project.user.action.kafka.create.topic}") + private String createUserActionTopic; + + @Value("${project.user.action.consumer.bulk.create.topic}") + private String bulkCreateUserActionTopic; + + @Value("${project.user.action.kafka.update.topic}") + private String updateUserActionTopic; + + @Value("${project.user.action.consumer.bulk.update.topic}") + private String bulkUpdateUserActionTopic; + + @Value("${project.location.capture.consumer.bulk.create.topic}") + private String bulkCreateLocationCaptureTopic; + + @Value("${project.location.capture.kafka.create.topic}") + private String createLocationCaptureTopic; + + @Value("${egov.boundary.host}") + private String boundaryServiceHost; + + @Value("${egov.boundary.search.url}") + private String boundarySearchUrl; } diff --git a/health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java b/health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java new file mode 100644 index 00000000000..e3714e98bb6 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java @@ -0,0 +1,106 @@ +package org.egov.project.consumer; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.project.service.LocationCaptureService; +import org.egov.project.service.UserActionService; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class UserActionConsumer { + + private final UserActionService userActionService; + private final LocationCaptureService locationCaptureService; + private final ObjectMapper objectMapper; + + @Autowired + public UserActionConsumer(UserActionService userActionService, LocationCaptureService locationCaptureService, ObjectMapper objectMapper) { + // Constructor injection for services and object mapper + this.userActionService = userActionService; + this.locationCaptureService = locationCaptureService; + this.objectMapper = objectMapper; + } + + /** + * Kafka listener for bulk creating user actions. + * + * @param consumerRecord The Kafka consumer record as a map. + * @param topic The topic from which the message was received. + * @return List of created UserAction objects. + */ + @KafkaListener(topics = "${project.user.action.consumer.bulk.create.topic}") + public void bulkCreateUserAction(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + // Convert consumer record to UserActionBulkRequest object + UserActionBulkRequest request = objectMapper.convertValue(consumerRecord, UserActionBulkRequest.class); + // Call the userActionService to handle the create operation + userActionService.create(request, true); + } catch (Exception exception) { + // Log any exception that occurs + log.error("error in user action consumer bulk create", ExceptionUtils.getStackTrace(exception)); + // throw custom exception + throw new CustomException("PROJECT_USER_ACTION_BULK_CREATE", exception.getMessage()); + } + } + + /** + * Kafka listener for bulk updating user actions. + * + * @param consumerRecord The Kafka consumer record as a map. + * @param topic The topic from which the message was received. + * @return List of updated UserAction objects. + */ + @KafkaListener(topics = "${project.user.action.consumer.bulk.update.topic}") + public void bulkUpdateUserAction(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + // Convert consumer record to UserActionBulkRequest object + UserActionBulkRequest request = objectMapper.convertValue(consumerRecord, UserActionBulkRequest.class); + // Call the userActionService to handle the update operation + userActionService.update(request, true); + } catch (Exception exception) { + // Log any exception that occurs + log.error("error in user action consumer bulk update", ExceptionUtils.getStackTrace(exception)); + // throw custom exception + throw new CustomException("PROJECT_USER_ACTION_BULK_UPDATE", exception.getMessage()); + } + } + + /** + * Kafka listener for bulk creating location captures. + * + * @param consumerRecord The Kafka consumer record as a map. + * @param topic The topic from which the message was received. + * @return List of created UserAction objects. + */ + @KafkaListener(topics = "${project.location.capture.consumer.bulk.create.topic}") + public void bulkCreateLocationCapture(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + // Convert consumer record to UserActionBulkRequest object + UserActionBulkRequest request = objectMapper.convertValue(consumerRecord, UserActionBulkRequest.class); + // Call the locationCaptureService to handle the create operation + locationCaptureService.create(request, true); + } catch (Exception exception) { + // Log any exception that occurs + log.error("error in location capture consumer bulk create", ExceptionUtils.getStackTrace(exception)); + // throw custom exception + throw new CustomException("PROJECT_USER_ACTION_LOCATION_CAPTURE_BULK_CREATE", exception.getMessage()); + } + } + +} diff --git a/health-services/project/src/main/java/org/egov/project/repository/LocationCaptureRepository.java b/health-services/project/src/main/java/org/egov/project/repository/LocationCaptureRepository.java new file mode 100644 index 00000000000..9127c0272b8 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/repository/LocationCaptureRepository.java @@ -0,0 +1,135 @@ +package org.egov.project.repository; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.data.query.builder.GenericQueryBuilder; +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.core.URLParams; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionSearch; +import org.egov.common.producer.Producer; +import org.egov.common.utils.CommonUtils; +import org.egov.project.repository.rowmapper.LocationCaptureRowMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ReflectionUtils; + +import static org.egov.common.utils.CommonUtils.getIdMethod; + +@Repository +@Slf4j +public class LocationCaptureRepository extends GenericRepository { + + private final String selectQuery = "SELECT id, clientreferenceid, tenantid, projectid, latitude, longitude, locationaccuracy, boundarycode, action, createdby, createdtime, lastmodifiedby, lastmodifiedtime, clientcreatedtime, clientlastmodifiedtime, clientcreatedby, clientlastmodifiedby, additionaldetails FROM user_location ul "; + + @Autowired + protected LocationCaptureRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, RedisTemplate redisTemplate, SelectQueryBuilder selectQueryBuilder, LocationCaptureRowMapper locationCaptureRowMapper) { + // Initialize the repository with producer, JDBC template, Redis template, query builder, and row mapper + super(producer, namedParameterJdbcTemplate, redisTemplate, selectQueryBuilder, locationCaptureRowMapper, Optional.of("user_location")); + } + + /** + * Finds user locations based on search criteria and URL parameters. + * + * @param searchObject The search criteria for user locations. + * @param urlParams The URL parameters including pagination and filtering information. + * @return A SearchResponse containing the list of user locations and the total count. + */ + public SearchResponse find(UserActionSearch searchObject, URLParams urlParams) { + log.info("Executing find with searchObject: {} and urlParams: {}", searchObject, urlParams); + + String query = selectQuery + ""; + + Map paramsMap = new HashMap<>(); + List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); + query = GenericQueryBuilder.generateQuery(query, whereFields).toString(); + query = query.replace("id IN (:id)", "ul.id IN (:id)"); + query = query.replace("clientReferenceId IN (:clientReferenceId)", "ul.clientReferenceId IN (:clientReferenceId)"); + + if (CollectionUtils.isEmpty(whereFields)) { + query = query + " WHERE ul.tenantId=:tenantId "; + } else { + query = query + " AND ul.tenantId=:tenantId "; + } + + if (urlParams.getLastChangedSince() != null) { + query = query + " AND ul.lastModifiedTime>=:lastModifiedTime "; + } + paramsMap.put("tenantId", urlParams.getTenantId()); + paramsMap.put("lastModifiedTime", urlParams.getLastChangedSince()); + + try { + log.debug("Executing query to fetch total count"); + Long totalCount = CommonUtils.constructTotalCountCTEAndReturnResult(query, paramsMap, this.namedParameterJdbcTemplate); + + query = query + " ORDER BY ul.id ASC LIMIT :limit OFFSET :offset"; + paramsMap.put("limit", urlParams.getLimit()); + paramsMap.put("offset", urlParams.getOffset()); + + log.debug("Executing query to fetch user locations: {}", query); + List locationCaptureList = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); + + log.info("Successfully fetched user locations: {}", locationCaptureList.size()); + return SearchResponse.builder().response(locationCaptureList).totalCount(totalCount).build(); + } catch (Exception e) { + log.error("Failed to execute query for finding user locations", e); + return SearchResponse.builder().response(Collections.emptyList()).totalCount(0L).build(); + } + } + + /** + * Finds user locations by their IDs, first checking the cache before querying the database. + * + * @param ids The list of IDs to search for. + * @param columnName The name of the column to search by. + * @return A SearchResponse containing the list of user locations found. + */ + public SearchResponse findById(List ids, String columnName) { + log.info("Executing findById with ids: {} and columnName: {}", ids, columnName); + + List objFound = findInCache(ids); + + if (!objFound.isEmpty()) { + Method idMethod = getIdMethod(objFound, columnName); + ids.removeAll(objFound.stream() + .map(obj -> (String) ReflectionUtils.invokeMethod(idMethod, obj)) + .collect(Collectors.toList())); + + if (ids.isEmpty()) { + log.info("All requested user locations found in cache"); + return SearchResponse.builder().response(objFound).build(); + } + } + + String query = String.format(selectQuery + " WHERE ul.%s IN (:ids)", columnName); + Map paramMap = new HashMap<>(); + paramMap.put("ids", ids); + + try { + log.debug("Executing query to fetch user locations by ID: {}", query); + List locationCaptureList = this.namedParameterJdbcTemplate.query(query, paramMap, this.rowMapper); + + objFound.addAll(locationCaptureList); + putInCache(objFound); + + log.info("Successfully fetched user locations by ID: {}", locationCaptureList.size()); + return SearchResponse.builder().response(objFound).build(); + } catch (Exception e) { + log.error("Failed to execute query for finding user locations by ID", e); + return SearchResponse.builder().response(Collections.emptyList()).totalCount(0L).build(); + } + } +} diff --git a/health-services/project/src/main/java/org/egov/project/repository/UserActionRepository.java b/health-services/project/src/main/java/org/egov/project/repository/UserActionRepository.java new file mode 100644 index 00000000000..a5e61318fe8 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/repository/UserActionRepository.java @@ -0,0 +1,139 @@ +package org.egov.project.repository; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.data.query.builder.GenericQueryBuilder; +import org.egov.common.data.query.builder.QueryFieldChecker; +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.core.URLParams; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionSearch; +import org.egov.common.producer.Producer; +import org.egov.common.utils.CommonUtils; +import org.egov.project.repository.rowmapper.UserActionRowMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ReflectionUtils; + +import static org.egov.common.utils.CommonUtils.getIdMethod; + +@Repository +@Slf4j +public class UserActionRepository extends GenericRepository { + + private final String selectQuery = + "SELECT id, clientreferenceid, tenantid, projectid, latitude, longitude, locationaccuracy, boundarycode, action, beneficiarytag, resourcetag, status, additionaldetails, createdby, createdtime, lastmodifiedby, lastmodifiedtime, clientcreatedtime, clientlastmodifiedtime, clientcreatedby, clientlastmodifiedby, rowversion FROM user_action ua"; + @Autowired + protected UserActionRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, + RedisTemplate redisTemplate, SelectQueryBuilder selectQueryBuilder, + UserActionRowMapper rowMapper) { + super(producer, namedParameterJdbcTemplate, redisTemplate, selectQueryBuilder, rowMapper, Optional.of("user_action")); + } + + /** + * Finds user actions based on search criteria and URL parameters. + * + * @param searchObject The search criteria for user actions. + * @param urlParams The URL parameters including pagination and filtering information. + * @return A SearchResponse containing the list of user actions and the total count. + * @throws QueryBuilderException If there is an error building the query. + */ + public SearchResponse find(UserActionSearch searchObject, URLParams urlParams) throws QueryBuilderException { + log.info("Executing find with searchObject: {} and urlParams: {}", searchObject, urlParams); + + String query = ""+selectQuery; + + Map paramsMap = new HashMap<>(); + List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); + query = GenericQueryBuilder.generateQuery(query, whereFields).toString(); + query = query.replace("id IN (:id)", "ua.id IN (:id)"); + query = query.replace("clientReferenceId IN (:clientReferenceId)", "ua.clientReferenceId IN (:clientReferenceId)"); + + if (CollectionUtils.isEmpty(whereFields)) { + query = query + " WHERE ua.tenantId=:tenantId "; + } else { + query = query + " AND ua.tenantId=:tenantId "; + } + + if (urlParams.getLastChangedSince() != null) { + query = query + " AND lastModifiedTime>=:lastModifiedTime "; + } + paramsMap.put("tenantId", urlParams.getTenantId()); + paramsMap.put("isDeleted", urlParams.getIncludeDeleted()); + paramsMap.put("lastModifiedTime", urlParams.getLastChangedSince()); + + try { + log.debug("Executing query to fetch total count"); + Long totalCount = CommonUtils.constructTotalCountCTEAndReturnResult(query, paramsMap, this.namedParameterJdbcTemplate); + + query = query + " ORDER BY ua.id ASC LIMIT :limit OFFSET :offset"; + paramsMap.put("limit", urlParams.getLimit()); + paramsMap.put("offset", urlParams.getOffset()); + + log.debug("Executing query to fetch user actions: {}", query); + List userActionList = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); + + log.info("Successfully fetched user actions: {}", userActionList.size()); + return SearchResponse.builder().response(userActionList).totalCount(totalCount).build(); + } catch (Exception e) { + log.error("Failed to execute query for finding user actions", e); + return SearchResponse.builder().response(Collections.emptyList()).totalCount(0L).build(); + } + } + + /** + * Finds user actions by their IDs, first checking the cache before querying the database. + * + * @param ids The list of IDs to search for. + * @param columnName The name of the column to search by. + * @return A SearchResponse containing the list of user actions found. + */ + public SearchResponse findById(List ids, String columnName) { + log.info("Executing findById with ids: {} and columnName: {}", ids, columnName); + + List objFound = findInCache(ids); + + if (!objFound.isEmpty()) { + Method idMethod = getIdMethod(objFound, columnName); + ids.removeAll(objFound.stream() + .map(obj -> (String) ReflectionUtils.invokeMethod(idMethod, obj)) + .collect(Collectors.toList())); + + if (ids.isEmpty()) { + log.info("All requested user actions found in cache"); + return SearchResponse.builder().response(objFound).build(); + } + } + + String query = String.format(selectQuery + " WHERE ua.%s IN (:ids) ", columnName); + Map paramMap = new HashMap<>(); + paramMap.put("ids", ids); + + try { + log.debug("Executing query to fetch user actions by ID: {}", query); + List userActionList = this.namedParameterJdbcTemplate.query(query, paramMap, this.rowMapper); + + objFound.addAll(userActionList); + putInCache(objFound); + + log.info("Successfully fetched user actions by ID: {}", userActionList.size()); + return SearchResponse.builder().response(objFound).build(); + } catch (Exception e) { + log.error("Failed to execute query for finding user actions by ID", e); + return SearchResponse.builder().response(Collections.emptyList()).totalCount(0L).build(); + } + } +} 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 new file mode 100644 index 00000000000..b9ea8babec8 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/LocationCaptureRowMapper.java @@ -0,0 +1,91 @@ +package org.egov.project.repository.rowmapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.models.coremodels.AuditDetails; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.core.AdditionalFields; +import org.egov.common.models.project.UserActionEnum; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +/** + * RowMapper implementation for mapping rows of a ResultSet to UserAction objects. + * This class is used to map the result of a SQL query to UserAction instances. + */ +@Component +@Slf4j +public class LocationCaptureRowMapper implements RowMapper { + + private final ObjectMapper objectMapper; + + /** + * Constructor for dependency injection of ObjectMapper. + * + * @param objectMapper The ObjectMapper used for converting JSON strings to objects. + */ + @Autowired + public LocationCaptureRowMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + /** + * Map a single row of the ResultSet to a UserAction object. + * + * @param resultSet The ResultSet containing data from the database. + * @param rowNum The number of the current row. + * @return A UserAction object populated with data from the current row of the ResultSet. + * @throws SQLException If there is an issue accessing the ResultSet data. + */ + @Override + public UserAction mapRow(ResultSet resultSet, int rowNum) throws SQLException { + + // Creating AuditDetails object with information from the ResultSet + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("createdBy")) + .createdTime(resultSet.getLong("createdTime")) + .lastModifiedBy(resultSet.getString("lastModifiedBy")) + .lastModifiedTime(resultSet.getLong("lastModifiedTime")) + .build(); + + // Creating client-specific AuditDetails object with information from the ResultSet + AuditDetails clientAuditDetails = AuditDetails.builder() + .createdTime(resultSet.getLong("clientCreatedTime")) + .createdBy(resultSet.getString("clientCreatedBy")) + .lastModifiedTime(resultSet.getLong("clientLastModifiedTime")) + .lastModifiedBy(resultSet.getString("clientLastModifiedBy")) + .build(); + + UserAction locationCaptureUserAction; + try { + // Building the UserAction object with data from the ResultSet + locationCaptureUserAction = UserAction.builder() + .id(resultSet.getString("id")) + .tenantId(resultSet.getString("tenantId")) + .clientReferenceId(resultSet.getString("clientReferenceId")) + .projectId(resultSet.getString("projectId")) + .latitude(resultSet.getDouble("latitude")) + .longitude(resultSet.getDouble("longitude")) + .locationAccuracy(resultSet.getDouble("locationAccuracy")) + .boundaryCode(resultSet.getString("boundaryCode")) + .action(UserActionEnum.fromValue(resultSet.getString("action"))) + .auditDetails(auditDetails) + .clientAuditDetails(clientAuditDetails) + .additionalFields(resultSet.getString("additionalDetails") == null ? null : objectMapper + .readValue(resultSet.getString("additionalDetails"), AdditionalFields.class)) + .build(); + } catch (JsonProcessingException e) { + // Throwing a RuntimeException if there's an error processing JSON + log.error("Error processing Additional detail JSON in Location capture UserAction ", e); + throw new CustomException("HCM_PROJECT_USER_ACTION_LOCATION_CAPTURE_ROW_MAPPER_INVALID_ERROR", "Error processing JSON: " + e.getMessage()); + } + + return locationCaptureUserAction; + } +} 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 new file mode 100644 index 00000000000..6f0d9840d77 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/repository/rowmapper/UserActionRowMapper.java @@ -0,0 +1,95 @@ +package org.egov.project.repository.rowmapper; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.models.coremodels.AuditDetails; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.core.AdditionalFields; +import org.egov.common.models.project.UserActionEnum; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +/** + * RowMapper implementation for mapping rows of a ResultSet to UserAction objects. + * This class is used to map the result of a SQL query to UserAction instances. + */ +@Component +@Slf4j +public class UserActionRowMapper implements RowMapper { + + private final ObjectMapper objectMapper; + + /** + * Constructor for dependency injection of ObjectMapper. + * + * @param objectMapper The ObjectMapper used for converting JSON strings to objects. + */ + @Autowired + public UserActionRowMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + /** + * Map a single row of the ResultSet to a UserAction object. + * + * @param resultSet The ResultSet containing data from the database. + * @param rowNum The number of the current row. + * @return A UserAction object populated with data from the current row of the ResultSet. + * @throws SQLException If there is an issue accessing the ResultSet data or processing JSON. + */ + @Override + public UserAction mapRow(ResultSet resultSet, int rowNum) throws SQLException { + try { + // Creating AuditDetails object with information from the ResultSet + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("createdBy")) + .createdTime(resultSet.getLong("createdTime")) + .lastModifiedBy(resultSet.getString("lastModifiedBy")) + .lastModifiedTime(resultSet.getLong("lastModifiedTime")) + .build(); + + // Creating client-specific AuditDetails object with information from the ResultSet + AuditDetails clientAuditDetails = AuditDetails.builder() + .createdTime(resultSet.getLong("clientCreatedTime")) + .createdBy(resultSet.getString("clientCreatedBy")) + .lastModifiedTime(resultSet.getLong("clientLastModifiedTime")) + .lastModifiedBy(resultSet.getString("clientLastModifiedBy")) + .build(); + + // Building the UserAction object with data from the ResultSet + UserAction userAction = UserAction.builder() + .id(resultSet.getString("id")) + .tenantId(resultSet.getString("tenantId")) + .clientReferenceId(resultSet.getString("clientReferenceId")) + .projectId(resultSet.getString("projectId")) + .latitude(resultSet.getDouble("latitude")) + .longitude(resultSet.getDouble("longitude")) + .locationAccuracy(resultSet.getDouble("locationAccuracy")) + .boundaryCode(resultSet.getString("boundaryCode")) + .action(UserActionEnum.fromValue(resultSet.getString("action"))) + .status(resultSet.getString("status")) + .beneficiaryTag(resultSet.getString("beneficiaryTag")) + .resourceTag(resultSet.getString("resourceTag")) + .rowVersion(resultSet.getInt("rowVersion")) + .auditDetails(auditDetails) + .clientAuditDetails(clientAuditDetails) + .additionalFields(resultSet.getString("additionalDetails") == null ? null : objectMapper + .readValue(resultSet.getString("additionalDetails"), AdditionalFields.class)) + .build(); + + return userAction; + } catch (JsonProcessingException e) { + String id = resultSet.getString("id"); + String errorMessage = "Error processing JSON for UserAction mapping. Row number: " + rowNum + ", id: " + (id != null ? id : "not available"); + log.error(errorMessage, e); + throw new CustomException("HCM_PROJECT_USER_ACTION_ROW_MAPPER_INVALID_ERROR", errorMessage + ", " + e.getMessage()); + } + } +} diff --git a/health-services/project/src/main/java/org/egov/project/service/LocationCaptureService.java b/health-services/project/src/main/java/org/egov/project/service/LocationCaptureService.java new file mode 100644 index 00000000000..5667184beb0 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/service/LocationCaptureService.java @@ -0,0 +1,222 @@ +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.http.client.ServiceRequestClient; +import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; +import org.egov.common.models.core.URLParams; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.models.project.useraction.UserActionSearch; +import org.egov.common.models.project.useraction.UserActionSearchRequest; +import org.egov.common.service.IdGenService; +import org.egov.common.utils.CommonUtils; +import org.egov.common.validator.Validator; +import org.egov.project.config.ProjectConfiguration; +import org.egov.project.repository.LocationCaptureRepository; +import org.egov.project.service.enrichment.UserActionEnrichmentService; +import org.egov.project.validator.useraction.UaBoundaryValidator; +import org.egov.project.validator.useraction.UaExistentEntityValidator; +import org.egov.project.validator.useraction.UaProjectIdValidator; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.ReflectionUtils; + +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdMethod; +import static org.egov.common.utils.CommonUtils.handleErrors; +import static org.egov.common.utils.CommonUtils.havingTenantId; +import static org.egov.common.utils.CommonUtils.isSearchByIdOnly; +import static org.egov.common.utils.CommonUtils.lastChangedSince; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.project.Constants.SET_USER_ACTION; +import static org.egov.project.Constants.VALIDATION_ERROR; + +/** + * Service class for handling location capture tasks related to user actions. + * Provides methods for creating, validating, searching, and caching location capture tasks. + */ +@Service +@Slf4j +public class LocationCaptureService { + + private final IdGenService idGenService; + private final LocationCaptureRepository locationCaptureRepository; + private final ServiceRequestClient serviceRequestClient; + private final ProjectConfiguration projectConfiguration; + private final UserActionEnrichmentService userActionEnrichmentService; + private final List> validators; + + /** + * Predicate to determine if a validator is applicable for creation. + * Filters validators based on specific classes. + */ + private final Predicate> isApplicableForCreate = validator -> + validator.getClass().equals(UaProjectIdValidator.class) + || validator.getClass().equals(UaExistentEntityValidator.class) + || validator.getClass().equals(UaBoundaryValidator.class); + + /** + * Constructor for injecting dependencies into the LocationCaptureService. + * + * @param idGenService The service for generating unique IDs. + * @param locationCaptureRepository Repository for location capture tasks. + * @param serviceRequestClient Client for making service requests. + * @param projectConfiguration Configuration properties related to the project. + * @param userActionEnrichmentService Service for enriching location capture user action tasks. + * @param validators List of validators for user actions. + */ + @Autowired + public LocationCaptureService( + IdGenService idGenService, + LocationCaptureRepository locationCaptureRepository, + ServiceRequestClient serviceRequestClient, + ProjectConfiguration projectConfiguration, + UserActionEnrichmentService userActionEnrichmentService, + List> validators + ) { + this.idGenService = idGenService; + this.locationCaptureRepository = locationCaptureRepository; + this.serviceRequestClient = serviceRequestClient; + this.projectConfiguration = projectConfiguration; + this.userActionEnrichmentService = userActionEnrichmentService; + this.validators = validators; + } + + /** + * Creates location capture tasks in bulk. + * Validates the request, enriches valid tasks, saves them, and handles errors. + * + * @param request The bulk request containing location capture tasks. + * @param isBulk Flag indicating if the request is a bulk operation. + * @return A list of valid location capture tasks. + */ + public List create(UserActionBulkRequest request, boolean isBulk) { + log.info("Received request to create bulk location capture tasks"); + + // Validate the request and separate valid tasks from error details. + Tuple, Map> tuple = validate(validators, isApplicableForCreate, request, isBulk); + Map errorDetailsMap = tuple.getY(); + List validLocationCaptures = tuple.getX(); + + try { + if (!validLocationCaptures.isEmpty()) { + log.info("Processing {} valid entities", validLocationCaptures.size()); + + // Enrich valid location capture tasks. + userActionEnrichmentService.create(validLocationCaptures, request); + + // Save valid location capture tasks and send them to the Kafka topic. + locationCaptureRepository.save(validLocationCaptures, projectConfiguration.getCreateLocationCaptureTopic()); + log.info("Successfully created location capture tasks"); + } + } catch (Exception exception) { + // Log and handle exceptions that occur during task creation. + log.error("Error occurred while creating location capture tasks: {}", ExceptionUtils.getStackTrace(exception)); + populateErrorDetails(request, errorDetailsMap, validLocationCaptures, exception, SET_USER_ACTION); + } + + // Handle errors based on the validation results. + handleErrors(errorDetailsMap, isBulk, VALIDATION_ERROR); + + return validLocationCaptures; + } + + /** + * Validates the user action bulk request using the provided validators. + * Filters out tasks with errors and returns the valid ones. + * + * @param validators List of validators to use for validation. + * @param applicableValidators Predicate to filter applicable validators. + * @param request The bulk request to validate. + * @param isBulk Flag indicating if the request is a bulk operation. + * @return A tuple containing valid location capture tasks and error details. + */ + private Tuple, Map> validate( + List> validators, + Predicate> applicableValidators, + UserActionBulkRequest request, boolean isBulk) { + + log.info("Validating request"); + + // Perform validation and collect error details. + Map errorDetailsMap = CommonUtils.validate( + validators, + applicableValidators, + request, + SET_USER_ACTION + ); + + // Throw an exception if there are validation errors and it's not a bulk operation. + if (!errorDetailsMap.isEmpty() && !isBulk) { + throw new CustomException(VALIDATION_ERROR, errorDetailsMap.values().toString()); + } + + // Filter out tasks with no errors. + List validLocationCaptures = request.getUserActions().stream() + .filter(notHavingErrors()) + .collect(Collectors.toList()); + + return new Tuple<>(validLocationCaptures, errorDetailsMap); + } + + /** + * Searches for location capture tasks based on the provided search request and URL parameters. + * Supports searching by ID or by other criteria. + * + * @param locationCaptureSearchRequest The search request containing criteria for searching. + * @param urlParams URL parameters for filtering the search results. + * @return A SearchResponse containing the search results and total count. + */ + public SearchResponse search(UserActionSearchRequest locationCaptureSearchRequest, URLParams urlParams) { + log.info("Received request to search project task"); + + UserActionSearch locationCaptureSearch = locationCaptureSearchRequest.getUserAction(); + String idFieldName = getIdFieldName(locationCaptureSearch); + + if (isSearchByIdOnly(locationCaptureSearch, idFieldName)) { + log.info("Searching location capture by id"); + List ids = (List) ReflectionUtils.invokeMethod( + getIdMethod(Collections.singletonList(locationCaptureSearch)), + locationCaptureSearch + ); + log.info("Fetching location capture tasks with ids: {}", ids); + + // Perform search by IDs and filter results based on last changed date and tenant ID. + SearchResponse searchResponse = locationCaptureRepository.findById(ids, idFieldName); + return SearchResponse.builder() + .response(searchResponse.getResponse().stream() + .filter(lastChangedSince(urlParams.getLastChangedSince())) + .filter(havingTenantId(urlParams.getTenantId())) + .collect(Collectors.toList()) + ) + .totalCount(searchResponse.getTotalCount()) + .build(); + } + + log.info("Searching project beneficiaries using criteria"); + // Perform search based on other criteria. + return locationCaptureRepository.find(locationCaptureSearch, urlParams); + } + + /** + * Puts location capture tasks into cache. + * + * @param locationCaptures The list of location capture tasks to cache. + */ + public void putInCache(List locationCaptures) { + log.info("Putting {} location tracking tasks in cache", locationCaptures.size()); + locationCaptureRepository.putInCache(locationCaptures); + log.info("Successfully put location tracking tasks in cache"); + } +} diff --git a/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java b/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java index 12c8ea87062..42989bf6d57 100644 --- a/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java +++ b/health-services/project/src/main/java/org/egov/project/service/ProjectTaskService.java @@ -34,8 +34,6 @@ import org.egov.project.validator.task.PtProductVariantIdValidator; import org.egov.project.validator.task.PtProjectBeneficiaryIdValidator; import org.egov.project.validator.task.PtProjectIdValidator; -import org.egov.project.validator.task.PtIsResouceEmptyValidator; -import org.egov.project.validator.task.PtResourceQuantityValidator; import org.egov.project.validator.task.PtRowVersionValidator; import org.egov.project.validator.task.PtUniqueEntityValidator; import org.egov.project.validator.task.PtUniqueSubEntityValidator; @@ -72,19 +70,19 @@ public class ProjectTaskService { private final ProjectConfiguration projectConfiguration; private final ProjectTaskEnrichmentService enrichmentService; - + // || validator.getClass().equals(PtResourceQuantityValidator.class) FIXME add this back once requirement confirmation is done private final Predicate> isApplicableForCreate = validator -> validator.getClass().equals(PtProjectIdValidator.class) || validator.getClass().equals(PtExistentEntityValidator.class) || validator.getClass().equals(PtIsResouceEmptyValidator.class) - || validator.getClass().equals(PtResourceQuantityValidator.class) + || validator.getClass().equals(PtProjectBeneficiaryIdValidator.class) || validator.getClass().equals(PtProductVariantIdValidator.class); + // || validator.getClass().equals(PtResourceQuantityValidator.class) FIXME add this back once requirement confirmation is done private final Predicate> isApplicableForUpdate = validator -> validator.getClass().equals(PtProjectIdValidator.class) || validator.getClass().equals(PtIsResouceEmptyValidator.class) - || validator.getClass().equals(PtResourceQuantityValidator.class) || validator.getClass().equals(PtProjectBeneficiaryIdValidator.class) || validator.getClass().equals(PtProductVariantIdValidator.class) || validator.getClass().equals(PtNullIdValidator.class) diff --git a/health-services/project/src/main/java/org/egov/project/service/UserActionService.java b/health-services/project/src/main/java/org/egov/project/service/UserActionService.java new file mode 100644 index 00000000000..df59e6b1c07 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/service/UserActionService.java @@ -0,0 +1,215 @@ +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.data.query.exception.QueryBuilderException; +import org.egov.common.ds.Tuple; +import org.egov.common.http.client.ServiceRequestClient; +import org.egov.common.models.ErrorDetails; +import org.egov.common.models.core.SearchResponse; +import org.egov.common.models.core.URLParams; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.models.project.useraction.UserActionSearch; +import org.egov.common.models.project.useraction.UserActionSearchRequest; +import org.egov.common.service.IdGenService; +import org.egov.common.utils.CommonUtils; +import org.egov.common.validator.Validator; +import org.egov.project.config.ProjectConfiguration; +import org.egov.project.repository.UserActionRepository; +import org.egov.project.service.enrichment.UserActionEnrichmentService; +import org.egov.project.validator.useraction.UaBoundaryValidator; +import org.egov.project.validator.useraction.UaExistentEntityValidator; +import org.egov.project.validator.useraction.UaNonExistentEntityValidator; +import org.egov.project.validator.useraction.UaNullIdValidator; +import org.egov.project.validator.useraction.UaProjectIdValidator; +import org.egov.project.validator.useraction.UaRowVersionValidator; +import org.egov.project.validator.useraction.UaStatusValidator; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.ReflectionUtils; + +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdMethod; +import static org.egov.common.utils.CommonUtils.handleErrors; +import static org.egov.common.utils.CommonUtils.havingTenantId; +import static org.egov.common.utils.CommonUtils.includeDeleted; +import static org.egov.common.utils.CommonUtils.isSearchByIdOnly; +import static org.egov.common.utils.CommonUtils.lastChangedSince; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.project.Constants.SET_USER_ACTION; +import static org.egov.project.Constants.VALIDATION_ERROR; + +@Service +@Slf4j +public class UserActionService { + private final IdGenService idGenService; // Service for generating unique IDs + private final UserActionRepository userActionTaskRepository; // Repository for user actions + private final ServiceRequestClient serviceRequestClient; // Client for external service requests + private final ProjectConfiguration projectConfiguration; // Configuration properties for the project + private final UserActionEnrichmentService userActionEnrichmentService; // Service for enriching user actions + private final List> validators; // List of validators for user actions + + // Predicate to filter validators applicable for creation + private final Predicate> isApplicableForCreate = validator -> + validator.getClass().equals(UaProjectIdValidator.class) + || validator.getClass().equals(UaExistentEntityValidator.class) + || validator.getClass().equals(UaBoundaryValidator.class); + + // Predicate to filter validators applicable for updates + private final Predicate> isApplicableForUpdate = validator -> + validator.getClass().equals(UaProjectIdValidator.class) + || validator.getClass().equals(UaNullIdValidator.class) + || validator.getClass().equals(UaNonExistentEntityValidator.class) + || validator.getClass().equals(UaRowVersionValidator.class) + || validator.getClass().equals(UaStatusValidator.class) + || validator.getClass().equals(UaBoundaryValidator.class); + + // Constructor for dependency injection + @Autowired + public UserActionService( + IdGenService idGenService, + UserActionRepository userActionTaskRepository, + ServiceRequestClient serviceRequestClient, + ProjectConfiguration projectConfiguration, + UserActionEnrichmentService userActionEnrichmentService, + List> validators + ) { + this.idGenService = idGenService; + this.userActionTaskRepository = userActionTaskRepository; + this.serviceRequestClient = serviceRequestClient; + this.projectConfiguration = projectConfiguration; + this.userActionEnrichmentService = userActionEnrichmentService; + this.validators = validators; + } + + // Method to handle the creation of user actions + public List create(UserActionBulkRequest request, boolean isBulk) { + log.info("Received request to create bulk closed household userActions"); + + // Validate the request and get valid user actions along with error details + Tuple, Map> tuple = validate(validators, isApplicableForCreate, request, isBulk); + Map errorDetailsMap = tuple.getY(); + List validUserActions = tuple.getX(); + + try { + // If there are valid user actions, enrich and save them + if (!validUserActions.isEmpty()) { + log.info("Processing {} valid entities", validUserActions.size()); + userActionEnrichmentService.create(validUserActions, request); + userActionTaskRepository.save(validUserActions, projectConfiguration.getCreateUserActionTopic()); + log.info("Successfully created closed household userActions"); + } + } catch (Exception exception) { + // Handle and log any exceptions that occur + log.error("Error occurred while creating closed household userActions: {}", ExceptionUtils.getStackTrace(exception)); + populateErrorDetails(request, errorDetailsMap, validUserActions, exception, SET_USER_ACTION); + } + + // Handle any validation errors + handleErrors(errorDetailsMap, isBulk, VALIDATION_ERROR); + + return validUserActions; + } + + // Method to handle the update of user actions + public List update(UserActionBulkRequest request, boolean isBulk) { + log.info("Received request to update bulk closed household userActions"); + + // Validate the request and get valid user actions along with error details + Tuple, Map> tuple = validate(validators, isApplicableForUpdate, request, isBulk); + Map errorDetailsMap = tuple.getY(); + List validUserActions = tuple.getX(); + + try { + // If there are valid user actions, enrich and update them + if (!validUserActions.isEmpty()) { + log.info("Processing {} valid entities", validUserActions.size()); + userActionEnrichmentService.update(validUserActions, request); + userActionTaskRepository.save(validUserActions, projectConfiguration.getUpdateUserActionTopic()); + log.info("Successfully updated bulk closed household userActions"); + } + } catch (Exception exception) { + // Handle and log any exceptions that occur + log.error("Error occurred while updating closed household userActions: {}", ExceptionUtils.getStackTrace(exception)); + populateErrorDetails(request, errorDetailsMap, validUserActions, exception, SET_USER_ACTION); + } + + // Handle any validation errors + handleErrors(errorDetailsMap, isBulk, VALIDATION_ERROR); + + return validUserActions; + } + + // Method to validate user action requests + private Tuple, Map> validate(List> validators, + Predicate> applicableValidators, + UserActionBulkRequest request, boolean isBulk) { + log.info("Validating request"); + + // Validate the request using the applicable validators + Map errorDetailsMap = CommonUtils.validate(validators, + applicableValidators, request, + SET_USER_ACTION); + + // Throw exception if there are validation errors and it's not a bulk request + if (!errorDetailsMap.isEmpty() && !isBulk) { + throw new CustomException(VALIDATION_ERROR, errorDetailsMap.values().toString()); + } + + // Filter and return valid user actions + List validUserActions = request.getUserActions().stream() + .filter(notHavingErrors()).collect(Collectors.toList()); + return new Tuple<>(validUserActions, errorDetailsMap); + } + + // Method to search for user actions based on the request and URL parameters + public SearchResponse search(UserActionSearchRequest request, URLParams urlParams) { + log.info("Received request to search project UserAction"); + + UserActionSearch userActionSearch = request.getUserAction(); + + // Determine the ID field name for search + String idFieldName = getIdFieldName(userActionSearch); + if (isSearchByIdOnly(userActionSearch, idFieldName)) { + log.info("Searching project UserAction by id"); + + // Retrieve IDs and search for user actions by ID + List ids = (List) ReflectionUtils.invokeMethod(getIdMethod(Collections + .singletonList(userActionSearch)), + userActionSearch); + log.info("Fetching closed household userActions with ids: {}", ids); + SearchResponse searchResponse = userActionTaskRepository.findById(ids, idFieldName); + return SearchResponse.builder().response(searchResponse.getResponse().stream() + .filter(lastChangedSince(urlParams.getLastChangedSince())) + .filter(havingTenantId(urlParams.getTenantId())) + .filter(includeDeleted(urlParams.getIncludeDeleted())) + .collect(Collectors.toList())).totalCount(searchResponse.getTotalCount()).build(); + } + + try { + // Search using the criteria specified in the request + log.info("Searching project user actions using criteria"); + return userActionTaskRepository.find(userActionSearch, urlParams); + } catch (QueryBuilderException e) { + // Handle and log query building exceptions + log.error("Error in building query: {}", ExceptionUtils.getStackTrace(e)); + throw new CustomException("ERROR_IN_QUERY", e.getMessage()); + } + } + + // Method to put user actions into cache + public void putInCache(List userActions) { + log.info("Putting {} closed household userActions in cache", userActions.size()); + userActionTaskRepository.putInCache(userActions); + log.info("Successfully put closed household userActions in cache"); + } +} diff --git a/health-services/project/src/main/java/org/egov/project/service/enrichment/UserActionEnrichmentService.java b/health-services/project/src/main/java/org/egov/project/service/enrichment/UserActionEnrichmentService.java new file mode 100644 index 00000000000..afa331fc1cc --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/service/enrichment/UserActionEnrichmentService.java @@ -0,0 +1,67 @@ +package org.egov.project.service.enrichment; + +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.service.IdGenService; +import org.egov.common.utils.CommonUtils; +import org.egov.project.config.ProjectConfiguration; +import org.egov.project.repository.UserActionRepository; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import static org.egov.common.utils.CommonUtils.enrichForCreate; +import static org.egov.common.utils.CommonUtils.enrichForUpdate; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; +import static org.egov.project.Constants.PROJECT_USER_ACTION_ENRICHMENT_ERROR; + +@Service +@Slf4j +public class UserActionEnrichmentService { + private final IdGenService idGenService; + + private final ProjectConfiguration projectConfiguration; + + private final UserActionRepository userActionRepository; + + @Autowired + public UserActionEnrichmentService( + IdGenService idGenService, + ProjectConfiguration projectConfiguration, + UserActionRepository userActionRepository + ) { + this.idGenService = idGenService; + this.projectConfiguration = projectConfiguration; + this.userActionRepository = userActionRepository; + } + + public void create(List entities, UserActionBulkRequest request) { + log.info("starting the enrichment for create UserActions"); + log.info("generating IDs using UUID"); + try { + List idList = CommonUtils.uuidSupplier().apply(entities.size()); + log.info("enriching UserActions with generated IDs"); + enrichForCreate(entities, idList, request.getRequestInfo(),false); + log.info("enrichment done"); + } catch (Exception exception) { + log.error("Error during enrichment for create UserActions", exception); + throw new CustomException(PROJECT_USER_ACTION_ENRICHMENT_ERROR, "Error during enrichment for create UserActions" + exception); + } + } + + public void update(List entities, UserActionBulkRequest request) { + log.info("starting the enrichment for update UserActions"); + try { + Map userActionMap = getIdToObjMap(entities); + enrichForUpdate(userActionMap, entities, request); + log.info("enrichment done"); + } catch (Exception exception) { + log.error("Error during enrichment for update UserActions", exception); + throw new CustomException(PROJECT_USER_ACTION_ENRICHMENT_ERROR, "Error during enrichment for update UserActions" + exception); + } + } +} 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 74a4e2df8fa..3a0a08d31ea 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 @@ -92,4 +92,4 @@ public void validateBoundaryDetails(Map> locations, String } } -} +} \ No newline at end of file diff --git a/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java b/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java index 8bebbfda738..32e73b66dc9 100644 --- a/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java +++ b/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java @@ -30,7 +30,15 @@ public enum TaskStatus { BENEFICIARY_REFERRED("BENEFICIARY_REFERRED"), BENEFICIARY_INELIGIBLE("BENEFICIARY_INELIGIBLE"), BENEFICIARY_SICK("BENEFICIARY_SICK"), - BENEFICIARY_ABSENT("BENEFICIARY_ABSENT"); + BENEFICIARY_ABSENT("BENEFICIARY_ABSENT"), + + SPRAYED("SPRAYED"), + REFUSED("REFUSED"), + HOUSE_CLOSED("HOUSE_CLOSED"), + INELIGIBLE("INELIGIBLE"), + RESOLVED("RESOLVED"), + LOCATION_CAPTURE("LOCATION_CAPTURE"), + ADMINISTRATION_FAILED("ADMINISTRATION_FAILED"); private String value; TaskStatus(String value) { diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java index 4487d0ae5e4..06368517146 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java @@ -41,7 +41,10 @@ public Map> validate(TaskBulkRequest request) { || ProjectConstants.TaskStatus.BENEFICIARY_INELIGIBLE.toString().equals(task.getStatus()) || ProjectConstants.TaskStatus.BENEFICIARY_REFERRED.toString().equals(task.getStatus()) || ProjectConstants.TaskStatus.BENEFICIARY_SICK.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_ABSENT.toString().equals(task.getStatus()))) { + || ProjectConstants.TaskStatus.BENEFICIARY_ABSENT.toString().equals(task.getStatus()) + || ProjectConstants.TaskStatus.ADMINISTRATION_FAILED.toString().equals(task.getStatus()) + ) + ) { /** * If the task resource is empty or null and task status is not BENEFICIARY_REFUSED it is invalid */ @@ -51,7 +54,9 @@ public Map> validate(TaskBulkRequest request) { ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_INELIGIBLE + ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_REFERRED + ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_SICK + - ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_ABSENT) + ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_ABSENT + + ProjectConstants.OR + ProjectConstants.TaskStatus.ADMINISTRATION_FAILED + ) .errorCode(TASK_NOT_ALLOWED) .type(Error.ErrorType.NON_RECOVERABLE) .exception(new CustomException(TASK_NOT_ALLOWED, @@ -64,14 +69,20 @@ public Map> validate(TaskBulkRequest request) { ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_SICK + ProjectConstants.OR + - ProjectConstants.TaskStatus.BENEFICIARY_ABSENT)).build(); + ProjectConstants.TaskStatus.BENEFICIARY_ABSENT + + ProjectConstants.OR + + ProjectConstants.TaskStatus.ADMINISTRATION_FAILED + )).build(); populateErrorDetails(task, error, errorDetailsMap); } else if (!CollectionUtils.isEmpty(task.getResources()) && (ProjectConstants.TaskStatus.BENEFICIARY_REFUSED.toString().equals(task.getStatus()) || ProjectConstants.TaskStatus.BENEFICIARY_INELIGIBLE.toString().equals(task.getStatus()) || ProjectConstants.TaskStatus.BENEFICIARY_REFERRED.toString().equals(task.getStatus()) || ProjectConstants.TaskStatus.BENEFICIARY_SICK.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_ABSENT.toString().equals(task.getStatus()))) { + || ProjectConstants.TaskStatus.BENEFICIARY_ABSENT.toString().equals(task.getStatus()) + || ProjectConstants.TaskStatus.ADMINISTRATION_FAILED.toString().equals(task.getStatus()) + ) + ) { /** * If the task resource is not empty and task status is BENEFICIARY_REFUSED */ diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaBoundaryValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaBoundaryValidator.java new file mode 100644 index 00000000000..4f0394c1556 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaBoundaryValidator.java @@ -0,0 +1,125 @@ +package org.egov.project.validator.useraction; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.http.client.ServiceRequestClient; +import org.egov.common.models.Error; +import org.egov.common.models.core.Boundary; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.project.config.ProjectConfiguration; +import org.egov.project.web.models.boundary.BoundaryResponse; +import org.egov.tracer.model.CustomException; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import static org.egov.common.utils.CommonUtils.populateErrorDetails; + +/** + * Validator class for validating userAction boundaries. + */ +@Component +@Order(value = 4) +@Slf4j +public class UaBoundaryValidator implements Validator { + + private final ServiceRequestClient serviceRequestClient; + + private final ProjectConfiguration projectConfiguration; + + /** + * Constructor to initialize the HBoundaryValidator. + * + * @param serviceRequestClient Service request client for making HTTP requests + * @param projectConfiguration Configuration properties for the userAction module + */ + public UaBoundaryValidator(ServiceRequestClient serviceRequestClient, ProjectConfiguration projectConfiguration) { + this.serviceRequestClient = serviceRequestClient; + this.projectConfiguration = projectConfiguration; + } + + /** + * Validates the userActions' boundaries. + * + * @param request the bulk request containing userActions + * @return a map containing userActions with their corresponding list of errors + */ + @Override + public Map> validate(UserActionBulkRequest request) { + log.debug("Validating userActions boundaries."); + // Create a HashMap to store error details for each userAction + HashMap> errorDetailsMap = new HashMap<>(); + + // Filter userActions with non-null addresses + List entitiesWithValidBoundaries = request.getUserActions().parallelStream() + .filter(userAction -> Objects.nonNull(userAction.getBoundaryCode())) // Exclude null boundary codes + .collect(Collectors.toList()); + + Map> tenantIdUserActionMap = entitiesWithValidBoundaries.stream().collect(Collectors.groupingBy(UserAction::getTenantId)); + + tenantIdUserActionMap.forEach((tenantId, userActions) -> { + // Group userActions by locality code + Map> boundaryCodeUserActionsMap = userActions.stream() + .collect(Collectors.groupingBy( + userAction -> userAction.getBoundaryCode() // Group by boundary code + )); + + List boundaries = new ArrayList<>(boundaryCodeUserActionsMap.keySet()); + if(!CollectionUtils.isEmpty(boundaries)) { + try { + // Fetch boundary details from the service + log.debug("Fetching boundary details for tenantId: {}, boundaries: {}", tenantId, boundaries); + BoundaryResponse boundarySearchResponse = serviceRequestClient.fetchResult( + new StringBuilder(projectConfiguration.getBoundaryServiceHost() + + projectConfiguration.getBoundarySearchUrl() + +"?limit=" + boundaries.size() + + "&offset=0&tenantId=" + tenantId + + "&codes=" + String.join(",", boundaries)), + request.getRequestInfo(), + BoundaryResponse.class + ); + log.debug("Boundary details fetched successfully for tenantId: {}", tenantId); + + List invalidBoundaryCodes = new ArrayList<>(boundaries); + invalidBoundaryCodes.removeAll(boundarySearchResponse.getBoundary().stream() + .map(Boundary::getCode) + .collect(Collectors.toList()) + ); + + // Filter out userActions with invalid boundary codes + List userActionsWithInvalidBoundaries = boundaryCodeUserActionsMap.entrySet().stream() + .filter(entry -> invalidBoundaryCodes.contains(entry.getKey())) // filter invalid boundary codes + .flatMap(entry -> entry.getValue().stream()) // Flatten the list of userActions + .collect(Collectors.toList()); + + // Create an error object for userActions with invalid boundaries + Error error = Error.builder() + .errorMessage("Boundary code does not exist in db") + .errorCode("PROJECT_USER_ACTION_INVALID_BOUNDARY_ERROR") + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException("PROJECT_USER_ACTION_INVALID_BOUNDARY_ERROR", "Boundary code does not exist in db")) + .build(); + userActionsWithInvalidBoundaries.forEach(userAction -> { + // Populate error details for the userAction + populateErrorDetails(userAction, error, errorDetailsMap); + }); + + } catch (Exception e) { + log.error("Exception while searching boundaries for tenantId: {}", tenantId, e); + // Throw a custom exception if an error occurs during boundary search + throw new CustomException("BOUNDARY_SERVICE_SEARCH_ERROR","Error in while fetching boundaries from Boundary Service : " + e.getMessage()); + } + } + }); + + return errorDetailsMap; + } +} diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java new file mode 100644 index 00000000000..60c6115d7d7 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java @@ -0,0 +1,76 @@ +package org.egov.project.validator.useraction; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.models.project.useraction.UserActionSearch; +import org.egov.common.validator.Validator; +import org.egov.project.repository.UserActionRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; + +@Component +@Order(value = 1) +@Slf4j +public class UaExistentEntityValidator implements Validator { + private UserActionRepository userActionRepository; + + @Autowired + public UaExistentEntityValidator(UserActionRepository userActionRepository) { + this.userActionRepository = userActionRepository; + } + + /** + * @param request + * @return + */ + /** + * Validates the existence of entities in the UserActionBulkRequest. + * @param request the bulk request containing UserAction entities + * @return a map of UserAction entities and their error details + */ + @Override + public Map> validate(UserActionBulkRequest request) { + // Map to hold UserAction entities and their error details + log.info("Validating existence of entities in UserActionBulkRequest with {} entities", request.getUserActions().size()); + Map> errorDetailsMap = new HashMap<>(); + // Get the list of UserAction entities from the request + List entities = request.getUserActions(); + // Extract client reference IDs from UserAction entities without errors + List clientReferenceIdList = entities.stream() + .filter(notHavingErrors()) + .map(UserAction::getClientReferenceId) + .collect(Collectors.toList()); + // Create a search object for querying entities by client reference IDs + UserActionSearch userActionSearch = UserActionSearch.builder() + .clientReferenceId(clientReferenceIdList) + .build(); + // Check if the client reference ID list is not empty + if (!CollectionUtils.isEmpty(clientReferenceIdList)) { + // Query the repository to find existing entities by client reference IDs + List existentEntities = userActionRepository.findById( + clientReferenceIdList, + getIdFieldName(userActionSearch) + ).getResponse(); + // For each existing entity, populate error details for uniqueness + existentEntities.forEach(entity -> { + Error error = getErrorForUniqueEntity(); + populateErrorDetails(entity, error, errorDetailsMap); + }); + } + return errorDetailsMap; + } +} diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaNonExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaNonExistentEntityValidator.java new file mode 100644 index 00000000000..c2b2534c1b0 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaNonExistentEntityValidator.java @@ -0,0 +1,96 @@ +package org.egov.project.validator.useraction; + +import java.lang.reflect.Method; +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.egov.common.models.Error; +import org.egov.common.models.core.URLParams; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.models.project.useraction.UserActionSearch; +import org.egov.common.validator.Validator; +import org.egov.project.repository.UserActionRepository; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.checkNonExistentEntities; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; +import static org.egov.common.utils.CommonUtils.getMethod; +import static org.egov.common.utils.CommonUtils.getObjClass; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; +import static org.egov.project.Constants.GET_ID; + +@Component +@Order(value = 4) +@Slf4j +public class UaNonExistentEntityValidator implements Validator { + + private final UserActionRepository userActionRepository; + + @Autowired + public UaNonExistentEntityValidator(UserActionRepository userActionRepository) { + this.userActionRepository = userActionRepository; + } + + + @Override + public Map> validate(UserActionBulkRequest request) { + log.info("Validating existence of entities in UserActionBulkRequest with {} user actions", request.getUserActions().size()); + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getUserActions(); + Class objClass = getObjClass(entities); + Method idMethod = getMethod(GET_ID, objClass); + Map eMap = getIdToObjMap(entities + .stream().filter(notHavingErrors()).collect(Collectors.toList()), idMethod); + // Lists to store IDs and client reference IDs + List idList = new ArrayList<>(); + List clientReferenceIdList = new ArrayList<>(); + // Extract IDs and client reference IDs from Project UserAction entities + entities.forEach(entity -> { + idList.add(entity.getId()); + clientReferenceIdList.add(entity.getClientReferenceId()); + }); + if (!eMap.isEmpty()) { + UserActionSearch taskSearch = UserActionSearch.builder() + .clientReferenceId(clientReferenceIdList) + .id(idList) + .build(); + + URLParams urlParams = URLParams.builder() + .tenantId(entities.get(0).getTenantId()) + .limit(entities.size()) + .offset(0) + .includeDeleted(false) + .lastChangedSince(null) + .build(); + + List existingEntities; + try { + // Query the repository to find existing entities + existingEntities = userActionRepository.find(taskSearch, urlParams).getResponse(); + } catch (Exception e) { + // Handle query builder exception + log.error("Search failed for ProjectUserAction with error: {}", e.getMessage(), e); + throw new CustomException("PROJECT_USER_ACTION_SEARCH_FAILED", "Search failed for ProjectUserAction with clientReferenceId(s): " + + clientReferenceIdList + " and id(s): " + idList + ". Error: " + e.getMessage()); + } + List nonExistentEntities = checkNonExistentEntities(eMap, + existingEntities, idMethod); + nonExistentEntities.forEach(task -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(task, error, errorDetailsMap); + }); + } + + return errorDetailsMap; + } +} diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaNullIdValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaNullIdValidator.java new file mode 100644 index 00000000000..52196f57f96 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaNullIdValidator.java @@ -0,0 +1,27 @@ +package org.egov.project.validator.useraction; + +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.validateForNullId; +import static org.egov.project.Constants.GET_USER_ACTION; + +@Component +@Order(value = 1) +@Slf4j +public class UaNullIdValidator implements Validator { + + @Override + public Map> validate(UserActionBulkRequest request) { + log.info("validating for null id"); + return validateForNullId(request, GET_USER_ACTION); + } +} diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaProjectIdValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaProjectIdValidator.java new file mode 100644 index 00000000000..b7c6ea63277 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaProjectIdValidator.java @@ -0,0 +1,96 @@ +package org.egov.project.validator.useraction; + +import java.lang.reflect.Method; +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.egov.common.models.Error; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.project.repository.ProjectRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; +import static org.egov.common.utils.CommonUtils.getMethod; +import static org.egov.common.utils.CommonUtils.getObjClass; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentRelatedEntity; + +/** + * UaProjectIdValidator is responsible for validating the Project IDs in UserActionBulkRequest. + * It checks if the Project IDs present in the UserAction entities exist in the Project repository. + */ +@Component +@Order(value = 6) +@Slf4j +public class UaProjectIdValidator implements Validator { + + private ProjectRepository projectRepository; + + @Autowired + public UaProjectIdValidator(ProjectRepository projectRepository) { + this.projectRepository = projectRepository; + } + + /** + * Validates the Project IDs in the UserActionBulkRequest. + * It checks if the Project IDs present in the UserAction entities exist in the Project repository. + * + * @param request the UserActionBulkRequest containing UserAction entities to be validated. + * @return a map of UserAction entities to a list of Errors encountered during validation. + */ + @Override + public Map> validate(UserActionBulkRequest request) { + log.info("Starting validation of project IDs in UserActionBulkRequest with {} entities", request.getUserActions().size()); + + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getUserActions(); + + // Retrieve the class of the UserAction entities + Class objClass = getObjClass(entities); + log.debug("Retrieved UserAction entity class: {}", objClass.getName()); + + // Retrieve the method to get ProjectId from UserAction entities + Method idMethod = getMethod("getProjectId", objClass); + log.debug("Retrieved getProjectId method from UserAction entity class"); + + // Create a map of Project IDs to UserAction entities + Map eMap = getIdToObjMap(entities.stream().filter(notHavingErrors()).collect(Collectors.toList()), idMethod); + log.info("Created map of Project IDs to UserAction entities with {} entries", eMap.size()); + + if (!eMap.isEmpty()) { + List entityIds = new ArrayList<>(eMap.keySet()); + log.debug("List of Project IDs to validate: {}", entityIds); + + // Validate the Project IDs by checking their existence in the Project repository + List existingProjectIds = projectRepository.validateIds(entityIds, getIdFieldName(idMethod)); + log.info("Retrieved list of existing Project IDs from Project repository: {}", existingProjectIds); + + // Identify invalid UserAction entities with non-existent Project IDs + List invalidEntities = entities.stream().filter(notHavingErrors()).filter(entity -> + !existingProjectIds.contains(entity.getProjectId())).collect(Collectors.toList()); + log.info("Identified {} invalid UserAction entities with non-existent Project IDs", invalidEntities.size()); + + // Populate error details for invalid UserAction entities + invalidEntities.forEach(userAction -> { + Error error = getErrorForNonExistentRelatedEntity(userAction.getProjectId()); + populateErrorDetails(userAction, error, errorDetailsMap); + log.debug("Populated error details for UserAction with invalid Project ID: {}", userAction.getProjectId()); + }); + } else { + log.info("No Project IDs to validate as the map of Project IDs to UserAction entities is empty"); + } + + log.info("Completed validation of project IDs in UserActionBulkRequest"); + return errorDetailsMap; + } +} diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaRowVersionValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaRowVersionValidator.java new file mode 100644 index 00000000000..45c8381d120 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaRowVersionValidator.java @@ -0,0 +1,69 @@ +package org.egov.project.validator.useraction; + +import java.lang.reflect.Method; +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.egov.common.models.Error; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.project.repository.UserActionRepository; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.getEntitiesWithMismatchedRowVersion; +import static org.egov.common.utils.CommonUtils.getIdFieldName; +import static org.egov.common.utils.CommonUtils.getIdMethod; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForRowVersionMismatch; + +@Component +@Order(value = 5) +@Slf4j +public class UaRowVersionValidator implements Validator { + + private final UserActionRepository userActionRepository; + + @Autowired + public UaRowVersionValidator(UserActionRepository userActionRepository) { + this.userActionRepository = userActionRepository; + } + + + @Override + public Map> validate(UserActionBulkRequest request) { + log.info("validating row version"); + Map> errorDetailsMap = new HashMap<>(); + try { + + Method idMethod = getIdMethod(request.getUserActions()); + Map eMap = getIdToObjMap(request.getUserActions().stream() + .filter(notHavingErrors()) + .collect(Collectors.toList()), idMethod); + if (!eMap.isEmpty()) { + List entityIds = new ArrayList<>(eMap.keySet()); + List existingEntities = userActionRepository.findById(entityIds, + getIdFieldName(idMethod)).getResponse(); + List entitiesWithMismatchedRowVersion = + getEntitiesWithMismatchedRowVersion(eMap, existingEntities, idMethod); + entitiesWithMismatchedRowVersion.forEach(individual -> { + Error error = getErrorForRowVersionMismatch(); + populateErrorDetails(individual, error, errorDetailsMap); + }); + } + } catch (Exception e) { + log.error("Exception occurred during validation: {}", e.getMessage()); + throw new CustomException("PROJECT_USER_ACTION_PROJECT_ID_VALIDATION_ERROR", "Error occurred while validating project IDs"+e); + } + return errorDetailsMap; + } +} diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java new file mode 100644 index 00000000000..3341d1d99eb --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java @@ -0,0 +1,99 @@ +package org.egov.project.validator.useraction; + +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.StringUtils; +import org.egov.common.models.Error; +import org.egov.common.models.core.Field; +import org.egov.common.models.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.project.util.ProjectConstants; +import org.egov.tracer.model.CustomException; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.project.Constants.HOUSEHOLD_ID; + +/** + * UaStatusValidator is responsible for validating the status of UserAction entities within a UserActionBulkRequest. + * Specifically, it ensures that UserActions with a status of 'RESOLVED' have a non-empty 'HouseholdId' field + * in their additional details. + */ +@Component +@Order(value = 3) +@Slf4j +public class UaStatusValidator implements Validator { + + /** + * Validates the UserAction entities within a UserActionBulkRequest based on their status and additional fields. + * It checks UserActions with a status of 'RESOLVED' to ensure that the 'HouseholdId' field + * in the additional details is present and has a non-empty value. + * + * @param request The UserActionBulkRequest object containing the list of UserActions to be validated. + * @return A map where each key is a UserAction that failed validation, and each value is a list of Error objects + * associated with that UserAction. + */ + @Override + public Map> validate(UserActionBulkRequest request) { + log.info("Starting validation of UserActions with status 'RESOLVED' in UserActionBulkRequest with {} entities", request.getUserActions().size()); + + // Initialize a map to store UserActions with validation errors and corresponding error details + Map> errorDetailsMap = new HashMap<>(); + + // Stream through the list of UserActions and filter out those that have status 'RESOLVED' but + // do not meet the criteria of having a non-empty 'HouseholdId' field. + List invalidEntities = request.getUserActions().stream() + .filter(userAction -> ProjectConstants.TaskStatus.RESOLVED.toString().equals(userAction.getStatus())) + .filter(userAction -> !validateResolvedStatus(userAction.getAdditionalFields().getFields())) + .collect(Collectors.toList()); + + log.info("Identified {} invalid UserActions with status 'RESOLVED' and missing 'HouseholdId'", invalidEntities.size()); + + // If there are any invalid UserActions, create error details and populate them in the map + if (!CollectionUtils.isEmpty(invalidEntities)) { + invalidEntities.forEach(userAction -> { + log.debug("Populating error details for UserAction with ID: {}", userAction.getId()); + + // Create an Error object with details about the missing 'HouseholdId' + Error error = Error.builder() + .errorMessage(HOUSEHOLD_ID + " is not present in AdditionalDetails of object.") + .errorCode("PROJECT_USER_ACTION_MISSING_HOUSEHOLD_ID") + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException("PROJECT_USER_ACTION_MISSING_HOUSEHOLD_ID", HOUSEHOLD_ID + " is not present in AdditionalDetails of userAction with ID: " + userAction.getId())) + .build(); + + // Populate the error details map with the UserAction and the created error + populateErrorDetails(userAction, error, errorDetailsMap); + }); + } + + log.info("Completed validation of UserActions with status 'RESOLVED'"); + return errorDetailsMap; + } + + /** + * Checks if the 'HouseholdId' field is present and correctly set in the list of additional fields. + * + * @param fields The list of additional fields associated with a UserAction. + * @return true if the 'HouseholdId' field is present and non-empty; false otherwise. + */ + private boolean validateResolvedStatus(List fields) { + log.debug("Validating additional fields for 'HouseholdId' presence and non-empty value"); + + // Stream through the list of fields to find one with the key 'HouseholdId' + boolean isValid = fields.stream() + .filter(field -> field.getKey().equals(HOUSEHOLD_ID)) + // Check if the value for this field is non-empty + .anyMatch(field -> !StringUtils.isEmpty(field.getValue())); + + log.debug("'HouseholdId' validation result: {}", isValid); + return isValid; + } +} diff --git a/health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java b/health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java new file mode 100644 index 00000000000..a2c31077309 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java @@ -0,0 +1,130 @@ +package org.egov.project.web.controllers; + +import io.swagger.annotations.ApiParam; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +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.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.models.project.useraction.UserActionBulkResponse; +import org.egov.common.models.project.useraction.UserActionSearchRequest; +import org.egov.common.producer.Producer; +import org.egov.common.utils.ResponseInfoFactory; +import org.egov.project.config.ProjectConfiguration; +import org.egov.project.service.LocationCaptureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Controller for handling requests related to location capture tasks. + * Provides endpoints for creating and searching location capture tasks. + */ +@Controller +@RequestMapping("/user-location") +@Validated +@Slf4j +public class LocationCaptureController { + + private final HttpServletRequest httpServletRequest; + private final LocationCaptureService locationCaptureService; + private final Producer producer; + private final ProjectConfiguration projectConfiguration; + + /** + * Constructor for injecting dependencies into the LocationCaptureController. + * + * @param httpServletRequest The HttpServletRequest to capture request details. + * @param locationCaptureService The service for handling location capture logic. + * @param producer The producer for sending messages to Kafka topics. + * @param projectConfiguration Configuration properties related to the project. + */ + @Autowired + public LocationCaptureController( + HttpServletRequest httpServletRequest, + LocationCaptureService locationCaptureService, + Producer producer, + ProjectConfiguration projectConfiguration + ) { + this.httpServletRequest = httpServletRequest; + this.locationCaptureService = locationCaptureService; + this.producer = producer; + this.projectConfiguration = projectConfiguration; + } + + /** + * Endpoint for creating location capture tasks in bulk. + * Receives a UserActionBulkRequest object, processes it, and sends it to the appropriate Kafka topic. + * + * @param request The bulk request containing user actions to be created. + * @return A ResponseEntity containing the response info with HTTP status ACCEPTED. + */ + @RequestMapping(value = "/v1/_create", method = RequestMethod.POST) + public ResponseEntity locationCaptureTaskV1BulkCreatePost( + @ApiParam(value = "Create Location Capture LocationCapture.", required = true) @Valid @RequestBody UserActionBulkRequest request) { + // Set the API ID in the request info using the current request URI. + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + + try { + // Send the request to the Kafka topic for bulk creation. + producer.push(projectConfiguration.getBulkCreateLocationCaptureTopic(), request); + } catch (Exception e) { + log.error("Error sending message to Kafka", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body( + ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), false) + ); + } + + // Create and return a ResponseInfo object with HTTP status ACCEPTED. + return ResponseEntity.status(HttpStatus.ACCEPTED).body( + ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), true) + ); + } + + /** + * Endpoint for searching location capture tasks based on given search criteria. + * Receives a UserActionSearchRequest object and returns the search results. + * + * @param urlParams URL parameters for the search. + * @param locationCaptureSearchRequest The request containing search criteria for location capture tasks. + * @return A ResponseEntity containing the search results with HTTP status OK. + * @throws Exception if there is an error during the search operation. + */ + @RequestMapping(value = "/v1/_search", method = RequestMethod.POST) + public ResponseEntity locationCaptureTaskV2SearchPost( + @Valid @ModelAttribute URLParams urlParams, + @ApiParam(value = "Search details of Location Capture.", required = true) @Valid @RequestBody UserActionSearchRequest locationCaptureSearchRequest + ) throws Exception { + + try { + // Perform the search using the locationCaptureService. + SearchResponse locationCaptureSearchResponse = locationCaptureService.search(locationCaptureSearchRequest, urlParams); + + // Build the response object with the search results and response info. + UserActionBulkResponse response = UserActionBulkResponse.builder() + .userActions(locationCaptureSearchResponse.getResponse()) + .totalCount(locationCaptureSearchResponse.getTotalCount()) + .responseInfo(ResponseInfoFactory.createResponseInfo(locationCaptureSearchRequest.getRequestInfo(), true)) + .build(); + + // Return the response with HTTP status OK. + return ResponseEntity.status(HttpStatus.OK).body(response); + } catch (Exception e) { + log.error("Error during search operation", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body( + UserActionBulkResponse.builder() + .responseInfo(ResponseInfoFactory.createResponseInfo(locationCaptureSearchRequest.getRequestInfo(), false)) + .build() + ); + } + } +} diff --git a/health-services/project/src/main/java/org/egov/project/web/controllers/UserActionController.java b/health-services/project/src/main/java/org/egov/project/web/controllers/UserActionController.java new file mode 100644 index 00000000000..34a56ae9ca5 --- /dev/null +++ b/health-services/project/src/main/java/org/egov/project/web/controllers/UserActionController.java @@ -0,0 +1,162 @@ +package org.egov.project.web.controllers; + +import io.swagger.annotations.ApiParam; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +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.project.useraction.UserAction; +import org.egov.common.models.project.useraction.UserActionBulkRequest; +import org.egov.common.models.project.useraction.UserActionBulkResponse; +import org.egov.common.models.project.useraction.UserActionSearchRequest; +import org.egov.common.producer.Producer; +import org.egov.common.utils.ResponseInfoFactory; +import org.egov.project.config.ProjectConfiguration; +import org.egov.project.service.UserActionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * Controller for handling user action-related requests. + * Provides endpoints for creating, updating, and searching user actions. + */ +@Controller +@RequestMapping("/user-action") +@Validated +@Slf4j +public class UserActionController { + + private final HttpServletRequest httpServletRequest; + private final UserActionService userActionService; + private final Producer producer; + private final ProjectConfiguration projectConfiguration; + + /** + * Constructor for injecting dependencies into the UserActionController. + * + * @param httpServletRequest The HttpServletRequest to capture request details. + * @param userActionService The service for handling user action logic. + * @param producer The producer for sending messages to Kafka topics. + * @param projectConfiguration Configuration properties related to the project. + */ + @Autowired + public UserActionController( + HttpServletRequest httpServletRequest, + UserActionService userActionService, + Producer producer, + ProjectConfiguration projectConfiguration + ) { + this.httpServletRequest = httpServletRequest; + this.userActionService = userActionService; + this.producer = producer; + this.projectConfiguration = projectConfiguration; + } + + /** + * Endpoint for creating user actions in bulk. + * Receives a UserActionBulkRequest object, processes it, and sends it to the appropriate Kafka topic. + * + * @param request The bulk request containing user actions to be created. + * @return A ResponseEntity containing the response info with HTTP status ACCEPTED. + */ + @RequestMapping(value = "/v1/_create", method = RequestMethod.POST) + public ResponseEntity userActionV1BulkCreatePost( + @ApiParam(value = "Capture linkage of Project and User Action UserAction.", required = true) @Valid @RequestBody UserActionBulkRequest request + ) { + // Set the API ID in the request info using the current request URI. + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + + try { + log.debug("Pushing user action bulk create request to Kafka topic: {}", projectConfiguration.getBulkCreateUserActionTopic()); + // Send the request to the Kafka topic for bulk creation. + producer.push(projectConfiguration.getBulkCreateUserActionTopic(), request); + log.info("Successfully pushed user action bulk create request to Kafka"); + } catch (Exception e) { + log.error("Failed to push user action bulk create request to Kafka", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body( + ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), false) + ); + } + + // Create and return a ResponseInfo object with HTTP status ACCEPTED. + return ResponseEntity.status(HttpStatus.ACCEPTED).body( + ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), true) + ); + } + + /** + * Endpoint for searching user actions based on given search criteria. + * Receives a UserActionSearchRequest object and returns the search results. + * + * @param urlParams URL parameters for the search. + * @param request The request containing search criteria for user actions. + * @return A ResponseEntity containing the search results with HTTP status OK. + */ + @RequestMapping(value = "/v1/_search", method = RequestMethod.POST) + public ResponseEntity userActionV2SearchPost( + @Valid @ModelAttribute URLParams urlParams, + @ApiParam(value = "Capture details of Project User Action UserAction.", required = true) @Valid @RequestBody UserActionSearchRequest request + ) { + log.debug("Executing search with URLParams: {} and request: {}", urlParams, request); + + // Perform the search using the userActionService. + SearchResponse userActions; + try { + // Perform the search using the userActionService. + userActions = userActionService.search(request, urlParams); + log.info("Successfully searched for user actions: {}", userActions.getResponse().size()); + } catch (Exception e) { + log.error("Failed to search for user actions", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + + // Build the response object with the search results and response info. + UserActionBulkResponse response = UserActionBulkResponse.builder() + .userActions(userActions.getResponse()) + .totalCount(userActions.getTotalCount()) + .responseInfo(ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), true)) + .build(); + + // Return the response with HTTP status OK. + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + /** + * Endpoint for updating user actions in bulk. + * Receives a UserActionBulkRequest object, processes it, and sends it to the appropriate Kafka topic. + * + * @param request The bulk request containing user actions to be updated. + * @return A ResponseEntity containing the response info with HTTP status ACCEPTED. + */ + @RequestMapping(value = "/v1/_update", method = RequestMethod.POST) + public ResponseEntity userActionV1BulkUpdatePost( + @ApiParam(value = "Capture linkage of Project and User Action UserAction.", required = true) @Valid @RequestBody UserActionBulkRequest request + ) { + // Set the API ID in the request info using the current request URI. + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + + try { + // Send the request to the Kafka topic for bulk update. + producer.push(projectConfiguration.getBulkUpdateUserActionTopic(), request); + } catch (Exception e) { + log.error("Failed to push user action bulk update request to Kafka", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body( + ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), false) + ); + } + + // Create and return a ResponseInfo object with HTTP status ACCEPTED. + return ResponseEntity.status(HttpStatus.ACCEPTED).body( + ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), true) + ); + } +} diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index f52ba8f6584..c9fc8ec680a 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -168,3 +168,12 @@ egov.location.hierarchy.type=ADMIN #---------Attendance-----------# project.staff.attendance.topic=project-staff-attendance-health-topic +#-------Closed Household Task-------# +project.user.action.kafka.create.topic=save-user-action-project-topic +project.user.action.kafka.update.topic=update-user-action-project-topic +project.user.action.consumer.bulk.create.topic=save-user-action-project-bulk-topic +project.user.action.consumer.bulk.update.topic=update-user-action-project-bulk-topic + +#-------Location Capture Task-------# +project.location.capture.task.kafka.create.topic=save-location-capture-project-topic +project.location.capture.task.consumer.bulk.create.topic=save-location-capture-project-bulk-topic diff --git a/health-services/project/src/main/resources/db/migration/main/V20240711175300__user_location_ddl.sql b/health-services/project/src/main/resources/db/migration/main/V20240711175300__user_location_ddl.sql new file mode 100644 index 00000000000..fd9a0f8f611 --- /dev/null +++ b/health-services/project/src/main/resources/db/migration/main/V20240711175300__user_location_ddl.sql @@ -0,0 +1,23 @@ +CREATE TABLE IF NOT EXISTS USER_LOCATION ( + id CHARACTER VARYING(64), + clientReferenceId CHARACTER VARYING(64), + tenantId CHARACTER VARYING(1000) NOT NULL, + projectId CHARACTER VARYING(64) NOT NULL, + latitude DOUBLE PRECISION NOT NULL, + longitude DOUBLE PRECISION NOT NULL, + locationAccuracy INTEGER NOT NULL, + boundaryCode CHARACTER VARYING(256) NOT NULL, + action CHARACTER VARYING(256), + createdBy CHARACTER VARYING(64) NOT NULL, + createdTime BIGINT NOT NULL, + lastModifiedBy CHARACTER VARYING(64) NOT NULL, + lastModifiedTime BIGINT NOT NULL, + clientCreatedTime BIGINT, + clientLastModifiedTime BIGINT, + clientCreatedBy CHARACTER VARYING(64), + clientLastModifiedBy CHARACTER VARYING(64), + additionalDetails jsonb, + CONSTRAINT pk_user_location PRIMARY KEY (id) +); + +CREATE INDEX IF NOT EXISTS idx_user_location_clientCreatedBy ON USER_LOCATION (clientCreatedBy); diff --git a/health-services/project/src/main/resources/db/migration/main/V20240711175500__user_action_ddl.sql b/health-services/project/src/main/resources/db/migration/main/V20240711175500__user_action_ddl.sql new file mode 100644 index 00000000000..411e86e86ef --- /dev/null +++ b/health-services/project/src/main/resources/db/migration/main/V20240711175500__user_action_ddl.sql @@ -0,0 +1,28 @@ +CREATE TABLE IF NOT EXISTS USER_ACTION ( +id character varying(64), +clientReferenceId character varying(64), +tenantId character varying(1000) not null, +projectId character varying(64) not null, +latitude double precision not null, +longitude double precision not null, +locationAccuracy INTEGER not null, +boundaryCode CHARACTER VARYING(256) not null, +action CHARACTER VARYING(256) not null, +beneficiaryTag CHARACTER VARYING(64), +resourceTag CHARACTER VARYING(64), +status character varying(1000), +additionalDetails jsonb, +createdBy character varying(64) not null, +createdTime bigint not null, +lastModifiedBy character varying(64) not null, +lastModifiedTime bigint not null, +clientCreatedTime bigint, +clientLastModifiedTime bigint, +clientCreatedBy character varying(64), +clientLastModifiedBy character varying(64), +rowVersion bigint, + CONSTRAINT pk_user_action_id PRIMARY KEY (id), + CONSTRAINT uk_user_action_clientReference_id UNIQUE (clientReferenceId) +); + +CREATE INDEX IF NOT EXISTS idx_user_action_projectId_clientCreatedBy ON USER_ACTION (projectId, clientCreatedBy); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/Constants.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/Constants.java index f33a82c8bea..b24119eb8dd 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/Constants.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/Constants.java @@ -1,6 +1,7 @@ package org.egov.referralmanagement; public interface Constants { + String SET_SIDE_EFFECTS = "setSideEffects"; String GET_SIDE_EFFECTS = "getSideEffects"; String SET_REFERRALS = "setReferrals"; @@ -15,5 +16,10 @@ public interface Constants { String STAFF = "STAFF"; String FACILITY = "FACILITY"; + public static final String HCM_MASTER_PROJECTTYPE = "projectTypes"; + public static final String HCM_MDMS_PROJECT_MODULE_NAME = "HCM-PROJECT-TYPES"; + public static final String HCM_PROJECT_TYPE_FILTER_CODE = "$.[?(@.code=='%s')]"; + public static final String HCM_MDMS_PROJECTTYPE_RES_PATH = "$.MdmsRes." + HCM_MDMS_PROJECT_MODULE_NAME + "." + HCM_MASTER_PROJECTTYPE + ".*"; + String INVALID_RECIPIENT_TYPE = "Invalid Recipient Type"; } diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/ReferralManagementConfiguration.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/ReferralManagementConfiguration.java index 1113ac58efb..e69325f19c5 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/ReferralManagementConfiguration.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/config/ReferralManagementConfiguration.java @@ -109,4 +109,10 @@ public class ReferralManagementConfiguration { @Value("${egov.search.individual.url}") private String individualSearchUrl; + @Value("${egov.mdms.host}") + private String mdmsHost; + + @Value("${egov.mdms.search.endpoint}") + private String mdmsSearchUrl; + } diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/DownsyncService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/DownsyncService.java index f3ca4fa075d..7db34924dd4 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/DownsyncService.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/DownsyncService.java @@ -3,11 +3,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; import org.egov.common.contract.request.RequestInfo; import org.egov.common.http.client.ServiceRequestClient; import org.egov.common.models.household.Household; @@ -46,6 +48,7 @@ import org.springframework.util.CollectionUtils; @Service +@Slf4j public class DownsyncService { private ServiceRequestClient restClient; @@ -58,28 +61,34 @@ public class DownsyncService { private ReferralManagementService referralService; + private MasterDataService masterDataService; + @Autowired - public DownsyncService(ServiceRequestClient serviceRequestClient, - ReferralManagementConfiguration referralManagementConfiguration, - NamedParameterJdbcTemplate jdbcTemplate, - SideEffectService sideEffectService, - ReferralManagementService referralService) { + public DownsyncService( ServiceRequestClient serviceRequestClient, + ReferralManagementConfiguration referralManagementConfiguration, + NamedParameterJdbcTemplate jdbcTemplate, + SideEffectService sideEffectService, + ReferralManagementService referralService, + MasterDataService masterDataService ) { this.restClient = serviceRequestClient; this.configs = referralManagementConfiguration; this.jdbcTemplate = jdbcTemplate; - this.sideEffectService = sideEffectService; - this.referralService = referralService; + this.sideEffectService=sideEffectService; + this.referralService=referralService; + this.masterDataService=masterDataService; } /** + * * @param downsyncRequest * @return Downsync */ public Downsync prepareDownsyncData(DownsyncRequest downsyncRequest) { Downsync downsync = new Downsync(); + DownsyncCriteria downsyncCriteria = downsyncRequest.getDownsyncCriteria(); List householdIds = null; Set individualIds = null; @@ -87,43 +96,60 @@ public Downsync prepareDownsyncData(DownsyncRequest downsyncRequest) { List beneficiaryClientRefIds = null; List taskClientRefIds = null; - downsync.setDownsyncCriteria(downsyncRequest.getDownsyncCriteria()); + + downsync.setDownsyncCriteria(downsyncCriteria); + boolean isSyncTimeAvailable = null != downsyncCriteria.getLastSyncedTime(); + + //Project project = getProjectType(downsyncRequest); + LinkedHashMap projectType = masterDataService.getProjectType(downsyncRequest); + /* search household */ householdIds = searchHouseholds(downsyncRequest, downsync); - if (!CollectionUtils.isEmpty(householdIds)) - /* search household member using household ids */ + /* search household member using household ids */ + if (isSyncTimeAvailable || !CollectionUtils.isEmpty(householdIds)) { individualIds = searchMembers(downsyncRequest, downsync, householdIds); + } - if (!CollectionUtils.isEmpty(individualIds)) { - - /* search individuals using individual ids */ + /* search individuals using individual ids */ + if (isSyncTimeAvailable || !CollectionUtils.isEmpty(individualIds) ) { individualClientRefIds = searchIndividuals(downsyncRequest, downsync, individualIds); } - if (!CollectionUtils.isEmpty(individualClientRefIds)) { - /* search beneficiary using individual ids */ - beneficiaryClientRefIds = searchBeneficiaries(downsyncRequest, downsync, individualClientRefIds); + /* search beneficiary using individual ids OR household ids */ + + String beneficiaryType = (String) projectType.get("beneficiaryType"); + + beneficiaryClientRefIds = individualClientRefIds; + + if("HOUSEHOLD".equalsIgnoreCase(beneficiaryType)) + beneficiaryClientRefIds = downsync.getHouseholds().stream().map(Household::getClientReferenceId).collect(Collectors.toList()); + + //fetch beneficiary in the db + if (isSyncTimeAvailable || !CollectionUtils.isEmpty(beneficiaryClientRefIds)) { + beneficiaryClientRefIds = searchBeneficiaries(downsyncRequest, downsync, beneficiaryClientRefIds); } - if (!CollectionUtils.isEmpty(beneficiaryClientRefIds)) { + /* search tasks using beneficiary uuids */ + if (isSyncTimeAvailable || !CollectionUtils.isEmpty(beneficiaryClientRefIds)) { - /* search tasks using beneficiary uuids */ - taskClientRefIds = searchTasks(downsyncRequest, downsync, beneficiaryClientRefIds); + taskClientRefIds = searchTasks(downsyncRequest, downsync, beneficiaryClientRefIds, projectType); /* ref search */ referralSearch(downsyncRequest, downsync, beneficiaryClientRefIds); } - if (!CollectionUtils.isEmpty(taskClientRefIds)) { + if (isSyncTimeAvailable || !CollectionUtils.isEmpty(taskClientRefIds)) { searchSideEffect(downsyncRequest, downsync, taskClientRefIds); } return downsync; } + /** + * * @param downsyncRequest * @param downsync * @return @@ -135,7 +161,7 @@ private List searchHouseholds(DownsyncRequest downsyncRequest, Downsync StringBuilder householdUrl = new StringBuilder(configs.getHouseholdHost()) .append(configs.getHouseholdSearchUrl()); - householdUrl = appendUrlParams(householdUrl, criteria, null, null); + householdUrl = appendUrlParams(householdUrl, criteria, null, null, true); HouseholdSearch householdSearch = HouseholdSearch.builder() .localityCode(criteria.getLocality()) @@ -151,13 +177,14 @@ private List searchHouseholds(DownsyncRequest downsyncRequest, Downsync downsync.setHouseholds(households); downsync.getDownsyncCriteria().setTotalCount(res.getTotalCount()); - if (CollectionUtils.isEmpty(households)) + if(CollectionUtils.isEmpty(households)) return Collections.emptyList(); return households.stream().map(Household::getId).collect(Collectors.toList()); } /** + * * @param downsyncRequest * @param downsync * @param individualIds @@ -171,12 +198,15 @@ private List searchIndividuals(DownsyncRequest downsyncRequest, Downsync StringBuilder url = new StringBuilder(configs.getIndividualHost()) .append(configs.getIndividualSearchUrl()); - url = appendUrlParams(url, criteria, 0, individualIds.size()); + + url = appendUrlParams(url, criteria, 0, individualIds.size(),true); IndividualSearch individualSearch = IndividualSearch.builder() - .id(new ArrayList<>(individualIds)) .build(); + if(!CollectionUtils.isEmpty(individualIds)) + individualSearch.setId(new ArrayList<>(individualIds)); + IndividualSearchRequest searchRequest = IndividualSearchRequest.builder() .individual(individualSearch) .requestInfo(requestInfo) @@ -189,6 +219,7 @@ private List searchIndividuals(DownsyncRequest downsyncRequest, Downsync } /** + * * @param downsyncRequest * @param householdIds * @return @@ -196,21 +227,17 @@ private List searchIndividuals(DownsyncRequest downsyncRequest, Downsync private Set searchMembers(DownsyncRequest downsyncRequest, Downsync downsync, List householdIds) { - StringBuilder memberUrl = new StringBuilder(configs.getHouseholdHost()) - .append(configs.getHouseholdMemberSearchUrl()); + Long lastChangedSince = downsyncRequest.getDownsyncCriteria().getLastSyncedTime(); - String memberIdsquery = "SELECT id from HOUSEHOLD_MEMBER where householdId IN (:householdIds)"; - - Map paramMap = new HashMap<>(); - paramMap.put("householdIds", householdIds); - appendUrlParams(memberUrl, downsyncRequest.getDownsyncCriteria(), 0, householdIds.size()); - - /* FIXME SHOULD BE REMOVED AND SEARCH SHOULD BE enhanced with list of household ids*/ - List memberids = jdbcTemplate.queryForList(memberIdsquery, paramMap, String.class); + List memberids = getPrimaryIds(householdIds, "householdId","HOUSEHOLD_MEMBER",lastChangedSince); if (CollectionUtils.isEmpty(memberids)) return Collections.emptySet(); + StringBuilder memberUrl = new StringBuilder(configs.getHouseholdHost()) + .append(configs.getHouseholdMemberSearchUrl()); + + appendUrlParams(memberUrl, downsyncRequest.getDownsyncCriteria(), 0, householdIds.size(), false); HouseholdMemberSearch memberSearch = HouseholdMemberSearch.builder() .id(memberids) @@ -228,92 +255,94 @@ private Set searchMembers(DownsyncRequest downsyncRequest, Downsync down } /** + * * @param downsyncRequest * @param downsync - * @param individualClientRefIds + * @param beneficiaryClientRefIds * @return clientreferenceid of beneficiary object */ private List searchBeneficiaries(DownsyncRequest downsyncRequest, Downsync downsync, - List individualClientRefIds) { + List beneficiaryClientRefIds) { DownsyncCriteria criteria = downsyncRequest.getDownsyncCriteria(); RequestInfo requestInfo = downsyncRequest.getRequestInfo(); + Long lastChangedSince =criteria.getLastSyncedTime(); + + List beneficiaryIds = getPrimaryIds( + beneficiaryClientRefIds, + "beneficiaryclientreferenceid", + "PROJECT_BENEFICIARY", + lastChangedSince + ); + + if(CollectionUtils.isEmpty(beneficiaryIds)) + return Collections.emptyList(); + + StringBuilder url = new StringBuilder(configs.getProjectHost()) + .append(configs.getProjectBeneficiarySearchUrl()); + + url = appendUrlParams(url, criteria, 0, beneficiaryClientRefIds.size(),false); + + ProjectBeneficiarySearch search = ProjectBeneficiarySearch.builder() + .id(beneficiaryIds) + .projectId(Collections.singletonList(downsyncRequest.getDownsyncCriteria().getProjectId())) + .build(); + + BeneficiarySearchRequest searchRequest = BeneficiarySearchRequest.builder() + .projectBeneficiary(search) + .requestInfo(requestInfo) + .build(); + + List beneficiaries = restClient.fetchResult(url, searchRequest, BeneficiaryBulkResponse.class).getProjectBeneficiaries(); + downsync.setProjectBeneficiaries(beneficiaries); + + return beneficiaries.stream().map(ProjectBeneficiary::getClientReferenceId).collect(Collectors.toList()); + } + - StringBuilder url = new StringBuilder(configs.getProjectHost()) - .append(configs.getProjectBeneficiarySearchUrl()); - url = appendUrlParams(url, criteria, 0, individualClientRefIds.size()); - - String beneficiaryIdQuery = "SELECT id from PROJECT_BENEFICIARY where beneficiaryclientreferenceid IN (:beneficiaryIds)"; - - Map paramMap = new HashMap<>(); - paramMap.put("beneficiaryIds", individualClientRefIds); - - /* FIXME SHOULD BE REMOVED AND SEARCH SHOULD BE enhanced with list of beneficiary ids*/ - List ids = jdbcTemplate.queryForList(beneficiaryIdQuery, paramMap, String.class); - - if(CollectionUtils.isEmpty(ids)) - return Collections.emptyList(); - - ProjectBeneficiarySearch search = ProjectBeneficiarySearch.builder() - .id(ids) - .projectId(Collections.singletonList(downsyncRequest.getDownsyncCriteria().getProjectId())) - .build(); - - BeneficiarySearchRequest searchRequest = BeneficiarySearchRequest.builder() - .projectBeneficiary(search) - .requestInfo(requestInfo) - .build(); - - List beneficiaries = restClient.fetchResult(url, searchRequest, BeneficiaryBulkResponse.class).getProjectBeneficiaries(); - downsync.setProjectBeneficiaries(beneficiaries); - - return beneficiaries.stream().map(ProjectBeneficiary::getClientReferenceId).collect(Collectors.toList()); - } /** + * * @param downsyncRequest * @param downsync * @param beneficiaryClientRefIds + * @param projectType * @return */ private List searchTasks(DownsyncRequest downsyncRequest, Downsync downsync, - List beneficiaryClientRefIds) { - - DownsyncCriteria criteria = downsyncRequest.getDownsyncCriteria(); - RequestInfo requestInfo = downsyncRequest.getRequestInfo(); - - StringBuilder url = new StringBuilder(configs.getProjectHost()) - .append(configs.getProjectTaskSearchUrl()); - - String taskIdQuery = "SELECT id from PROJECT_TASK where projectBeneficiaryClientReferenceId IN (:beneficiaryClientRefIds)"; - - Map paramMap = new HashMap<>(); - paramMap.put("beneficiaryClientRefIds", beneficiaryClientRefIds); - - /* FIXME SHOULD BE REMOVED AND TASK SEARCH SHOULD BE enhanced with list of client-ref-beneficiary ids*/ - List taskIds = jdbcTemplate.queryForList(taskIdQuery, paramMap, String.class); - url = appendUrlParams(url, criteria, 0, taskIds.size()); - - if(CollectionUtils.isEmpty(taskIds)) - return Collections.emptyList(); - - TaskSearch search = TaskSearch.builder() - .id(taskIds) - .projectId(Collections.singletonList(downsyncRequest.getDownsyncCriteria().getProjectId())) - .build(); - - TaskSearchRequest searchRequest = TaskSearchRequest.builder() - .task(search) - .requestInfo(requestInfo) - .build(); - - List tasks = restClient.fetchResult(url, searchRequest, TaskBulkResponse.class).getTasks(); - downsync.setTasks(tasks); - - return tasks.stream().map(Task::getClientReferenceId).collect(Collectors.toList()); - } + List beneficiaryClientRefIds, LinkedHashMap projectType) { + + DownsyncCriteria criteria = downsyncRequest.getDownsyncCriteria(); + RequestInfo requestInfo = downsyncRequest.getRequestInfo(); + List taskIds = getPrimaryIds(beneficiaryClientRefIds, "projectBeneficiaryClientReferenceId", "PROJECT_TASK", + criteria.getLastSyncedTime()); + + if(CollectionUtils.isEmpty(taskIds)) + return Collections.emptyList(); + + StringBuilder url = new StringBuilder(configs.getProjectHost()) + .append(configs.getProjectTaskSearchUrl()); + + url = appendUrlParams(url, criteria, 0, taskIds.size(), false); + + TaskSearch search = TaskSearch.builder() + .id(taskIds) + .projectId(Collections.singletonList(downsyncRequest.getDownsyncCriteria().getProjectId())) + .build(); + + TaskSearchRequest searchRequest = TaskSearchRequest.builder() + .task(search) + .requestInfo(requestInfo) + .build(); + + List tasks = restClient.fetchResult(url, searchRequest, TaskBulkResponse.class).getTasks(); + downsync.setTasks(tasks); + + return tasks.stream().map(Task::getClientReferenceId).collect(Collectors.toList()); + } /** + * * @param downsyncRequest * @param downsync * @param taskClientRefIds @@ -324,33 +353,29 @@ private void searchSideEffect(DownsyncRequest downsyncRequest, Downsync downsync DownsyncCriteria criteria = downsyncRequest.getDownsyncCriteria(); RequestInfo requestInfo = downsyncRequest.getRequestInfo(); - // search side effect FIXME - tasks id array search not available - String sEIdQuery = "SELECT id from SIDE_EFFECT where taskClientReferenceId IN (:taskClientRefIds)"; - - Map paramMap = new HashMap<>(); - paramMap.put("taskClientRefIds", taskClientRefIds); - /* FIXME SHOULD BE REMOVED AND TASK SEARCH SHOULD BE enhanced with list of client-ref-beneficiary ids*/ - List SEIds = jdbcTemplate.queryForList(sEIdQuery, paramMap, String.class); + List SEIds = getPrimaryIds(taskClientRefIds, "taskClientReferenceId", "SIDE_EFFECT", criteria.getLastSyncedTime()); - if (CollectionUtils.isEmpty(SEIds)) + if(CollectionUtils.isEmpty(SEIds)) return; SideEffectSearch search = SideEffectSearch.builder() .id(SEIds) .build(); + SideEffectSearchRequest effectSearchRequest = SideEffectSearchRequest.builder() .sideEffect(search) .requestInfo(requestInfo) .build(); List effects = sideEffectService.search( - effectSearchRequest, - SEIds.size(), - 0, - criteria.getTenantId(), - criteria.getLastSyncedTime(), - criteria.getIncludeDeleted()).getResponse(); + effectSearchRequest, + SEIds.size(), + 0, + criteria.getTenantId(), + criteria.getLastSyncedTime(), + criteria.getIncludeDeleted() + ).getResponse(); downsync.setSideEffects(effects); } @@ -360,28 +385,72 @@ private void referralSearch(DownsyncRequest downsyncRequest, Downsync downsync, DownsyncCriteria criteria = downsyncRequest.getDownsyncCriteria(); RequestInfo requestInfo = downsyncRequest.getRequestInfo(); + Integer limit = beneficiaryClientRefIds.size(); ReferralSearch search = ReferralSearch.builder() - .projectBeneficiaryClientReferenceId(beneficiaryClientRefIds) .build(); + if(!CollectionUtils.isEmpty(beneficiaryClientRefIds)) { + search.setProjectBeneficiaryClientReferenceId(beneficiaryClientRefIds); + limit = null; + } + ReferralSearchRequest searchRequest = ReferralSearchRequest.builder() .referral(search) .requestInfo(requestInfo) .build(); List referrals = referralService.search( - searchRequest, - beneficiaryClientRefIds.size(), - 0, - criteria.getTenantId(), - criteria.getLastSyncedTime(), - criteria.getIncludeDeleted()).getResponse(); + searchRequest, + limit, + 0, + criteria.getTenantId(), + criteria.getLastSyncedTime(), + criteria.getIncludeDeleted() + ).getResponse(); downsync.setReferrals(referrals); } + /** + * common method to fetch Ids with list of relation Ids like id of member with householdIds + * @param idList + * @param idListFieldName + * @param tableName + * @param lastChangedSince + * @return + */ + private List getPrimaryIds(List idList, String idListFieldName, String tableName, Long lastChangedSince) { + + /** + * Adding lastShangedSince to id query to avoid load on API search for members + */ + boolean isAndRequired = false; + Map paramMap = new HashMap<>(); + StringBuilder memberIdsquery = new StringBuilder("SELECT id from %s WHERE "); + + + if (!CollectionUtils.isEmpty(idList)) { + + memberIdsquery.append("%s IN (:%s)"); + paramMap.put(idListFieldName, idList); + isAndRequired = true; + } + + if (null != lastChangedSince) { + if(isAndRequired) + memberIdsquery.append(" AND "); + memberIdsquery.append(" lastModifiedTime >= (:lastChangedSince)"); + paramMap.put("lastChangedSince", lastChangedSince); + } + + String finalQuery = String.format(memberIdsquery.toString(), tableName, idListFieldName, idListFieldName); + /* FIXME SHOULD BE REMOVED AND SEARCH SHOULD BE enhanced with list of household ids*/ + List memberids = jdbcTemplate.queryForList(finalQuery, paramMap, String.class); + return memberids; + } + /** * append url params * @@ -389,9 +458,10 @@ private void referralSearch(DownsyncRequest downsyncRequest, Downsync downsync, * @param criteria * @param offset * @param limit + * @param sendPrevSyncTime * @return */ - private StringBuilder appendUrlParams(StringBuilder url, DownsyncCriteria criteria, Integer offset, Integer limit) { + private StringBuilder appendUrlParams(StringBuilder url, DownsyncCriteria criteria, Integer offset, Integer limit, boolean sendPrevSyncTime) { url.append("?tenantId=") .append(criteria.getTenantId()) @@ -399,18 +469,21 @@ private StringBuilder appendUrlParams(StringBuilder url, DownsyncCriteria criter .append(criteria.getIncludeDeleted()) .append("&limit="); - if (null != limit) + if (null != limit && limit != 0) url.append(limit); else url.append(criteria.getLimit()); url.append("&offset="); - if (null != offset) + if(null != offset) url.append(offset); else url.append(criteria.getOffset()); + if(sendPrevSyncTime && null != criteria.getLastSyncedTime()) + url.append("&lastChangedSince=").append(criteria.getLastSyncedTime()); + return url; } } 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 new file mode 100644 index 00000000000..3c09df3edde --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java @@ -0,0 +1,129 @@ +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 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; +import org.egov.common.models.project.Project; +import org.egov.common.models.project.ProjectRequest; +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.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import static org.egov.referralmanagement.Constants.HCM_MASTER_PROJECTTYPE; +import static org.egov.referralmanagement.Constants.HCM_MDMS_PROJECTTYPE_RES_PATH; +import static org.egov.referralmanagement.Constants.HCM_MDMS_PROJECT_MODULE_NAME; +import static org.egov.referralmanagement.Constants.HCM_PROJECT_TYPE_FILTER_CODE; + +@Slf4j +@Service +public class MasterDataService { + + private ServiceRequestClient restClient; + + private ReferralManagementConfiguration configs; + + @Autowired + public MasterDataService(ServiceRequestClient serviceRequestClient, + ReferralManagementConfiguration referralManagementConfiguration) { + + this.restClient = serviceRequestClient; + this.configs = referralManagementConfiguration; + + } + + + @SuppressWarnings("unchecked") + public LinkedHashMap getProjectType(DownsyncRequest downsyncRequest) { + + DownsyncCriteria downsyncCriteria = downsyncRequest.getDownsyncCriteria(); + RequestInfo info = downsyncRequest.getRequestInfo(); + String projectId = downsyncCriteria.getProjectId(); + + + Project project = getProject(downsyncCriteria, info, projectId); + + String projectCode = project.getProjectType(); // FIXME + + /* + * TODO FIXME code should get upgraded when next version of project is created with execution plan (project type master) in the additional details + */ + StringBuilder mdmsUrl = new StringBuilder(configs.getMdmsHost()) + .append(configs.getMdmsSearchUrl()); + + /* + * Assumption is that the project code is always unique + */ + MasterDetail masterDetail = MasterDetail.builder() + .name(HCM_MASTER_PROJECTTYPE) + .filter(String.format(HCM_PROJECT_TYPE_FILTER_CODE, projectCode)) // projectCode FIXME + .build(); + + ModuleDetail moduleDetail = ModuleDetail.builder() + .masterDetails(Arrays.asList(masterDetail)) + .moduleName(HCM_MDMS_PROJECT_MODULE_NAME) + .build(); + + MdmsCriteria mdmsCriteria = MdmsCriteria.builder() + .moduleDetails(Arrays.asList(moduleDetail)) + .tenantId(downsyncCriteria.getTenantId().split("//.")[0]) + .build(); + + MdmsCriteriaReq mdmsCriteriaReq = MdmsCriteriaReq.builder() + .mdmsCriteria(mdmsCriteria) + .requestInfo(info) + .build(); + + Map mdmsRes = restClient.fetchResult(mdmsUrl, mdmsCriteriaReq, HashMap.class); + List projectTypeRes = null; + try { + projectTypeRes = JsonPath.read(mdmsRes, HCM_MDMS_PROJECTTYPE_RES_PATH); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException("JSONPATH_ERROR", "Failed to parse mdms response"); + } + + return (LinkedHashMap) projectTypeRes.get(0); + + } + + + private Project getProject(DownsyncCriteria downsyncCriteria, RequestInfo info, String projectId) { + + StringBuilder url = new StringBuilder(configs.getProjectHost()) + .append(configs.getProjectSearchUrl()) + .append("?offset=0") + .append("&limit=100") + .append("&tenantId=").append(downsyncCriteria.getTenantId()); + + Project project = Project.builder() + .id(projectId) + .tenantId(downsyncCriteria.getTenantId()) + .build(); + + ProjectRequest projectRequest = ProjectRequest.builder() + .projects(Arrays.asList(project)) + .requestInfo(info) + .build(); + + ProjectResponse res = restClient.fetchResult(url, projectRequest, ProjectResponse.class); + return res.getProject().get(0); + } +} From 948e75ada10d7945a413b9292c0a8468b64646f0 Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Thu, 8 Aug 2024 12:54:58 +0530 Subject: [PATCH 02/20] Hcmpre 240 (#846) * HLM closed household status * HCMPRE-240: validate no resource task status scenario with configurable statuses * HCMPRE-240: fixed issues related to string trimming * HLM fixed rowversion referral bug, mis placement of rowversion validator * HCMPRE-240: code review changes * HCMPRE-242: updated for null resources and address check * HCMPRE-242: added for proper null check * HCMPRE-242: added checks for task resource where ever applicable * HCMPRE-242: updated taskstatus to enum from string * HCMPRE-242, HCMPRE-240: renamed task's status field to taskStatus field, as there is contradiction with EgovModel status field * HCMPRE-242: fixed dupcalite entity cache issue for existing entity validation during bulk create * HCMPRE-242: updated project test case for taskStatus field contraints changes : not null * HCMPRE-242: fix generic repository code * HCMPRE-242: added taskstatus migration script * HCMPRE-240: updated PtIsResourceEmptyValidator, for task status * HLM-242: added changes as per code review * Revert "HCMPRE-242: added taskstatus migration script", and removed status field from EgovModel, and rename TaskStatus to status This reverts commit 7caf0c43241154bdabc97bc20c876b86d984fdb6. * HCMPRE-240: FIXED all task status reference --------- Co-authored-by: sivajiganesh-dev --- health-services/household/pom.xml | 2 +- .../validators/HmExistentEntityValidator.java | 6 +- .../household/HExistentEntityValidator.java | 5 +- health-services/individual/pom.xml | 2 +- .../validators/IExistentEntityValidator.java | 6 +- .../libraries/health-services-common/pom.xml | 2 +- .../data/repository/GenericRepository.java | 13 +++ .../egov/common/models/core/EgovModel.java | 3 - .../org/egov/common/models/project/Task.java | 17 ++-- .../common/models/project/TaskStatus.java | 35 +++++++ health-services/project/pom.xml | 2 +- .../project/config/ProjectConfiguration.java | 5 + .../rowmapper/ProjectTaskRowMapper.java | 3 +- .../rowmapper/UserActionRowMapper.java | 1 - .../project/service/UserActionService.java | 2 - .../ProjectTaskEnrichmentService.java | 29 +++--- .../egov/project/util/ProjectConstants.java | 38 +------ .../PbExistentEntityValidator.java | 6 +- .../task/PtExistentEntityValidator.java | 5 +- .../task/PtIsResouceEmptyValidator.java | 68 +++++-------- .../task/PtNonExistentEntityValidator.java | 8 +- .../task/PtResourceQuantityValidator.java | 11 ++- .../useraction/UaExistentEntityValidator.java | 5 +- .../useraction/UaStatusValidator.java | 99 ------------------- .../src/main/resources/application.properties | 7 +- .../egov/project/helper/TaskTestBuilder.java | 8 +- health-services/referralmanagement/pom.xml | 2 +- .../service/ReferralManagementService.java | 6 +- .../validator/RmExistentEntityValidator.java | 5 +- .../HfrExistentEntityValidator.java | 6 +- .../sideeffect/SeExistentEntityValidator.java | 6 +- health-services/stock/pom.xml | 2 +- .../stock/SExistentEntityValidator.java | 6 +- .../SrExistentEntityValidator.java | 7 +- 34 files changed, 149 insertions(+), 279 deletions(-) create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java delete mode 100644 health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java diff --git a/health-services/household/pom.xml b/health-services/household/pom.xml index 1d59cc57c94..e97fd87ec1f 100644 --- a/health-services/household/pom.xml +++ b/health-services/household/pom.xml @@ -45,7 +45,7 @@ org.egov.common health-services-common - 1.0.17-SNAPSHOT + 1.0.17-dev-SNAPSHOT org.egov.common diff --git a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java index 1e335cd753e..e9aa42116e0 100644 --- a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java @@ -67,10 +67,8 @@ public Map> validate(HouseholdMemberBulkRequest req // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = householdMemberRepository.findById( - clientReferenceIdList, - getIdFieldName(householdSearch), - Boolean.FALSE).getResponse(); + List existentEntities = + householdMemberRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java index 57162432093..cad34c44206 100644 --- a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java @@ -66,10 +66,7 @@ public Map> validate(HouseholdBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = householdRepository.findById( - clientReferenceIdList, - getIdFieldName(householdSearch), - Boolean.FALSE).getResponse(); + List existentEntities = householdRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/individual/pom.xml b/health-services/individual/pom.xml index f739e08e736..02c05ffd93d 100644 --- a/health-services/individual/pom.xml +++ b/health-services/individual/pom.xml @@ -53,7 +53,7 @@ org.egov.common health-services-common - 1.0.17-SNAPSHOT + 1.0.17-dev-SNAPSHOT org.egov.common diff --git a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java index a5f75eaa0b8..82a332600a4 100644 --- a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java +++ b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java @@ -66,10 +66,8 @@ public Map> validate(IndividualBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = individualRepository.findById( - clientReferenceIdList, - getIdFieldName(individualSearch), - Boolean.FALSE).getResponse(); + List existentEntities = + individualRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/libraries/health-services-common/pom.xml b/health-services/libraries/health-services-common/pom.xml index a48b96a222d..0047646dc80 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.17-SNAPSHOT + 1.0.17-dev-SNAPSHOT Shared classes among services 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 872d11c9d2a..829603c599a 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 @@ -291,4 +291,17 @@ public List validateIds(List idsToValidate, String columnName){ return validIds.stream().map((obj) -> (String) ReflectionUtils.invokeMethod(idMethod, obj)) .collect(Collectors.toList()); } + + public List validateClientReferenceIdsFromDB(List clientReferenceIds) { + List objFound = new ArrayList<>(); + + String query = String.format("SELECT * FROM %s WHERE clientReferenceId IN (:ids) AND isDeleted = false", tableName); + Map paramMap = new HashMap<>(); + paramMap.put("ids", clientReferenceIds); + + objFound.addAll(namedParameterJdbcTemplate.query(query, paramMap, rowMapper)); + putInCache(objFound); + + return objFound; + } } 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 d125458f9af..f68ea5cea75 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 @@ -30,9 +30,6 @@ public class EgovModel { @Size(min = 2, max = 1000) protected String tenantId; - @JsonProperty("status") - protected String status; - @JsonProperty("source") protected String source; //TODO what are the various sources and needs comments diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java index eddbeb82f0f..9f0160c34b5 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Task.java @@ -1,9 +1,13 @@ package org.egov.common.models.project; -import com.fasterxml.jackson.annotation.JsonIgnore; +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 jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,12 +16,6 @@ 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.List; - /** * Task */ @@ -75,7 +73,8 @@ public class Task extends EgovOfflineModel { private Boolean isDeleted = Boolean.FALSE; @JsonProperty("status") - private String status = null; + @NotNull + TaskStatus status = null; public Task addResourcesItem(TaskResource resourcesItem) { this.resources.add(resourcesItem); diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java new file mode 100644 index 00000000000..c551a68acb4 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java @@ -0,0 +1,35 @@ +package org.egov.common.models.project; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum TaskStatus { + ADMINISTRATION_FAILED("ADMINISTRATION_FAILED"), + ADMINISTRATION_SUCCESS("ADMINISTRATION_SUCCESS"), + BENEFICIARY_REFUSED("BENEFICIARY_REFUSED"), + CLOSED_HOUSEHOLD("CLOSED_HOUSEHOLD"), + DELIVERED("DELIVERED"), + NOT_ADMINISTERED("NOT_ADMINISTERED"); + + private String value; + + TaskStatus(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static TaskStatus fromValue(String text) { + for (TaskStatus status : TaskStatus.values()) { + if (String.valueOf(status.value).equals(text)) { + return status; + } + } + return null; + } +} diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml index 157705fbe73..ccd901f62ed 100644 --- a/health-services/project/pom.xml +++ b/health-services/project/pom.xml @@ -45,7 +45,7 @@ org.egov.common health-services-common - 1.0.17-SNAPSHOT + 1.0.17-dev-SNAPSHOT org.egov.common 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 a3854075dab..87863679a07 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 @@ -1,5 +1,7 @@ package org.egov.project.config; +import java.util.List; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -214,4 +216,7 @@ public class ProjectConfiguration { @Value("${egov.boundary.search.url}") private String boundarySearchUrl; + + @Value("${project.task.no.resource.validation.status}") + private List noResourceStatuses; } 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 caafec9a8e1..ccff648bd41 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 @@ -8,6 +8,7 @@ import org.egov.common.models.project.AddressType; import org.egov.common.models.core.Boundary; import org.egov.common.models.project.Task; +import org.egov.common.models.project.TaskStatus; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Component; @@ -47,7 +48,7 @@ public Task mapRow(ResultSet resultSet, int i) throws SQLException { .plannedEndDate(resultSet.getLong("plannedEndDate")) .actualStartDate(resultSet.getLong("actualStartDate")) .actualEndDate(resultSet.getLong("actualEndDate")) - .status(resultSet.getString("status")) + .status(TaskStatus.fromValue(resultSet.getString("status"))) .auditDetails(auditDetails) .clientAuditDetails(clientAuditDetails) .additionalFields(resultSet.getString("additionalDetails") == null ? null : objectMapper 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 6f0d9840d77..8a63f0f3c99 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 @@ -74,7 +74,6 @@ public UserAction mapRow(ResultSet resultSet, int rowNum) throws SQLException { .locationAccuracy(resultSet.getDouble("locationAccuracy")) .boundaryCode(resultSet.getString("boundaryCode")) .action(UserActionEnum.fromValue(resultSet.getString("action"))) - .status(resultSet.getString("status")) .beneficiaryTag(resultSet.getString("beneficiaryTag")) .resourceTag(resultSet.getString("resourceTag")) .rowVersion(resultSet.getInt("rowVersion")) diff --git a/health-services/project/src/main/java/org/egov/project/service/UserActionService.java b/health-services/project/src/main/java/org/egov/project/service/UserActionService.java index df59e6b1c07..0e0f76dec0e 100644 --- a/health-services/project/src/main/java/org/egov/project/service/UserActionService.java +++ b/health-services/project/src/main/java/org/egov/project/service/UserActionService.java @@ -30,7 +30,6 @@ import org.egov.project.validator.useraction.UaNullIdValidator; import org.egov.project.validator.useraction.UaProjectIdValidator; import org.egov.project.validator.useraction.UaRowVersionValidator; -import org.egov.project.validator.useraction.UaStatusValidator; import org.egov.tracer.model.CustomException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -70,7 +69,6 @@ public class UserActionService { || validator.getClass().equals(UaNullIdValidator.class) || validator.getClass().equals(UaNonExistentEntityValidator.class) || validator.getClass().equals(UaRowVersionValidator.class) - || validator.getClass().equals(UaStatusValidator.class) || validator.getClass().equals(UaBoundaryValidator.class); // Constructor for dependency injection 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 9706c877ff2..db974db9be9 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 @@ -1,5 +1,9 @@ package org.egov.project.service.enrichment; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import digit.models.coremodels.AuditDetails; import lombok.extern.slf4j.Slf4j; import org.egov.common.models.project.Address; @@ -11,10 +15,6 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - import static org.egov.common.utils.CommonUtils.enrichForCreate; import static org.egov.common.utils.CommonUtils.enrichForUpdate; import static org.egov.common.utils.CommonUtils.enrichId; @@ -67,20 +67,24 @@ public void delete(List validTasks, TaskBulkRequest request) throws Except for (Task task : validTasks) { if (task.getIsDeleted()) { log.info("enriching all task resources for delete"); - for (TaskResource resource : task.getResources()) { - resource.setIsDeleted(true); - updateAuditDetailsForResource(request, resource); + if(!CollectionUtils.isEmpty(task.getResources())) { + for (TaskResource resource : task.getResources()) { + resource.setIsDeleted(true); + updateAuditDetailsForResource(request, resource); + } } updateAuditDetailsForTask(request, task); task.setRowVersion(task.getRowVersion() + 1); } else { int previousRowVersion = task.getRowVersion(); log.info("enriching task resources for delete"); - task.getResources().stream().filter(TaskResource::getIsDeleted).forEach(resource -> { - updateAuditDetailsForResource(request, resource); - updateAuditDetailsForTask(request, task); - task.setRowVersion(previousRowVersion + 1); - }); + if(!CollectionUtils.isEmpty(task.getResources())) { + task.getResources().stream().filter(TaskResource::getIsDeleted).forEach(resource -> { + updateAuditDetailsForResource(request, resource); + updateAuditDetailsForTask(request, task); + task.setRowVersion(previousRowVersion + 1); + }); + } } } log.info("enrichment done"); @@ -103,6 +107,7 @@ private static void updateAuditDetailsForResource(TaskBulkRequest request, TaskR private static void enrichResourcesForUpdate(TaskBulkRequest request, List tasks) { log.info("enriching resources"); for (Task task : tasks) { + if(CollectionUtils.isEmpty(task.getResources())) continue; List resourcesToCreate = task.getResources().stream() .filter(r -> r.getId() == null).collect(Collectors.toList()); List resourcesToUpdate = task.getResources().stream() diff --git a/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java b/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java index 32e73b66dc9..0252281f736 100644 --- a/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java +++ b/health-services/project/src/main/java/org/egov/project/util/ProjectConstants.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; +import org.egov.common.models.project.TaskStatus; public class ProjectConstants { public static final String MASTER_TENANTS = "tenants"; @@ -25,41 +26,4 @@ public class ProjectConstants { public static final String OR = " OR "; - public enum TaskStatus { - BENEFICIARY_REFUSED("BENEFICIARY_REFUSED"), - BENEFICIARY_REFERRED("BENEFICIARY_REFERRED"), - BENEFICIARY_INELIGIBLE("BENEFICIARY_INELIGIBLE"), - BENEFICIARY_SICK("BENEFICIARY_SICK"), - BENEFICIARY_ABSENT("BENEFICIARY_ABSENT"), - - SPRAYED("SPRAYED"), - REFUSED("REFUSED"), - HOUSE_CLOSED("HOUSE_CLOSED"), - INELIGIBLE("INELIGIBLE"), - RESOLVED("RESOLVED"), - LOCATION_CAPTURE("LOCATION_CAPTURE"), - ADMINISTRATION_FAILED("ADMINISTRATION_FAILED"); - private String value; - - TaskStatus(String value) { - this.value = value; - } - - @Override - @JsonValue - public String toString() { - return String.valueOf(value); - } - - @JsonCreator - public static TaskStatus fromValue(String text) { - for (TaskStatus status : TaskStatus.values()) { - if (String.valueOf(status.value).equals(text)) { - return status; - } - } - return null; - } - } - } \ No newline at end of file diff --git a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java index 167969d09e3..a1c46063bf6 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java @@ -67,10 +67,8 @@ public Map> validate(BeneficiaryBulkRequest requ // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = projectBeneficiaryRepository.findById( - clientReferenceIdList, - getIdFieldName(projectBeneficiarySearch), - Boolean.FALSE).getResponse(); + List existentEntities = + projectBeneficiaryRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java index c3cb60b2b8c..8f3812303f3 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java @@ -67,10 +67,7 @@ public Map> validate(TaskBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = projectTaskRepository.findById( - clientReferenceIdList, - getIdFieldName(taskSearch), - Boolean.FALSE).getResponse(); + List existentEntities = projectTaskRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java index 06368517146..03838764dce 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtIsResouceEmptyValidator.java @@ -1,20 +1,22 @@ package org.egov.project.validator.task; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; import org.egov.common.models.project.Task; import org.egov.common.models.project.TaskBulkRequest; import org.egov.common.validator.Validator; +import org.egov.project.config.ProjectConfiguration; import org.egov.project.util.ProjectConstants; import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.project.util.ProjectConstants.TASK_NOT_ALLOWED; @@ -26,6 +28,13 @@ @Slf4j public class PtIsResouceEmptyValidator implements Validator { + private final ProjectConfiguration projectConfiguration; + + @Autowired + public PtIsResouceEmptyValidator(ProjectConfiguration projectConfiguration) { + this.projectConfiguration = projectConfiguration; + } + /** * Returns all the invalid objects in the request based on the task resources. * @param request of TaskBulkRequest class @@ -36,53 +45,20 @@ public Map> validate(TaskBulkRequest request) { List entities = request.getTasks(); if(!entities.isEmpty()) { entities.forEach(task -> { - if(CollectionUtils.isEmpty(task.getResources()) && - !(ProjectConstants.TaskStatus.BENEFICIARY_REFUSED.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_INELIGIBLE.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_REFERRED.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_SICK.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_ABSENT.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.ADMINISTRATION_FAILED.toString().equals(task.getStatus()) - ) - ) { + if (CollectionUtils.isEmpty(task.getResources()) && + !projectConfiguration.getNoResourceStatuses().contains(task.getStatus().toString())) { /** * If the task resource is empty or null and task status is not BENEFICIARY_REFUSED it is invalid */ + String errorMessage = ProjectConstants.TASK_NOT_ALLOWED_RESOURCE_CANNOT_EMPTY_ERROR_MESSAGE + + String.join(ProjectConstants.OR, projectConfiguration.getNoResourceStatuses()); Error error = Error.builder() - .errorMessage(ProjectConstants.TASK_NOT_ALLOWED_RESOURCE_CANNOT_EMPTY_ERROR_MESSAGE + - ProjectConstants.TaskStatus.BENEFICIARY_REFUSED + - ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_INELIGIBLE + - ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_REFERRED + - ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_SICK + - ProjectConstants.OR + ProjectConstants.TaskStatus.BENEFICIARY_ABSENT + - ProjectConstants.OR + ProjectConstants.TaskStatus.ADMINISTRATION_FAILED - ) - .errorCode(TASK_NOT_ALLOWED) - .type(Error.ErrorType.NON_RECOVERABLE) - .exception(new CustomException(TASK_NOT_ALLOWED, - ProjectConstants.TASK_NOT_ALLOWED_RESOURCE_CANNOT_EMPTY_ERROR_MESSAGE + - ProjectConstants.TaskStatus.BENEFICIARY_REFUSED + - ProjectConstants.OR + - ProjectConstants.TaskStatus.BENEFICIARY_INELIGIBLE + - ProjectConstants.OR + - ProjectConstants.TaskStatus.BENEFICIARY_REFERRED + - ProjectConstants.OR + - ProjectConstants.TaskStatus.BENEFICIARY_SICK + - ProjectConstants.OR + - ProjectConstants.TaskStatus.BENEFICIARY_ABSENT + - ProjectConstants.OR + - ProjectConstants.TaskStatus.ADMINISTRATION_FAILED - )).build(); + .errorMessage(errorMessage) + .errorCode(TASK_NOT_ALLOWED) + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException(TASK_NOT_ALLOWED, errorMessage)).build(); populateErrorDetails(task, error, errorDetailsMap); - } else if (!CollectionUtils.isEmpty(task.getResources()) && - (ProjectConstants.TaskStatus.BENEFICIARY_REFUSED.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_INELIGIBLE.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_REFERRED.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_SICK.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.BENEFICIARY_ABSENT.toString().equals(task.getStatus()) - || ProjectConstants.TaskStatus.ADMINISTRATION_FAILED.toString().equals(task.getStatus()) - ) - ) { + } else if (!CollectionUtils.isEmpty(task.getResources()) && projectConfiguration.getNoResourceStatuses().contains(task.getStatus().toString())) { /** * If the task resource is not empty and task status is BENEFICIARY_REFUSED */ diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtNonExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtNonExistentEntityValidator.java index 52b577acdbe..5a1ceaa0b3b 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtNonExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtNonExistentEntityValidator.java @@ -88,10 +88,10 @@ public Map> validate(TaskBulkRequest request) { }); existingEntities.forEach(task -> { - validateSubEntity(errorDetailsMap, eMap, task, + if(task.getAddress() != null) validateSubEntity(errorDetailsMap, eMap, task, Collections.singletonList(task.getAddress()), GET_ADDRESS); - validateSubEntity(errorDetailsMap, eMap, task, + if(task.getResources() != null) validateSubEntity(errorDetailsMap, eMap, task, task.getResources(), GET_RESOURCES); }); } @@ -106,10 +106,10 @@ private void validateSubEntity(Map> errorDetailsMap, String getSubEntityMethodName) { Object objFromReq = ReflectionUtils.invokeMethod(getMethod(getSubEntityMethodName, Task.class), eMap.get(entity.getId())); - List subEntitiesInReq; + List subEntitiesInReq = null; if (objFromReq instanceof List) { subEntitiesInReq = (List) objFromReq; - } else { + } else if(objFromReq != null) { // if else condition here is added to prevent creating a list of null values, and if objFromReq is null then it will bypass line 116 till end of function. subEntitiesInReq = (List) Collections.singletonList(objFromReq); } 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 94b2aaea221..e3be161fabb 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 @@ -26,6 +26,7 @@ import org.egov.tracer.model.CustomException; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import static org.egov.project.Constants.INTERNAL_SERVER_ERROR; import static org.egov.project.Constants.MDMS_RESPONSE; @@ -76,10 +77,12 @@ public Map> validate(TaskBulkRequest request) { List errors = new ArrayList<>(); // Extract the list of task resources List taskResources = task.getResources(); - for(TaskResource taskResource : taskResources){ - Error error = validateResourceQuantity(taskResource, request.getRequestInfo()); - if(error != null){ - errors.add(error); + if(!CollectionUtils.isEmpty(taskResources)) { + for(TaskResource taskResource : taskResources){ + Error error = validateResourceQuantity(taskResource, request.getRequestInfo()); + if(error != null){ + errors.add(error); + } } } if (!errors.isEmpty()){ diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java index 60c6115d7d7..a75315ce081 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java @@ -61,10 +61,7 @@ public Map> validate(UserActionBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = userActionRepository.findById( - clientReferenceIdList, - getIdFieldName(userActionSearch) - ).getResponse(); + List existentEntities = userActionRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java deleted file mode 100644 index 3341d1d99eb..00000000000 --- a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaStatusValidator.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.egov.project.validator.useraction; - -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.StringUtils; -import org.egov.common.models.Error; -import org.egov.common.models.core.Field; -import org.egov.common.models.project.useraction.UserAction; -import org.egov.common.models.project.useraction.UserActionBulkRequest; -import org.egov.common.validator.Validator; -import org.egov.project.util.ProjectConstants; -import org.egov.tracer.model.CustomException; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import static org.egov.common.utils.CommonUtils.populateErrorDetails; -import static org.egov.project.Constants.HOUSEHOLD_ID; - -/** - * UaStatusValidator is responsible for validating the status of UserAction entities within a UserActionBulkRequest. - * Specifically, it ensures that UserActions with a status of 'RESOLVED' have a non-empty 'HouseholdId' field - * in their additional details. - */ -@Component -@Order(value = 3) -@Slf4j -public class UaStatusValidator implements Validator { - - /** - * Validates the UserAction entities within a UserActionBulkRequest based on their status and additional fields. - * It checks UserActions with a status of 'RESOLVED' to ensure that the 'HouseholdId' field - * in the additional details is present and has a non-empty value. - * - * @param request The UserActionBulkRequest object containing the list of UserActions to be validated. - * @return A map where each key is a UserAction that failed validation, and each value is a list of Error objects - * associated with that UserAction. - */ - @Override - public Map> validate(UserActionBulkRequest request) { - log.info("Starting validation of UserActions with status 'RESOLVED' in UserActionBulkRequest with {} entities", request.getUserActions().size()); - - // Initialize a map to store UserActions with validation errors and corresponding error details - Map> errorDetailsMap = new HashMap<>(); - - // Stream through the list of UserActions and filter out those that have status 'RESOLVED' but - // do not meet the criteria of having a non-empty 'HouseholdId' field. - List invalidEntities = request.getUserActions().stream() - .filter(userAction -> ProjectConstants.TaskStatus.RESOLVED.toString().equals(userAction.getStatus())) - .filter(userAction -> !validateResolvedStatus(userAction.getAdditionalFields().getFields())) - .collect(Collectors.toList()); - - log.info("Identified {} invalid UserActions with status 'RESOLVED' and missing 'HouseholdId'", invalidEntities.size()); - - // If there are any invalid UserActions, create error details and populate them in the map - if (!CollectionUtils.isEmpty(invalidEntities)) { - invalidEntities.forEach(userAction -> { - log.debug("Populating error details for UserAction with ID: {}", userAction.getId()); - - // Create an Error object with details about the missing 'HouseholdId' - Error error = Error.builder() - .errorMessage(HOUSEHOLD_ID + " is not present in AdditionalDetails of object.") - .errorCode("PROJECT_USER_ACTION_MISSING_HOUSEHOLD_ID") - .type(Error.ErrorType.NON_RECOVERABLE) - .exception(new CustomException("PROJECT_USER_ACTION_MISSING_HOUSEHOLD_ID", HOUSEHOLD_ID + " is not present in AdditionalDetails of userAction with ID: " + userAction.getId())) - .build(); - - // Populate the error details map with the UserAction and the created error - populateErrorDetails(userAction, error, errorDetailsMap); - }); - } - - log.info("Completed validation of UserActions with status 'RESOLVED'"); - return errorDetailsMap; - } - - /** - * Checks if the 'HouseholdId' field is present and correctly set in the list of additional fields. - * - * @param fields The list of additional fields associated with a UserAction. - * @return true if the 'HouseholdId' field is present and non-empty; false otherwise. - */ - private boolean validateResolvedStatus(List fields) { - log.debug("Validating additional fields for 'HouseholdId' presence and non-empty value"); - - // Stream through the list of fields to find one with the key 'HouseholdId' - boolean isValid = fields.stream() - .filter(field -> field.getKey().equals(HOUSEHOLD_ID)) - // Check if the value for this field is non-empty - .anyMatch(field -> !StringUtils.isEmpty(field.getValue())); - - log.debug("'HouseholdId' validation result: {}", isValid); - return isValid; - } -} diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index c9fc8ec680a..779e76f3e99 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -175,5 +175,8 @@ project.user.action.consumer.bulk.create.topic=save-user-action-project-bulk-top project.user.action.consumer.bulk.update.topic=update-user-action-project-bulk-topic #-------Location Capture Task-------# -project.location.capture.task.kafka.create.topic=save-location-capture-project-topic -project.location.capture.task.consumer.bulk.create.topic=save-location-capture-project-bulk-topic +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 diff --git a/health-services/project/src/test/java/org/egov/project/helper/TaskTestBuilder.java b/health-services/project/src/test/java/org/egov/project/helper/TaskTestBuilder.java index ddda5a11de5..453e3be4d11 100644 --- a/health-services/project/src/test/java/org/egov/project/helper/TaskTestBuilder.java +++ b/health-services/project/src/test/java/org/egov/project/helper/TaskTestBuilder.java @@ -1,10 +1,11 @@ package org.egov.project.helper; +import java.util.Arrays; + import org.egov.common.helper.AuditDetailsTestBuilder; import org.egov.common.models.project.Task; import org.egov.common.models.project.TaskResource; - -import java.util.Arrays; +import org.egov.common.models.project.TaskStatus; public class TaskTestBuilder { @@ -31,7 +32,8 @@ public TaskTestBuilder withTask() { TaskResource.builder().tenantId("default").isDelivered(false) .quantity(100.0).productVariantId("v101").build())) .projectId("some-id").createdBy("some-id") - .createdDate(100L).status("status") + .createdDate(100L) + .status(TaskStatus.DELIVERED) .isDeleted(false).projectBeneficiaryId("some-id") .rowVersion(0) .hasErrors(Boolean.FALSE) diff --git a/health-services/referralmanagement/pom.xml b/health-services/referralmanagement/pom.xml index 915072c78a1..06abfeaa971 100644 --- a/health-services/referralmanagement/pom.xml +++ b/health-services/referralmanagement/pom.xml @@ -46,7 +46,7 @@ org.egov.common health-services-common - 1.0.17-SNAPSHOT + 1.0.17-dev-SNAPSHOT org.egov.common diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/ReferralManagementService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/ReferralManagementService.java index b14512d7551..38973d34e3c 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/ReferralManagementService.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/ReferralManagementService.java @@ -66,8 +66,7 @@ public class ReferralManagementService { || validator.getClass().equals(RmExistentEntityValidator.class) || validator.getClass().equals(RmReferrerIdValidator.class) || validator.getClass().equals(RmRecipientIdValidator.class) - || validator.getClass().equals(RmSideEffectIdValidator.class) - || validator.getClass().equals(RmRowVersionValidator.class); + || validator.getClass().equals(RmSideEffectIdValidator.class); private final Predicate> isApplicableForUpdate = validator -> validator.getClass().equals(RmProjectBeneficiaryIdValidator.class) @@ -82,7 +81,8 @@ public class ReferralManagementService { private final Predicate> isApplicableForDelete = validator -> validator.getClass().equals(RmNullIdValidator.class) - || validator.getClass().equals(RmNonExistentEntityValidator.class); + || validator.getClass().equals(RmNonExistentEntityValidator.class) + || validator.getClass().equals(RmRowVersionValidator.class); public ReferralManagementService(IdGenService idGenService, ReferralRepository referralRepository, ReferralManagementConfiguration referralManagementConfiguration, ReferralManagementEnrichmentService referralManagementEnrichmentService, List> validators) { diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java index 8725344af7d..8de1be52d8d 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java @@ -66,10 +66,7 @@ public Map> validate(ReferralBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = referralRepository.findById( - clientReferenceIdList, - getIdFieldName(referralSearch), - Boolean.FALSE).getResponse(); + List existentEntities = referralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java index 33e3e750911..7d670403a93 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java @@ -67,11 +67,7 @@ public Map> validate(HFReferralBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = hfReferralRepository.findById( - clientReferenceIdList, - Boolean.FALSE, - getIdFieldName(hfReferralSearch) - ); + List existentEntities = hfReferralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java index 9ed78e8db17..9f427614e89 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java @@ -67,10 +67,8 @@ public Map> validate(SideEffectBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = sideEffectRepository.findById( - clientReferenceIdList, - getIdFieldName(sideEffectSearch), - Boolean.FALSE); + List existentEntities = + sideEffectRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/stock/pom.xml b/health-services/stock/pom.xml index fcceea2e322..49c0615b5f0 100644 --- a/health-services/stock/pom.xml +++ b/health-services/stock/pom.xml @@ -45,7 +45,7 @@ org.egov.common health-services-common - 1.0.17-SNAPSHOT + 1.0.17-dev-SNAPSHOT org.egov.common diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java index 7ad90579428..e7f25737b27 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java @@ -67,11 +67,7 @@ public Map> validate(StockBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = stockRepository.findById( - clientReferenceIdList, - Boolean.FALSE, - getIdFieldName(stockSearch) - ); + List existentEntities = stockRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java index e7c0ec35d16..d8afed3f9a9 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java @@ -67,11 +67,8 @@ public Map> validate(StockReconciliationBulkReq // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = stockReconciliationRepository.findById( - clientReferenceIdList, - Boolean.FALSE, - getIdFieldName(stockReconciliationSearch) - ); + List existentEntities = + stockReconciliationRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness existentEntities.forEach(entity -> { Error error = getErrorForUniqueEntity(); From 852e041217a701401660b0cfa368fe07160ea5c8 Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:09:42 +0530 Subject: [PATCH 03/20] HLM rowmapper issue in household, referral fixed (#848) * HLM rowmapper issue in household, referral fixed * HCMPRE-255: updated the changes for household * reverted local changes commit by mistake --- .../member/validators/HmExistentEntityValidator.java | 11 +++++++---- .../household/HExistentEntityValidator.java | 11 ++++++++--- .../validators/IExistentEntityValidator.java | 10 +++++++--- .../common/data/repository/GenericRepository.java | 9 ++++----- .../beneficiary/PbExistentEntityValidator.java | 11 ++++++++--- .../validator/task/PtExistentEntityValidator.java | 11 ++++++++--- .../useraction/UaExistentEntityValidator.java | 11 ++++++++--- .../validator/RmExistentEntityValidator.java | 11 ++++++++--- .../hfreferral/HfrExistentEntityValidator.java | 11 ++++++++--- .../sideeffect/SeExistentEntityValidator.java | 11 ++++++++--- .../validator/stock/SExistentEntityValidator.java | 11 ++++++++--- .../SrExistentEntityValidator.java | 11 ++++++++--- 12 files changed, 90 insertions(+), 39 deletions(-) diff --git a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java index e9aa42116e0..8360bbf1eb8 100644 --- a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java @@ -15,8 +15,8 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; @@ -64,15 +64,18 @@ public Map> validate(HouseholdMemberBulkRequest req HouseholdMemberSearch householdSearch = HouseholdMemberSearch.builder() .clientReferenceId(clientReferenceIdList) .build(); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = + List existingClientReferenceIds = householdMemberRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java index cad34c44206..9c07be651ad 100644 --- a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java @@ -10,11 +10,13 @@ import org.egov.common.models.household.Household; import org.egov.common.models.household.HouseholdBulkRequest; import org.egov.common.models.household.HouseholdSearch; +import org.egov.common.models.individual.Individual; import org.egov.common.validator.Validator; import org.egov.household.repository.HouseholdRepository; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -59,6 +61,9 @@ public Map> validate(HouseholdBulkRequest request) { .filter(notHavingErrors()) .map(Household::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs HouseholdSearch householdSearch = HouseholdSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -66,11 +71,11 @@ public Map> validate(HouseholdBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = householdRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = householdRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java index 82a332600a4..ec4f2db3b6b 100644 --- a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java +++ b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java @@ -15,6 +15,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -59,6 +60,9 @@ public Map> validate(IndividualBulkRequest request) { .filter(notHavingErrors()) .map(Individual::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs IndividualSearch individualSearch = IndividualSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -66,12 +70,12 @@ public Map> validate(IndividualBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = + List existingClientReferenceIds = individualRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; 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 829603c599a..c941a2cbc37 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 @@ -292,15 +292,14 @@ public List validateIds(List idsToValidate, String columnName){ .collect(Collectors.toList()); } - public List validateClientReferenceIdsFromDB(List clientReferenceIds) { - List objFound = new ArrayList<>(); + public List validateClientReferenceIdsFromDB(List clientReferenceIds) { + List objFound = new ArrayList<>(); - String query = String.format("SELECT * FROM %s WHERE clientReferenceId IN (:ids) AND isDeleted = false", tableName); + String query = String.format("SELECT clientReferenceId FROM %s WHERE clientReferenceId IN (:ids) AND isDeleted = false", tableName); Map paramMap = new HashMap<>(); paramMap.put("ids", clientReferenceIds); - objFound.addAll(namedParameterJdbcTemplate.query(query, paramMap, rowMapper)); - putInCache(objFound); + objFound.addAll(namedParameterJdbcTemplate.queryForList(query, paramMap, String.class)); return objFound; } diff --git a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java index a1c46063bf6..e5fb8e579b8 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.project.BeneficiaryBulkRequest; import org.egov.common.models.project.ProjectBeneficiary; import org.egov.common.models.project.ProjectBeneficiarySearch; @@ -15,6 +16,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -64,15 +66,18 @@ public Map> validate(BeneficiaryBulkRequest requ ProjectBeneficiarySearch projectBeneficiarySearch = ProjectBeneficiarySearch.builder() .clientReferenceId(clientReferenceIdList) .build(); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = + List existingClientReferenceIds = projectBeneficiaryRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java index 8f3812303f3..b811627fcd4 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.project.Task; import org.egov.common.models.project.TaskBulkRequest; import org.egov.common.models.project.TaskSearch; @@ -15,6 +16,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -60,6 +62,9 @@ public Map> validate(TaskBulkRequest request) { .filter(notHavingErrors()) .map(Task::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs TaskSearch taskSearch = TaskSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -67,11 +72,11 @@ public Map> validate(TaskBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = projectTaskRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = projectTaskRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java index a75315ce081..09d8d575d83 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.project.useraction.UserAction; import org.egov.common.models.project.useraction.UserActionBulkRequest; import org.egov.common.models.project.useraction.UserActionSearch; @@ -16,6 +17,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -54,6 +56,9 @@ public Map> validate(UserActionBulkRequest request) { .filter(notHavingErrors()) .map(UserAction::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs UserActionSearch userActionSearch = UserActionSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -61,11 +66,11 @@ public Map> validate(UserActionBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = userActionRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = userActionRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java index 8de1be52d8d..c48bf3265d8 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.referralmanagement.Referral; import org.egov.common.models.referralmanagement.ReferralBulkRequest; import org.egov.common.models.referralmanagement.ReferralSearch; @@ -15,6 +16,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -59,6 +61,9 @@ public Map> validate(ReferralBulkRequest request) { .filter(notHavingErrors()) .map(Referral::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs ReferralSearch referralSearch = ReferralSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -66,11 +71,11 @@ public Map> validate(ReferralBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = referralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = referralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java index 7d670403a93..1608d67315d 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.referralmanagement.hfreferral.HFReferral; import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; import org.egov.common.models.referralmanagement.hfreferral.HFReferralSearch; @@ -15,6 +16,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -60,6 +62,9 @@ public Map> validate(HFReferralBulkRequest request) { .filter(notHavingErrors()) .map(HFReferral::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs HFReferralSearch hfReferralSearch = HFReferralSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -67,11 +72,11 @@ public Map> validate(HFReferralBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = hfReferralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = hfReferralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java index 9f427614e89..059dba86be4 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.referralmanagement.sideeffect.SideEffect; import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; import org.egov.common.models.referralmanagement.sideeffect.SideEffectSearch; @@ -15,6 +16,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -64,15 +66,18 @@ public Map> validate(SideEffectBulkRequest request) { SideEffectSearch sideEffectSearch = SideEffectSearch.builder() .clientReferenceId(clientReferenceIdList) .build(); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = + List existingClientReferenceIds = sideEffectRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java index e7f25737b27..176bfa80ff0 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockBulkRequest; import org.egov.common.models.stock.StockSearch; @@ -15,6 +16,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -60,6 +62,9 @@ public Map> validate(StockBulkRequest request) { .filter(notHavingErrors()) .map(Stock::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs StockSearch stockSearch = StockSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -67,11 +72,11 @@ public Map> validate(StockBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = stockRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = stockRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java index d8afed3f9a9..2aa3dcf0d98 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.individual.Individual; import org.egov.common.models.stock.StockReconciliation; import org.egov.common.models.stock.StockReconciliationBulkRequest; import org.egov.common.models.stock.StockReconciliationSearch; @@ -15,6 +16,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; @@ -60,6 +62,9 @@ public Map> validate(StockReconciliationBulkReq .filter(notHavingErrors()) .map(StockReconciliation::getClientReferenceId) .collect(Collectors.toList()); + Map map = entities.stream() + .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Create a search object for querying entities by client reference IDs StockReconciliationSearch stockReconciliationSearch = StockReconciliationSearch.builder() .clientReferenceId(clientReferenceIdList) @@ -67,12 +72,12 @@ public Map> validate(StockReconciliationBulkReq // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existentEntities = + List existingClientReferenceIds = stockReconciliationRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); // For each existing entity, populate error details for uniqueness - existentEntities.forEach(entity -> { + existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); - populateErrorDetails(entity, error, errorDetailsMap); + populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } return errorDetailsMap; From b41383e5af6cd932ebe95fe6dc20fa86bea9e61c Mon Sep 17 00:00:00 2001 From: nitish-egov <137176807+nitish-egov@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:28:38 +0530 Subject: [PATCH 04/20] added logic for cascading project date updates (#834) * added logic for cascading project date updates * updated application.properties * refactored logic for using ProjectRequest pojo to send message to kafka instead of Ancestor and Descendant Projects pojo * added comments and enhanced search project logic * made public back to private * made more concise the method in project service separated create project map logic * separated concerns of update based on action whether null or updateProjectDates * updated action logic for just test purpose * updated version of health-service-models library * update logic * updated final logic for cascading update project dates based on flag in project request * reverted config * reverted config 2 * added multiple line comments * udpated error messages --- .../libraries/health-services-models/pom.xml | 2 +- .../common/models/project/ProjectRequest.java | 4 + health-services/project/pom.xml | 2 +- .../project/config/ProjectConfiguration.java | 3 + .../egov/project/service/ProjectService.java | 204 ++++++++++++++++-- .../service/enrichment/ProjectEnrichment.java | 188 +++++++++++++++- .../egov/project/util/ProjectServiceUtil.java | 62 ++++++ .../src/main/resources/application.properties | 1 + 8 files changed, 441 insertions(+), 25 deletions(-) diff --git a/health-services/libraries/health-services-models/pom.xml b/health-services/libraries/health-services-models/pom.xml index f0bef369759..d0d38bea5d3 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.20-dev-SNAPSHOT + 1.0.21-dev-SNAPSHOT 17 ${java.version} 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 fd09b6b635b..da4ae0343e4 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 @@ -38,6 +38,10 @@ public class ProjectRequest { @Size(min=1) private List projects = new ArrayList<>(); + @JsonProperty("isCascadingProjectDateUpdate") + @Valid + private boolean isCascadingProjectDateUpdate = false; + @JsonProperty("apiOperation") @Valid private ApiOperation apiOperation = null; diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml index ccd901f62ed..e957915b1dc 100644 --- a/health-services/project/pom.xml +++ b/health-services/project/pom.xml @@ -50,7 +50,7 @@ org.egov.common health-services-models - 1.0.20-dev-SNAPSHOT + 1.0.21-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 87863679a07..26759e381e2 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 @@ -191,6 +191,9 @@ public class ProjectConfiguration { @Value("${project.staff.attendance.topic}") private String projectStaffAttendanceTopic; + @Value("${project.management.system.kafka.update.date.topic}") + private String updateProjectDateTopic; + // closed household task @Value("${project.user.action.kafka.create.topic}") 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 f0dd5a2645b..56e2665792a 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,6 +1,9 @@ package org.egov.project.service; +import com.fasterxml.jackson.databind.ObjectMapper; +import digit.models.coremodels.AuditDetails; import jakarta.validation.Valid; +import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.egov.common.contract.request.RequestInfo; @@ -12,7 +15,9 @@ import org.egov.project.config.ProjectConfiguration; import org.egov.project.repository.ProjectRepository; import org.egov.project.service.enrichment.ProjectEnrichment; +import org.egov.project.util.ProjectServiceUtil; import org.egov.project.validator.project.ProjectValidator; +import org.egov.tracer.model.CustomException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -24,6 +29,7 @@ @Slf4j public class ProjectService { + private final ProjectRepository projectRepository; private final ProjectValidator projectValidator; @@ -34,15 +40,21 @@ public class ProjectService { private final Producer producer; + private final ProjectServiceUtil projectServiceUtil; + + private final ObjectMapper objectMapper; + @Autowired public ProjectService( ProjectRepository projectRepository, - ProjectValidator projectValidator, ProjectEnrichment projectEnrichment, ProjectConfiguration projectConfiguration, Producer producer) { + ProjectValidator projectValidator, ProjectEnrichment projectEnrichment, ProjectConfiguration projectConfiguration, Producer producer,ProjectServiceUtil projectServiceUtil) { this.projectRepository = projectRepository; this.projectValidator = projectValidator; this.projectEnrichment = projectEnrichment; this.projectConfiguration = projectConfiguration; this.producer = producer; + this.projectServiceUtil = projectServiceUtil; + this.objectMapper = new ObjectMapper(); } public List validateProjectIds(List productIds) { @@ -100,22 +112,190 @@ public List searchProject(ProjectSearchRequest projectSearchRequest, @V return projectRepository.getProjects(projectSearchRequest.getProject(), urlParams); } - public ProjectRequest updateProject(ProjectRequest project) { - projectValidator.validateUpdateProjectRequest(project); + public ProjectRequest updateProject(ProjectRequest request) { + /* + * Validate the update project request + */ + projectValidator.validateUpdateProjectRequest(request); log.info("Update project request validated"); - //Search projects based on project ids - List projectsFromDB = searchProject(getSearchProjectRequest(project.getProjects(), project.getRequestInfo(), false), projectConfiguration.getMaxLimit(), projectConfiguration.getDefaultOffset(), project.getProjects().get(0).getTenantId(), null, false, false, false, null, null); + + /* + * Search for projects based on project IDs provided in the request + */ + List projectsFromDB = searchProject( + getSearchProjectRequest(request.getProjects(), request.getRequestInfo(), false), + projectConfiguration.getMaxLimit(), projectConfiguration.getDefaultOffset(), + request.getProjects().get(0).getTenantId(), null, false, false, false, null, null + ); log.info("Fetched projects for update request"); - //Validate Update project request against projects fetched form database - projectValidator.validateUpdateAgainstDB(project.getProjects(), projectsFromDB); - projectEnrichment.enrichProjectOnUpdate(project, projectsFromDB); - log.info("Enriched with project Number, Ids and AuditDetails"); - producer.push(projectConfiguration.getUpdateProjectTopic(), project); - log.info("Pushed to kafka"); - return project; + /* + * Validate the update project request against the projects fetched from the database + */ + projectValidator.validateUpdateAgainstDB(request.getProjects(), projectsFromDB); + + /* + * Process each project in the update request + */ + for (Project project : request.getProjects()) { + processProjectUpdate(request, project, projectsFromDB); + } + + return request; } + private void processProjectUpdate(ProjectRequest request, Project project, List projectsFromDB) { + /* + * Convert project ID to string for comparison + */ + String projectId = String.valueOf(project.getId()); + + /* + * Find the project from the database that matches the current project ID + */ + Project projectFromDB = findProjectById(projectId, projectsFromDB); + boolean isCascadingProjectDateUpdate = request.isCascadingProjectDateUpdate(); + + if (projectFromDB != null) { + /* + * Merge additional details of the project from the request and project from DB + */ + projectServiceUtil.mergeAdditionalDetails(project, projectFromDB); + + /* + * Handle cases where cascading project date update is true + */ + if (isCascadingProjectDateUpdate) { + handleUpdateProjectDates(request, project, projectFromDB); + } + /* + * Handle cases for normal update flow + */ + else { + handleNormalUpdate(request, project, projectFromDB); + } + } + } + + private Project findProjectById(String projectId, List projectsFromDB) { + /* + * Find and return the project with the matching ID from the list of projects fetched from the database + */ + return projectsFromDB.stream() + .filter(p -> projectId.equals(String.valueOf(p.getId()))) + .findFirst() + .orElse(null); + } + + + private void handleNormalUpdate(ProjectRequest request, Project project, Project projectFromDB) { + /* + * Ensure that start and end dates are not being updated when flag is false + */ + if (!project.getStartDate().equals(projectFromDB.getStartDate()) || + !project.getEndDate().equals(projectFromDB.getEndDate())) { + throw new CustomException("PROJECT_CASCADE_UPDATE_DATE_ERROR", + "Can't Update Date Range if Cascade Project Date Update false"); + } + + /* + * Enrich the project with values other than the start, end dates, and AdditionalDetails, + * and push the update to the message broker + */ + projectEnrichment.enrichProjectOnUpdate(request, project, projectFromDB); + producer.push(projectConfiguration.getUpdateProjectTopic(), request); + } + + private void handleUpdateProjectDates(ProjectRequest request, Project project, Project projectFromDB) { + /* + * Save original values of start date, end date, and additional details + */ + Long originalStartDate = projectFromDB.getStartDate(); + Long originalEndDate = projectFromDB.getEndDate(); + Object originalAdditionalDetails = projectFromDB.getAdditionalDetails(); + AuditDetails originalAuditDetails = projectFromDB.getAuditDetails(); + + + /* + * Update the project with new start date, end date, and additional details + */ + projectFromDB.setStartDate(project.getStartDate()); + projectFromDB.setEndDate(project.getEndDate()); + projectFromDB.setAdditionalDetails(project.getAdditionalDetails()); + projectFromDB.setAuditDetails(project.getAuditDetails()); + + /* + * Ensure that no other properties are being updated besides the start and end dates + */ + if (!objectMapper.valueToTree(projectFromDB).equals(objectMapper.valueToTree(project))) { + throw new CustomException( + "PROJECT_CASCADE_UPDATE_ERROR", + "Can only update Project dates and additional details if cascade Project date update true" + ); + } + + /* + * Restore original values of start date, end date, and additional details + */ + projectFromDB.setStartDate(originalStartDate); + projectFromDB.setEndDate(originalEndDate); + projectFromDB.setAdditionalDetails(originalAdditionalDetails); + projectFromDB.setAuditDetails(originalAuditDetails); + + /* + * Update lastModifiedTime and lastModifiedBy for the project + */ + projectEnrichment.enrichProjectRequestOnUpdate(project, projectFromDB, request.getRequestInfo()); + + /* + * Check and enrich cascading project dates and push the update to the message broker + */ + checkAndEnrichCascadingProjectDates(request, project); + producer.push(projectConfiguration.getUpdateProjectDateTopic(), request); + } + + + /** + * Checks and enriches cascading project dates. + * + * @param request The project request containing projects and request information. + */ + private void checkAndEnrichCascadingProjectDates(ProjectRequest request, Project project) { + /* + * Retrieve tenant ID from the first project in the request + */ + String tenantId = request.getProjects().get(0).getTenantId(); + String projectId = String.valueOf(project.getId()); + + /* + * Fetch projects from the database with ancestors and descendants + */ + List projectsFromDbWithAncestorsAndDescendants = searchProject( + getSearchProjectRequest(request.getProjects(), request.getRequestInfo(), false), + projectConfiguration.getMaxLimit(), + projectConfiguration.getDefaultOffset(), + tenantId, + null, + false, + true, + true, + null, + null + ); + + /* + * Create a map of projects from the database with ancestors and descendants + */ + Map projectFromDbWithAncestorsAndDescendantsMap = projectServiceUtil.createProjectMap(projectsFromDbWithAncestorsAndDescendants); + Project projectFromDbWithAncestorsAndDescendants = projectFromDbWithAncestorsAndDescendantsMap.get(projectId); + + /* + * Enrich project cascading dates based on the retrieved data + */ + projectEnrichment.enrichProjectCascadingDatesOnUpdate(project, projectFromDbWithAncestorsAndDescendants); + } + + /* Search for parent projects based on "parent" field and returns parent projects */ private List getParentProjects(ProjectRequest projectRequest) { List parentProjects = null; 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 6bea9a663b5..2bd670f589f 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 @@ -1,6 +1,12 @@ package org.egov.project.service.enrichment; +import com.fasterxml.jackson.core.type.TypeReference; +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 java.util.Map; +import java.util.ArrayList; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -9,8 +15,10 @@ import org.egov.common.models.project.Project; import org.egov.common.models.project.ProjectRequest; import org.egov.common.models.project.Target; +import org.egov.common.producer.Producer; import org.egov.common.service.IdGenService; import org.egov.project.config.ProjectConfiguration; +import org.egov.project.service.ProjectService; import org.egov.project.util.ProjectServiceUtil; import org.egov.tracer.model.CustomException; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +38,11 @@ public class ProjectEnrichment { @Autowired private ProjectServiceUtil projectServiceUtil; + @Autowired + private Producer producer; + @Autowired + private ProjectConfiguration projectConfiguration; + @Autowired private IdGenService idGenService; @@ -78,15 +91,8 @@ public void enrichProjectOnCreate(ProjectRequest request, List parentPr } /* Enrich Project on Update Request */ - public void enrichProjectOnUpdate(ProjectRequest request, List projectsFromDB) { + public void enrichProjectOnUpdate(ProjectRequest request, Project project , Project projectFromDB) { RequestInfo requestInfo = request.getRequestInfo(); - List projectsFromRequest = request.getProjects(); - - for (Project project : projectsFromRequest) { - String projectId = String.valueOf(project.getId()); - Project projectFromDB = projectsFromDB.stream().filter(p -> projectId.equals(String.valueOf(p.getId()))).findFirst().orElse(null); - - if (projectFromDB != null) { //Updating lastModifiedTime and lastModifiedBy for Project enrichProjectRequestOnUpdate(project, projectFromDB, requestInfo); log.info("Enriched project in update project request"); @@ -102,8 +108,6 @@ public void enrichProjectOnUpdate(ProjectRequest request, List projects //Add new document if id is empty or update lastModifiedTime and lastModifiedBy if id exists enrichProjectDocumentOnUpdate(project, projectFromDB, requestInfo); log.info("Enriched document in update project request"); - } - } } /* Enrich Project with id and audit details */ @@ -118,12 +122,174 @@ private void enrichProjectRequestOnCreate(Project projectRequest, RequestInfo re } /* Enrich Project update request with last modified by and last modified time */ - private void enrichProjectRequestOnUpdate(Project projectRequest, Project projectFromDB, RequestInfo requestInfo) { + public void enrichProjectRequestOnUpdate(Project projectRequest, Project projectFromDB, RequestInfo requestInfo) { projectRequest.setAuditDetails(projectFromDB.getAuditDetails()); AuditDetails auditDetails = projectServiceUtil.getAuditDetails(requestInfo.getUserInfo().getUuid(), projectFromDB.getAuditDetails(), false); projectRequest.setAuditDetails(auditDetails); log.info("Enriched project audit details for project " + projectRequest.getId()); } + public void enrichProjectCascadingDatesOnUpdate(Project project, Project projectFromDB) + { + // enrich project start and end dates along with ancestors and descendants + enrichProjectStartAndEndDateOfBothAncestorsAndDescendantsIfFoundAccordingly(project, + projectFromDB); + } + + private void enrichProjectStartAndEndDateOfBothAncestorsAndDescendantsIfFoundAccordingly( + Project projectRequest, Project projectFromDB) { + long startDate = projectRequest.getStartDate(); + long endDate = projectRequest.getEndDate(); + + /* + * Update both cycle dates and project start and end dates of descendants + */ + updateProjects(projectRequest, projectFromDB, startDate, endDate, true); + + /* + * Update both cycle dates and project start and end dates of ancestors in a way like start date = min(current, existing) + * and end date = max(current, existing) + */ + updateProjects(projectRequest, projectFromDB, startDate, endDate, false); + } + + + private void updateProjects(Project projectRequest, Project projectFromDB, long startDate, long endDate, boolean isDescendant) { + /* + * Get the list of projects from the database that are either descendants or ancestors + */ + List projectsFromDb = isDescendant ? projectFromDB.getDescendants() : projectFromDB.getAncestors(); + List modifiedProjectsFromDb = new ArrayList<>(); + + if (projectsFromDb != null) { + for (Project project : projectsFromDb) { + /* + * Update the project dates based on whether it is a descendant or ancestor + */ + updateProjectDates(project, startDate, endDate, isDescendant); + + /* + * Update the project cycles based on the request and whether it is a descendant or ancestor + */ + updateCycles(project, projectRequest, isDescendant); + + /* + * Add the modified project to the list + */ + modifiedProjectsFromDb.add(project); + } + + /* + * Push the modified projects to Kafka + */ + pushProjectsToKafka(modifiedProjectsFromDb); + } + } + + private void updateProjectDates(Project project, long startDate, long endDate, boolean isDescendant) { + if (isDescendant) { + /* + * For descendant projects, directly set the start and end dates + */ + project.setStartDate(startDate); + project.setEndDate(endDate); + } else { + /* + * For ancestor projects, set the start date to the minimum of the current and existing start dates, + * and set the end date to the maximum of the current and existing end dates + */ + project.setStartDate(Math.min(startDate, project.getStartDate())); + project.setEndDate(Math.max(endDate, project.getEndDate())); + } + } + + + private void updateCycles(Project descendantOrAncestor, Project projectRequest, boolean isDescendant) { + if (descendantOrAncestor.getAdditionalDetails() == null) { + return; + } + + ObjectMapper objectMapper = new ObjectMapper(); + + /* + * Extract additional details from descendant and request projects + */ + JsonNode descendantOrAncestorAdditionalDetails = objectMapper.valueToTree( + descendantOrAncestor.getAdditionalDetails()); + JsonNode descendantOrAncestorProjectTypeNode = descendantOrAncestorAdditionalDetails.get("projectType"); + + if (descendantOrAncestorProjectTypeNode != null) { + JsonNode descendantOrAncestorCyclesNode = descendantOrAncestorProjectTypeNode.get("cycles"); + + if (descendantOrAncestorCyclesNode != null && descendantOrAncestorCyclesNode.isArray()) { + /* + * Extract cycles from the request project + */ + JsonNode requestAdditionalDetails = objectMapper.valueToTree( + projectRequest.getAdditionalDetails()); + JsonNode requestProjectTypeNode = requestAdditionalDetails.get("projectType"); + + if (requestProjectTypeNode != null) { + JsonNode requestCyclesNode = requestProjectTypeNode.get("cycles"); + + if (requestCyclesNode != null && requestCyclesNode.isArray()) { + /* + * Iterate over descendant cycles and update as necessary + */ + for (JsonNode descendantOrAncestorCycleNode : descendantOrAncestorCyclesNode) { + String descendantOrAncestorCycleId = descendantOrAncestorCycleNode.get("id").asText(); + + for (JsonNode requestCycleNode : requestCyclesNode) { + String requestCycleId = requestCycleNode.get("id").asText(); + + if (descendantOrAncestorCycleId.equals(requestCycleId)) { + /* + * Update start and end dates of descendant cycle node + */ + long requestStartDate = requestCycleNode.get("startDate").asLong(); + long requestEndDate = requestCycleNode.get("endDate").asLong(); + long currentStartDate = descendantOrAncestorCycleNode.get("startDate").asLong(); + long currentEndDate = descendantOrAncestorCycleNode.get("endDate").asLong(); + if (isDescendant) { + ((ObjectNode) descendantOrAncestorCycleNode).put("startDate", requestStartDate); + ((ObjectNode) descendantOrAncestorCycleNode).put("endDate", requestEndDate); + } else { + ((ObjectNode) descendantOrAncestorCycleNode).put("startDate", + Math.min(requestStartDate, currentStartDate)); + ((ObjectNode) descendantOrAncestorCycleNode).put("endDate", + Math.max(requestEndDate, currentEndDate)); + } + break; // Once updated, exit the loop for this descendantCycleNode + } + } + } + + /* + * Convert updated additional details back to a map and set it on the descendant or ancestor project + */ + Map updatedAdditionalDetails = objectMapper.convertValue( + descendantOrAncestorAdditionalDetails, new TypeReference>() {}); + descendantOrAncestor.setAdditionalDetails(updatedAdditionalDetails); + } + } + } + } + } + + + private void pushProjectsToKafka(List projects) { + /* + * Create a ProjectRequest object with the list of projects + */ + ProjectRequest projectRequest = ProjectRequest.builder() + .projects(projects) + .build(); + + /* + * Push the ProjectRequest to the Kafka topic for updating projects + */ + producer.push(projectConfiguration.getUpdateProjectTopic(), projectRequest); + } + //Enrich Project with Parent Hierarchy. If parent Project hierarchy is not present then add parent locality at the beginning of project hierarchy, if present add Parent project's project hierarchy private void enrichProjectHierarchy(Project projectRequest, List parentProjects) { 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 90b2c3cfe12..7d750e8d984 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 @@ -1,10 +1,23 @@ package org.egov.project.util; +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 java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.egov.common.models.project.Project; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import static java.util.Objects.isNull; @Component public class ProjectServiceUtil { + @Autowired + private ObjectMapper objectMapper; public AuditDetails getAuditDetails(String by, AuditDetails auditDetails, Boolean isCreate) { Long time = System.currentTimeMillis(); @@ -14,4 +27,53 @@ public AuditDetails getAuditDetails(String by, AuditDetails auditDetails, Boolea return AuditDetails.builder().createdBy(auditDetails.getCreatedBy()).lastModifiedBy(by) .createdTime(auditDetails.getCreatedTime()).lastModifiedTime(time).build(); } + + + /** + * Creates a map from a list of projects, using project IDs as keys. + * + * @param projects The list of projects to be converted into a map. + * @return A map with project IDs as keys and project objects as values. + */ + public Map createProjectMap(List projects) { + return projects.stream() + .collect(Collectors.toMap(p -> String.valueOf(p.getId()), Function.identity())); + } + + public void mergeAdditionalDetails( Project project , Project projectFromDb) { + project.setAdditionalDetails(jsonMerge( objectMapper.valueToTree(projectFromDb.getAdditionalDetails()), + objectMapper.valueToTree(project.getAdditionalDetails()))); + } + /** + * Method to merge additional details during update + * + * @param mainNode + * @param updateNode + * @return + */ + public JsonNode jsonMerge(JsonNode mainNode, JsonNode updateNode) { + + if (isNull(mainNode) || mainNode.isNull()) + return updateNode; + if (isNull(updateNode) || updateNode.isNull()) + return mainNode; + + Iterator fieldNames = updateNode.fieldNames(); + while (fieldNames.hasNext()) { + String fieldName = fieldNames.next(); + JsonNode jsonNode = mainNode.get(fieldName); + // if field exists and is an embedded object + if (jsonNode != null && jsonNode.isObject()) { + jsonMerge(jsonNode, updateNode.get(fieldName)); + } else { + if (mainNode instanceof ObjectNode) { + // Overwrite field + JsonNode value = updateNode.get(fieldName); + ((ObjectNode) mainNode).set(fieldName, value); + } + } + + } + return mainNode; + } } diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index 779e76f3e99..93f601466a9 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -144,6 +144,7 @@ project.search.max.limit=200 project.management.system.kafka.create.topic=save-project project.management.system.kafka.update.topic=update-project +project.management.system.kafka.update.date.topic=update-project-date # BOUNDARY SERVICE egov.boundary.host=http://localhost:8081 From 3bef90b0205440a39e6c427cbe058d57e4ca1985 Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:00:20 +0530 Subject: [PATCH 05/20] HLM fixed issues in useraction existent entity validator (#850) * HLM fixed issues in useraction existent entity validator * updated after code review comments --- .../member/validators/HmExistentEntityValidator.java | 2 +- .../household/HExistentEntityValidator.java | 3 ++- .../validators/IExistentEntityValidator.java | 2 +- .../common/data/repository/GenericRepository.java | 11 +++++++++-- .../beneficiary/PbExistentEntityValidator.java | 2 +- .../validator/task/PtExistentEntityValidator.java | 2 +- .../useraction/UaExistentEntityValidator.java | 2 +- .../validator/RmExistentEntityValidator.java | 2 +- .../hfreferral/HfrExistentEntityValidator.java | 2 +- .../sideeffect/SeExistentEntityValidator.java | 2 +- .../validator/stock/SExistentEntityValidator.java | 2 +- .../SrExistentEntityValidator.java | 2 +- 12 files changed, 21 insertions(+), 13 deletions(-) diff --git a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java index 8360bbf1eb8..debe4901496 100644 --- a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java @@ -71,7 +71,7 @@ public Map> validate(HouseholdMemberBulkRequest req if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = - householdMemberRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + householdMemberRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java index 9c07be651ad..959d7641e7a 100644 --- a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java @@ -71,7 +71,8 @@ public Map> validate(HouseholdBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existingClientReferenceIds = householdRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = + householdRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java index ec4f2db3b6b..420e4ea4b6a 100644 --- a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java +++ b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java @@ -71,7 +71,7 @@ public Map> validate(IndividualBulkRequest request) { if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = - individualRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + individualRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); 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 c941a2cbc37..537a82400cc 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 @@ -292,10 +292,17 @@ public List validateIds(List idsToValidate, String columnName){ .collect(Collectors.toList()); } - public List validateClientReferenceIdsFromDB(List clientReferenceIds) { + public List validateClientReferenceIdsFromDB(List clientReferenceIds, Boolean isDeletedKeyPresent) { List objFound = new ArrayList<>(); - String query = String.format("SELECT clientReferenceId FROM %s WHERE clientReferenceId IN (:ids) AND isDeleted = false", tableName); + String query = null; + + if(isDeletedKeyPresent) { + query = String.format("SELECT clientReferenceId FROM %s WHERE clientReferenceId IN (:ids) AND isDeleted = false", tableName); + } else { + query = String.format("SELECT clientReferenceId FROM %s WHERE clientReferenceId IN (:ids) ", tableName); + } + Map paramMap = new HashMap<>(); paramMap.put("ids", clientReferenceIds); diff --git a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java index e5fb8e579b8..ddb40944149 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java @@ -73,7 +73,7 @@ public Map> validate(BeneficiaryBulkRequest requ if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = - projectBeneficiaryRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + projectBeneficiaryRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java index b811627fcd4..1ace860e5cf 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java @@ -72,7 +72,7 @@ public Map> validate(TaskBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existingClientReferenceIds = projectTaskRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = projectTaskRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java index 09d8d575d83..dac31dba570 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java @@ -66,7 +66,7 @@ public Map> validate(UserActionBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existingClientReferenceIds = userActionRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = userActionRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.FALSE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java index c48bf3265d8..f6fbcba5c33 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java @@ -71,7 +71,7 @@ public Map> validate(ReferralBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existingClientReferenceIds = referralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = referralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java index 1608d67315d..b891ab6f1b3 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java @@ -72,7 +72,7 @@ public Map> validate(HFReferralBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existingClientReferenceIds = hfReferralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = hfReferralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java index 059dba86be4..0f5f435f39f 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java @@ -73,7 +73,7 @@ public Map> validate(SideEffectBulkRequest request) { if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = - sideEffectRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + sideEffectRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java index 176bfa80ff0..ce43f76fe4e 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java @@ -72,7 +72,7 @@ public Map> validate(StockBulkRequest request) { // Check if the client reference ID list is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs - List existingClientReferenceIds = stockRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + List existingClientReferenceIds = stockRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java index 2aa3dcf0d98..fad98920354 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java @@ -73,7 +73,7 @@ public Map> validate(StockReconciliationBulkReq if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = - stockReconciliationRepository.validateClientReferenceIdsFromDB(clientReferenceIdList); + stockReconciliationRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); // For each existing entity, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { Error error = getErrorForUniqueEntity(); From af4b8ed68685b5b3652e57300b56183b7d3ea1ea Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:07:38 +0530 Subject: [PATCH 06/20] updated version for hcm v1.5 release (#852) * updated version for hcm v1.5 release * HLM updated the code as per code review from code rabbit * HCMPRE-209: updated code review comments and code documentation --- health-services/household/pom.xml | 2 +- .../validators/HmExistentEntityValidator.java | 36 ++++++---- .../household/HExistentEntityValidator.java | 38 +++++++---- health-services/individual/pom.xml | 2 +- .../validators/IExistentEntityValidator.java | 38 +++++++---- .../health-services-common/CHANGELOG.md | 3 + .../libraries/health-services-common/pom.xml | 2 +- .../health-services-models/CHANGELOG.md | 6 ++ .../libraries/health-services-models/pom.xml | 2 +- .../common/models/project/TaskStatus.java | 66 ++++++++++++++++++- .../models/project/useraction/UserAction.java | 2 +- health-services/project/CHANGELOG.md | 2 + health-services/project/pom.xml | 6 +- .../project/consumer/UserActionConsumer.java | 9 +-- .../PbExistentEntityValidator.java | 57 ++++++++++------ .../task/PtExistentEntityValidator.java | 59 +++++++++++------ .../useraction/UaExistentEntityValidator.java | 65 +++++++++++------- .../LocationCaptureController.java | 4 +- .../referralmanagement/CHANGELOG.md | 4 ++ health-services/referralmanagement/pom.xml | 4 +- .../validator/RmExistentEntityValidator.java | 54 ++++++++------- .../HfrExistentEntityValidator.java | 47 +++++++------ .../sideeffect/SeExistentEntityValidator.java | 45 ++++++++----- health-services/stock/pom.xml | 2 +- .../stock/SExistentEntityValidator.java | 35 ++++++---- .../SrExistentEntityValidator.java | 35 ++++++---- 26 files changed, 419 insertions(+), 206 deletions(-) diff --git a/health-services/household/pom.xml b/health-services/household/pom.xml index e97fd87ec1f..955934b5e1a 100644 --- a/health-services/household/pom.xml +++ b/health-services/household/pom.xml @@ -45,7 +45,7 @@ org.egov.common health-services-common - 1.0.17-dev-SNAPSHOT + 1.0.18-SNAPSHOT org.egov.common diff --git a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java index debe4901496..cc9eb6c12d7 100644 --- a/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/household/member/validators/HmExistentEntityValidator.java @@ -45,40 +45,52 @@ public HmExistentEntityValidator(HouseholdMemberRepository householdMemberReposi /** * Validates the existence of entities with the given client reference IDs. + * This method checks if any of the HouseholdMember entities in the request already exist in the database, + * based on their client reference IDs. If an entity is found to exist, an error is added to the error details map. * * @param request The bulk request containing HouseholdMember entities. - * @return A map containing HouseholdMember entities and their associated error details. + * @return A map containing HouseholdMember entities and their associated error details, if any. */ @Override public Map> validate(HouseholdMemberBulkRequest request) { - // Map to hold HouseholdMember entities and their error details + // Map to hold HouseholdMember entities and their associated error details Map> errorDetailsMap = new HashMap<>(); + // Get the list of HouseholdMember entities from the request List entities = request.getHouseholdMembers(); - // Extract client reference IDs from HouseholdMember entities without errors + + // Extract client reference IDs from HouseholdMember entities that do not have errors List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(HouseholdMember::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities that already have errors + .map(HouseholdMember::getClientReferenceId) // Map to client reference IDs + .collect(Collectors.toList()); // Collect the IDs into a list + // Create a search object for querying entities by client reference IDs HouseholdMemberSearch householdSearch = HouseholdMemberSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search .build(); + + // Create a map of client reference ID to HouseholdMember entity for easy lookup Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Check if the client reference ID list is not empty + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map + + // Check if the client reference ID list is not empty before querying the database if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = householdMemberRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation Error error = getErrorForUniqueEntity(); + // Populate error details for the HouseholdMember entity associated with the client reference ID populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing HouseholdMember entities and their associated error details return errorDetailsMap; } - } diff --git a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java index 959d7641e7a..33253089919 100644 --- a/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java +++ b/health-services/household/src/main/java/org/egov/household/validators/household/HExistentEntityValidator.java @@ -10,7 +10,6 @@ import org.egov.common.models.household.Household; import org.egov.common.models.household.HouseholdBulkRequest; import org.egov.common.models.household.HouseholdSearch; -import org.egov.common.models.individual.Individual; import org.egov.common.validator.Validator; import org.egov.household.repository.HouseholdRepository; import org.springframework.core.annotation.Order; @@ -18,7 +17,6 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; @@ -26,6 +24,7 @@ /** * Validator class for checking the existence of entities with the given client reference IDs. * This validator checks if the provided household entities already exist in the database based on their client reference IDs. + * * @author kanishq-egov */ @Component @@ -46,39 +45,52 @@ public HExistentEntityValidator(HouseholdRepository householdRepository) { /** * Validates the existence of entities with the given client reference IDs. + * This method checks if any of the household entities in the request already exist in the database, + * based on their client reference IDs. If an entity is found to exist, an error is added to the error details map. * * @param request The bulk request containing household entities. - * @return A map containing household entities and their associated error details. + * @return A map containing household entities and their associated error details, if any. */ @Override public Map> validate(HouseholdBulkRequest request) { - // Map to hold household entities and their error details + // Map to hold household entities and their associated error details Map> errorDetailsMap = new HashMap<>(); + // Get the list of household entities from the request List entities = request.getHouseholds(); - // Extract client reference IDs from household entities without errors + + // Extract client reference IDs from household entities that do not have errors List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(Household::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities that already have errors + .map(Household::getClientReferenceId) // Map to client reference IDs + .collect(Collectors.toList()); // Collect the IDs into a list + + // Create a map of client reference ID to Household entity for easy lookup Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map + // Create a search object for querying entities by client reference IDs HouseholdSearch householdSearch = HouseholdSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search .build(); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = householdRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation Error error = getErrorForUniqueEntity(); + // Populate error details for the household entity associated with the client reference ID populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing household entities and their associated error details return errorDetailsMap; } diff --git a/health-services/individual/pom.xml b/health-services/individual/pom.xml index 02c05ffd93d..ab7767c7206 100644 --- a/health-services/individual/pom.xml +++ b/health-services/individual/pom.xml @@ -53,7 +53,7 @@ org.egov.common health-services-common - 1.0.17-dev-SNAPSHOT + 1.0.18-SNAPSHOT org.egov.common diff --git a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java index 420e4ea4b6a..39bb06f6ed8 100644 --- a/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java +++ b/health-services/individual/src/main/java/org/egov/individual/validators/IExistentEntityValidator.java @@ -17,7 +17,6 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; @@ -25,6 +24,7 @@ /** * Validator class for checking the existence of entities with the given client reference IDs. * This validator checks if the provided individual entities already exist in the database based on their client reference IDs. + * * @author kanishq-egov */ @Component @@ -45,41 +45,53 @@ public IExistentEntityValidator(IndividualRepository individualRepository) { /** * Validates the existence of entities with the given client reference IDs. + * This method checks if any of the individual entities in the request already exist in the database, + * based on their client reference IDs. If an entity is found to exist, an error is added to the error details map. * * @param request The bulk request containing individual entities. - * @return A map containing individual entities and their associated error details. + * @return A map containing individual entities and their associated error details, if any. */ @Override public Map> validate(IndividualBulkRequest request) { - // Map to hold individual entities and their error details + // Map to hold individual entities and their associated error details Map> errorDetailsMap = new HashMap<>(); + // Get the list of individual entities from the request List entities = request.getIndividuals(); - // Extract client reference IDs from individual entities without errors + + // Extract client reference IDs from individual entities that do not have errors List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(Individual::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities that already have errors + .map(Individual::getClientReferenceId) // Map to client reference IDs + .collect(Collectors.toList()); // Collect the IDs into a list + + // Create a map of client reference ID to Individual entity for easy lookup Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map + // Create a search object for querying entities by client reference IDs IndividualSearch individualSearch = IndividualSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search .build(); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database if (!CollectionUtils.isEmpty(clientReferenceIdList)) { // Query the repository to find existing entities by client reference IDs List existingClientReferenceIds = individualRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, populate error details for uniqueness existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation Error error = getErrorForUniqueEntity(); + // Populate error details for the individual entity associated with the client reference ID populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing individual entities and their associated error details return errorDetailsMap; } } - diff --git a/health-services/libraries/health-services-common/CHANGELOG.md b/health-services/libraries/health-services-common/CHANGELOG.md index 14669d15d9f..fbb085523fc 100644 --- a/health-services/libraries/health-services-common/CHANGELOG.md +++ b/health-services/libraries/health-services-common/CHANGELOG.md @@ -1,5 +1,8 @@ All notable changes to this module will be documented in this file. +## 1.0.18 - 2024-08-09 +- Added validateClientReferenceIdsFromDB method to GenericRepository. + ## 1.0.16 - 2024-05-29 - Introduced multiple reusable functions to streamline and simplify the codebase. - Enhanced function modularity for better maintainability and readability. diff --git a/health-services/libraries/health-services-common/pom.xml b/health-services/libraries/health-services-common/pom.xml index 0047646dc80..8f5e0d4fae9 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.17-dev-SNAPSHOT + 1.0.18-SNAPSHOT Shared classes among services diff --git a/health-services/libraries/health-services-models/CHANGELOG.md b/health-services/libraries/health-services-models/CHANGELOG.md index 531680fc20e..c7476cbe79b 100644 --- a/health-services/libraries/health-services-models/CHANGELOG.md +++ b/health-services/libraries/health-services-models/CHANGELOG.md @@ -1,5 +1,11 @@ All notable changes to this module will be documented in this file. +## 1.0.21 - 2024-08-07 +- Added UserActionEnum, UserAction Entities, TaskStatus enum +- Added isCascadingProjectDateUpdate in ProjectRequest model +- Removed status field from EgovModel + + ## 1.0.20 - 2024-05-29 - Added EgovModel, EgovSearchModel, EgovOfflineModel, EgovOfflineSearchModel - Updated Lombok to 1.18.22 for SuperBuilder annotation support. diff --git a/health-services/libraries/health-services-models/pom.xml b/health-services/libraries/health-services-models/pom.xml index d0d38bea5d3..6ca95c3fe47 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-dev-SNAPSHOT + 1.0.21-SNAPSHOT 17 ${java.version} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java index c551a68acb4..a17652a89c0 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java @@ -3,26 +3,90 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; +/** + * Enum representing the various possible statuses for a task. + *

+ * Each status corresponds to a specific state of the task in the system. + * The status is stored as a string value and can be serialized/deserialized + * from JSON using Jackson annotations. + *

+ */ public enum TaskStatus { + + /** + * Indicates that the task administration has failed. + * This status represents an error or issue encountered during + * the administrative process of the task. + */ ADMINISTRATION_FAILED("ADMINISTRATION_FAILED"), + + /** + * Indicates that the task administration was successful. + * This status signifies that the task has been processed correctly + * without any issues. + */ ADMINISTRATION_SUCCESS("ADMINISTRATION_SUCCESS"), + + /** + * Indicates that the beneficiary has refused the task. + * This status means that the individual or entity for whom the task + * was intended has declined to participate or accept it. + */ BENEFICIARY_REFUSED("BENEFICIARY_REFUSED"), + + /** + * Indicates that the household associated with the task has been closed. + * This status implies that the household is no longer active or + * relevant to the task, possibly due to its closure or other reasons. + */ CLOSED_HOUSEHOLD("CLOSED_HOUSEHOLD"), + + /** + * Indicates that the task has been delivered. + * This status shows that the task has been successfully completed + * and the deliverables have been provided. + */ DELIVERED("DELIVERED"), + + /** + * Indicates that the task has not been administered. + * This status signifies that the task has not been processed or + * handled yet. + */ NOT_ADMINISTERED("NOT_ADMINISTERED"); + // The string value associated with the task status. private String value; + /** + * Constructor to initialize the TaskStatus with a specific string value. + * + * @param value The string value representing the task status. + */ TaskStatus(String value) { this.value = value; } + /** + * Returns the string representation of the TaskStatus. + * This method is used for serialization of the enum value to JSON. + * + * @return The string value of the task status. + */ @Override @JsonValue public String toString() { return String.valueOf(value); } + /** + * Creates a TaskStatus enum from a string value. + * This method is used for deserialization of the enum value from JSON. + * + * @param text The string value representing the task status. + * @return The TaskStatus enum corresponding to the provided value, + * or null if no match is found. + */ @JsonCreator public static TaskStatus fromValue(String text) { for (TaskStatus status : TaskStatus.values()) { @@ -30,6 +94,6 @@ public static TaskStatus fromValue(String text) { return status; } } - return null; + return null; // Return null if no matching status is found } } diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java index ac20f32e157..d58d98996d8 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserAction.java @@ -33,7 +33,7 @@ public class UserAction extends EgovOfflineModel { * It must be between 2 and 64 characters long and cannot be null. */ @JsonProperty("projectId") - @Size(min = 2, max = 64) + @Size(min = 2, max = 64, message = "Project ID must be between 2 and 64 characters") @NotNull private String projectId; diff --git a/health-services/project/CHANGELOG.md b/health-services/project/CHANGELOG.md index 427aa3e5917..7865206457c 100644 --- a/health-services/project/CHANGELOG.md +++ b/health-services/project/CHANGELOG.md @@ -1,5 +1,7 @@ All notable changes to this module will be documented in this file. +## 1.1.5 - 2024-08-07 +- Added UserAction functionality with support for Location capture. ## 1.1.4 - 2024-05-29 - Integrated Core 2.9LTS diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml index e957915b1dc..fd0b688dcc3 100644 --- a/health-services/project/pom.xml +++ b/health-services/project/pom.xml @@ -5,7 +5,7 @@ project jar project - 1.1.4 + 1.1.5 17 ${java.version} @@ -45,12 +45,12 @@ org.egov.common health-services-common - 1.0.17-dev-SNAPSHOT + 1.0.18-SNAPSHOT org.egov.common health-services-models - 1.0.21-dev-SNAPSHOT + 1.0.21-SNAPSHOT compile diff --git a/health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java b/health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java index e3714e98bb6..f01d2e00913 100644 --- a/health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java +++ b/health-services/project/src/main/java/org/egov/project/consumer/UserActionConsumer.java @@ -1,13 +1,10 @@ package org.egov.project.consumer; -import java.util.Collections; -import java.util.List; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; -import org.egov.common.models.project.useraction.UserAction; import org.egov.common.models.project.useraction.UserActionBulkRequest; import org.egov.project.service.LocationCaptureService; import org.egov.project.service.UserActionService; @@ -51,7 +48,7 @@ public void bulkCreateUserAction(Map consumerRecord, userActionService.create(request, true); } catch (Exception exception) { // Log any exception that occurs - log.error("error in user action consumer bulk create", ExceptionUtils.getStackTrace(exception)); + log.error("Error processing bulk create for user actions from topic {}: {}", topic, ExceptionUtils.getStackTrace(exception)); // throw custom exception throw new CustomException("PROJECT_USER_ACTION_BULK_CREATE", exception.getMessage()); } @@ -74,7 +71,7 @@ public void bulkUpdateUserAction(Map consumerRecord, userActionService.update(request, true); } catch (Exception exception) { // Log any exception that occurs - log.error("error in user action consumer bulk update", ExceptionUtils.getStackTrace(exception)); + log.error("Error processing bulk update for user actions from topic {}: {}", topic, ExceptionUtils.getStackTrace(exception)); // throw custom exception throw new CustomException("PROJECT_USER_ACTION_BULK_UPDATE", exception.getMessage()); } @@ -97,7 +94,7 @@ public void bulkCreateLocationCapture(Map consumerRecord, locationCaptureService.create(request, true); } catch (Exception exception) { // Log any exception that occurs - log.error("error in location capture consumer bulk create", ExceptionUtils.getStackTrace(exception)); + log.error("Error processing bulk create for location captures from topic {}: {}", topic, ExceptionUtils.getStackTrace(exception)); // throw custom exception throw new CustomException("PROJECT_USER_ACTION_LOCATION_CAPTURE_BULK_CREATE", exception.getMessage()); } diff --git a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java index ddb40944149..97acdc3d867 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/beneficiary/PbExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.project.BeneficiaryBulkRequest; import org.egov.common.models.project.ProjectBeneficiary; import org.egov.common.models.project.ProjectBeneficiarySearch; @@ -18,15 +17,17 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; /** - * Validator class for checking the existence of entities with the given client reference IDs. + * Validator class for checking the existence of ProjectBeneficiary entities with the given client reference IDs. * This validator checks if the provided ProjectBeneficiary entities already exist in the database based on their client reference IDs. * + * The validation ensures that each ProjectBeneficiary entity in the bulk request has a unique client reference ID, + * and if an entity with the same client reference ID already exists, an error is recorded. + * * @author kanishq-egov */ @Component @@ -40,46 +41,62 @@ public class PbExistentEntityValidator implements Validator> validate(BeneficiaryBulkRequest request) { - // Map to hold ProjectBeneficiary entities and their error details + // Initialize a map to hold ProjectBeneficiary entities and their associated error details. Map> errorDetailsMap = new HashMap<>(); - // Get the list of ProjectBeneficiary entities from the request + + // Extract the list of ProjectBeneficiary entities from the request. List entities = request.getProjectBeneficiaries(); - // Extract client reference IDs from ProjectBeneficiary entities without errors + + // Extract the client reference IDs from ProjectBeneficiary entities that do not have existing errors. List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(ProjectBeneficiary::getClientReferenceId) - .collect(Collectors.toList()); - // Create a search object for querying entities by client reference IDs + .filter(notHavingErrors()) // Filter out entities that already have errors. + .map(ProjectBeneficiary::getClientReferenceId) // Map to extract client reference IDs. + .collect(Collectors.toList()); // Collect the IDs into a list. + + // Create a map of client reference ID to ProjectBeneficiary entity for quick lookup. + Map map = entities.stream() + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty. + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map. + + // Create a search object to query entities by client reference IDs. ProjectBeneficiarySearch projectBeneficiarySearch = ProjectBeneficiarySearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search. .build(); - Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database. if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs + // Query the repository to find existing entities with the given client reference IDs. List existingClientReferenceIds = projectBeneficiaryRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, populate error details for the corresponding ProjectBeneficiary entity. existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation. Error error = getErrorForUniqueEntity(); + // Populate error details for the individual entity associated with the client reference ID. populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing ProjectBeneficiary entities and their associated error details. return errorDetailsMap; } diff --git a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java index 1ace860e5cf..ba4ebc24889 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/task/PtExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.project.Task; import org.egov.common.models.project.TaskBulkRequest; import org.egov.common.models.project.TaskSearch; @@ -18,14 +17,16 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; /** - * Validator class for checking the existence of entities with the given client reference IDs. - * This validator checks if the provided Task entities already exist in the database based on their client reference IDs. + * Validator class for checking the existence of ProjectTask entities with the given client reference IDs. + * This validator ensures that the Task entities provided in the bulk request do not have duplicate client reference IDs in the database. + * + * The validation checks if each Task entity's client reference ID is unique across the database, + * and if a duplicate ID is found, it adds an error to the map with the entity. * * @author: kanishq-egov */ @@ -39,46 +40,62 @@ public class PtExistentEntityValidator implements Validator> validate(TaskBulkRequest request) { - // Map to hold Task entities and their error details + // Initialize a map to store Task entities and their associated error details. Map> errorDetailsMap = new HashMap<>(); - // Get the list of Task entities from the request + + // Extract the list of Task entities from the request. List entities = request.getTasks(); - // Extract client reference IDs from Task entities without errors + + // Extract client reference IDs from Task entities that do not have existing errors. List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(Task::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities that already have errors. + .map(Task::getClientReferenceId) // Map to extract client reference IDs. + .collect(Collectors.toList()); // Collect the IDs into a list. + + // Create a map for quick lookup of Task entities by client reference ID. Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Create a search object for querying entities by client reference IDs + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty. + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map. + + // Create a search object to query for existing entities based on client reference IDs. TaskSearch taskSearch = TaskSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search. .build(); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database. if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs + // Query the repository to find existing entities with the given client reference IDs. List existingClientReferenceIds = projectTaskRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, add an error to the map for the corresponding Task entity. existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation. Error error = getErrorForUniqueEntity(); + // Populate error details for the individual Task entity associated with the client reference ID. populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing Task entities and their associated error details. return errorDetailsMap; } } diff --git a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java index dac31dba570..e5f3ff7a026 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/useraction/UaExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.project.useraction.UserAction; import org.egov.common.models.project.useraction.UserActionBulkRequest; import org.egov.common.models.project.useraction.UserActionSearch; @@ -19,60 +18,82 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; +/** + * Validator class for checking the existence of UserAction entities based on their client reference IDs. + * This validator ensures that the UserAction entities in the bulk request do not have duplicate client reference IDs in the database. + * + * The validation checks if each UserAction entity's client reference ID already exists in the database. + * If a duplicate ID is found, it adds an error to the map with the entity. + * + * @author: kanishq-egov + */ @Component @Order(value = 1) @Slf4j public class UaExistentEntityValidator implements Validator { private UserActionRepository userActionRepository; + /** + * Constructs a UaExistentEntityValidator with the specified UserActionRepository. + * + * @param userActionRepository the repository used to validate UserAction entities. + */ @Autowired public UaExistentEntityValidator(UserActionRepository userActionRepository) { this.userActionRepository = userActionRepository; } /** - * @param request - * @return - */ - /** - * Validates the existence of entities in the UserActionBulkRequest. - * @param request the bulk request containing UserAction entities - * @return a map of UserAction entities and their error details + * Validates the existence of UserAction entities in the UserActionBulkRequest. + * Checks if the provided UserAction entities already exist in the database based on their client reference IDs. + * + * @param request the bulk request containing UserAction entities. + * @return a map of UserAction entities and their associated error details. */ @Override public Map> validate(UserActionBulkRequest request) { - // Map to hold UserAction entities and their error details + // Map to hold UserAction entities and their error details. log.info("Validating existence of entities in UserActionBulkRequest with {} entities", request.getUserActions().size()); Map> errorDetailsMap = new HashMap<>(); - // Get the list of UserAction entities from the request + + // Get the list of UserAction entities from the request. List entities = request.getUserActions(); - // Extract client reference IDs from UserAction entities without errors + + // Extract client reference IDs from UserAction entities that do not have existing errors. List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(UserAction::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities that already have errors. + .map(UserAction::getClientReferenceId) // Map to extract client reference IDs. + .collect(Collectors.toList()); // Collect the IDs into a list. + + // Create a map for quick lookup of UserAction entities by client reference ID. Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Create a search object for querying entities by client reference IDs + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty. + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map. + + // Create a search object to query for existing UserAction entities based on client reference IDs. UserActionSearch userActionSearch = UserActionSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search. .build(); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database. if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs + // Query the repository to find existing UserAction entities with the given client reference IDs. List existingClientReferenceIds = userActionRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.FALSE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, add an error to the map for the corresponding UserAction entity. existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation. Error error = getErrorForUniqueEntity(); + // Populate error details for the individual UserAction entity associated with the client reference ID. populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing UserAction entities and their associated error details. return errorDetailsMap; } } diff --git a/health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java b/health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java index a2c31077309..2214594b313 100644 --- a/health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java +++ b/health-services/project/src/main/java/org/egov/project/web/controllers/LocationCaptureController.java @@ -78,7 +78,7 @@ public ResponseEntity locationCaptureTaskV1BulkCreatePost( // Send the request to the Kafka topic for bulk creation. producer.push(projectConfiguration.getBulkCreateLocationCaptureTopic(), request); } catch (Exception e) { - log.error("Error sending message to Kafka", e); + log.error("Error sending bulk create request for location captures to Kafka: {}", e.getMessage(), e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body( ResponseInfoFactory.createResponseInfo(request.getRequestInfo(), false) ); @@ -119,7 +119,7 @@ public ResponseEntity locationCaptureTaskV2SearchPost( // Return the response with HTTP status OK. return ResponseEntity.status(HttpStatus.OK).body(response); } catch (Exception e) { - log.error("Error during search operation", e); + log.error("Error occurred during search operation for location captures: {}", e.getMessage(), e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body( UserActionBulkResponse.builder() .responseInfo(ResponseInfoFactory.createResponseInfo(locationCaptureSearchRequest.getRequestInfo(), false)) diff --git a/health-services/referralmanagement/CHANGELOG.md b/health-services/referralmanagement/CHANGELOG.md index c605b868638..21e78657688 100644 --- a/health-services/referralmanagement/CHANGELOG.md +++ b/health-services/referralmanagement/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this module will be documented in this file. +## 1.0.3 - 2024-08-09 +- Upgraded downsync logic. + + ## 1.0.2 - 2024-05-29 - Upgraded to Core 2.9LTS - Client reference ID validation added diff --git a/health-services/referralmanagement/pom.xml b/health-services/referralmanagement/pom.xml index 06abfeaa971..b9d85ad8269 100644 --- a/health-services/referralmanagement/pom.xml +++ b/health-services/referralmanagement/pom.xml @@ -6,7 +6,7 @@ referralmanagement jar referralmanagement - 1.0.2 + 1.0.3 17 ${java.version} @@ -46,7 +46,7 @@ org.egov.common health-services-common - 1.0.17-dev-SNAPSHOT + 1.0.18-SNAPSHOT org.egov.common diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java index f6fbcba5c33..c12c03054ef 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/RmExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.referralmanagement.Referral; import org.egov.common.models.referralmanagement.ReferralBulkRequest; import org.egov.common.models.referralmanagement.ReferralSearch; @@ -18,14 +17,14 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; /** - * Validator class for checking the existence of entities with the given client reference IDs. - * This validator checks if the provided referral entities already exist in the database based on their client reference IDs. + * Validator class for checking the existence of referral entities with the given client reference IDs. + * This validator checks if the provided Referral entities already exist in the database based on their client reference IDs. + * * @author kanishq-egov */ @Component @@ -38,47 +37,58 @@ public class RmExistentEntityValidator implements Validator> validate(ReferralBulkRequest request) { - // Map to hold referral entities and their error details + // Map to hold Referral entities and their error details Map> errorDetailsMap = new HashMap<>(); - // Get the list of referral entities from the request + + // Get the list of Referral entities from the request List entities = request.getReferrals(); - // Extract client reference IDs from referral entities without errors + + // Extract client reference IDs from Referral entities that do not have existing errors List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(Referral::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities that already have errors + .map(Referral::getClientReferenceId) // Extract client reference IDs from Referral entities + .collect(Collectors.toList()); // Collect the IDs into a list + + // Create a map for quick lookup of Referral entities by client reference ID Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Create a search object for querying entities by client reference IDs + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map + + // Create a search object for querying existing Referral entities by client reference IDs ReferralSearch referralSearch = ReferralSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search .build(); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs + // Query the repository to find existing Referral entities with the given client reference IDs List existingClientReferenceIds = referralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, add an error to the map for the corresponding Referral entity existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation Error error = getErrorForUniqueEntity(); + // Populate error details for the individual Referral entity associated with the client reference ID populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing Referral entities and their associated error details return errorDetailsMap; } - } diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java index b891ab6f1b3..de041f238e8 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.referralmanagement.hfreferral.HFReferral; import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; import org.egov.common.models.referralmanagement.hfreferral.HFReferralSearch; @@ -18,13 +17,12 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; /** - * Validator class for checking the existence of entities with the given client reference IDs. + * Validator class for checking the existence of HFReferral entities with the given client reference IDs. * This validator checks if the provided HFReferral entities already exist in the database based on their client reference IDs. * * @author kanishq-egov @@ -46,40 +44,51 @@ public HfrExistentEntityValidator(HFReferralRepository hfReferralRepository) { } /** - * Validates the existence of entities with the given client reference IDs. + * Validates the existence of HFReferral entities in the HFReferralBulkRequest. + * Checks if the provided HFReferral entities already exist in the database based on their client reference IDs. * * @param request The bulk request containing HFReferral entities. - * @return A map containing HFReferral entities and their associated error details. + * @return A map containing HFReferral entities and their associated error details if any duplicates are found. */ @Override public Map> validate(HFReferralBulkRequest request) { - // Map to hold HFReferral entities and their error details + // Map to hold HFReferral entities and their error details. Map> errorDetailsMap = new HashMap<>(); - // Get the list of HFReferral entities from the request + + // Get the list of HFReferral entities from the request. List entities = request.getHfReferrals(); - // Extract client reference IDs from HFReferral entities without errors + + // Extract client reference IDs from HFReferral entities that do not have existing errors. List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(HFReferral::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities that already have errors. + .map(HFReferral::getClientReferenceId) // Extract client reference IDs from HFReferral entities. + .collect(Collectors.toList()); // Collect the IDs into a list. + + // Create a map for quick lookup of HFReferral entities by client reference ID. Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Create a search object for querying entities by client reference IDs + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty. + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map. + + // Create a search object for querying existing HFReferral entities by client reference IDs. HFReferralSearch hfReferralSearch = HFReferralSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search. .build(); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database. if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs + // Query the repository to find existing HFReferral entities with the given client reference IDs. List existingClientReferenceIds = hfReferralRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, add an error to the map for the corresponding HFReferral entity. existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation. Error error = getErrorForUniqueEntity(); + // Populate error details for the individual HFReferral entity associated with the client reference ID. populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing HFReferral entities and their associated error details. return errorDetailsMap; } - } diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java index 0f5f435f39f..961272cb95d 100644 --- a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/sideeffect/SeExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.referralmanagement.sideeffect.SideEffect; import org.egov.common.models.referralmanagement.sideeffect.SideEffectBulkRequest; import org.egov.common.models.referralmanagement.sideeffect.SideEffectSearch; @@ -18,7 +17,6 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; @@ -46,40 +44,51 @@ public SeExistentEntityValidator(SideEffectRepository sideEffectRepository) { } /** - * Validates the existence of SideEffect entities with the given client reference IDs. + * Validates the existence of SideEffect entities in the SideEffectBulkRequest. + * Checks if the provided SideEffect entities already exist in the database based on their client reference IDs. * * @param request The bulk request containing SideEffect entities. - * @return A map containing SideEffect entities and their associated error details. + * @return A map containing SideEffect entities and their associated error details if any duplicates are found. */ @Override public Map> validate(SideEffectBulkRequest request) { // Map to hold SideEffect entities and their error details Map> errorDetailsMap = new HashMap<>(); + // Get the list of SideEffect entities from the request List entities = request.getSideEffects(); - // Extract client reference IDs from SideEffect entities without errors + + // Extract client reference IDs from SideEffect entities that do not have existing errors List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(SideEffect::getClientReferenceId) - .collect(Collectors.toList()); - // Create a search object for querying entities by client reference IDs + .filter(notHavingErrors()) // Filter out entities that already have errors + .map(SideEffect::getClientReferenceId) // Extract client reference IDs from SideEffect entities + .collect(Collectors.toList()); // Collect the IDs into a list + + // Create a map for quick lookup of SideEffect entities by client reference ID + Map map = entities.stream() + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map + + // Create a search object for querying existing SideEffect entities by client reference IDs SideEffectSearch sideEffectSearch = SideEffectSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search .build(); - Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Check if the client reference ID list is not empty + + // Check if the client reference ID list is not empty before querying the database if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs - List existingClientReferenceIds = - sideEffectRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + // Query the repository to find existing SideEffect entities with the given client reference IDs + List existingClientReferenceIds = sideEffectRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); + + // For each existing client reference ID, add an error to the map for the corresponding SideEffect entity existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation Error error = getErrorForUniqueEntity(); + // Populate error details for the individual SideEffect entity associated with the client reference ID populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing SideEffect entities and their associated error details return errorDetailsMap; } } diff --git a/health-services/stock/pom.xml b/health-services/stock/pom.xml index 49c0615b5f0..d204ba58903 100644 --- a/health-services/stock/pom.xml +++ b/health-services/stock/pom.xml @@ -45,7 +45,7 @@ org.egov.common health-services-common - 1.0.17-dev-SNAPSHOT + 1.0.18-SNAPSHOT org.egov.common diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java index ce43f76fe4e..85d5d2bf613 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockBulkRequest; import org.egov.common.models.stock.StockSearch; @@ -18,7 +17,6 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; @@ -55,30 +53,41 @@ public SExistentEntityValidator(StockRepository stockRepository) { public Map> validate(StockBulkRequest request) { // Map to hold Stock entities and their error details Map> errorDetailsMap = new HashMap<>(); + // Get the list of Stock entities from the request List entities = request.getStock(); - // Extract client reference IDs from Stock entities without errors + + // Extract client reference IDs from Stock entities that do not already have errors List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(Stock::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Exclude entities with existing errors + .map(Stock::getClientReferenceId) // Map entities to their client reference IDs + .collect(Collectors.toList()); // Collect IDs into a list + + // Create a map for quick lookup of Stock entities by their client reference ID Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Create a search object for querying entities by client reference IDs + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map + + // Create a search object to query existing entities by client reference IDs StockSearch stockSearch = StockSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search .build(); - // Check if the client reference ID list is not empty + + // Check if the list of client reference IDs is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs + // Query the repository to find existing Stock entities with the given client reference IDs List existingClientReferenceIds = stockRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, add an error to the map for the corresponding Stock entity existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation Error error = getErrorForUniqueEntity(); + // Populate error details for the individual Stock entity associated with the client reference ID populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing Stock entities and their associated error details return errorDetailsMap; } } diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java index fad98920354..6917135941a 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stockreconciliation/SrExistentEntityValidator.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; -import org.egov.common.models.individual.Individual; import org.egov.common.models.stock.StockReconciliation; import org.egov.common.models.stock.StockReconciliationBulkRequest; import org.egov.common.models.stock.StockReconciliationSearch; @@ -18,7 +17,6 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import static org.egov.common.utils.CommonUtils.getIdFieldName; import static org.egov.common.utils.CommonUtils.notHavingErrors; import static org.egov.common.utils.CommonUtils.populateErrorDetails; import static org.egov.common.utils.ValidatorUtils.getErrorForUniqueEntity; @@ -55,31 +53,42 @@ public SrExistentEntityValidator(StockReconciliationRepository stockReconciliati public Map> validate(StockReconciliationBulkRequest request) { // Map to hold StockReconciliation entities and their error details Map> errorDetailsMap = new HashMap<>(); + // Get the list of StockReconciliation entities from the request List entities = request.getStockReconciliation(); - // Extract client reference IDs from StockReconciliation entities without errors + + // Extract client reference IDs from StockReconciliation entities that do not already have errors List clientReferenceIdList = entities.stream() - .filter(notHavingErrors()) - .map(StockReconciliation::getClientReferenceId) - .collect(Collectors.toList()); + .filter(notHavingErrors()) // Filter out entities with existing errors + .map(StockReconciliation::getClientReferenceId) // Map entities to their client reference IDs + .collect(Collectors.toList()); // Collect IDs into a list + + // Create a map for quick lookup of StockReconciliation entities by their client reference ID Map map = entities.stream() - .filter(individual -> StringUtils.isEmpty(individual.getClientReferenceId())) - .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); - // Create a search object for querying entities by client reference IDs + .filter(entity -> StringUtils.hasText(entity.getClientReferenceId())) // Ensure client reference ID is not empty + .collect(Collectors.toMap(entity -> entity.getClientReferenceId(), entity -> entity)); // Collect to a map + + // Create a search object to query existing entities by client reference IDs StockReconciliationSearch stockReconciliationSearch = StockReconciliationSearch.builder() - .clientReferenceId(clientReferenceIdList) + .clientReferenceId(clientReferenceIdList) // Set the client reference IDs for the search .build(); - // Check if the client reference ID list is not empty + + // Check if the list of client reference IDs is not empty if (!CollectionUtils.isEmpty(clientReferenceIdList)) { - // Query the repository to find existing entities by client reference IDs + // Query the repository to find existing StockReconciliation entities with the given client reference IDs List existingClientReferenceIds = stockReconciliationRepository.validateClientReferenceIdsFromDB(clientReferenceIdList, Boolean.TRUE); - // For each existing entity, populate error details for uniqueness + + // For each existing client reference ID, add an error to the map for the corresponding StockReconciliation entity existingClientReferenceIds.forEach(clientReferenceId -> { + // Get a predefined error object for unique entity validation Error error = getErrorForUniqueEntity(); + // Populate error details for the individual StockReconciliation entity associated with the client reference ID populateErrorDetails(map.get(clientReferenceId), error, errorDetailsMap); }); } + + // Return the map containing StockReconciliation entities and their associated error details return errorDetailsMap; } } From 2705fed0751062ff698673fd71f9f63e0ba52a04 Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:48:53 +0530 Subject: [PATCH 07/20] Hcmpre 309 rebase (#857) * removed digit-models from health-services-models library * removed digit-models from health-services-models library * added SMSRequest model * Updated individual models * Updating health services models version in health services common library * version bump * hcmpre-309: merged removed-digit-models and rebase to dev * HLM-309: updated common models version --------- Co-authored-by: shubhang-egov --- health-services/individual/pom.xml | 4 ++-- .../repository/rowmapper/AddressRowMapper.java | 10 +++++----- .../rowmapper/IdentifierRowMapper.java | 8 ++++---- .../rowmapper/IndividualRowMapper.java | 4 ++-- .../repository/rowmapper/SkillRowMapper.java | 8 ++++---- .../individual/service/EnrichmentService.java | 2 +- .../service/NotificationService.java | 12 ++++++------ .../libraries/health-services-common/pom.xml | 9 ++------- .../common/helper/AuditDetailsTestBuilder.java | 2 +- .../org/egov/common/service/IdGenService.java | 8 ++++---- .../org/egov/common/service/UserService.java | 4 ++-- .../org/egov/common/utils/CommonUtils.java | 2 +- .../org/egov/common/helpers/SomeObject.java | 2 +- .../helpers/SomeObjectWithClientRefId.java | 2 +- .../org/egov/common/utils/CommonUtilsTest.java | 2 +- .../libraries/health-services-models/pom.xml | 7 +------ .../org/egov/common/models/core/Boundary.java | 5 ++--- .../org/egov/common/models/core/EgovModel.java | 7 +++---- .../common/models/core/EgovOfflineModel.java | 7 +++---- .../egov/common/models/core/SMSRequest.java | 18 ++++++++++++++++++ .../models/facility/AdditionalFields.java | 12 ++++++------ .../egov/common/models/facility/Facility.java | 9 ++------- .../models/facility/FacilityBulkRequest.java | 12 ++++++------ .../models/facility/FacilityBulkResponse.java | 10 +++++----- .../models/facility/FacilityRequest.java | 5 ++--- .../models/facility/FacilityResponse.java | 5 ++--- .../models/facility/FacilitySearchRequest.java | 5 ++--- .../common/models/facility/TenantRole.java | 10 +++++----- .../egov/common/models/facility/UserInfo.java | 10 +++++----- .../models/household/AdditionalFields.java | 12 ++++++------ .../egov/common/models/household/Field.java | 5 ++--- .../common/models/household/Household.java | 2 +- .../models/household/HouseholdBulkRequest.java | 12 ++++++------ .../household/HouseholdBulkResponse.java | 10 +++++----- .../models/household/HouseholdMember.java | 8 +------- .../household/HouseholdMemberBulkRequest.java | 12 ++++++------ .../household/HouseholdMemberBulkResponse.java | 10 +++++----- .../household/HouseholdMemberRequest.java | 5 ++--- .../household/HouseholdMemberResponse.java | 5 ++--- .../HouseholdMemberSearchRequest.java | 5 ++--- .../models/household/HouseholdRequest.java | 5 ++--- .../models/household/HouseholdResponse.java | 5 ++--- .../household/HouseholdSearchRequest.java | 5 ++--- .../common/models/household/TenantRole.java | 10 +++++----- .../egov/common/models/household/UserInfo.java | 10 +++++----- .../models/individual/AdditionalFields.java | 12 ++++++------ .../egov/common/models/individual/Address.java | 13 ++++++------- .../egov/common/models/individual/Field.java | 5 ++--- .../common/models/individual/Identifier.java | 9 ++++----- .../common/models/individual/Individual.java | 17 +++++++---------- .../individual/IndividualBulkRequest.java | 12 ++++++------ .../individual/IndividualBulkResponse.java | 10 +++++----- .../models/individual/IndividualRequest.java | 5 ++--- .../models/individual/IndividualResponse.java | 5 ++--- .../egov/common/models/individual/Name.java | 3 +-- .../egov/common/models/individual/Skill.java | 9 ++++----- .../common/models/individual/UserDetails.java | 10 +++++----- .../models/product/AdditionalFields.java | 12 ++++++------ .../org/egov/common/models/product/Field.java | 5 ++--- .../egov/common/models/product/Product.java | 8 ++------ .../common/models/product/ProductRequest.java | 12 ++++++------ .../common/models/product/ProductResponse.java | 10 +++++----- .../models/product/ProductSearchRequest.java | 5 ++--- .../common/models/product/ProductVariant.java | 5 ++--- .../models/product/ProductVariantRequest.java | 12 ++++++------ .../models/product/ProductVariantResponse.java | 10 +++++----- .../product/ProductVariantSearchRequest.java | 5 ++--- .../models/product/ProjectProductVariant.java | 3 +-- .../egov/common/models/product/TenantRole.java | 10 +++++----- .../egov/common/models/product/UserInfo.java | 10 +++++----- .../models/project/AdditionalFields.java | 12 ++++++------ .../egov/common/models/project/Address.java | 11 +++++------ .../models/project/BeneficiaryBulkRequest.java | 12 ++++++------ .../project/BeneficiaryBulkResponse.java | 10 +++++----- .../models/project/BeneficiaryRequest.java | 5 ++--- .../models/project/BeneficiaryResponse.java | 5 ++--- .../project/BeneficiarySearchRequest.java | 5 ++--- .../egov/common/models/project/Document.java | 9 ++++----- .../org/egov/common/models/project/Field.java | 5 ++--- .../egov/common/models/project/Project.java | 10 +++++----- .../models/project/ProjectBeneficiary.java | 11 +++-------- .../project/ProjectFacilityBulkRequest.java | 12 ++++++------ .../project/ProjectFacilityBulkResponse.java | 11 ++++++----- .../models/project/ProjectFacilityRequest.java | 5 ++--- .../project/ProjectFacilityResponse.java | 5 ++--- .../models/project/ProjectProductVariant.java | 3 +-- .../common/models/project/ProjectRequest.java | 12 ++++++------ .../common/models/project/ProjectResource.java | 9 ++------- .../project/ProjectResourceBulkRequest.java | 12 ++++++------ .../project/ProjectResourceBulkResponse.java | 10 +++++----- .../models/project/ProjectResourceRequest.java | 5 ++--- .../project/ProjectResourceResponse.java | 5 ++--- .../common/models/project/ProjectResponse.java | 10 +++++----- .../models/project/ProjectSearchRequest.java | 1 - .../common/models/project/ProjectStaff.java | 17 +++++------------ .../project/ProjectStaffBulkRequest.java | 12 ++++++------ .../project/ProjectStaffBulkResponse.java | 10 +++++----- .../models/project/ProjectStaffRequest.java | 5 ++--- .../models/project/ProjectStaffResponse.java | 5 ++--- .../common/models/project/ProjectType.java | 12 ++++++------ .../org/egov/common/models/project/Role.java | 5 ++--- .../org/egov/common/models/project/Target.java | 2 +- .../common/models/project/TaskBulkRequest.java | 12 ++++++------ .../models/project/TaskBulkResponse.java | 10 +++++----- .../common/models/project/TaskRequest.java | 5 ++--- .../common/models/project/TaskResource.java | 2 +- .../models/project/TaskResourceRequest.java | 12 ++++++------ .../models/project/TaskResourceResponse.java | 10 +++++----- .../common/models/project/TaskResponse.java | 5 ++--- .../models/project/TaskSearchRequest.java | 5 ++--- .../egov/common/models/project/TenantRole.java | 10 +++++----- .../egov/common/models/project/UserInfo.java | 10 +++++----- .../models/project/UserServiceResponse.java | 6 +++--- .../project/useraction/UserActionSearch.java | 2 -- .../models/referralmanagement/Referral.java | 1 - .../hfreferral/HFReferral.java | 1 - .../sideeffect/SideEffect.java | 1 - .../common/models/stock/AdditionalFields.java | 12 ++++++------ .../org/egov/common/models/stock/Field.java | 5 ++--- .../org/egov/common/models/stock/Stock.java | 8 ++------ .../common/models/stock/StockBulkRequest.java | 12 ++++++------ .../common/models/stock/StockBulkResponse.java | 10 +++++----- .../models/stock/StockReconciliation.java | 9 ++------- .../stock/StockReconciliationBulkRequest.java | 12 ++++++------ .../stock/StockReconciliationBulkResponse.java | 10 +++++----- .../stock/StockReconciliationRequest.java | 5 ++--- .../stock/StockReconciliationResponse.java | 5 ++--- .../StockReconciliationSearchRequest.java | 5 ++--- .../egov/common/models/stock/StockRequest.java | 5 ++--- .../common/models/stock/StockResponse.java | 5 ++--- .../models/stock/StockSearchRequest.java | 5 ++--- .../egov/common/models/stock/TenantRole.java | 10 +++++----- .../org/egov/common/models/stock/UserInfo.java | 10 +++++----- 133 files changed, 466 insertions(+), 556 deletions(-) create mode 100644 health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/SMSRequest.java diff --git a/health-services/individual/pom.xml b/health-services/individual/pom.xml index ab7767c7206..392df06c2e1 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/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..17c27125802 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.19-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,7 @@ org.egov.common health-services-models - 1.0.20-SNAPSHOT + 1.0.22-SNAPSHOT compile 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..cae31ed2480 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.22-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..4209e6e2311 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,18 +1,18 @@ 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 */ 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..6ed081c182e 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,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; - /** * IndividualResponse */ 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..3b7c899ebfe 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,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; - /** * ProjectFacilityResponse */ 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..2fdba28281a 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 */ 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..73d80462fb0 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,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; - /** * ProjectStaffResponse */ 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/project/useraction/UserActionSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearch.java index 0e2051b6be6..4c6ad63a53f 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearch.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/useraction/UserActionSearch.java @@ -1,7 +1,5 @@ package org.egov.common.models.project.useraction; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.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/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..3f52835a270 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,18 +1,18 @@ 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 */ 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..17ea81e8ed7 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,18 +1,18 @@ 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 */ 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. */ From f99475a8003bf8835dc1c3d4806998ffa272936e Mon Sep 17 00:00:00 2001 From: Priyanka-eGov <74049060+Priyanka-eGov@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:26:57 +0530 Subject: [PATCH 08/20] HCMPRE-169 code review comments (#835) * HCMPRE-169 code review comments * HCMPRE-169 adding code comments * HCMPRE-169 adding code comments * HCMPRE-169 changing mdms v2 field name for uom * HCMPRE-169 code review comments * HCMPRE-169 code review comments --- health-services/plan-service/pom.xml | 6 + .../src/main/java/digit/Main.java | 2 +- .../java/digit/config/ServiceConstants.java | 59 ++++- .../PlanConfigurationRepository.java | 1 + .../service/PlanConfigurationService.java | 14 +- .../java/digit/service/PlanValidator.java | 137 +++++++---- .../service/enrichment/EnrichmentService.java | 61 ++--- .../validator/PlanConfigurationValidator.java | 229 +++++++++++------- .../web/controllers/PlanConfigController.java | 8 +- .../src/main/java/digit/web/models/File.java | 12 +- .../java/digit/web/models/MetricDetail.java | 11 +- .../main/java/digit/web/models/Operation.java | 12 +- 12 files changed, 332 insertions(+), 220 deletions(-) diff --git a/health-services/plan-service/pom.xml b/health-services/plan-service/pom.xml index ce6a2dff717..148766ff97d 100644 --- a/health-services/plan-service/pom.xml +++ b/health-services/plan-service/pom.xml @@ -89,6 +89,12 @@ junit test + + org.egov.services + services-common + 2.9.0-SNAPSHOT + compile + 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/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 2266c82de93..8e04d50c123 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 @@ -23,25 +23,25 @@ public class ServiceConstants { 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 FILESTORE_ID_INVALID_MESSAGE = " Resource mapping does not have a Valid File Store Id "; public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE = "ASSUMPTION_KEY_NOT_FOUND_IN_MDMS"; - public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS"; + public static final String ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE = "Assumption Key is not present in MDMS "; public static final String 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 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 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"; @@ -76,6 +76,51 @@ public class ServiceConstants { public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE = "BOUNDARY_CODE_MAPPING_NOT_FOUND"; public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE = "Boundary Code Mapping is required column is not found."; + public static final String 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 PLAN_RESOURCES_NOT_ALLOWED_CODE = "PLAN_RESOURCES_NOT_ALLOWED"; + public static final String PLAN_RESOURCES_NOT_ALLOWED_MESSAGE = "Resources are not allowed if plan configuration id is provided"; + + public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE = "INVALID_RESOURCE_ACTIVITY_LINKAGE"; + public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE = "Resource-Activity linkage is invalid"; + + 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"; + //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions"; diff --git a/health-services/plan-service/src/main/java/digit/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/service/PlanConfigurationService.java b/health-services/plan-service/src/main/java/digit/service/PlanConfigurationService.java index 303d9477e70..85238f723a5 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 @@ -2,6 +2,7 @@ import digit.config.Configuration; import digit.kafka.Producer; +import digit.repository.PlanConfigurationRepository; import digit.repository.impl.PlanConfigurationRepositoryImpl; import digit.service.enrichment.EnrichmentService; import digit.service.validator.PlanConfigurationValidator; @@ -26,12 +27,12 @@ public class PlanConfigurationService { 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) { + , PlanConfigurationValidator validator, PlanConfigurationRepository repository, ResponseInfoFactory responseInfoFactory) { this.producer = producer; this.enrichmentService = enrichmentService; this.config = config; @@ -45,12 +46,17 @@ public PlanConfigurationService(Producer producer, EnrichmentService enrichmentS * @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; + PlanConfigurationResponse response = PlanConfigurationResponse.builder() + .planConfiguration(Collections.singletonList(request.getPlanConfiguration())) + .responseInfo(responseInfoFactory + .createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .build(); + return response; } /** diff --git a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java index b52c3450c6d..40958a9e0d3 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -5,28 +5,16 @@ import digit.repository.PlanRepository; import digit.util.MdmsUtil; import digit.web.models.*; +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.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; 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; +import static digit.config.ServiceConstants.*; @Component public class PlanValidator { @@ -37,10 +25,13 @@ public class PlanValidator { private MdmsUtil mdmsUtil; - public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil) { + private MultiStateInstanceUtil centralInstanceUtil; + + public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, MultiStateInstanceUtil centralInstanceUtil) { this.planRepository = planRepository; this.planConfigurationRepository = planConfigurationRepository; this.mdmsUtil = mdmsUtil; + this.centralInstanceUtil = centralInstanceUtil; } /** @@ -48,7 +39,7 @@ public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository * @param request */ public void validatePlanCreate(PlanRequest request) { - String rootTenantId = request.getPlan().getTenantId().split("\\.")[0]; + String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); // Validate activities @@ -100,7 +91,7 @@ private void checkForCycleInActivityDependencies(PlanRequest request) { 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"); + throw new CustomException(CYCLIC_ACTIVITY_DEPENDENCY_CODE, CYCLIC_ACTIVITY_DEPENDENCY_MESSAGE); }); }); } @@ -120,7 +111,7 @@ private void validateDependentActivityCodes(PlanRequest request) { if(!CollectionUtils.isEmpty(activity.getDependencies())) { activity.getDependencies().forEach(dependency -> { if(!activityCodes.contains(dependency)) - throw new CustomException("INVALID_ACTIVITY_DEPENDENCY", "Activity dependency is invalid"); + throw new CustomException(INVALID_ACTIVITY_DEPENDENCY_CODE, INVALID_ACTIVITY_DEPENDENCY_MESSAGE); }); } }); @@ -134,7 +125,7 @@ private void validateDependentActivityCodes(PlanRequest 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"); + throw new CustomException(ACTIVITIES_CANNOT_BE_NULL_CODE, ACTIVITIES_CANNOT_BE_NULL_MESSAGE); Set activityCodes = request.getPlan().getActivities().stream() .map(Activity::getCode) @@ -142,26 +133,26 @@ private void validateActivities(PlanRequest request) { // 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"); + 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().getExecutionPlanId()) && CollectionUtils.isEmpty(request.getPlan().getActivities())) { - throw new CustomException("PLAN_ACTIVITIES_MANDATORY", "Activities are mandatory if execution plan id is not provided"); + throw new CustomException(PLAN_ACTIVITIES_MANDATORY_CODE, PLAN_ACTIVITIES_MANDATORY_MESSAGE); } // If execution plan id is provided, providing activities is not allowed if(!ObjectUtils.isEmpty(request.getPlan().getExecutionPlanId()) && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { - throw new CustomException("PLAN_ACTIVITIES_NOT_ALLOWED", "Activities are not allowed if execution plan id is provided"); + 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", "Planned end date cannot be before planned start date"); + throw new CustomException(INVALID_ACTIVITY_DATES_CODE, INVALID_ACTIVITY_DATES_MESSAGE); }); } } @@ -188,13 +179,13 @@ 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"); + throw new CustomException(PLAN_RESOURCES_MANDATORY_CODE, PLAN_RESOURCES_MANDATORY_MESSAGE); } // If plan configuration id is provided, providing resources is not allowed if(!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && !CollectionUtils.isEmpty(request.getPlan().getResources())) { - throw new CustomException("PLAN_RESOURCES_NOT_ALLOWED", "Resources are not allowed if plan configuration id is provided"); + throw new CustomException(PLAN_RESOURCES_NOT_ALLOWED_CODE, PLAN_RESOURCES_NOT_ALLOWED_MESSAGE); } // Validate resource type existence @@ -220,7 +211,7 @@ private void validateResourceActivityLinkage(PlanRequest request) { // 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"); + throw new CustomException(INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE, INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE); }); } } @@ -239,7 +230,7 @@ private void validateTargetActivityLinkage(PlanRequest request) { // 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"); + throw new CustomException(INVALID_TARGET_ACTIVITY_LINKAGE_CODE, INVALID_TARGET_ACTIVITY_LINKAGE_MESSAGE); }); } } @@ -252,7 +243,7 @@ public void validatePlanUpdate(PlanRequest request) { // Validate plan existence validatePlanExistence(request); - String rootTenantId = request.getPlan().getTenantId().split("\\.")[0]; + String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); // Validate activities @@ -290,42 +281,61 @@ public void validatePlanUpdate(PlanRequest request) { } + /** + * 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 + // 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"); + // 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 + // 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"); + // 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 + // 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"); + // 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 @@ -335,10 +345,21 @@ private void validatePlanExistence(PlanRequest request) { 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"); + throw new CustomException(INVALID_PLAN_ID_CODE, INVALID_PLAN_ID_MESSAGE); } } + /** + * 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"; @@ -350,14 +371,26 @@ public void validateTargetMetrics(PlanRequest request, Object mdmsData) { } catch (Exception e) { throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - - for (Target target : plan.getTargets()) { - if (!metricListFromMDMS.contains(target.getMetric())) { + 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(); @@ -365,19 +398,21 @@ public void validateMetricDetailUnit(PlanRequest request, Object mdmsData) { .map(Target::getMetricDetail) .toList(); - List metricUnitListFromMDMS = null; - final String jsonPathForMetricUnit = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UOM + ".*.code"; + 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); } - for (MetricDetail metricDetail : metricDetails) { - if (!metricUnitListFromMDMS.contains(metricDetail.getMetricUnit())) { + 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); } - } + }); + } } 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..86c1fdb4b81 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 @@ -6,14 +6,13 @@ import digit.web.models.PlanConfigurationRequest; import digit.web.models.ResourceMapping; 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 java.util.List; -import static digit.config.ServiceConstants.USERINFO_MISSING_CODE; -import static digit.config.ServiceConstants.USERINFO_MISSING_MESSAGE; +import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; + import org.springframework.util.ObjectUtils; @Component @@ -27,23 +26,13 @@ public EnrichmentService(Configuration config) { /** * 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"); // Generate id for plan configuration @@ -64,17 +53,8 @@ public void enrichPlanConfiguration(PlanConfiguration planConfiguration) { // Generate id for resource mappings 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)); } /** @@ -84,21 +64,9 @@ public void enrichAuditDetails(PlanConfigurationRequest request, Boolean isCreat * @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); - - enrichAuditDetails(request, Boolean.FALSE); - } - - /** - * 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(); - // For Files + // Generate id for Files planConfiguration.getFiles().forEach(file -> { if (ObjectUtils.isEmpty(file.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); @@ -106,27 +74,28 @@ public void enrichPlanConfigurationForUpdate(PlanConfigurationRequest request) { enrichActiveForResourceMapping(file, request.getPlanConfiguration().getResourceMapping()); }); - // For Assumptions + // Generate id for Assumptions planConfiguration.getAssumptions().forEach(assumption -> { if (ObjectUtils.isEmpty(assumption.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id"); } }); - // For Operations + // Generate id for Operations planConfiguration.getOperations().forEach(operation -> { if (ObjectUtils.isEmpty(operation.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(operation, "id"); } }); - // For ResourceMappings + // Generate id for ResourceMappings planConfiguration.getResourceMapping().forEach(resourceMapping -> { if (ObjectUtils.isEmpty(resourceMapping.getId())) { UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); } }); + planConfiguration.setAuditDetails(prepareAuditDetails(request.getPlanConfiguration().getAuditDetails(), request.getRequestInfo(), Boolean.FALSE)); } /** @@ -138,11 +107,9 @@ public void enrichPlanConfigurationForUpdate(PlanConfigurationRequest request) { 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)); } } 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..d042850934b 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 @@ -12,9 +12,11 @@ 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 org.springframework.util.ObjectUtils; import static digit.config.ServiceConstants.*; @@ -27,9 +29,12 @@ public class PlanConfigurationValidator { private PlanConfigurationRepository planConfigRepository; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository) { + private MultiStateInstanceUtil centralInstanceUtil; + + public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository, MultiStateInstanceUtil centralInstanceUtil) { this.mdmsUtil = mdmsUtil; this.planConfigRepository = planConfigRepository; + this.centralInstanceUtil = centralInstanceUtil; } /** @@ -38,16 +43,33 @@ public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository */ 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); + // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); + + // Validate that the assumption values in the plan configuration are correct validateAssumptionValue(planConfiguration); + + // Validate the filestore ID in the plan configuration's request mappings validateFilestoreId(planConfiguration); + + // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); + + // Validate that the inputs for operations in the request match those in the MDMS data validateOperationsInputAgainstMDMS(request, mdmsData); + + // Validate that the resource mappings in the request match those in the MDMS data validateResourceMappingAgainstMDMS(request, mdmsData); + + // Validate the uniqueness of the 'mappedTo' fields in the resource mappings validateMappedToUniqueness(planConfiguration.getResourceMapping()); + + // Validate the user information in the request + validateUserInfo(request); + } /** @@ -63,14 +85,15 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { .map(Assumption::getKey) .collect(Collectors.toSet()); - List operations = planConfiguration.getOperations(); - for (Operation operation : operations) { - // Check if the operation is using an assumption key that is not in the set of active assumption keys - if (operation.getActive() && !activeAssumptionKeys.contains(operation.getAssumptionValue())) { - log.error("Assumption Value " + operation.getAssumptionValue() + " is not present in the list of active Assumption Keys"); - throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + operation.getAssumptionValue()); - } - } + planConfiguration.getOperations().stream() + .filter(Operation::getActive) + .forEach(operation -> { + if (!activeAssumptionKeys.contains(operation.getAssumptionValue())) { + log.error("Assumption Value " + operation.getAssumptionValue() + " is not present in the list of active Assumption Keys"); + throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + operation.getAssumptionValue()); + } + }); + } @@ -92,14 +115,15 @@ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, O 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); - } - } + HashSet assumptionSetFromMDMS = new HashSet<>(assumptionListFromMDMS); + planConfiguration.getAssumptions().forEach(assumption -> { + if (!assumptionSetFromMDMS.contains(assumption.getKey())) { + log.error(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey()); + throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + " at JSONPath: " + jsonPathForAssumption); + } + } + ); + } /** @@ -111,13 +135,13 @@ public void validateFilestoreId(PlanConfiguration planConfiguration) { .map(File::getFilestoreId) .collect(Collectors.toSet()); - List resourceMappingList = planConfiguration.getResourceMapping(); - for (ResourceMapping mapping : resourceMappingList) { + planConfiguration.getResourceMapping().stream().forEach(mapping -> { if (!fileStoreIds.contains(mapping.getFilestoreId())) { log.error("Resource Mapping " + mapping.getMappedTo() + " does not have valid fileStoreId " + mapping.getFilestoreId()); throw new CustomException(FILESTORE_ID_INVALID_CODE, FILESTORE_ID_INVALID_MESSAGE); } - } + }); + } /** @@ -145,19 +169,22 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque 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(!templateIdentifierListFromMDMS.contains(file.getTemplateIdentifier())) + if(!templateIdentifierSetFromMDMS.contains(file.getTemplateIdentifier())) { - log.error("Template Identifier " + file.getTemplateIdentifier() + " is not present in MDMS"); + 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 (requiredTemplateIdentifierFromMDMS.contains(templateIdentifier)) { // Check if the template identifier is required + 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 with the required Template Identifier should be present " + file.getTemplateIdentifier()); + 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); } } @@ -165,12 +192,14 @@ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest reque } // 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); - } - } + requiredTemplateIdentifierSetFromMDMS + .stream() + .forEach(requiredTemplate -> { + if (!activeRequiredTemplates.contains(requiredTemplate)) { + log.error("Required Template Identifier " + requiredTemplate + " does not have any active file."); + throw new CustomException(REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_CODE, REQUIRED_TEMPLATE_IDENTIFIER_NOT_FOUND_MESSAGE); + } + }); } @@ -201,37 +230,50 @@ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, log.error(e.getMessage()); throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - List allowedColumns = getRuleConfigInputsFromSchema(ruleInputsListFromMDMS, templateIds, inputFileTypes); + + HashSet ruleInputsSetFromMDMS = new HashSet<>(ruleInputsListFromMDMS); + + HashSet allowedColumns = getColumnsFromSchemaThatAreRuleInputs(ruleInputsSetFromMDMS, templateIds, inputFileTypes); planConfiguration.getOperations().stream() .map(Operation::getOutput) .forEach(allowedColumns::add); - for (Operation operation : planConfiguration.getOperations()) { + + planConfiguration.getOperations().stream().forEach(operation -> { if (!allowedColumns.contains(operation.getInput())) { log.error("Input Value " + operation.getInput() + " is not present in MDMS Input List"); throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE); } - } + }); + } - // helper function - public static List getRuleConfigInputsFromSchema(List schemas, List templateIds, List inputFileTypes) { + /** + * Filters the Schema MDMS data by type and section + * returns the list of columns which have the property 'isRuleConfigureInputs' as true + * + * @param schemas List of schemas from MDMS + * @param templateIds The list of template identifiers from request object + * @param inputFileTypes The list of input file type from request object + */ + public static HashSet getColumnsFromSchemaThatAreRuleInputs(HashSet schemas, List templateIds, List inputFileTypes) { if (schemas == null) { - return new ArrayList<>(); + return new HashSet<>(); } - Set finalData = new HashSet<>(); + HashSet finalData = new HashSet<>(); for (Object item : schemas) { LinkedHashMap schemaEntity = (LinkedHashMap) item; if(!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) continue; LinkedHashMap columns = (LinkedHashMap)((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); - if(columns == null) return new 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()); - } - } + if(columns == null) return new HashSet<>(); + columns.entrySet().stream() + .forEach(column -> { + LinkedHashMap data = column.getValue(); + if(data.get(MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT)){ + finalData.add(column.getKey()); + } + }); // Add the keys to finalData } - return new ArrayList<>(finalData); + return finalData; } @@ -244,14 +286,13 @@ public static List getRuleConfigInputsFromSchema(List schemas, L */ public static void validateMappedToUniqueness(List resourceMappings) { Set uniqueMappedToSet = new HashSet<>(); - for (ResourceMapping mapping : resourceMappings) { + resourceMappings.stream().forEach(mapping -> { String uniqueKey = mapping.getFilestoreId() + "-" + mapping.getMappedTo(); if (!uniqueMappedToSet.add(uniqueKey)) { log.error("Duplicate MappedTo " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - throw new CustomException(DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE, - DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE + " - " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); + throw new CustomException(DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE, DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE + " - " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); } - } + }); } @@ -280,22 +321,39 @@ private void validateSearchCriteria(PlanConfigurationSearchRequest planConfigura */ 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); - // Validate plan existence - PlanConfiguration planConfigurationFromDB = validatePlanConfigExistence(request); + // Validate the existence of the plan configuration in the request + validatePlanConfigExistence(request); + // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); + + // Validate that the assumption values in the plan configuration are correct validateAssumptionValue(planConfiguration); + + // Validate the filestore ID in the plan configuration's request mappings validateFilestoreId(planConfiguration); -// validateFilesActive(planConfigurationFromDB, planConfiguration); + + // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); + + // Validate that the inputs for operations in the request match those in the MDMS data validateOperationsInputAgainstMDMS(request, mdmsData); + + // Validate the dependencies between operations in the plan configuration validateOperationDependencies(planConfiguration); + + // Validate that the resource mappings in the request match those in the MDMS data validateResourceMappingAgainstMDMS(request, mdmsData); + + // Validate the uniqueness of the 'mappedTo' fields in the resource mappings validateMappedToUniqueness(planConfiguration.getResourceMapping()); + // Validate the user information in the request + validateUserInfo(request); + } /** @@ -330,12 +388,12 @@ public static void validateOperationDependencies(PlanConfiguration planConfigura .collect(Collectors.toSet()); // Check for each inactive operation - for (Operation operation : planConfiguration.getOperations()) { + planConfiguration.getOperations().stream().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()); } - } + }); } @@ -349,11 +407,11 @@ public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request, List files = planConfiguration.getFiles(); List templateIds = files.stream() .map(File::getTemplateIdentifier) - .collect(Collectors.toList()); + .toList(); List inputFileTypes = files.stream() .map(File::getInputFileType) .map(File.InputFileTypeEnum::toString) - .collect(Collectors.toList()); + .toList(); final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS; List ruleInputsListFromMDMS = null; @@ -364,7 +422,8 @@ public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request, log.error(e.getMessage()); throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); } - List requiredColumns = getIsTruePropertyFromSchema(ruleInputsListFromMDMS, templateIds, inputFileTypes); + HashSet ruleInputsSetFromMDMS = new HashSet<>(ruleInputsListFromMDMS); + HashSet requiredColumns = getRequiredColumnsFromSchema(ruleInputsSetFromMDMS, templateIds, inputFileTypes); List resourceMappings = planConfiguration.getResourceMapping(); // Throw a custom exception if no active mappings with BOUNDARY_CODE are found @@ -380,45 +439,45 @@ public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request, /** - * 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 + * Filters the Schema MDMS data by type and section + * returns the list of columns which have the property 'isRequired' as true + * + * @param schemas List of schemas from MDMS + * @param templateIds The list of template identifiers from request object + * @param inputFileTypes The list of input file type from request object + * @return List of Columns that are required */ - public static List getIsTruePropertyFromSchema(List schemas, List templateIds, List inputFileTypes) { - if (schemas == null) { - return new ArrayList<>(); + public static HashSet getRequiredColumnsFromSchema(HashSet schemas, List templateIds, List inputFileTypes) { + if (CollectionUtils.isEmpty(schemas)) { + return new HashSet<>(); } - Set finalData = new HashSet<>(); + HashSet finalData = new HashSet<>(); for (Object item : schemas) { LinkedHashMap schemaEntity = (LinkedHashMap) item; if(!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) continue; LinkedHashMap columns = (LinkedHashMap)((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); - if(columns == null) return new ArrayList<>(); - for(Map.Entry column : columns.entrySet()){ + if (columns == null) return new HashSet<>(); + columns.entrySet().stream().forEach(column -> { LinkedHashMap data = column.getValue(); - if(data.get(MDMS_SCHEMA_PROPERTIES_IS_REQUIRED)){ + if (data.get(MDMS_SCHEMA_PROPERTIES_IS_REQUIRED)) { finalData.add(column.getKey()); } - } + }); } - return new ArrayList<>(finalData); + return finalData; } - public void validateFilesActive(PlanConfiguration planConfigurationFromDB, PlanConfiguration planConfiguration) + /** + * Validates the user information within the provided PlanConfigurationRequest. + * + * @param request the PlanConfigurationRequest containing the user information to be validated + * @throws CustomException if the user information is missing in the request + */ + public void validateUserInfo(PlanConfigurationRequest request) { - // 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"); - } + if (ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) { + log.error(USERINFO_MISSING_MESSAGE); + throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); } } } 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..4729cdd736e 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 @@ -45,13 +45,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/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..fbc647cfc1d 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 */ @@ -80,12 +82,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 + "'")); } } From 1ed7c59f8a1b74589ca71fac952dabc7cef45ab8 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov <74049060+Priyanka-eGov@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:31:27 +0530 Subject: [PATCH 09/20] HCMPRE-218 adding validation for plan config name (#844) * HCMPRE-218 adding validation for name validation * HCMPRE-218 adding validation for name validation * HCMPRE-218 moving "$." into constants * HCMPRE-218 code review comments --------- Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com> --- .../java/digit/config/ServiceConstants.java | 12 ++++ .../validator/PlanConfigurationValidator.java | 61 ++++++++++++++++--- .../src/main/java/digit/util/MdmsUtil.java | 6 +- .../src/main/java/digit/util/ServiceUtil.java | 23 +++++++ .../digit/web/models/PlanConfiguration.java | 3 +- 5 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 health-services/plan-service/src/main/java/digit/util/ServiceUtil.java diff --git a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java index 8e04d50c123..ab694a05961 100644 --- a/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java +++ b/health-services/plan-service/src/main/java/digit/config/ServiceConstants.java @@ -76,6 +76,12 @@ public class ServiceConstants { public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE = "BOUNDARY_CODE_MAPPING_NOT_FOUND"; public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE = "Boundary Code Mapping is required column is not found."; + public static final String 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"; @@ -121,6 +127,7 @@ public class ServiceConstants { public static final String DUPLICATE_ACTIVITY_UUIDS_CODE = "DUPLICATE_ACTIVITY_UUIDS"; public static final String DUPLICATE_ACTIVITY_UUIDS_MESSAGE = "Activity UUIDs should be unique"; + //mdms constants public static final String MDMS_PLAN_MODULE_NAME = "hcm-microplanning"; public static final String MDMS_MASTER_ASSUMPTION = "HypothesisAssumptions"; @@ -129,6 +136,9 @@ public class ServiceConstants { public static final String MDMS_MASTER_SCHEMAS = "Schemas"; public static final String MDMS_MASTER_METRIC = "Metric"; public static final String MDMS_MASTER_UOM = "Uom"; + public static final String MDMS_MASTER_NAME_VALIDATION= "MicroplanNamingRegex"; + + public static final String JSON_ROOT_PATH = "$."; public static final String DOT_SEPARATOR = "."; @@ -155,4 +165,6 @@ public class ServiceConstants { public static final String MDMS_SCHEMA_PROPERTIES_IS_REQUIRED = "isRequired"; public static final String BOUNDARY_CODE = "boundaryCode"; + public static final String NAME_VALIDATION_DATA = "Data"; + } diff --git a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java index d042850934b..22d316b707e 100644 --- a/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java @@ -4,9 +4,12 @@ import digit.config.ServiceConstants; import digit.repository.PlanConfigurationRepository; import digit.util.MdmsUtil; +import digit.util.ServiceUtil; import digit.web.models.*; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -29,12 +32,15 @@ public class PlanConfigurationValidator { private PlanConfigurationRepository planConfigRepository; + + private ServiceUtil serviceUtil; private MultiStateInstanceUtil centralInstanceUtil; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository, MultiStateInstanceUtil centralInstanceUtil) { + public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository, ServiceUtil serviceUtil, MultiStateInstanceUtil centralInstanceUtil) { this.mdmsUtil = mdmsUtil; this.planConfigRepository = planConfigRepository; - this.centralInstanceUtil = centralInstanceUtil; + this.serviceUtil = serviceUtil; + this.centralInstanceUtil = centralInstanceUtil; } /** @@ -67,11 +73,48 @@ public void validateCreate(PlanConfigurationRequest request) { // Validate the uniqueness of the 'mappedTo' fields in the resource mappings validateMappedToUniqueness(planConfiguration.getResourceMapping()); + //Validating plan config name against MDMS data + validatePlanConfigName(request, mdmsData); + // Validate the user information in the request validateUserInfo(request); } + /** + * 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 validatePlanConfigName(PlanConfigurationRequest request, Object mdmsData) + { + PlanConfiguration planConfiguration = request.getPlanConfiguration(); + + final String jsonPathForNameValidation = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_NAME_VALIDATION + "[*].data"; + + List nameValidationListFromMDMS = null; + try { + nameValidationListFromMDMS = JsonPath.read(mdmsData, jsonPathForNameValidation); + } catch (Exception e) { + log.error(jsonPathForNameValidation); + throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + } + + if (CollectionUtils.isEmpty(nameValidationListFromMDMS)) { + throw new CustomException(NAME_VALIDATION_LIST_EMPTY_CODE, NAME_VALIDATION_LIST_EMPTY_MESSAGE); + } + + String regexPattern = (String) nameValidationListFromMDMS.get(0); + if (!serviceUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) { + throw new CustomException(NAME_VALIDATION_FAILED_CODE, NAME_VALIDATION_FAILED_MESSAGE); + } + + } + + /** * Validates the assumption values against the assumption keys in the plan configuration. * If an operation uses an inactive assumption, throws an exception. @@ -104,7 +147,7 @@ public void validateAssumptionValue(PlanConfiguration planConfiguration) { */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; + final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; List assumptionListFromMDMS = null; try { @@ -153,8 +196,8 @@ public void validateFilestoreId(PlanConfiguration planConfiguration) { */ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForTemplateIdentifier = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + ".*.id"; - final String jsonPathForTemplateIdentifierIsRequired = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_UPLOAD_CONFIGURATION + "[?(@.required == true)].id"; + 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; @@ -221,7 +264,7 @@ public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, .map(File.InputFileTypeEnum::toString) .collect(Collectors.toList()); - final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS; + final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS; List ruleInputsListFromMDMS = null; try { log.info(jsonPathForRuleInputs); @@ -351,9 +394,11 @@ public void validateUpdateRequest(PlanConfigurationRequest request) { // Validate the uniqueness of the 'mappedTo' fields in the resource mappings validateMappedToUniqueness(planConfiguration.getResourceMapping()); + //Validating plan config name against MDMS data + validatePlanConfigName(request, mdmsData); + // Validate the user information in the request validateUserInfo(request); - } /** @@ -413,7 +458,7 @@ public void validateResourceMappingAgainstMDMS(PlanConfigurationRequest request, .map(File.InputFileTypeEnum::toString) .toList(); - final String jsonPathForRuleInputs = "$." + MDMS_PLAN_MODULE_NAME + "." + MDMS_MASTER_SCHEMAS; + final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS; List ruleInputsListFromMDMS = null; try { log.info(jsonPathForRuleInputs); 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..fb0f6560908 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 @@ -75,14 +75,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/ServiceUtil.java b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java new file mode 100644 index 00000000000..51959990534 --- /dev/null +++ b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java @@ -0,0 +1,23 @@ +package digit.util; + +import org.springframework.stereotype.Component; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Component +public class ServiceUtil { + + /** + * Validates the given input string against the provided regex pattern. + * + * @param patternString the regex pattern to validate against + * @param inputString the input string to be validated + * @return true if the input string matches the regex pattern, false otherwise + */ + public Boolean validateStringAgainstRegex(String patternString, String inputString) { + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(inputString); + return matcher.matches(); + } +} diff --git a/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java b/health-services/plan-service/src/main/java/digit/web/models/PlanConfiguration.java index dbf9ed7f139..9032da0bfed 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 @@ -38,8 +38,7 @@ 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") From 6498f888b443318e289c3fe87b876302cd181bb0 Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Mon, 23 Sep 2024 15:25:16 +0530 Subject: [PATCH 10/20] HCMPRE-646: added changes (#897) --- .../java/org/egov/project/config/ProjectConfiguration.java | 3 +++ .../org/egov/project/validator/project/ProjectValidator.java | 2 +- .../project/src/main/resources/application.properties | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java index 26759e381e2..67ee5a87af6 100644 --- a/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java +++ b/health-services/project/src/main/java/org/egov/project/config/ProjectConfiguration.java @@ -222,4 +222,7 @@ public class ProjectConfiguration { @Value("${project.task.no.resource.validation.status}") private List noResourceStatuses; + + @Value("${project.attendance.feature.enabled:true}") + private Boolean isAttendanceFeatureEnabled; } diff --git a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java index 266f664312d..9aaba88a427 100644 --- a/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java +++ b/health-services/project/src/main/java/org/egov/project/validator/project/ProjectValidator.java @@ -75,7 +75,7 @@ public void validateCreateProjectRequest(ProjectRequest request) { //Verify MDMS Data // TODO: Uncomment and fix as per HCM once we get clarity // validateRequestMDMSData(request, tenantId, errorMap); - validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); + if(config.getIsAttendanceFeatureEnabled()) validateAttendanceSessionAgainstMDMS(request,errorMap,tenantId); //Get boundaries in list from all Projects in request body for validation Map> boundariesForValidation = getBoundaryForValidation(request.getProjects()); diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index 93f601466a9..71af8eab0d3 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -180,4 +180,7 @@ project.location.capture.kafka.create.topic=save-location-capture-project-topic project.location.capture.consumer.bulk.create.topic=save-location-capture-project-bulk-topic #---------No resource statuses ------------# -project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED \ No newline at end of file +project.task.no.resource.validation.status=ADMINISTRATION_FAILED, BENEFICIARY_REFUSED, CLOSED_HOUSEHOLD, NOT_ADMINISTERED + +#---------Attendance Feature ------------# +project.attendance.feature.enabled=true From 958201fbba040e5429d184aa17cb3a7702649142 Mon Sep 17 00:00:00 2001 From: "kavi_elrey@1993" <25226238+kavi-egov@users.noreply.github.com> Date: Mon, 30 Sep 2024 11:02:41 +0530 Subject: [PATCH 11/20] Update CODEOWNERS (#924) --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index e5b57cd157d..cacb23525d2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @kavi-egov @sathishp-eGov \ No newline at end of file +* @kavi-egov @sathishp-eGov @shashwat-egov From de909f187c807a4763d0e321ce86559ab4b5e75d Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Mon, 30 Sep 2024 17:26:04 +0530 Subject: [PATCH 12/20] Hcmpre 639 shashwat changes (#919) * Removed the project facility mapping validation check as it is not required * Removed the project facilty valaidation check in ValidatorUtil.java * Removed the local receiverId in ValidatorUtil.java --------- Co-authored-by: Shashwat12-egov --- .../main/java/org/egov/stock/service/FacilityService.java | 3 --- .../src/main/java/org/egov/stock/util/ValidatorUtil.java | 6 +----- 2 files changed, 1 insertion(+), 8 deletions(-) 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..723fd98f967 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 @@ -99,9 +99,6 @@ public Map> validateProjectFacilityMappings(List ent if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType())) { facilityIds.add(stock.getSenderId()); } - if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType())) { - facilityIds.add(stock.getReceiverId()); - } } } 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..4f975144e32 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 @@ -266,7 +266,6 @@ private static void enrichErrorForStock(List validEntities, for (Stock stock : validEntities) { String senderId = stock.getSenderId(); - String receiverId = stock.getReceiverId(); List facilityIds = ProjectFacilityMappingOfIds.get(stock.getReferenceId()); if (!CollectionUtils.isEmpty(facilityIds)) { @@ -274,11 +273,8 @@ private static void enrichErrorForStock(List validEntities, if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) && !facilityIds.contains(senderId)) { populateErrorForStock(stock, senderId, errorDetailsMap); } - - if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) && !facilityIds.contains(receiverId)) - populateErrorForStock(stock, receiverId, errorDetailsMap); } else { - populateErrorForStock(stock, senderId + " and " + receiverId, errorDetailsMap); + populateErrorForStock(stock, senderId, errorDetailsMap); } } } From 1a737194e4ec8811c4195e83b468ffcfbbde4969 Mon Sep 17 00:00:00 2001 From: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:45:44 +0530 Subject: [PATCH 13/20] Fixed multiple role search in individual service (#992) --- .../egov/individual/repository/IndividualRepository.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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) { From caaf7071e0ec934a68cbaab81d3de70751d1cc48 Mon Sep 17 00:00:00 2001 From: Shashwat12-egov Date: Wed, 6 Nov 2024 12:28:03 +0530 Subject: [PATCH 14/20] Hcmpre 639 shashwat changes (#973) * Removed the project facility mapping validation check as it is not required * Removed the project facilty valaidation check in ValidatorUtil.java * Removed the local receiverId in ValidatorUtil.java * Validating the sender and receiver based on transactiontype * Validating the sender and receiver based on transactiontype * Corrected the validation for the failed case * Added the comments --------- Co-authored-by: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com> --- .../egov/stock/service/FacilityService.java | 20 +++++++++-- .../org/egov/stock/util/ValidatorUtil.java | 36 +++++++++++++++++-- 2 files changed, 51 insertions(+), 5 deletions(-) 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 723fd98f967..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,33 +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()); } + + // 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() @@ -118,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/util/ValidatorUtil.java b/health-services/stock/src/main/java/org/egov/stock/util/ValidatorUtil.java index 4f975144e32..a4f0f61648a 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 @@ -13,6 +13,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.common.service.UserService; import org.egov.stock.service.FacilityService; import org.egov.tracer.model.CustomException; @@ -265,13 +266,42 @@ private static void enrichErrorForStock(List validEntities, for (Stock stock : validEntities) { + // Get the sender and receiver IDs from the stock object String senderId = stock.getSenderId(); + // 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); + } + + // 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); } } else { populateErrorForStock(stock, senderId, errorDetailsMap); From 46751ca6f6255e4ab5828de2e8c2971300a47f15 Mon Sep 17 00:00:00 2001 From: yashita-egov Date: Mon, 11 Nov 2024 13:29:04 +0530 Subject: [PATCH 15/20] HCMPRE-371: Added service definition update api (#996) * update service definition api added * fix values persister config * fix "values" persister config * active added in service definition persister config * resolved code review comments * added includeDeleted parameter in search * fix some issues * fix create api --- core-services/service-request/pom.xml | 2 +- .../servicerequest/config/Configuration.java | 3 + .../egov/servicerequest/error/ErrorCode.java | 14 ++ .../ServiceDefinitionQueryBuilder.java | 8 +- .../ServiceDefinitionRequestService.java | 14 +- .../ServiceRequestEnrichmentService.java | 65 +++++++ .../ServiceDefinitionRequestValidator.java | 67 +++++-- .../ServiceDefinitionSearchRequest.java | 3 +- .../src/main/resources/application.properties | 1 + .../resources/service-request-persister.yml | 183 +++++++++++++----- 10 files changed, 285 insertions(+), 75 deletions(-) diff --git a/core-services/service-request/pom.xml b/core-services/service-request/pom.xml index 3c16fbe8189..151055f4c03 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..c9e5f7b3cb0 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 { @@ -61,4 +62,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/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/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 From e1cefd620747c74fa39514bb1b05a93952634653 Mon Sep 17 00:00:00 2001 From: Shashwat12-egov Date: Wed, 13 Nov 2024 15:29:56 +0530 Subject: [PATCH 16/20] Update ValidatorUtil.java (#1112) --- .../stock/src/main/java/org/egov/stock/util/ValidatorUtil.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 a4f0f61648a..402f6fa3414 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 @@ -268,6 +268,7 @@ private static void enrichErrorForStock(List 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()); @@ -303,8 +304,6 @@ private static void enrichErrorForStock(List validEntities, // If facilityIds are empty, log an error for both sender and receiver populateErrorForStock(stock, senderId + " and " + receiverId, errorDetailsMap); } - } else { - populateErrorForStock(stock, senderId, errorDetailsMap); } } } From 9bba4d06a8d61c4ce19306ca23d001cc41819e43 Mon Sep 17 00:00:00 2001 From: nitish-egov <137176807+nitish-egov@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:27:59 +0530 Subject: [PATCH 17/20] added-search-criterias-project-service (#1169) --- .../querybuilder/ProjectAddressQueryBuilder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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=? "); From 26763cf493b3fec8bdcb4ba1e9dff137df31aaa0 Mon Sep 17 00:00:00 2001 From: Shashwat12-egov Date: Wed, 4 Dec 2024 17:42:56 +0530 Subject: [PATCH 18/20] Service additional field (#1146) * changed additionalDetails to additionalFields * boolean data type added in attribute definition * Added the filter for isActive * changed the serviceDefinition.code size from character varying(64) to character varying(256) * Revert "changed the serviceDefinition.code size from character varying(64) to character varying(256)" This reverts commit 24c971f354d78392b731ef8b6d8f30c861f9dc94. * Revert "Added the filter for isActive" This reverts commit 09d65c444e15b6783f629fc3b483eb2f9a5ecfd9. * changed the code character size from 64 to 256 (#1147) Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com> * added validation for boolean data type in service-request --------- Co-authored-by: yashita-egov Co-authored-by: Jagankumar <53823168+jagankumar-egov@users.noreply.github.com> Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com> --- .../egov/servicerequest/error/ErrorCode.java | 2 ++ .../validators/ServiceRequestValidator.java | 24 ++++--------------- .../web/models/AttributeDefinition.java | 6 +++-- .../web/models/AttributeValue.java | 2 +- .../servicerequest/web/models/Service.java | 2 +- .../web/models/ServiceDefinition.java | 4 ++-- ...115143930__servicedefinition_alter_ddl.sql | 9 +++++++ 7 files changed, 24 insertions(+), 25 deletions(-) create mode 100644 core-services/service-request/src/main/resources/db/migration/main/V20241115143930__servicedefinition_alter_ddl.sql 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 c9e5f7b3cb0..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 @@ -31,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 "; 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 cefb96adac8..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"), @@ -110,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/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); From ff4c11b9ecf67cb2e2741f4531f99d6653887548 Mon Sep 17 00:00:00 2001 From: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:58:41 +0530 Subject: [PATCH 19/20] Hcmpre 469 pagination all (#891) * HCMPRE-469: added changes for facility count * HCMPRE-469: added changes for models, added totalCount fields in required model classes * HCMPRE-469: added changes for project facility, project staff, project resource, hf-referral, stock and stock reconciliation, also added helper function in common utils for findWithCount * HCMPRE-469: added changes for removing digit-models deprecated dependency, replaced with tracer library references and mdms client references * HCMPRE-469: added changes for project service, removed reference for digits model * Removed the dev from version * Removed the dev from version of common libraries * Removed the dev from version of common libraries * Removed the order by id statement while searching the facility * Removed setting of total count line from the FacilityService file * Removed setting of total count line from the FacilityService file --------- Co-authored-by: Shashwat12-egov Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com> --- health-services/facility/pom.xml | 4 +- .../repository/FacilityRepository.java | 21 +++++--- .../rowmapper/FacilityRowMapper.java | 2 +- .../facility/service/FacilityService.java | 21 +++++--- .../validator/FNonExistentValidator.java | 2 +- .../validator/FRowVersionValidator.java | 2 +- .../controllers/FacilityApiController.java | 7 ++- .../NonExistentEntityValidatorTest.java | 8 +++- .../validator/RowVersionValidatorTest.java | 8 +++- .../libraries/health-services-common/pom.xml | 10 +++- .../data/repository/GenericRepository.java | 48 +++++++++++++++++++ .../libraries/health-services-models/pom.xml | 2 +- .../models/facility/FacilityBulkResponse.java | 23 +++++++-- .../individual/IndividualBulkResponse.java | 24 +++++++--- .../project/ProjectFacilityBulkResponse.java | 23 +++++++-- .../project/ProjectResourceBulkResponse.java | 5 ++ .../project/ProjectStaffBulkResponse.java | 27 +++++++++-- .../hfreferral/HFReferralBulkResponse.java | 18 +++++++ .../models/stock/StockBulkResponse.java | 26 ++++++++-- .../StockReconciliationBulkResponse.java | 25 ++++++++-- health-services/project/pom.xml | 4 +- .../repository/ProjectFacilityRepository.java | 11 +++-- .../rowmapper/DocumentRowMapper.java | 2 +- .../rowmapper/LocationCaptureRowMapper.java | 2 +- .../rowmapper/ProjectAddressRowMapper.java | 2 +- .../ProjectBeneficiaryRowMapper.java | 2 +- .../rowmapper/ProjectFacilityRowMapper.java | 2 +- .../rowmapper/ProjectResourceRowMapper.java | 2 +- .../rowmapper/ProjectRowMapper.java | 2 +- .../rowmapper/ProjectStaffRowMapper.java | 2 +- .../rowmapper/ProjectTaskRowMapper.java | 2 +- .../repository/rowmapper/TargetRowMapper.java | 2 +- .../rowmapper/TaskResourceRowMapper.java | 2 +- .../rowmapper/UserActionRowMapper.java | 2 +- .../service/ProjectFacilityService.java | 31 ++++++------ .../service/ProjectResourceService.java | 18 +++---- .../egov/project/service/ProjectService.java | 2 +- .../project/service/ProjectStaffService.java | 20 ++++---- .../service/enrichment/ProjectEnrichment.java | 2 +- .../ProjectTaskEnrichmentService.java | 2 +- .../org/egov/project/util/BoundaryUtil.java | 16 +++---- .../java/org/egov/project/util/MDMSUtils.java | 8 ++-- .../egov/project/util/ProjectServiceUtil.java | 2 +- .../beneficiary/BeneficiaryValidator.java | 8 ++-- .../validator/staff/PsUserIdValidator.java | 14 +++--- .../task/PtResourceQuantityValidator.java | 8 ++-- .../web/controllers/ProjectApiController.java | 10 ++-- .../ProjectResourceApiController.java | 8 +++- .../ProjectBeneficiaryServiceCreateTest.java | 2 +- .../ProjectBeneficiaryServiceUpdateTest.java | 2 +- .../ProjectFacilityServiceSearchTest.java | 14 +++--- .../ProjectStaffServiceSearchTest.java | 13 ++--- .../ProjectFacilityApiControllerTest.java | 6 ++- .../ProjectStaffApiControllerTest.java | 3 +- health-services/referralmanagement/pom.xml | 4 +- .../repository/HFReferralRepository.java | 19 +++++--- .../rowmapper/HFReferralRowMapper.java | 2 +- .../rowmapper/ReferralRowMapper.java | 2 +- .../rowmapper/SideEffectRowMapper.java | 2 +- .../service/HFReferralService.java | 16 ++++--- .../service/MasterDataService.java | 11 ++--- .../util/ValidatorUtil.java | 2 +- .../HfrNonExistentEntityValidator.java | 3 +- .../hfreferral/HfrRowVersionValidator.java | 2 +- .../controllers/HFReferralApiController.java | 8 +++- health-services/stock/pom.xml | 4 +- .../StockReconciliationRowMapper.java | 2 +- .../repository/rowmapper/StockRowMapper.java | 2 +- .../service/StockReconciliationService.java | 18 +++---- .../org/egov/stock/service/StockService.java | 18 +++---- .../org/egov/stock/util/ValidatorUtil.java | 2 +- .../web/controllers/StockApiController.java | 5 +- .../StockReconciliationApiController.java | 8 +++- 73 files changed, 451 insertions(+), 213 deletions(-) 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/libraries/health-services-common/pom.xml b/health-services/libraries/health-services-common/pom.xml index 17c27125802..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.19-SNAPSHOT + 1.0.20-SNAPSHOT Shared classes among services @@ -115,7 +115,13 @@ org.egov.common health-services-models - 1.0.22-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-models/pom.xml b/health-services/libraries/health-services-models/pom.xml index cae31ed2480..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.22-SNAPSHOT + 1.0.23-SNAPSHOT 17 ${java.version} 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 4209e6e2311..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 @@ -14,27 +14,42 @@ import org.springframework.validation.annotation.Validated; /** - * 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/individual/IndividualBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualBulkResponse.java index 6ed081c182e..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 @@ -15,11 +15,10 @@ import org.springframework.validation.annotation.Validated; /** - * 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/project/ProjectFacilityBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectFacilityBulkResponse.java index 3b7c899ebfe..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 @@ -15,29 +15,46 @@ import org.springframework.validation.annotation.Validated; /** - * 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/ProjectResourceBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectResourceBulkResponse.java index 2fdba28281a..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 @@ -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/ProjectStaffBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffBulkResponse.java index 73d80462fb0..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 @@ -15,11 +15,9 @@ import org.springframework.validation.annotation.Validated; /** -* 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/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/stock/StockBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockBulkResponse.java index 3f52835a270..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 @@ -14,11 +14,9 @@ import org.springframework.validation.annotation.Validated; /** - * 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/StockReconciliationBulkResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/StockReconciliationBulkResponse.java index 17ea81e8ed7..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 @@ -14,11 +14,9 @@ import org.springframework.validation.annotation.Validated; /** - * 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/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/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/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/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/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..a2d0a3f5277 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,12 @@ 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 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 +15,10 @@ 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/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/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 402f6fa3414..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,8 +6,8 @@ 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; 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); } From 7d3c4cbeac6f4f38b2f4ed507bebed27bb8ead89 Mon Sep 17 00:00:00 2001 From: Priyanka-eGov <74049060+Priyanka-eGov@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:07:39 +0530 Subject: [PATCH 20/20] PR to develop branch for Microplanning v0.1 (changes in plan-service, resource-generator service) (#1176) * HCMPRE-599 updating Plan service models * HCMPRE-599 updating Plan service models * HCMPRE-599 changes * HCMPRE-599 adding census POJOs * HCMPRE-599changes for triggering pland census records on workflow status * HCMPRE-599 app.prop changes for resource generator service * Renaming resource-estimation-service to resource-generator * HCMPRE-1078 enrichment of resource mapping * HCMPRE-1122 changing processing logic * HCMPRE-1122 changing processing logic * HCMPRE-1122 updating operation related validations * HCMPRE-1122 adding method comments * enhancement in facilityCatchmentConsumer * enhancement in facilityCatchmentConsumer * removing catchement topic that was added before * added wf validation for approving estimations * adding additionalDetails as string while preparing rows for batchUpdate * adding additionalDetails as string while preparing rows for batchUpdate * HCMPRE-1094 changes for facility mapping create trigger on workflow * reverting the change in census-bulk-api * parsing additional details in bulk update api * Added plan config name in plan employee's and plan facility's search criteria * Bypassing validations for operations when source is CUSTOM * added workflow validations * removing unused service constants * Changes for triggering plan-facility mapping * adding project factory data create host * handling case for empty areaCodes in search criteria * handling case for empty areaCodes in search criteria * adding project factory data create host * Adding facility create trigger status * Adding additionalField table in census * adding plan config name in plan employee and plan facility pojo * Adding additionalField table in census * implemented partial search in plan config name * Changing datatype of value * HCMPRE-1162 enrich additionalfieldForCensus * HCMPRE-1162 enrich additionalfieldForCensus * updated query builder for census * handling null pointer exception on updating additional details * Changes to allow assumption values in input * Removing older method for getting input value * Making editable false for uploaded additional field during census create * HCMPRE-853 removing lat long fields from additional field overridekeys * Changes for adding execution order for operations * Changes for adding execution order for operations * Adding facilityName column and enriching servingPop * HCMPRE-853 added chnages for census search and fetching boundarycodes from one sheet * HCMPRE-853 changes for updating file with approved census data * HCMPRE-853 adding logs * pull from microplanning-dev * HCMPRE-853 integrating with project factory with updated resources * modification in wf-service * workflow auto-assignee issue * HCMPRE-853 commenting project factory integration * adding pagination for plan-employee api * changed the data type of BigDecimal * HCMPRE-1282 changes for updating estimates into plan * HCMPRE-1282 app.prop changes * Adding case for when celltype is formula. * enriching additional details with additional field key-value * modified orderBy clause * made changes in order by clause * added facilityType * pull from microplanning-dev * making fuzzy search cAse-insenSItive * making fuzzy search cAse-insenSItive * making fuzzy search cAse-insenSItive * pull from microplanning-dev * pull from microplanning-dev * modified pagination * HCMPRE-1282 changes for updating approved plans into file for campaign integration * added planConfigStatus in search criteria * HCMPRE-1282 changes for updating approved plans into file for campaign integration * HCMPRE-771 merging multiple alter table migration scripts into create table scripts. * Adding workflow restricted roles in census * Adding workflow restricted roles in census * Fixing limit and adding check for empty row * Fixing limit and adding check for empty row * added ranked query for plan employee assignment * added ranked query for plan employee assignment * HCMPRE-1300 DB migration script cleanup * adding plan bulk update topic * Adding facility name in census additional details * Wf auto assignment to multiple people * Wf auto assignment to multiple people * Adding boundaryTypeHierarchy Pojos and search endpoint * enriching jurisdiction mapping in census * changing jurisdictionMapping from jsonIgnore to jsonProperty * optimizing the enrichment functions and adding comments * handling null pointer exception * Wf auto assignment to multiple people * Set last modified time on update call * enriching serving population with sum of confirmed target population of serving boundaries * Reverting campaign update at the end. * modifying Wf for send back actions * enriching jurisdiction mapping in plan * setting assignees separetly for send back actions * Changing assignee column to Text in db * Changing assignee column to Text in db * enriching jurisdiction mapping * Changing validation logic for operations * enriching jurisdiction mapping * Changes for only validating when operation is active * Sort operations in planconfig search by execution order * Sort operations in planconfig search by execution order * Sort operations in planconfig search by execution order * Sort operations in planconfig search by execution order * type casting jurisdiction into list * Adding census changelog * Adding census changelog * Adding census changelog * Adding census changelog * Adding census changelog * Show on UI false for lat long fields * Updated plan service CHANGELOG * update plan config validation * Adding jurisdiction mapping in plan facility * Changing all collection dataType from list to set in API search criteria * Changing all collection dataType from list to set in API search criteria * removing validation for operation source * adding overloaded method for query builder in plan * adding overloaded method for query builder in plan * Adding validation to check for duplicates * pull from census-bulk-api * pull from census-bulk-api * Removing comments from WF in resource generator * Decreasing min size of assumptionvalue in Operation POJO to 1. * Changing mdms master in plan service for hierarchyConfig * changing min size of resource type in resource pojo * increasing request size for producer * changed version from 1.1.0 to 1.0.0 * changed version from 1.1.0 to 1.0.0 * changing the order * changing the order * changing the order * Increasing request size in application.properties * Updating resource generator changelog * Updating resource generator changelog * Adding boundaryAncestralPath for Plan Facility API * Adding boundaryAncestralPath for Plan Facility API * Adding ProjectFactory consumer in Plan Facility Service * Adding ProjectFactory consumer in Plan Facility Service * Adding plan changelog * Adding empty list as service boundary when null in consumer for project-factory * Increasing the max-request-size in census producer configuration * Increasing the max-request-size in plan producer configuration * Adding orderBy clause for plan search query * Removing unused census consumer * Replacing map from set for duplicate check in census row mapper * Replacing map from set for duplicate check in plan config row mapper * Replacing map from set for duplicate check in census row mapper * Replacing map from set for duplicate check in census row mapper * Replacing map from set for duplicate check in plan config row mapper * Replacing map from set for duplicate check in plan row mapper * Clearing set on new census entry * Clearing set on new plan entry * Clearing set on new plan config entry --------- Co-authored-by: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com> Co-authored-by: Tanishi Goyal --- build/build-config.yml | 13 +- health-services/census-service/CHANGELOG.md | 13 + health-services/census-service/README.md | 18 + health-services/census-service/pom.xml | 141 ++++ .../src/main/java/digit/Main.java | 20 + .../main/java/digit/config/Configuration.java | 86 +++ .../java/digit/config/MainConfiguration.java | 41 ++ .../java/digit/config/ServiceConstants.java | 114 +++ .../kafka/FacilityCatchmentConsumer.java | 99 +++ .../src/main/java/digit/kafka/Producer.java | 20 + .../digit/kafka/ResourceCensusConsumer.java | 37 + .../digit/repository/CensusRepository.java | 21 + .../repository/ServiceRequestRepository.java | 45 ++ .../repository/impl/CensusRepositoryImpl.java | 219 ++++++ .../querybuilder/CensusQueryBuilder.java | 219 ++++++ .../repository/rowmapper/CensusRowMapper.java | 148 ++++ .../rowmapper/StatusCountRowMapper.java | 30 + .../java/digit/service/CensusService.java | 127 ++++ .../service/enrichment/CensusEnrichment.java | 218 ++++++ .../enrichment/CensusTimeframeEnrichment.java | 47 ++ .../service/validator/CensusValidator.java | 337 +++++++++ .../service/workflow/WorkflowService.java | 331 +++++++++ .../main/java/digit/util/BoundaryUtil.java | 111 +++ .../java/digit/util/BusinessServiceUtil.java | 81 +++ .../src/main/java/digit/util/CommonUtil.java | 151 ++++ .../util/PlanEmployeeAssignmnetUtil.java | 59 ++ .../src/main/java/digit/util/QueryUtil.java | 139 ++++ .../java/digit/util/ResponseInfoFactory.java | 27 + .../web/controllers/CensusController.java | 76 ++ .../digit/web/models/AdditionalField.java} | 27 +- .../digit/web/models/BulkCensusRequest.java | 33 + .../main/java/digit/web/models/Census.java | 142 ++++ .../main/java/digit/web/models/CensusDTO.java | 104 +++ .../java/digit/web/models/CensusRequest.java | 31 + .../digit/web/models/CensusRequestDTO.java | 31 + .../java/digit/web/models/CensusResponse.java | 42 ++ .../web/models/CensusSearchCriteria.java | 72 ++ .../digit/web/models/CensusSearchRequest.java | 33 + .../web/models/PopulationByDemographic.java | 69 ++ .../digit/web/models/RequestInfoWrapper.java | 18 + .../boundary/BoundarySearchResponse.java | 42 ++ .../boundary/BoundaryTypeHierarchy.java | 30 + .../BoundaryTypeHierarchyDefinition.java | 45 ++ .../BoundaryTypeHierarchyResponse.java | 36 + .../BoundaryTypeHierarchySearchCriteria.java | 38 + .../BoundaryTypeHierarchySearchRequest.java | 33 + .../web/models/boundary/EnrichedBoundary.java | 42 ++ .../models/boundary/HierarchyRelation.java | 34 + .../models/plan/PlanEmployeeAssignment.java | 63 ++ .../plan/PlanEmployeeAssignmentResponse.java | 37 + .../PlanEmployeeAssignmentSearchCriteria.java | 50 ++ .../PlanEmployeeAssignmentSearchRequest.java | 29 + .../web/models/plan/PlanFacilityDTO.java | 72 ++ .../models/plan/PlanFacilityRequestDTO.java | 33 + .../src/main/resources/application.properties | 82 +++ .../src/main/resources/db/Dockerfile | 9 + .../src/main/resources/db/migrate.sh | 2 +- .../V20240925155908__census_create_ddl.sql | 36 + ...00__census_additional_field_create_ddl.sql | 12 + ...0700__alter_census_assignee_create_ddl.sql | 1 + .../src/main/resources/start.sh | 11 + .../test/java/digit/TestConfiguration.java | 16 + .../web/controllers/CensusControllerTest.java | 69 ++ health-services/plan-service/CHANGELOG.md | 42 +- health-services/plan-service/pom.xml | 5 + .../main/java/digit/config/Configuration.java | 88 ++- .../java/digit/config/ServiceConstants.java | 249 ++++++- ...jectFactoryCreatePlanFacilityConsumer.java | 57 ++ .../digit/kafka/UpdatePlanConfigConsumer.java | 1 + .../PlanEmployeeAssignmentRepository.java | 16 + .../repository/PlanFacilityRepository.java | 15 + .../java/digit/repository/PlanRepository.java | 10 +- .../repository/ServiceRequestRepository.java | 5 +- .../impl/PlanEmployeeAssignmentImpl.java | 121 ++++ .../impl/PlanFacilityRepositoryImpl.java | 150 ++++ .../repository/impl/PlanRepositoryImpl.java | 124 +++- .../querybuilder/PlanConfigQueryBuilder.java | 62 +- .../PlanEmployeeAssignmentQueryBuilder.java | 170 +++++ .../PlanFacilityQueryBuilder.java | 154 ++++ .../querybuilder/PlanQueryBuilder.java | 136 +++- .../rowmapper/PlanConfigRowMapper.java | 87 ++- .../PlanEmployeeAssignmentRowMapper.java | 66 ++ .../rowmapper/PlanFacilityRowMapper.java | 79 +++ .../repository/rowmapper/PlanRowMapper.java | 88 +-- .../rowmapper/PlanStatusCountRowMapper.java | 31 + .../service/PlanConfigurationService.java | 50 +- .../digit/service/PlanEmployeeService.java | 91 +++ .../main/java/digit/service/PlanEnricher.java | 130 +++- .../digit/service/PlanFacilityService.java | 98 +++ .../main/java/digit/service/PlanService.java | 48 +- .../java/digit/service/PlanValidator.java | 333 ++++++++- .../service/enrichment/EnrichmentService.java | 174 +++-- .../PlanEmployeeAssignmentEnricher.java | 71 ++ .../enrichment/PlanFacilityEnricher.java | 213 ++++++ .../validator/PlanConfigurationValidator.java | 667 ++++++++++-------- .../PlanEmployeeAssignmentValidator.java | 349 +++++++++ .../validator/PlanFacilityValidator.java | 301 ++++++++ .../service/validator/WorkflowValidator.java | 141 ++++ .../service/workflow/WorkflowService.java | 432 ++++++++++++ .../main/java/digit/util/BoundaryUtil.java | 111 +++ .../main/java/digit/util/CampaignUtil.java | 91 +++ .../src/main/java/digit/util/CensusUtil.java | 60 ++ .../src/main/java/digit/util/CommonUtil.java | 275 ++++++++ .../main/java/digit/util/FacilityUtil.java | 84 +++ .../src/main/java/digit/util/MdmsUtil.java | 32 +- .../src/main/java/digit/util/MdmsV2Util.java | 76 ++ .../src/main/java/digit/util/QueryUtil.java | 91 ++- .../src/main/java/digit/util/ServiceUtil.java | 13 +- .../src/main/java/digit/util/UserUtil.java | 73 ++ .../web/controllers/PlanConfigController.java | 1 - .../digit/web/controllers/PlanController.java | 17 +- .../controllers/PlanEmployeeController.java | 62 ++ .../controllers/PlanFacilityController.java | 61 ++ .../java/digit/web/models/Assumption.java | 13 +- .../digit/web/models/BulkPlanRequest.java | 33 + .../main/java/digit/web/models/Operation.java | 20 +- .../java/digit/web/models/Pagination.java | 35 + .../src/main/java/digit/web/models/Plan.java | 30 +- .../digit/web/models/PlanConfiguration.java | 36 +- .../PlanConfigurationSearchCriteria.java | 13 +- .../main/java/digit/web/models/PlanDTO.java | 90 +++ .../web/models/PlanEmployeeAssignment.java | 71 ++ .../web/models/PlanEmployeeAssignmentDTO.java | 69 ++ .../models/PlanEmployeeAssignmentRequest.java | 30 + .../PlanEmployeeAssignmentRequestDTO.java | 30 + .../PlanEmployeeAssignmentResponse.java | 36 + .../PlanEmployeeAssignmentSearchCriteria.java | 72 ++ .../PlanEmployeeAssignmentSearchRequest.java | 29 + .../java/digit/web/models/PlanFacility.java | 92 +++ .../digit/web/models/PlanFacilityDTO.java | 79 +++ .../digit/web/models/PlanFacilityRequest.java | 33 + .../web/models/PlanFacilityRequestDTO.java | 33 + .../web/models/PlanFacilityResponse.java | 33 + .../models/PlanFacilitySearchCriteria.java | 64 ++ .../web/models/PlanFacilitySearchRequest.java | 34 + .../java/digit/web/models/PlanRequestDTO.java | 29 + .../java/digit/web/models/PlanResponse.java | 10 + .../digit/web/models/PlanSearchCriteria.java | 29 +- .../digit/web/models/RequestInfoWrapper.java | 18 + .../main/java/digit/web/models/Resource.java | 2 +- .../main/java/digit/web/models/Source.java | 5 + .../boundary/BoundarySearchResponse.java | 42 ++ .../boundary/BoundaryTypeHierarchy.java | 30 + .../BoundaryTypeHierarchyDefinition.java | 45 ++ .../BoundaryTypeHierarchyResponse.java | 36 + .../BoundaryTypeHierarchySearchCriteria.java | 39 + .../BoundaryTypeHierarchySearchRequest.java | 31 + .../web/models/boundary/EnrichedBoundary.java | 42 ++ .../models/boundary/HierarchyRelation.java | 34 + .../web/models/census/AdditionalField.java | 48 ++ .../java/digit/web/models/census/Census.java | 139 ++++ .../web/models/census/CensusResponse.java | 42 ++ .../models/census/CensusSearchCriteria.java | 72 ++ .../models/census/CensusSearchRequest.java | 31 + .../census/PopulationByDemographic.java | 69 ++ .../web/models/facility/AdditionalFields.java | 25 + .../digit/web/models/facility/Address.java | 62 ++ .../digit/web/models/facility/Facility.java | 64 ++ .../web/models/facility/FacilityDetail.java | 19 + .../web/models/facility/FacilityResponse.java | 22 + .../facility/FacilitySearchCriteria.java | 30 + .../facility/FacilitySearchRequest.java | 20 + .../java/digit/web/models/facility/Field.java | 20 + .../digit/web/models/facility/Locality.java | 33 + .../java/digit/web/models/mdmsV2/Mdms.java | 55 ++ .../web/models/mdmsV2/MdmsCriteriaReqV2.java | 23 + .../web/models/mdmsV2/MdmsCriteriaV2.java | 62 ++ .../web/models/mdmsV2/MdmsResponseV2.java | 25 + .../web/models/projectFactory/Boundary.java | 32 + .../models/projectFactory/CampaignDetail.java | 85 +++ .../projectFactory/CampaignResponse.java | 29 + .../CampaignSearchCriteria.java | 51 ++ .../projectFactory/CampaignSearchReq.java | 22 + .../web/models/projectFactory/Condition.java | 27 + .../models/projectFactory/DeliveryRule.java | 43 ++ .../web/models/projectFactory/Pagination.java | 35 + .../web/models/projectFactory/Product.java | 26 + .../web/models/projectFactory/Resource.java | 32 + .../src/main/resources/application.properties | 50 +- .../src/main/resources/db/Dockerfile | 4 +- .../src/main/resources/db/migrate.sh | 2 +- ...5113045__plan_configuration_create_ddl.sql | 40 +- .../main/V20240305113047__plan_create_ddl.sql | 5 +- ...plan_configuration_add_filestoreid_ddl.sql | 1 - ...figuration_add_template_identifier_ddl.sql | 1 - ...240923113045__plan_facility_create_ddl.sql | 19 + ...000__plan_configuration_add_status_ddl.sql | 2 - ...000__plan_configuration_add_active_ddl.sql | 11 - ...0__plan_employee_assignment_create_ddl.sql | 19 + ...115700__alter_plan_assignee_create_ddl.sql | 1 + ...cility_add_boundary_ancestral_path_ddl.sql | 1 + .../resource-estimation-service/CHANGELOG.md | 8 - .../processor/config/ServiceConstants.java | 72 -- .../processor/web/models/MetricDetail.java | 34 - .../resource-generator/CHANGELOG.md | 13 + .../LOCALSETUP.md | 0 .../README.md | 0 .../pom.xml | 8 +- .../main/java/org/egov/processor/Main.java | 0 .../egov/processor/config/Configuration.java | 67 +- .../processor/config/MainConfiguration.java | 0 .../processor/config/ServiceConstants.java | 123 ++++ .../egov/processor/kafka/PlanConsumer.java | 17 +- .../org/egov/processor/kafka/Producer.java | 0 .../repository/ServiceRequestRepository.java | 0 .../egov/processor/service/ExcelParser.java | 366 +++++----- .../egov/processor/service/FileParser.java | 0 .../egov/processor/service/GeoJsonParser.java | 0 .../service/ResourceEstimationService.java | 27 +- .../processor/service/ShapeFileParser.java | 0 .../org/egov/processor/util/BoundaryUtil.java | 0 .../egov/processor/util/CalculationUtil.java | 58 +- .../util/CampaignIntegrationUtil.java | 210 ++++-- .../org/egov/processor/util/CensusUtil.java | 191 +++++ .../egov/processor/util/EnrichmentUtil.java | 304 ++++++++ .../egov/processor/util/FilestoreUtil.java | 0 .../org/egov/processor/util/LocaleUtil.java | 18 +- .../org/egov/processor/util/MdmsUtil.java | 2 +- .../org/egov/processor/util/MdmsV2Util.java | 79 +++ .../org/egov/processor/util/ParsingUtil.java | 202 +++++- .../processor/util/PlanConfigurationUtil.java | 18 +- .../org/egov/processor/util/PlanUtil.java | 84 ++- .../org/egov/processor/web/PlanResponse.java | 42 ++ .../processor/web/PlanSearchCriteria.java | 57 ++ .../egov/processor/web/PlanSearchRequest.java | 30 + .../web/controllers/FileController.java | 0 .../egov/processor/web/models/Activity.java | 12 +- .../egov/processor/web/models/Assumption.java | 58 ++ .../egov/processor/web/models/Condition.java | 6 +- .../org/egov/processor/web/models/File.java | 27 +- .../org/egov/processor/web/models/Locale.java | 0 .../processor/web/models/LocaleResponse.java | 0 .../processor/web/models/MetricDetail.java | 75 ++ .../egov/processor/web/models/Operation.java | 38 +- .../org/egov/processor/web/models/Plan.java | 36 +- .../web/models/PlanConfiguration.java | 38 +- .../web/models/PlanConfigurationRequest.java | 0 .../web/models/PlanConfigurationResponse.java | 0 .../PlanConfigurationSearchCriteria.java | 0 .../PlanConfigurationSearchRequest.java | 0 .../processor/web/models/PlanRequest.java | 0 .../egov/processor/web/models/Resource.java | 8 +- .../processor/web/models/ResourceMapping.java | 7 +- .../org/egov/processor/web/models/Source.java | 5 + .../org/egov/processor/web/models/Target.java | 6 +- .../boundary/BoundarySearchResponse.java | 0 .../web/models/boundary/EnrichedBoundary.java | 0 .../models/boundary/HierarchyRelation.java | 0 .../campaignManager/AdditionalDetails.java | 0 .../web/models/campaignManager/Boundary.java | 0 .../web/models/campaignManager/Campaign.java | 18 +- .../campaignManager/CampaignCondition.java | 0 .../campaignManager/CampaignDetails.java | 0 .../campaignManager/CampaignRequest.java | 0 .../campaignManager/CampaignResources.java | 0 .../campaignManager/CampaignResponse.java | 0 .../CampaignSearchRequest.java | 0 .../campaignManager/CycleConfigureDate.java | 0 .../web/models/campaignManager/CycleData.java | 0 .../models/campaignManager/DeliveryRule.java | 0 .../campaignManager/MicroplanDetails.java | 32 + .../MicroplanDetailsRequest.java | 26 + .../web/models/campaignManager/Product.java | 0 .../campaignManager/ResourceDetails.java | 48 ++ .../ResourceDetailsRequest.java | 30 + .../web/models/census/AdditionalField.java | 48 ++ .../processor/web/models/census/Census.java | 138 ++++ .../web/models/census/CensusRequest.java | 31 + .../web/models/census/CensusResponse.java | 41 ++ .../models/census/CensusSearchCriteria.java | 71 ++ .../models/census/CensusSearchRequest.java | 31 + .../census/PopulationByDemographic.java | 69 ++ .../processor/web/models/mdmsV2/Mdms.java | 55 ++ .../web/models/mdmsV2/MdmsCriteriaReqV2.java | 26 + .../web/models/mdmsV2/MdmsCriteriaV2.java | 62 ++ .../web/models/mdmsV2/MdmsResponseV2.java | 28 + .../src/main/resources/application.properties | 33 +- .../src/main/resources/db/Dockerfile | 2 +- .../src/main/resources/db/migrate.sh | 3 + 279 files changed, 14914 insertions(+), 1303 deletions(-) create mode 100644 health-services/census-service/CHANGELOG.md create mode 100644 health-services/census-service/README.md create mode 100644 health-services/census-service/pom.xml create mode 100644 health-services/census-service/src/main/java/digit/Main.java create mode 100644 health-services/census-service/src/main/java/digit/config/Configuration.java create mode 100644 health-services/census-service/src/main/java/digit/config/MainConfiguration.java create mode 100644 health-services/census-service/src/main/java/digit/config/ServiceConstants.java create mode 100644 health-services/census-service/src/main/java/digit/kafka/FacilityCatchmentConsumer.java create mode 100644 health-services/census-service/src/main/java/digit/kafka/Producer.java create mode 100644 health-services/census-service/src/main/java/digit/kafka/ResourceCensusConsumer.java create mode 100644 health-services/census-service/src/main/java/digit/repository/CensusRepository.java create mode 100644 health-services/census-service/src/main/java/digit/repository/ServiceRequestRepository.java create mode 100644 health-services/census-service/src/main/java/digit/repository/impl/CensusRepositoryImpl.java create mode 100644 health-services/census-service/src/main/java/digit/repository/querybuilder/CensusQueryBuilder.java create mode 100644 health-services/census-service/src/main/java/digit/repository/rowmapper/CensusRowMapper.java create mode 100644 health-services/census-service/src/main/java/digit/repository/rowmapper/StatusCountRowMapper.java create mode 100644 health-services/census-service/src/main/java/digit/service/CensusService.java create mode 100644 health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java create mode 100644 health-services/census-service/src/main/java/digit/service/enrichment/CensusTimeframeEnrichment.java create mode 100644 health-services/census-service/src/main/java/digit/service/validator/CensusValidator.java create mode 100644 health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java create mode 100644 health-services/census-service/src/main/java/digit/util/BoundaryUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/BusinessServiceUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/CommonUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/PlanEmployeeAssignmnetUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/QueryUtil.java create mode 100644 health-services/census-service/src/main/java/digit/util/ResponseInfoFactory.java create mode 100644 health-services/census-service/src/main/java/digit/web/controllers/CensusController.java rename health-services/{resource-estimation-service/src/main/java/org/egov/processor/web/models/Assumption.java => census-service/src/main/java/digit/web/models/AdditionalField.java} (52%) create mode 100644 health-services/census-service/src/main/java/digit/web/models/BulkCensusRequest.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/Census.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusDTO.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusRequest.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusRequestDTO.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusSearchCriteria.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/CensusSearchRequest.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/PopulationByDemographic.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/RequestInfoWrapper.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignment.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentResponse.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchCriteria.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanEmployeeAssignmentSearchRequest.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityDTO.java create mode 100644 health-services/census-service/src/main/java/digit/web/models/plan/PlanFacilityRequestDTO.java create mode 100644 health-services/census-service/src/main/resources/application.properties create mode 100644 health-services/census-service/src/main/resources/db/Dockerfile rename health-services/{resource-estimation-service => census-service}/src/main/resources/db/migrate.sh (67%) create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20240925155908__census_create_ddl.sql create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241105152700__census_additional_field_create_ddl.sql create mode 100644 health-services/census-service/src/main/resources/db/migration/main/V20241126120700__alter_census_assignee_create_ddl.sql create mode 100644 health-services/census-service/src/main/resources/start.sh create mode 100644 health-services/census-service/src/test/java/digit/TestConfiguration.java create mode 100644 health-services/census-service/src/test/java/digit/web/controllers/CensusControllerTest.java create mode 100644 health-services/plan-service/src/main/java/digit/kafka/ProjectFactoryCreatePlanFacilityConsumer.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/PlanEmployeeAssignmentRepository.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/PlanFacilityRepository.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/impl/PlanEmployeeAssignmentImpl.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/impl/PlanFacilityRepositoryImpl.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanEmployeeAssignmentQueryBuilder.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/querybuilder/PlanFacilityQueryBuilder.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanEmployeeAssignmentRowMapper.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanFacilityRowMapper.java create mode 100644 health-services/plan-service/src/main/java/digit/repository/rowmapper/PlanStatusCountRowMapper.java create mode 100644 health-services/plan-service/src/main/java/digit/service/PlanEmployeeService.java create mode 100644 health-services/plan-service/src/main/java/digit/service/PlanFacilityService.java create mode 100644 health-services/plan-service/src/main/java/digit/service/enrichment/PlanEmployeeAssignmentEnricher.java create mode 100644 health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/PlanEmployeeAssignmentValidator.java create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java create mode 100644 health-services/plan-service/src/main/java/digit/service/validator/WorkflowValidator.java create mode 100644 health-services/plan-service/src/main/java/digit/service/workflow/WorkflowService.java create mode 100644 health-services/plan-service/src/main/java/digit/util/BoundaryUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/util/CampaignUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/util/CensusUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/util/CommonUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/util/FacilityUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/util/MdmsV2Util.java create mode 100644 health-services/plan-service/src/main/java/digit/util/UserUtil.java create mode 100644 health-services/plan-service/src/main/java/digit/web/controllers/PlanEmployeeController.java create mode 100644 health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/BulkPlanRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/Pagination.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignment.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentRequestDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanEmployeeAssignmentSearchRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityRequestDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanFacilitySearchRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/PlanRequestDTO.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/RequestInfoWrapper.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/Source.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundarySearchResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchy.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyDefinition.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchyResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/BoundaryTypeHierarchySearchRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/EnrichedBoundary.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/boundary/HierarchyRelation.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/AdditionalField.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/Census.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/CensusSearchRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/census/PopulationByDemographic.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/AdditionalFields.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Address.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Facility.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilityDetail.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilityResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/FacilitySearchRequest.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Field.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/facility/Locality.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/Mdms.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaReqV2.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsCriteriaV2.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/mdmsV2/MdmsResponseV2.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignDetail.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignResponse.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchCriteria.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/CampaignSearchReq.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Condition.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/DeliveryRule.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Pagination.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Product.java create mode 100644 health-services/plan-service/src/main/java/digit/web/models/projectFactory/Resource.java delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240404113045__plan_configuration_add_filestoreid_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240404150000__plan_configuration_add_template_identifier_ddl.sql create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20241604150000__plan_configuration_add_status_ddl.sql delete mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242105150000__plan_configuration_add_active_ddl.sql create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242109141800__plan_employee_assignment_create_ddl.sql create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242110115700__alter_plan_assignee_create_ddl.sql create mode 100644 health-services/plan-service/src/main/resources/db/migration/main/V20242112141500__alter plan_facility_add_boundary_ancestral_path_ddl.sql delete mode 100644 health-services/resource-estimation-service/CHANGELOG.md delete mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/config/ServiceConstants.java delete mode 100644 health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/MetricDetail.java create mode 100644 health-services/resource-generator/CHANGELOG.md rename health-services/{resource-estimation-service => resource-generator}/LOCALSETUP.md (100%) rename health-services/{resource-estimation-service => resource-generator}/README.md (100%) rename health-services/{resource-estimation-service => resource-generator}/pom.xml (95%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/Main.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/config/Configuration.java (54%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/config/MainConfiguration.java (100%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/kafka/PlanConsumer.java (66%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/kafka/Producer.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/repository/ServiceRequestRepository.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/ExcelParser.java (73%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/FileParser.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/GeoJsonParser.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/ResourceEstimationService.java (82%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/service/ShapeFileParser.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/BoundaryUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/CalculationUtil.java (74%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java (61%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/util/CensusUtil.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/FilestoreUtil.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/LocaleUtil.java (89%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/MdmsUtil.java (99%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/util/MdmsV2Util.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/ParsingUtil.java (59%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/PlanConfigurationUtil.java (85%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/util/PlanUtil.java (70%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/PlanResponse.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchCriteria.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/PlanSearchRequest.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/controllers/FileController.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Activity.java (99%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/Assumption.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Condition.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/File.java (81%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Locale.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/LocaleResponse.java (100%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/MetricDetail.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Operation.java (70%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Plan.java (63%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfiguration.java (68%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchCriteria.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanConfigurationSearchRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/PlanRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Resource.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/ResourceMapping.java (99%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/Source.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/Target.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/boundary/EnrichedBoundary.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/boundary/HierarchyRelation.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/AdditionalDetails.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/Boundary.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/Campaign.java (94%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignCondition.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignDetails.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResources.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignResponse.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CampaignSearchRequest.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/CycleData.java (100%) rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/DeliveryRule.java (100%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetails.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/MicroplanDetailsRequest.java rename health-services/{resource-estimation-service => resource-generator}/src/main/java/org/egov/processor/web/models/campaignManager/Product.java (100%) create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetails.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/campaignManager/ResourceDetailsRequest.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/AdditionalField.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/Census.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusRequest.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusResponse.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchCriteria.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/CensusSearchRequest.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/census/PopulationByDemographic.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/Mdms.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaReqV2.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsCriteriaV2.java create mode 100644 health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MdmsResponseV2.java rename health-services/{resource-estimation-service => resource-generator}/src/main/resources/application.properties (68%) rename health-services/{resource-estimation-service => resource-generator}/src/main/resources/db/Dockerfile (83%) create mode 100644 health-services/resource-generator/src/main/resources/db/migrate.sh diff --git a/build/build-config.yml b/build/build-config.yml index dec24965782..2002805a366 100644 --- a/build/build-config.yml +++ b/build/build-config.yml @@ -250,15 +250,22 @@ config: dockerfile: "build/17/maven/Dockerfile" - work-dir: "health-services/plan-service/src/main/resources/db" image-name: "plan-service-db" - - name: "builds/health-campaign-services/health-services/resource-estimation-service" + - name: "builds/health-campaign-services/health-services/resource-generator" build: - - work-dir: "health-services/resource-estimation-service" - image-name: "resource-estimation-service" + - work-dir: "health-services/resource-generator" + image-name: "resource-generator" dockerfile: "build/17/maven/Dockerfile" - name: "builds/health-campaign-services/analytics/auth-proxy" build: - work-dir: "analytics/auth-proxy" image-name: "auth-proxy" + - name: "builds/health-campaign-services/health-services/census-service" + build: + - work-dir: "health-services/census-service" + image-name: "census-service" + dockerfile: "build/17/maven/Dockerfile" + - work-dir: "health-services/census-service/src/main/resources/db" + image-name: "census-service-db" # frontend - name: builds/health-campaign-services/frontend/workbench-ui 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/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 148766ff97d..c41f44a9f05 100644 --- a/health-services/plan-service/pom.xml +++ b/health-services/plan-service/pom.xml @@ -95,6 +95,11 @@ 2.9.0-SNAPSHOT compile + + org.apache.commons + commons-text + 1.10.0 + diff --git a/health-services/plan-service/src/main/java/digit/config/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 ab694a05961..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,21 +12,41 @@ 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 "; @@ -38,29 +58,72 @@ public class ServiceConstants { public static final String ONLY_ONE_FILE_OF_REQUIRED_TEMPLATE_IDENTIFIER_MESSAGE = "Only one file of the required template identifier should be present "; public static final String INPUT_KEY_NOT_FOUND_CODE = "INPUT_KEY_NOT_FOUND"; - public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key not present in MDMS "; - - public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_CODE = "LOCALITY_NOT_PRESENT_IN_MAPPED_TO"; - public static final String LOCALITY_NOT_PRESENT_IN_MAPPED_TO_MESSAGE = "Resource Mapping's MappedTo must contain 'Locality' "; - - public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE = "DUPLICATE_MAPPED_TO_VALIDATION_ERROR"; - public static final String DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE = "Duplicate MappedTo found in Resource Mapping"; - - public static final String TENANT_NOT_FOUND_IN_MDMS_CODE = "TENANT_ID_NOT_FOUND_IN_MDMS"; - public static final String TENANT_NOT_FOUND_IN_MDMS_MESSAGE = "Tenant Id is not present in MDMS"; + public static final String INPUT_KEY_NOT_FOUND_MESSAGE = "Operation's Input key is not present in allowed columns or previous outputs - "; public static final String TENANT_ID_EMPTY_CODE = "TENANT_ID_EMPTY"; public static final String TENANT_ID_EMPTY_MESSAGE = "Tenant Id cannot be empty, TenantId should be present"; + 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,9 +136,6 @@ public class ServiceConstants { public static final String JSONPATH_ERROR_CODE = "JSONPATH_ERROR"; public static final String JSONPATH_ERROR_MESSAGE = "Failed to parse mdms response with given Jsonpath" ; - public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_CODE = "BOUNDARY_CODE_MAPPING_NOT_FOUND"; - public static final String BOUNDARY_CODE_MAPPING_NOT_FOUND_MESSAGE = "Boundary Code Mapping is required column is not found."; - public static final String NAME_VALIDATION_LIST_EMPTY_CODE = "NAME_VALIDATION_LIST_EMPTY"; public static final String NAME_VALIDATION_LIST_EMPTY_MESSAGE = "Name Validation list from MDMS is empty"; @@ -109,9 +169,6 @@ public class ServiceConstants { public static final String PLAN_RESOURCES_MANDATORY_CODE = "PLAN_RESOURCES_MANDATORY"; public static final String PLAN_RESOURCES_MANDATORY_MESSAGE = "Resources are mandatory if plan configuration id is not provided"; - public static final String PLAN_RESOURCES_NOT_ALLOWED_CODE = "PLAN_RESOURCES_NOT_ALLOWED"; - public static final String PLAN_RESOURCES_NOT_ALLOWED_MESSAGE = "Resources are not allowed if plan configuration id is provided"; - public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE = "INVALID_RESOURCE_ACTIVITY_LINKAGE"; public static final String INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE = "Resource-Activity linkage is invalid"; @@ -127,9 +184,38 @@ public class ServiceConstants { public static final String DUPLICATE_ACTIVITY_UUIDS_CODE = "DUPLICATE_ACTIVITY_UUIDS"; public static final String DUPLICATE_ACTIVITY_UUIDS_MESSAGE = "Activity UUIDs should be unique"; + public static final String ADDITIONAL_DETAILS_MISSING_CODE = "ADDITIONAL_DETAILS_MISSING"; + public static final String ADDITIONAL_DETAILS_MISSING_MESSAGE = "Additional details are missing in the plan configuration request."; + + public static final String PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_CODE = "PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT"; + public static final String PROVIDED_KEY_IS_NOT_PRESENT_IN_JSON_OBJECT_MESSAGE = "Key is not present in json object - "; + + 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"; @@ -137,6 +223,17 @@ public class ServiceConstants { 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 = "$."; @@ -144,10 +241,14 @@ public class ServiceConstants { public static final String DOT_REGEX = "\\."; + public static final String PIPE_REGEX = "\\|"; + public static final String FILTER_CODE = "$.*.code"; public static final String FILTER_ID = "$.*.id"; + public static final String FILTER_TO_GET_ALL_IDS = "*.id"; + public static final String FILTER_DATA = "$.*.data"; public static final String LOCALITY_CODE = "Locality"; @@ -163,8 +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/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 85238f723a5..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,48 +1,54 @@ package digit.service; -import digit.config.Configuration; -import digit.kafka.Producer; import digit.repository.PlanConfigurationRepository; -import digit.repository.impl.PlanConfigurationRepositoryImpl; import digit.service.enrichment.EnrichmentService; import digit.service.validator.PlanConfigurationValidator; +import digit.service.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 PlanConfigurationRepository repository; private ResponseInfoFactory responseInfoFactory; - public PlanConfigurationService(Producer producer, EnrichmentService enrichmentService, Configuration config - , PlanConfigurationValidator validator, PlanConfigurationRepository 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. */ @@ -51,41 +57,43 @@ public PlanConfigurationResponse create(PlanConfigurationRequest request) { validator.validateCreate(request); enrichmentService.enrichCreate(request); repository.create(request); - PlanConfigurationResponse response = PlanConfigurationResponse.builder() + + return PlanConfigurationResponse.builder() .planConfiguration(Collections.singletonList(request.getPlanConfiguration())) - .responseInfo(responseInfoFactory - .createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) + .responseInfo(responseInfoFactory.createResponseInfoFromRequestInfo(request.getRequestInfo(), true)) .build(); - return response; } /** * 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 index 75d79c840a3..b01c78ea82a 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanEnricher.java @@ -1,16 +1,18 @@ package digit.service; +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.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; @Component public class PlanEnricher { @@ -105,5 +107,125 @@ public void enrichPlanUpdate(PlanRequest body) { } }); + // 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/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..4acaf58218b 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanService.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanService.java @@ -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.workflow.WorkflowService; +import digit.web.models.*; +import org.egov.common.contract.response.ResponseInfo; 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 index 40958a9e0d3..8f495a271f8 100644 --- a/health-services/plan-service/src/main/java/digit/service/PlanValidator.java +++ b/health-services/plan-service/src/main/java/digit/service/PlanValidator.java @@ -1,10 +1,18 @@ package digit.service; import com.jayway.jsonpath.JsonPath; +import digit.config.Configuration; import digit.repository.PlanConfigurationRepository; import digit.repository.PlanRepository; +import digit.util.BoundaryUtil; +import digit.util.CampaignUtil; +import digit.util.CommonUtil; import digit.util.MdmsUtil; import digit.web.models.*; +import digit.web.models.boundary.BoundarySearchResponse; +import digit.web.models.boundary.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; @@ -27,20 +35,47 @@ public class PlanValidator { private MultiStateInstanceUtil centralInstanceUtil; - public PlanValidator(PlanRepository planRepository, PlanConfigurationRepository planConfigurationRepository, MdmsUtil mdmsUtil, 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); @@ -65,10 +100,32 @@ public void validatePlanCreate(PlanRequest request) { // Validate Metric Detail's Unit against MDMS validateMetricDetailUnit(request, mdmsData); + + // Validate if campaign id exists against project factory + validateCampaignId(campaignResponse); + + // 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) { @@ -81,6 +138,7 @@ private void validateActivityDependencies(PlanRequest request) { /** * This method checks if the activity dependencies form a cycle + * * @param request */ private void checkForCycleInActivityDependencies(PlanRequest request) { @@ -90,7 +148,7 @@ private void checkForCycleInActivityDependencies(PlanRequest request) { activityCodeVsDependenciesMap.keySet().forEach(activityCode -> { activityCodeVsDependenciesMap.get(activityCode).forEach(dependency -> { - if(activityCodeVsDependenciesMap.get(dependency).contains(activityCode)) + if (activityCodeVsDependenciesMap.get(dependency).contains(activityCode)) throw new CustomException(CYCLIC_ACTIVITY_DEPENDENCY_CODE, CYCLIC_ACTIVITY_DEPENDENCY_MESSAGE); }); }); @@ -98,6 +156,7 @@ private void checkForCycleInActivityDependencies(PlanRequest request) { /** * This method validates if the dependent activity codes are valid + * * @param request */ private void validateDependentActivityCodes(PlanRequest request) { @@ -108,9 +167,9 @@ private void validateDependentActivityCodes(PlanRequest request) { // Check if the dependent activity codes are valid request.getPlan().getActivities().forEach(activity -> { - if(!CollectionUtils.isEmpty(activity.getDependencies())) { + if (!CollectionUtils.isEmpty(activity.getDependencies())) { activity.getDependencies().forEach(dependency -> { - if(!activityCodes.contains(dependency)) + if (!activityCodes.contains(dependency)) throw new CustomException(INVALID_ACTIVITY_DEPENDENCY_CODE, INVALID_ACTIVITY_DEPENDENCY_MESSAGE); }); } @@ -120,11 +179,12 @@ private void validateDependentActivityCodes(PlanRequest request) { /** * This method validates the activities provided in the request + * * @param request */ private void validateActivities(PlanRequest request) { // Collect all activity codes - if(request.getPlan().getActivities() == null) + if (request.getPlan().getActivities() == null) throw new CustomException(ACTIVITIES_CANNOT_BE_NULL_CODE, ACTIVITIES_CANNOT_BE_NULL_MESSAGE); Set activityCodes = request.getPlan().getActivities().stream() @@ -132,26 +192,26 @@ private void validateActivities(PlanRequest request) { .collect(Collectors.toSet()); // If activity codes are not unique, throw an exception - if(activityCodes.size() != request.getPlan().getActivities().size()) { + if (activityCodes.size() != request.getPlan().getActivities().size()) { throw new CustomException(DUPLICATE_ACTIVITY_CODES, DUPLICATE_ACTIVITY_CODES_MESSAGE); } // If execution plan id is not provided, providing activities is mandatory - if(ObjectUtils.isEmpty(request.getPlan().getExecutionPlanId()) + if (ObjectUtils.isEmpty(request.getPlan().getCampaignId()) && CollectionUtils.isEmpty(request.getPlan().getActivities())) { throw new CustomException(PLAN_ACTIVITIES_MANDATORY_CODE, PLAN_ACTIVITIES_MANDATORY_MESSAGE); } // If execution plan id is provided, providing activities is not allowed - if(!ObjectUtils.isEmpty(request.getPlan().getExecutionPlanId()) + if (!ObjectUtils.isEmpty(request.getPlan().getCampaignId()) && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { throw new CustomException(PLAN_ACTIVITIES_NOT_ALLOWED_CODE, PLAN_ACTIVITIES_NOT_ALLOWED_MESSAGE); } // Validate activity dates - if(!CollectionUtils.isEmpty(request.getPlan().getActivities())) { + if (!CollectionUtils.isEmpty(request.getPlan().getActivities())) { request.getPlan().getActivities().forEach(activity -> { - if(activity.getPlannedEndDate() < activity.getPlannedStartDate()) + if (activity.getPlannedEndDate() < activity.getPlannedStartDate()) throw new CustomException(INVALID_ACTIVITY_DATES_CODE, INVALID_ACTIVITY_DATES_MESSAGE); }); } @@ -159,49 +219,37 @@ private void validateActivities(PlanRequest request) { /** * This method validates if the plan configuration id provided in the request exists + * * @param request */ private void validatePlanConfigurationExistence(PlanRequest request) { // If plan id provided is invalid, throw an exception - if(!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && CollectionUtils.isEmpty(planConfigurationRepository.search(PlanConfigurationSearchCriteria.builder() - .id(request.getPlan().getPlanConfigurationId()) - .tenantId(request.getPlan().getTenantId()) - .build()))) { + if (!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && + CollectionUtils.isEmpty(commonUtil.searchPlanConfigId(request.getPlan().getPlanConfigurationId(), request.getPlan().getTenantId()))) { throw new CustomException(INVALID_PLAN_CONFIG_ID_CODE, INVALID_PLAN_CONFIG_ID_MESSAGE); } } /** * This method validates the resources provided in the request + * * @param request */ private void validateResources(PlanRequest request) { // If plan configuration id is not provided, providing resources is mandatory - if(ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) + if (ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && CollectionUtils.isEmpty(request.getPlan().getResources())) { throw new CustomException(PLAN_RESOURCES_MANDATORY_CODE, PLAN_RESOURCES_MANDATORY_MESSAGE); } - - // If plan configuration id is provided, providing resources is not allowed - if(!ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) - && !CollectionUtils.isEmpty(request.getPlan().getResources())) { - throw new CustomException(PLAN_RESOURCES_NOT_ALLOWED_CODE, PLAN_RESOURCES_NOT_ALLOWED_MESSAGE); - } - - // Validate resource type existence - if(!CollectionUtils.isEmpty(request.getPlan().getResources())) { - request.getPlan().getResources().forEach(resource -> { - // Validate resource type existence - }); - } } /** * This method validates the linkage between resources and activities + * * @param request */ private void validateResourceActivityLinkage(PlanRequest request) { - if(ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) + if (ObjectUtils.isEmpty(request.getPlan().getPlanConfigurationId()) && !CollectionUtils.isEmpty(request.getPlan().getActivities())) { // Collect all activity codes Set activityCodes = request.getPlan().getActivities().stream() @@ -210,7 +258,7 @@ private void validateResourceActivityLinkage(PlanRequest request) { // Validate resource-activity linkage request.getPlan().getResources().forEach(resource -> { - if(!activityCodes.contains(resource.getActivityCode())) + if (!activityCodes.contains(resource.getActivityCode())) throw new CustomException(INVALID_RESOURCE_ACTIVITY_LINKAGE_CODE, INVALID_RESOURCE_ACTIVITY_LINKAGE_MESSAGE); }); } @@ -218,10 +266,11 @@ private void validateResourceActivityLinkage(PlanRequest request) { /** * This method validates the linkage between targets and activities + * * @param request */ private void validateTargetActivityLinkage(PlanRequest request) { - if(!CollectionUtils.isEmpty(request.getPlan().getActivities())) { + if (!CollectionUtils.isEmpty(request.getPlan().getActivities())) { // Collect all activity codes Set activityCodes = request.getPlan().getActivities().stream() .map(Activity::getCode) @@ -229,7 +278,7 @@ private void validateTargetActivityLinkage(PlanRequest request) { // Validate target-activity linkage request.getPlan().getTargets().forEach(target -> { - if(!activityCodes.contains(target.getActivityCode())) + if (!activityCodes.contains(target.getActivityCode())) throw new CustomException(INVALID_TARGET_ACTIVITY_LINKAGE_CODE, INVALID_TARGET_ACTIVITY_LINKAGE_MESSAGE); }); } @@ -237,6 +286,7 @@ private void validateTargetActivityLinkage(PlanRequest request) { /** * This method performs business validations on plan update requests + * * @param request */ public void validatePlanUpdate(PlanRequest request) { @@ -245,6 +295,12 @@ public void validatePlanUpdate(PlanRequest request) { String rootTenantId = centralInstanceUtil.getStateLevelTenant(request.getPlan().getTenantId()); Object mdmsData = mdmsUtil.fetchMdmsData(request.getRequestInfo(), rootTenantId); + CampaignResponse campaignResponse = campaignUtil.fetchCampaignData(request.getRequestInfo(), request.getPlan().getCampaignId(), rootTenantId); + BoundaryTypeHierarchyResponse boundaryTypeHierarchyResponse = boundaryUtil.fetchBoundaryHierarchy(request.getRequestInfo(), request.getPlan().getTenantId(), campaignResponse.getCampaignDetails().get(0).getHierarchyType()); + + //TODO: remove after setting the flag in consumer + request.getPlan().setRequestFromResourceEstimationConsumer(Boolean.TRUE); + // Validate activities validateActivities(request); @@ -279,6 +335,14 @@ public void validatePlanUpdate(PlanRequest request) { // 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)); } /** @@ -338,15 +402,19 @@ private void validateActivitiesUuidUniqueness(PlanRequest request) { /** * This method validates if the plan id provided in the update request exists - * @param request + * + * @param request the PlanRequest containing the plan */ private void validatePlanExistence(PlanRequest request) { // If plan id provided is invalid, throw an exception - if(CollectionUtils.isEmpty(planRepository.search(PlanSearchCriteria.builder() + List planFromDatabase = planRepository.search(PlanSearchCriteria.builder() .ids(Collections.singleton(request.getPlan().getId())) - .build()))) { + .build()); + if (CollectionUtils.isEmpty(planFromDatabase)) { throw new CustomException(INVALID_PLAN_ID_CODE, INVALID_PLAN_ID_MESSAGE); } + // enriching boundary ancestral path for incoming plan request from the database + request.getPlan().setBoundaryAncestralPath(planFromDatabase.get(0).getBoundaryAncestralPath()); } /** @@ -355,7 +423,7 @@ private void validatePlanExistence(PlanRequest request) { * This method checks each target metric in the plan to ensure it exists in the MDMS data. * If a metric is not found, it throws a CustomException. * - * @param request the PlanRequest containing the plan and target metrics to be validated + * @param request the PlanRequest containing the plan and target metrics to be validated * @param mdmsData the MDMS data against which the target metrics are validated * @throws CustomException if there is an error reading the MDMS data using JsonPath * or if any target metric is not found in the MDMS data @@ -386,7 +454,7 @@ public void validateTargetMetrics(PlanRequest request, Object mdmsData) { * This method extracts metric details from the plan and checks if each metric unit * is present in the MDMS data. If a metric unit is not found, it throws a CustomException. * - * @param request the PlanRequest containing the plan and metric details to be validated + * @param request the PlanRequest containing the plan and metric details to be validated * @param mdmsData the MDMS data against which the metric units are validated * @throws CustomException if there is an error reading the MDMS data using JsonPath * or if any metric unit is not found in the MDMS data @@ -415,4 +483,195 @@ public void validateMetricDetailUnit(PlanRequest request, Object mdmsData) { } + /** + * Validates the plan's employee assignment and ensures the jurisdiction is valid based on tenant, employee, role, and plan configuration. + * If no assignment is found, throws a custom exception. + * + * @param planRequest the request containing the plan and workflow details + * @throws CustomException if no employee assignment is found or jurisdiction is invalid + */ + public void validatePlanEmployeeAssignmentAndJurisdiction(PlanRequest planRequest) { + PlanEmployeeAssignmentSearchCriteria planEmployeeAssignmentSearchCriteria = PlanEmployeeAssignmentSearchCriteria + .builder() + .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); + } + + //TODO: change to if(!plan.isRequestFromResourceEstimationConsumer()) after triggering from consumer + + // Enrich the boundary ancestral path and jurisdiction mapping for the provided boundary code + if(plan.isRequestFromResourceEstimationConsumer()) + planEnricher.enrichBoundaryAncestralPath(plan, tenantBoundary); + } + + /** + * TODO - 1. plan existence 2. plan employee assignment 3. uniqueness check across records + * @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())) + ); + } } diff --git a/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java b/health-services/plan-service/src/main/java/digit/service/enrichment/EnrichmentService.java index 86c1fdb4b81..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,33 +1,37 @@ package digit.service.enrichment; import digit.config.Configuration; -import digit.web.models.File; -import digit.web.models.PlanConfiguration; -import digit.web.models.PlanConfigurationRequest; -import digit.web.models.ResourceMapping; +import digit.util.CommonUtil; +import digit.web.models.*; import lombok.extern.slf4j.Slf4j; import org.egov.common.utils.UUIDEnrichmentUtil; import org.egov.tracer.model.CustomException; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.util.List; -import static org.egov.common.utils.AuditDetailsEnrichmentUtil.prepareAuditDetails; -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. * 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. */ @@ -35,24 +39,35 @@ public void enrichCreate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); log.info("Enriching plan config with generated IDs"); + //set Draft status on create + planConfiguration.setStatus(DRAFT_STATUS); + // Generate id for plan configuration UUIDEnrichmentUtil.enrichRandomUuid(planConfiguration, "id"); // 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")); + } planConfiguration.setAuditDetails(prepareAuditDetails(planConfiguration.getAuditDetails(), request.getRequestInfo(), Boolean.TRUE)); } @@ -60,6 +75,7 @@ public void enrichCreate(PlanConfigurationRequest request) { /** * Enriches the PlanConfigurationRequest for updating an existing plan configuration. * This method enriches the plan configuration for update, validates user information, and enriches audit details for update operation. + * * @param request The PlanConfigurationRequest to be enriched. * @throws CustomException if user information is missing in the request. */ @@ -67,41 +83,54 @@ public void enrichUpdate(PlanConfigurationRequest request) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); // Generate id for Files - planConfiguration.getFiles().forEach(file -> { - if (ObjectUtils.isEmpty(file.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); - } - enrichActiveForResourceMapping(file, request.getPlanConfiguration().getResourceMapping()); - }); + if (!CollectionUtils.isEmpty(planConfiguration.getFiles())) { + planConfiguration.getFiles().forEach(file -> { + if (ObjectUtils.isEmpty(file.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(file, "id"); + } + enrichActiveForResourceMapping(file, request.getPlanConfiguration().getResourceMapping()); + }); + } // Generate id for Assumptions - planConfiguration.getAssumptions().forEach(assumption -> { - if (ObjectUtils.isEmpty(assumption.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id"); - } - }); + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { + planConfiguration.getAssumptions().forEach(assumption -> { + if (ObjectUtils.isEmpty(assumption.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(assumption, "id"); + } + }); + } // Generate id for Operations - planConfiguration.getOperations().forEach(operation -> { - if (ObjectUtils.isEmpty(operation.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(operation, "id"); - } - }); + if (!CollectionUtils.isEmpty(planConfiguration.getOperations())) { + planConfiguration.getOperations().forEach(operation -> { + if (ObjectUtils.isEmpty(operation.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(operation, "id"); + } + }); + } // Generate id for ResourceMappings - planConfiguration.getResourceMapping().forEach(resourceMapping -> { - if (ObjectUtils.isEmpty(resourceMapping.getId())) { - UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); - } - }); + if (!CollectionUtils.isEmpty(planConfiguration.getResourceMapping())) { + planConfiguration.getResourceMapping().forEach(resourceMapping -> { + if (ObjectUtils.isEmpty(resourceMapping.getId())) { + UUIDEnrichmentUtil.enrichRandomUuid(resourceMapping, "id"); + } + }); + } 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) { @@ -120,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/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 22d316b707e..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,25 +1,24 @@ 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.ServiceUtil; +import digit.util.MdmsV2Util; import digit.web.models.*; - -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -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 org.springframework.util.ObjectUtils; + +import java.util.*; +import java.util.stream.Collectors; import static digit.config.ServiceConstants.*; @@ -27,60 +26,96 @@ @Slf4j public class PlanConfigurationValidator { - private MdmsUtil mdmsUtil; + private MdmsV2Util mdmsV2Util; + private PlanConfigurationRepository planConfigRepository; + private CommonUtil commonUtil; - private ServiceUtil serviceUtil; private MultiStateInstanceUtil centralInstanceUtil; - public PlanConfigurationValidator(MdmsUtil mdmsUtil, PlanConfigurationRepository planConfigRepository, ServiceUtil serviceUtil, 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.serviceUtil = serviceUtil; - this.centralInstanceUtil = centralInstanceUtil; + 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 = 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); - // Validate that the assumption values in the plan configuration are correct - validateAssumptionValue(planConfiguration); - - // Validate the filestore ID in the plan configuration's request mappings - validateFilestoreId(planConfiguration); + // Validate that the 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); - // Validate that the inputs for operations in the request match those in the MDMS data - validateOperationsInputAgainstMDMS(request, mdmsData); - - // Validate that the resource mappings in the request match those in the MDMS data - validateResourceMappingAgainstMDMS(request, mdmsData); - - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings - validateMappedToUniqueness(planConfiguration.getResourceMapping()); + //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 - validateUserInfo(request); + commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validates the vehicle id from additional details object against the data from mdms v2 + validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); } + /** + * Validates if plan configuration for the provided name and campaign id already exists + * + * @param planConfiguration the plan configuration from the create request + */ + private void validateDuplicateRecord(PlanConfiguration planConfiguration) { + List planConfigurationsFromSearch = planConfigRepository.search(PlanConfigurationSearchCriteria.builder() + .tenantId(planConfiguration.getTenantId()) + .campaignId(planConfiguration.getCampaignId()) + .name(planConfiguration.getName()) + .build()); + + 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 name of the plan configuration against a regex pattern retrieved from MDMS data. * @@ -89,12 +124,10 @@ public void validateCreate(PlanConfigurationRequest request) { * @throws CustomException if the JSONPath evaluation fails, the name validation list from MDMS is empty, * or the plan configuration name validation fails. */ - public void validatePlanConfigName(PlanConfigurationRequest request, Object mdmsData) - { + public void validatePlanConfigName(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); final String jsonPathForNameValidation = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_NAME_VALIDATION + "[*].data"; - List nameValidationListFromMDMS = null; try { nameValidationListFromMDMS = JsonPath.read(mdmsData, jsonPathForNameValidation); @@ -108,10 +141,9 @@ public void validatePlanConfigName(PlanConfigurationRequest request, Object mdms } String regexPattern = (String) nameValidationListFromMDMS.get(0); - if (!serviceUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) { + if (!commonUtil.validateStringAgainstRegex(regexPattern, planConfiguration.getName())) { throw new CustomException(NAME_VALIDATION_FAILED_CODE, NAME_VALIDATION_FAILED_MESSAGE); } - } @@ -121,226 +153,129 @@ public void validatePlanConfigName(PlanConfigurationRequest request, Object mdms * * @param planConfiguration The plan configuration to validate. */ - public void validateAssumptionValue(PlanConfiguration planConfiguration) { - // Collect all active assumption keys - Set activeAssumptionKeys = planConfiguration.getAssumptions().stream() - .filter(Assumption::getActive) - .map(Assumption::getKey) - .collect(Collectors.toSet()); - - planConfiguration.getOperations().stream() - .filter(Operation::getActive) - .forEach(operation -> { - if (!activeAssumptionKeys.contains(operation.getAssumptionValue())) { - log.error("Assumption Value " + operation.getAssumptionValue() + " is not present in the list of active Assumption Keys"); - throw new CustomException(ASSUMPTION_VALUE_NOT_FOUND_CODE, ASSUMPTION_VALUE_NOT_FOUND_MESSAGE + " - " + operation.getAssumptionValue()); - } - }); - - } /** * Validates the assumption keys against MDMS data. - * @param request The request containing the plan configuration and the MDMS data. + * + * @param request The request containing the plan configuration and the MDMS data. * @param mdmsData The MDMS data. */ public void validateAssumptionKeyAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - final String jsonPathForAssumption = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_ASSUMPTION + "[*].assumptions[*]"; + if (!CollectionUtils.isEmpty(planConfiguration.getAssumptions())) { - 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); - } + Object additionalDetails = request.getPlanConfiguration().getAdditionalDetails(); + if (additionalDetails == null) { + throw new CustomException(ADDITIONAL_DETAILS_MISSING_CODE, ADDITIONAL_DETAILS_MISSING_MESSAGE); + } - HashSet assumptionSetFromMDMS = new HashSet<>(assumptionListFromMDMS); - planConfiguration.getAssumptions().forEach(assumption -> { - if (!assumptionSetFromMDMS.contains(assumption.getKey())) { + 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); + } + + 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 + " at JSONPath: " + jsonPathForAssumption); + throw new CustomException(ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_CODE, ASSUMPTION_KEY_NOT_FOUND_IN_MDMS_MESSAGE + assumption.getKey() + " at JSONPath: " + jsonPathForAssumption); } - } - ); - + }); + } } /** - * Validates the file store IDs in the provided PlanConfiguration's Resource Mapping list. - * @param planConfiguration The PlanConfiguration to validate. + * Validates the uniqueness of assumption keys in the provided PlanConfiguration. + * If any duplicate keys are found, a CustomException is thrown. + * + * @param planConfig the PlanConfiguration object containing a list of Assumptions to validate + * @throws CustomException if a duplicate assumption key is found */ - public void validateFilestoreId(PlanConfiguration planConfiguration) { - Set fileStoreIds = planConfiguration.getFiles().stream() - .map(File::getFilestoreId) - .collect(Collectors.toSet()); + public void validateAssumptionUniqueness(PlanConfiguration planConfig) { + Set assumptionKeys = new HashSet<>(); - planConfiguration.getResourceMapping().stream().forEach(mapping -> { - if (!fileStoreIds.contains(mapping.getFilestoreId())) { - log.error("Resource Mapping " + mapping.getMappedTo() + " does not have valid fileStoreId " + mapping.getFilestoreId()); - throw new CustomException(FILESTORE_ID_INVALID_CODE, FILESTORE_ID_INVALID_MESSAGE); + 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()); } - }); - + } } /** * Validates the template identifiers of files in the PlanConfigurationRequest against the list of template identifiers * obtained from MDMS (Master Data Management System) data. * - * @param request The PlanConfigurationRequest containing the PlanConfiguration to validate. - * @param mdmsData The MDMS data containing template identifiers to validate against. + * @param request The PlanConfigurationRequest containing the PlanConfiguration to validate. + * @param mdmsData The MDMS data containing template identifiers to validate against. */ public void validateTemplateIdentifierAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { PlanConfiguration planConfiguration = request.getPlanConfiguration(); - 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); - } + 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); + 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); - } + 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); + 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 - requiredTemplateIdentifierSetFromMDMS - .stream() - .forEach(requiredTemplate -> { + // 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 operations input against the Master Data Management System (MDMS) data. - * - * @param request The PlanConfigurationRequest containing the plan configuration and other details. - * @param mdmsData The MDMS data containing the master rule configure inputs. - */ - public void validateOperationsInputAgainstMDMS(PlanConfigurationRequest request, Object mdmsData) { - PlanConfiguration planConfiguration = request.getPlanConfiguration(); - List files = planConfiguration.getFiles(); - List templateIds = files.stream() - .map(File::getTemplateIdentifier) - .collect(Collectors.toList()); - List inputFileTypes = files.stream() - .map(File::getInputFileType) - .map(File.InputFileTypeEnum::toString) - .collect(Collectors.toList()); - - final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS; - List ruleInputsListFromMDMS = null; - try { - log.info(jsonPathForRuleInputs); - ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); - } - - HashSet ruleInputsSetFromMDMS = new HashSet<>(ruleInputsListFromMDMS); - - HashSet allowedColumns = getColumnsFromSchemaThatAreRuleInputs(ruleInputsSetFromMDMS, templateIds, inputFileTypes); - planConfiguration.getOperations().stream() - .map(Operation::getOutput) - .forEach(allowedColumns::add); - - planConfiguration.getOperations().stream().forEach(operation -> { - if (!allowedColumns.contains(operation.getInput())) { - log.error("Input Value " + operation.getInput() + " is not present in MDMS Input List"); - throw new CustomException(INPUT_KEY_NOT_FOUND_CODE, INPUT_KEY_NOT_FOUND_MESSAGE); } - }); - - } - /** - * Filters the Schema MDMS data by type and section - * returns the list of columns which have the property 'isRuleConfigureInputs' as true - * - * @param schemas List of schemas from MDMS - * @param templateIds The list of template identifiers from request object - * @param inputFileTypes The list of input file type from request object - */ - public static HashSet getColumnsFromSchemaThatAreRuleInputs(HashSet schemas, List templateIds, List inputFileTypes) { - if (schemas == null) { - return new HashSet<>(); } - HashSet finalData = new HashSet<>(); - for (Object item : schemas) { - LinkedHashMap schemaEntity = (LinkedHashMap) item; - if(!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) continue; - LinkedHashMap columns = (LinkedHashMap)((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); - if(columns == null) return new HashSet<>(); - columns.entrySet().stream() - .forEach(column -> { - LinkedHashMap data = column.getValue(); - if(data.get(MDMS_SCHEMA_PROPERTIES_IS_RULE_CONFIGURE_INPUT)){ - finalData.add(column.getKey()); - } - }); // Add the keys to finalData - } - return finalData; } - - /** - * Validates that the 'mappedTo' values in the list of 'resourceMappings' are unique. - * If a duplicate 'mappedTo' value is found, it logs an error and throws a CustomException. - * - * @param resourceMappings The list of 'ResourceMapping' objects to validate. - * @throws CustomException If a duplicate 'mappedTo' value is found. - */ - public static void validateMappedToUniqueness(List resourceMappings) { - Set uniqueMappedToSet = new HashSet<>(); - resourceMappings.stream().forEach(mapping -> { - String uniqueKey = mapping.getFilestoreId() + "-" + mapping.getMappedTo(); - if (!uniqueMappedToSet.add(uniqueKey)) { - log.error("Duplicate MappedTo " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - throw new CustomException(DUPLICATE_MAPPED_TO_VALIDATION_ERROR_CODE, DUPLICATE_MAPPED_TO_VALIDATION_ERROR_MESSAGE + " - " + mapping.getMappedTo() + " for FilestoreId " + mapping.getFilestoreId()); - } - }); - } - - /** * Validates the search request for plan configurations. + * * @param planConfigurationSearchRequest The search request for plan configurations. */ public void validateSearchRequest(PlanConfigurationSearchRequest planConfigurationSearchRequest) { @@ -360,62 +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 = 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 if campaign id exists against project factory + validateCampaignId(campaignResponse); + // Validate that the assumption keys in the request are present in the MDMS data validateAssumptionKeyAgainstMDMS(request, mdmsData); - // Validate that the assumption values in the plan configuration are correct - validateAssumptionValue(planConfiguration); + // Validate that the assumption keys in the request are unique + validateAssumptionUniqueness(planConfiguration); - // Validate the filestore ID in the plan configuration's request mappings - validateFilestoreId(planConfiguration); + //Validating operation's input and assumptionValue fields + validateOperations(request, campaignResponse); // Validate that the template identifiers in the request match those in the MDMS data validateTemplateIdentifierAgainstMDMS(request, mdmsData); - // Validate that the inputs for operations in the request match those in the MDMS data - validateOperationsInputAgainstMDMS(request, mdmsData); - - // Validate the dependencies between operations in the plan configuration - validateOperationDependencies(planConfiguration); - - // Validate that the resource mappings in the request match those in the MDMS data - validateResourceMappingAgainstMDMS(request, mdmsData); - - // Validate the uniqueness of the 'mappedTo' fields in the resource mappings - validateMappedToUniqueness(planConfiguration.getResourceMapping()); - //Validating plan config name against MDMS data validatePlanConfigName(request, mdmsData); // Validate the user information in the request - validateUserInfo(request); + commonUtil.validateUserInfo(request.getRequestInfo()); + + // Validates the vehicle id from additional details object against the data from mdms v2 + validateVehicleIdsFromAdditionalDetailsAgainstMDMS(request, mdmsV2Data); + } /** * 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); } /** @@ -426,103 +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 - planConfiguration.getOperations().stream().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()); - } - }); + + /** + * 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) - .toList(); - List inputFileTypes = files.stream() - .map(File::getInputFileType) - .map(File.InputFileTypeEnum::toString) - .toList(); - - final String jsonPathForRuleInputs = JSON_ROOT_PATH + MDMS_PLAN_MODULE_NAME + DOT_SEPARATOR + MDMS_MASTER_SCHEMAS; - List ruleInputsListFromMDMS = null; - try { - log.info(jsonPathForRuleInputs); - ruleInputsListFromMDMS = JsonPath.read(mdmsData, jsonPathForRuleInputs); - } catch (Exception e) { - log.error(e.getMessage()); - throw new CustomException(JSONPATH_ERROR_CODE, JSONPATH_ERROR_MESSAGE); + /** + * 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); } - HashSet ruleInputsSetFromMDMS = new HashSet<>(ruleInputsListFromMDMS); - HashSet requiredColumns = getRequiredColumnsFromSchema(ruleInputsSetFromMDMS, templateIds, inputFileTypes); - List resourceMappings = planConfiguration.getResourceMapping(); + } - // Throw a custom exception if no active mappings with BOUNDARY_CODE are found - if(requiredColumns.contains(ServiceConstants.BOUNDARY_CODE)) { - boolean exists = resourceMappings.stream() - .anyMatch(mapping -> mapping.getActive() && mapping.getMappedTo().equals(ServiceConstants.BOUNDARY_CODE)); + /** + * 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); } + } + + /** + * 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); + } /** - * Filters the Schema MDMS data by type and section - * returns the list of columns which have the property 'isRequired' as true + * Retrieves allowed columns based on MDMS data and campaign type. * - * @param schemas List of schemas from MDMS - * @param templateIds The list of template identifiers from request object - * @param inputFileTypes The list of input file type from request object - * @return List of Columns that are required + * @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 HashSet getRequiredColumnsFromSchema(HashSet schemas, List templateIds, List inputFileTypes) { - if (CollectionUtils.isEmpty(schemas)) { - return new HashSet<>(); + 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); + } + } } - HashSet finalData = new HashSet<>(); - for (Object item : schemas) { - LinkedHashMap schemaEntity = (LinkedHashMap) item; - if(!templateIds.contains(schemaEntity.get(MDMS_SCHEMA_SECTION)) || !inputFileTypes.contains(schemaEntity.get(MDMS_SCHEMA_TYPE))) continue; - LinkedHashMap columns = (LinkedHashMap)((LinkedHashMap) schemaEntity.get(MDMS_SCHEMA_SCHEMA)).get(MDMS_SCHEMA_PROPERTIES); - if (columns == null) return new HashSet<>(); - columns.entrySet().stream().forEach(column -> { - 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 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()); + } } - return finalData; } /** - * Validates the user information within the provided PlanConfigurationRequest. + * Validates the assumption values of operations against allowed columns, active keys, and previous outputs. * - * @param request the PlanConfigurationRequest containing the user information to be validated - * @throws CustomException if the user information is missing in the request + * @param planConfiguration The plan configuration containing operations. + * @param allowedColumns The allowed column names for assumption validation. + * @param activeAssumptionKeys The set of active assumption keys. */ - public void validateUserInfo(PlanConfigurationRequest request) - { - if (ObjectUtils.isEmpty(request.getRequestInfo().getUserInfo())) { - log.error(USERINFO_MISSING_MESSAGE); - throw new CustomException(USERINFO_MISSING_CODE, USERINFO_MISSING_MESSAGE); + 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/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 fb0f6560908..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<>(); 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 index 51959990534..19c7bebeea7 100644 --- a/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java +++ b/health-services/plan-service/src/main/java/digit/util/ServiceUtil.java @@ -8,16 +8,5 @@ @Component public class ServiceUtil { - /** - * Validates the given input string against the provided regex pattern. - * - * @param patternString the regex pattern to validate against - * @param inputString the input string to be validated - * @return true if the input string matches the regex pattern, false otherwise - */ - public Boolean validateStringAgainstRegex(String patternString, String inputString) { - Pattern pattern = Pattern.compile(patternString); - Matcher matcher = pattern.matcher(inputString); - return matcher.matches(); - } + } diff --git a/health-services/plan-service/src/main/java/digit/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 4729cdd736e..d50610832e9 100644 --- a/health-services/plan-service/src/main/java/digit/web/controllers/PlanConfigController.java +++ b/health-services/plan-service/src/main/java/digit/web/controllers/PlanConfigController.java @@ -3,7 +3,6 @@ import digit.service.PlanConfigurationService; import digit.util.ResponseInfoFactory; -import digit.web.models.PlanConfiguration; import digit.web.models.PlanConfigurationRequest; import digit.web.models.PlanConfigurationResponse; import digit.web.models.PlanConfigurationSearchRequest; diff --git a/health-services/plan-service/src/main/java/digit/web/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/Operation.java b/health-services/plan-service/src/main/java/digit/web/models/Operation.java index fbc647cfc1d..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 @@ -40,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; 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 9032da0bfed..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; @@ -41,50 +39,40 @@ public class PlanConfiguration { @Size(min = 3, max = 128) private String name = null; - @JsonProperty("executionPlanId") + @JsonProperty("campaignId") @NotNull @Size(min = 2, max = 64) - @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Execution Plan Id must not contain only special characters") - private String executionPlanId = null; + @Pattern(regexp = "^(?!\\p{Punct}+$).*$", message = "Campaign Id must not contain only special characters") + private String campaignId = null; @JsonProperty("status") - @NotNull - 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/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 73% 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..2cd695cec55 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); - + //TODO: processsheetforestimate and processsheetforcensus + 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,16 @@ 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 +335,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,18 +360,9 @@ 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()) @@ -344,29 +370,10 @@ private void performRowLevelCalculations(PlanConfigurationRequest planConfigurat mapOfColumnNameAndIndex, campaignBoundaryList, resultMap); planUtil.create(planConfigurationRequest, feature, resultMap, mappedValues); // TODO: remove after testing - printRow(sheet, row); + parsingUtil.printRow(sheet, row); } } - /** - * Checks if a given row is empty. - * - * A row is considered empty if it is null or if all of its cells are empty or of type BLANK. - * - * @param row the Row to check - * @return true if the row is empty, false otherwise - */ - public static boolean isRowEmpty(Row row) { - if (row == null) { - return true; - } - for (Cell cell : row) { - if (cell != null && cell.getCellType() != CellType.BLANK) { - return false; - } - } - return true; - } /** * Performs calculations on operations for a specific row in the sheet. @@ -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..d0cd40201ff --- /dev/null +++ b/health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java @@ -0,0 +1,304 @@ +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()); + + } + } + } + //TODO: remove after testing + log.info("After updating values in sheet -> "); + parsingUtil.printRow(sheet, row); + + log.info("Successfully update file with approved census data."); + } + } + + public List getBoundaryCodesFromTheSheet(Sheet sheet, PlanConfigurationRequest planConfigurationRequest, String fileStoreId) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + + Map mappedValues = planConfig.getResourceMapping().stream() + .filter(f -> f.getFilestoreId().equals(fileStoreId)) + .collect(Collectors.toMap(ResourceMapping::getMappedTo, ResourceMapping::getMappedFrom)); + + Map mapOfColumnNameAndIndex = parsingUtil.getAttributeNameIndexFromExcel(sheet); + + Integer indexOfBoundaryCode = parsingUtil.getIndexOfBoundaryCode(0, + parsingUtil.sortColumnByIndex(mapOfColumnNameAndIndex), mappedValues); + + List boundaryCodes = new ArrayList<>(); + + for (Row row : sheet) { + // Skip the header row and empty rows + if (row.getRowNum() == 0 || parsingUtil.isRowEmpty(row)) { + continue; + } + + // Get the boundary code cell + Cell boundaryCodeCell = row.getCell(indexOfBoundaryCode); + + // Check if the cell is non-empty and collect its value + if (boundaryCodeCell != null && boundaryCodeCell.getCellType() == CellType.STRING) { + String boundaryCode = boundaryCodeCell.getStringCellValue().trim(); + if (!boundaryCode.isEmpty()) { + boundaryCodes.add(boundaryCode); + } + } + } + + return boundaryCodes; + } + + public List getCensusRecordsForEnrichment(PlanConfigurationRequest planConfigurationRequest, List boundaryCodes) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + CensusSearchCriteria censusSearchCriteria = CensusSearchCriteria.builder() + .tenantId(planConfig.getTenantId()) + .areaCodes(boundaryCodes) + .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) { + 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(); + + Plan planEstimate = planMap.get(boundaryCode); + + if (planEstimate != null) { + Map resourceTypeToEstimatedNumberMap = planEstimate.getResources().stream() + .collect(Collectors.toMap(Resource::getResourceType, Resource::getEstimatedNumber)); + + // Iterate over each output column to update the row cells with resource values + for (String resourceType : outputColumnList) { + BigDecimal estimatedValue = resourceTypeToEstimatedNumberMap.get(resourceType); + + if (estimatedValue != null) { + // Get the index of the column to update + Integer columnIndex = mapOfColumnNameAndIndex.get(resourceType); + if (columnIndex != null) { + // Update the cell with the resource value + Cell cell = row.getCell(columnIndex); + if (cell == null) { + cell = row.createCell(columnIndex); + } + cell.setCellValue(estimatedValue.doubleValue()); + } + } + } + } + //TODO: remove after testing + log.info("After updating values in sheet -> "); + parsingUtil.printRow(sheet, row); + + log.info("Successfully update file with approved census data."); + } + } + + + public List getPlanRecordsForEnrichment(PlanConfigurationRequest planConfigurationRequest, List boundaryCodes) { + PlanConfiguration planConfig = planConfigurationRequest.getPlanConfiguration(); + PlanSearchCriteria planSearchCriteria = PlanSearchCriteria.builder() + .tenantId(planConfig.getTenantId()) + .locality(boundaryCodes) + .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