diff --git a/build/build-config.yml b/build/build-config.yml index 235f7b72caa..13bc1db43fa 100644 --- a/build/build-config.yml +++ b/build/build-config.yml @@ -89,7 +89,7 @@ config: build: - work-dir: "core-services/error-handler" image-name: "error-handler" - dockerfile: "build/maven/Dockerfile" + dockerfile: "build/maven/Dockerfile" - name: "builds/health-campaign-services/core-services/dashboard-analytics" build: - work-dir: "core-services/dashboard-analytics" diff --git a/core-services/egov-hrms/CHANGELOG.md b/core-services/egov-hrms/CHANGELOG.md new file mode 100644 index 00000000000..ff7b8ed8811 --- /dev/null +++ b/core-services/egov-hrms/CHANGELOG.md @@ -0,0 +1,37 @@ +# Changelog +All notable changes to this module will be documented in this file. + +## 1.2.5 - 2023-02-02 + +- Transition from 1.2.5-beta version to 1.2.5 version + +## 1.2.5-beta - 2022-03-02 +- Added security fix for restricting employee search from citizen role + +## 1.2.4 - 2022-01-13 +- Updated to log4j2 version 2.17.1 + +## 1.2.3 - 2021-07-26 + - Fixed RAIN-3056: Able to re-activate employee by selecting the previous date + +## 1.2.2 - 2021-05-11 + - VUL-WEB-L008 + - Added @SafeHtml annotaion on string fields + - Updated POM to add safeHtml validator libraries + +## 1.2.1 - 2021-02-26 +- Updated domain name in application.properties + +## 1.2.0 - 2021-01-12 +- Added employee reactivation feature + +## 1.1.0 - 2020-05-27 + +- Upgraded to `tracer:2.0.0-SNAPSHOT` +- Upgraded to `Spring boot 2.2.6` +- Renamed `ReferenceType` enum to `EmployeeDocumentReferenceType` +- Added typescript interface generation plugin + +## 1.0.0 + +- Base version diff --git a/core-services/egov-hrms/LOCALSETUP.md b/core-services/egov-hrms/LOCALSETUP.md new file mode 100644 index 00000000000..275a5420e3c --- /dev/null +++ b/core-services/egov-hrms/LOCALSETUP.md @@ -0,0 +1,46 @@ +# Local Setup + +To setup the egov-hrms service in your local system, clone the [Core Service repository](https://github.com/egovernments/core-services). + +## Dependencies + +### Infra Dependency + +- [x] Postgres DB +- [ ] Redis +- [ ] Elasticsearch +- [x] Kafka + - [ ] Consumer + - [x] Producer + +## Running Locally + +To run the egov-hrms services in local system, you need to port forward below services. + +```bash +function kgpt(){kubectl get pods -n egov --selector=app=$1 --no-headers=true | head -n1 | awk '{print $1}'} +kubectl port-forward -n egov $(kgpt egov-idgen) 8087:8080 & +kubectl port-forward -n egov $(kgpt egov-mdms-service) 8088:8080 & +kubectl port-forward -n egov $(kgpt egov-user) 8089:8080 & +kubectl port-forward -n egov $(kgpt egov-filestore) 8090:8080 & +kubectl port-forward -n egov $(kgpt egov-localization) 8091:8080 & +``` + +Update below listed properties in `application.properties` before running the project: + +```ini +# {Id Gen service hostname} +egov.idgen.host = http://127.0.0.1:8087 + +# {mdms hostname} +egov.mdms.host=http://127.0.0.1:8088 + +# {user service hostname} +egov.user.host = http://127.0.0.1:8089 + +# {Filestore service hostname} +egov.filestore.host = http://127.0.0.1:8090 + +# {Localization service hostname} +egov.localization.host = http://127.0.0.1:8091 +``` diff --git a/core-services/egov-hrms/README.md b/core-services/egov-hrms/README.md new file mode 100644 index 00000000000..ceb2f235664 --- /dev/null +++ b/core-services/egov-hrms/README.md @@ -0,0 +1,112 @@ +# Egov-HRMS Service +### HRMS Service +The objective of HRMS is to provide a service that manages all the employees enrolled onto the system. HRMS provides extensive APIs to create, update and search the employees with attributes like assignments, service history, jurisdiction etc. HRMS can be treated a sub-set of the egov-user service, Every employee created through HRMS will also be created as a user in egov-user. + +### DB UML Diagram + +- NA + +### Service Dependencies +- egov-user +- egov-localization +- egov-idgen +- egov-mdms +- egov-filestore + +### Swagger API Contract +- Please refer to the [Swagger API contarct](https://editor.swagger.io/?url=https://raw.githubusercontent.com/egovernments/business-services/master/Docs/hrms-v1.0.0.yaml#!/) for HRMS service to understand the structure of APIs and to have visualization of all internal APIs. + + +## Service Details +**Details of all the entities involved:** + +**a) Assignments:** Every employee is assigned a list of assignments, every assignment is a designation provided to that employee for a given period of time. These designations are mapped to departments. This also includes marking the employee as HOD for that dept if needed. Employee can also provide information on who does he report to. + + - **Constraints:** + 1. For a given period of time an employee shouldn't have more than one assignments. + 2. The department and designation part of the employee must be configured in the system. + 3. Details of assignment once entered in the system cannot be deleted. + 4. An employee cannot have more than one active assignment. + +**b) Jurisdictions:** A jurisdiction is a area of power for any employee. It can be a zone, ward, block, city, state or the country. Currently a jurisdiction is defined as combination of Hierarchy type, Boundary Type and the actual Boundary. However, in the current system we are not validating these jurisdictions. This is being collected only for the sake of data. + + - **Constraints:** + 1. The details pertaining to a jurisdiction like Hierarchy, Boundary Type and Boundary must be configured in the system. + 2. An employee can have more than one jurisdictions. + 3. Currently in the system jurisdiction is limited to within a ULB. + +**c) Service History:** Service history is the record of an employee's professional experience. It captures information about location and period of work with necessary order number. Information about the current work details are to be entered here. + + - **Constraints:** + 1. There's no rule on period, dates of different services can overlap. + 2. There's no cap on the number of entries in the service history. + 3. Captured as legacy data. + +**d) Educational Details:** Captures educational details of the employee. Captures information like Degree, Year of Passing, University, Specialization etc as part of the educational details. + + - **Constraints:** + 1. Details pertaining to educational details like Degree, Specialization must be configured. + + +**e) Departmental Tests:** Captures details of the tests undertaken by the employee. Like name of the test and year of passing. + + - **Constraints:** + 1. Test details must be configures in the system. + +**f) Deactivation Details:** Details of deactivation of the employee, which captures reason for deactivation, period of deactivation and other necessary details. + + - **Constraints:** + 1. Deactivation details are compulsory while deactivating an employee. + +**f) Reactivation Details:** Details of reactivation of the employee, which captures reason for reactivation, the effective date from when reactivation take place and other necessary details. + + - **Constraints:** + 1. Reactivation details are compulsory while reactivating an employee. + + + +**Uniqueness Constraints:** +- Employee code has to be unique and will be used as username for login. +- Phone number has to be unique, which means no 2 employees can have the same phone number. + + + +**Notification:** +- Notification is sent to the phone number of the employee who has been created in the system. This is an SMS notification. + +### Configurable properties + +| Environment Variables | Description | Value | +| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------| +| `egov.hrms.employee.app.link` | This is the link to the mseva app, which differs based on the environment. | https://mseva.lgpunjab.gov.in/employee/user/login | +| `egov.hrms.default.pagination.limit` | This is the pagination limit on search results of employee search, it can be set to any numeric value without decimals. | 200 | +| `egov.hrms.default.pwd.length` | This is the length of password to be generated at the time of employee creation. However, please ensure this is in sync with the egov-user pwd policy. | 10 | +| `open.search.enabled.roles` | This is a list of Role codes that are allowed to perform an open-search in hrms. | SUPERUSER,ADMIN | +| `egov.idgen.ack.name` | Key to be configured in Idgen alongwith the ID format to generate employee code. | hrms.employeecode | +| `egov.idgen.ack.format` | Format to be configured in ID gen to generate employee code. | EMP-[city]-[SEQ_EG_HRMS_EMP_CODE] | +### API Details + +`BasePath` /egov-hrms/employees/[API endpoint] + +##### Method +**a) Create Employee `POST /_create` :** API (Bulk API) to create an employee with the following details: Assignments, Jurisdictions, Service History, Educational Details, Departmental Tests + +**b) Update Employee `POST /_update` :** API (Bulk API) to update the details of an employee with the following details: Assignments, Jurisdictions, Service History, Educational Details, Departmental Tests. There are constraints under which the update works, which are listed in the details of entities. As part of the personal details of the employee, Code of the employee cannot be updated once created. + +Deactivation is a part of the update API where the employee is marked inactive. This marks the user entry of this employee also as inactive. While deactivating an employee it is mandatory to provide deactivation details as well. + +**c) Search Employee `POST /_search` :** API to search the employee in the system on the following criteria: Id, UUID, Name, Code, Status, Type, Department, Designation, Position. All of them being arrays, at a time more than one employees can be fetched. +Constraints: a. Open Search is enabled only for a set of users. Currently it is enabled only for SUPERUSER, if it has to be enabled for other roles, add those roles to the parameter 'open.search.enabled.roles' in app.properties with values(role codes) separated by comma. + +**d) Count of Employee `POST /_count` :** This API is use to get list of active and inactive employee present in the system. + +### Kafka Consumers + +- NA + +### Kafka Producers + +- Following are the Producer topic. + - **save-hrms-employee** :- This topic is used to create new employee in the system. + - **update-hrms-employee** :- This topic is used to update the existing employee in the systen. + - **egov.core.notification.sms** :- This topic is used to send noification to the phone number of the employee who has been created in the system. \ No newline at end of file diff --git a/core-services/egov-hrms/egov-hrms.iml b/core-services/egov-hrms/egov-hrms.iml new file mode 100644 index 00000000000..abf9c52d541 --- /dev/null +++ b/core-services/egov-hrms/egov-hrms.iml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/core-services/egov-hrms/pom.xml b/core-services/egov-hrms/pom.xml new file mode 100644 index 00000000000..63ff6fcda8c --- /dev/null +++ b/core-services/egov-hrms/pom.xml @@ -0,0 +1,176 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.6.RELEASE + + org.egov + egov-hrms + 1.2.6-SNAPSHOT + egov-hrms + HR Management System + + 2.17.1 + UTF-8 + 1.8 + 2.9.6 + UTF-8 + 3.3.9 + 1.18.8 + 2.6 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework + spring-beans + 5.2.20.RELEASE + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.flywaydb + flyway-core + + + org.postgresql + postgresql + + + org.egov.services + services-common + 1.1.1-SNAPSHOT + + + commons-lang + commons-lang + ${commons-lang-version} + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-devtools + + + org.springframework + spring-test + test + + + org.springframework.boot + spring-boot-starter-test + test + + + com.google.code.gson + gson + 2.8.0 + + + org.egov + mdms-client + 0.0.2-SNAPSHOT + + + org.egov.services + tracer + 2.1.2-SNAPSHOT + + + org.hibernate + hibernate-validator + 6.0.16.Final + + + org.jsoup + jsoup + 1.10.2 + + + org.egov.common + health-services-models + 1.0.9-SNAPSHOT + compile + + + + + 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/ + + always + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-devtools + + + + + + cz.habarta.typescript-generator + typescript-generator-maven-plugin + 2.22.595 + + + generate + + generate + + process-classes + + + + jackson2 + + org.egov.hrms.web.contract.EmployeeRequest + org.egov.hrms.web.contract.EmployeeResponse + org.egov.hrms.web.contract.EmployeeSearchCriteria + + + + + org.egov.hrms.web.contract.User:User + org.egov.hrms.model.AuditDetails:AuditDetails + org.egov.common.contract.request.User:User + org.egov.common.contract.request.RequestInfo:RequestInfo + org.egov.common.contract.response.ResponseInfo:ResponseInfo + + Digit + true + module + + + + + diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/EgovEmployeeApplication.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/EgovEmployeeApplication.java new file mode 100644 index 00000000000..12c7c5daeb5 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/EgovEmployeeApplication.java @@ -0,0 +1,120 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms; + +import java.util.TimeZone; + +import javax.annotation.PostConstruct; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.utils.MultiStateInstanceUtil; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.repository.RestCallRepository; +import org.egov.hrms.service.DefaultUserService; +import org.egov.hrms.service.IndividualService; +import org.egov.hrms.service.UserService; +import org.egov.tracer.config.TracerConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Import; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.context.annotation.Primary; + +@SpringBootApplication +@ComponentScan(basePackages = { "org.egov.hrms", "org.egov.hrms.web.controller" , "org.egov.hrms.config"}) +@Import({TracerConfiguration.class, MultiStateInstanceUtil.class}) +@Slf4j +public class EgovEmployeeApplication { + + @Value("${app.timezone}") + private String timeZone; + + @PostConstruct + public void initialize() { + TimeZone.setDefault(TimeZone.getTimeZone(timeZone)); + } + + @Bean + public ObjectMapper getObjectMapper() { + final ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + objectMapper.setTimeZone(TimeZone.getTimeZone(timeZone)); + return objectMapper; + } + + @Bean + @Primary + public UserService getUserService(@Value("${egov.hrms.user.service.qualifier}") String userServiceQualifier, + @Autowired PropertiesManager propertiesManager, + @Autowired RestCallRepository restCallRepository, + @Autowired ObjectMapper objectMapper, + @Autowired MultiStateInstanceUtil multiStateInstanceUtil, + @Value("${egov.user.create.endpoint}") String userCreateEndpoint, + @Value("${egov.user.update.endpoint}") String userUpdateEndpoint, + @Value("${egov.user.search.endpoint}") String userSearchEndpoint) { + if (userServiceQualifier.equalsIgnoreCase("individualService")) { + log.info("using individual module as user service"); + return new IndividualService(propertiesManager, restCallRepository); + } + else { + log.info("using egov-user module as user service"); + DefaultUserService userService = new DefaultUserService(); + userService.setPropertiesManager(propertiesManager); + userService.setRestCallRepository(restCallRepository); + userService.setObjectMapper(objectMapper); + userService.setCentralInstanceUtil(multiStateInstanceUtil); + userService.setUserCreateEndpoint(userCreateEndpoint); + userService.setUserUpdateEndpoint(userUpdateEndpoint); + userService.setUserSearchEndpoint(userSearchEndpoint); + return userService; + } + } + + public static void main(String[] args) { + SpringApplication.run(EgovEmployeeApplication.class, args); + } +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/config/PropertiesManager.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/config/PropertiesManager.java new file mode 100644 index 00000000000..dd0fb1ee4c6 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/config/PropertiesManager.java @@ -0,0 +1,137 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.empernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@empernments.org. + */ + +package org.egov.hrms.config; + +import lombok.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class PropertiesManager { + + //Hosts and Endpoints + @Value("${egov.mdms.host}") + public String mdmsHost; + + @Value("${egov.mdms.search.endpoint}") + public String mdmsSearchEndpoint; + + @Value("${egov.user.host}") + public String userHost; + + @Value("${egov.user.search.endpoint}") + public String userSearchEndpoint; + + @Value("${egov.user.create.endpoint}") + public String userCreateEndpoint; + + @Value("${egov.user.update.endpoint}") + public String userUpdateEndpoint; + + @Value("${egov.localization.host}") + public String localizationHost; + + @Value("${egov.localization.search.endpoint}") + public String localizationSearchEndpoint; + + @Value("${egov.idgen.host}") + public String idGenHost; + + @Value("${egov.idgen.path}") + public String idGenEndpoint; + + + //Kafka Topics + @Value("${kafka.topics.save.service}") + public String saveEmployeeTopic; + + @Value("${kafka.topics.update.service}") + public String UpdateEmployeeTopic; + + @Value("${kafka.topics.notification.sms}") + public String coreNotificationTopic; + + @Value("${kafka.topics.hrms.updateData}") + public String updateTopic; + + + //Variables + @Value("${egov.idgen.ack.name}") + public String hrmsIdGenKey; + + @Value("${egov.idgen.ack.format}") + public String hrmsIdGenFormat; + + @Value("${open.search.enabled.roles}") + public String openSearchEnabledRoles; + + @Value("${state.level.tenant.id}") + public String stateLevelTenantId; + + @Value("${parent.level.tenant.id}") + private String parentLevelTenantId; + + @Value("${decryption.abac.enable}") + private Boolean isDecryptionEnable; + + @Value("${egov.individual.host}") + private String individualHost; + + @Value("${egov.individual.create.endpoint}") + private String individualCreateEndpoint; + + @Value("${egov.individual.update.endpoint}") + private String individualUpdateEndpoint; + + @Value("${egov.individual.delete.endpoint}") + private String individualDeleteEndpoint; + + @Value("${egov.individual.search.endpoint}") + private String individualSearchEndpoint; + + @Value("${egov.hrms.auto.generate.password}") + private boolean autoGeneratePassword; +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/consumer/HrmsConsumer.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/consumer/HrmsConsumer.java new file mode 100644 index 00000000000..a4c33b0c096 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/consumer/HrmsConsumer.java @@ -0,0 +1,47 @@ +package org.egov.hrms.consumer; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.admin.NewTopic; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.producer.HRMSProducer; +import org.egov.hrms.service.NotificationService; +import org.egov.hrms.web.contract.EmployeeRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +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.HashMap; + +@Component +@Slf4j +public class HrmsConsumer { + + @Autowired + private NotificationService notificationService; + + @Autowired + private ObjectMapper mapper; + + @Autowired + private HRMSProducer hrmsProducer; + + @Autowired + private PropertiesManager propertiesManager; + + @KafkaListener(topics = {"${kafka.topics.hrms.updateData}"}) + public void listenUpdateEmployeeData(final HashMap record,@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + EmployeeRequest employeeRequest = mapper.convertValue(record, EmployeeRequest.class); + hrmsProducer.push(propertiesManager.getUpdateEmployeeTopic(), employeeRequest); + notificationService.sendReactivationNotification(employeeRequest); + } catch (final Exception e) { + + log.error("Error while listening to value: " + record + " on topic: " + topic + ": ", e); + } + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Assignment.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Assignment.java new file mode 100644 index 00000000000..9df7a4b92bd --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Assignment.java @@ -0,0 +1,96 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.*; +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@AllArgsConstructor +@Builder +@Getter +@NoArgsConstructor +@Setter +@ToString +public class Assignment { + + @SafeHtml + private String id; + + private Long position; + + @SafeHtml + @NotNull + private String designation; + + @SafeHtml + @NotNull + private String department; + + @NotNull + private Long fromDate; + + private Long toDate; + + @SafeHtml + private String govtOrderNumber; + + @SafeHtml + private String tenantid; + + @SafeHtml + private String reportingTo; + + @JsonProperty("isHOD") + private Boolean isHOD=false; + + @NotNull + @JsonProperty("isCurrentAssignment") + private Boolean isCurrentAssignment; + + private AuditDetails auditDetails; + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/AuditDetails.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/AuditDetails.java new file mode 100644 index 00000000000..bb368cd9852 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/AuditDetails.java @@ -0,0 +1,25 @@ +package org.egov.hrms.model; + +import lombok.*; + +import javax.validation.constraints.NotNull; + + +@AllArgsConstructor +@Builder +@Getter +@NoArgsConstructor +@Setter +@ToString +public class AuditDetails { + + private String createdBy; + + private Long createdDate; + + private String lastModifiedBy; + + private Long lastModifiedDate; + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/DeactivationDetails.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/DeactivationDetails.java new file mode 100644 index 00000000000..32b7787825f --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/DeactivationDetails.java @@ -0,0 +1,45 @@ +package org.egov.hrms.model; + +import lombok.*; +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class DeactivationDetails { + + @SafeHtml + private String id; + + @SafeHtml + @NotNull + private String reasonForDeactivation; + + @SafeHtml + private String orderNo; + + @SafeHtml + private String remarks; + + @NotNull + private Long effectiveFrom; + + @SafeHtml + private String tenantId; + + private AuditDetails auditDetails; + + + + +} + + diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/DepartmentalTest.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/DepartmentalTest.java new file mode 100644 index 00000000000..6341ce3893a --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/DepartmentalTest.java @@ -0,0 +1,80 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import lombok.*; + +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class DepartmentalTest { + + @SafeHtml + private String id; + + @SafeHtml + @NotNull + private String test; + + @NotNull + private Long yearOfPassing; + + @SafeHtml + private String remarks; + + @SafeHtml + private String tenantId; + + private AuditDetails auditDetails; + + private Boolean isActive; + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/EducationalQualification.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/EducationalQualification.java new file mode 100644 index 00000000000..2071915c165 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/EducationalQualification.java @@ -0,0 +1,88 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import lombok.*; + +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class EducationalQualification { + + @SafeHtml + private String id; + + @SafeHtml + @NotNull + private String qualification; + + @SafeHtml + @NotNull + private String stream; + + @NotNull + private Long yearOfPassing; + + @SafeHtml + private String university; + + @SafeHtml + private String remarks; + + @SafeHtml + private String tenantId; + + private AuditDetails auditDetails; + + private Boolean isActive; + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Employee.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Employee.java new file mode 100644 index 00000000000..f6a9b5cd59a --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Employee.java @@ -0,0 +1,133 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import lombok.*; +import org.egov.hrms.web.contract.User; +import org.hibernate.validator.constraints.NotEmpty; +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.List; + +@Validated +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class Employee { + + private Long id; + + @SafeHtml + @Size(max = 1024) + private String uuid; + + @SafeHtml + @Size(min = 1, max = 256) + private String code; + + @SafeHtml + @Size(max = 250) + private String employeeStatus; + + @SafeHtml + @NotNull + @Size(max = 250) + private String employeeType; + + private Long dateOfAppointment; + + @Valid + @NotEmpty + @Size(min = 1,max = 50) + private List jurisdictions = new ArrayList<>(); + + + @Valid + private List assignments = new ArrayList<>(); + + @Valid + @Size(max=25) + private List serviceHistory = new ArrayList<>(); + + + private Boolean IsActive; + + @Valid + @Size(max=25) + private List education = new ArrayList<>(); + + @Valid + @Size(max=25) + private List tests = new ArrayList<>(); + + @SafeHtml + @NotNull + @Size(max = 250) + private String tenantId; + + @Valid + @Size(max=50) + private List documents = new ArrayList<>(); + + @Valid + private List deactivationDetails = new ArrayList<>(); + + private List reactivationDetails = new ArrayList<>(); + + private AuditDetails auditDetails; + + private Boolean reActivateEmployee; + + @Valid + @NotNull + private User user; + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/EmployeeDocument.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/EmployeeDocument.java new file mode 100644 index 00000000000..d93c69f4cf0 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/EmployeeDocument.java @@ -0,0 +1,85 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import org.egov.hrms.model.enums.EmployeeDocumentReferenceType; +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class EmployeeDocument { + + @SafeHtml + private String id; + + @SafeHtml + private String documentName; + + @SafeHtml + private String documentId; + + private EmployeeDocumentReferenceType referenceType; + + @SafeHtml + private String referenceId; + + @SafeHtml + private String tenantId; + + private AuditDetails auditDetails; + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Jurisdiction.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Jurisdiction.java new file mode 100644 index 00000000000..5afc27194cb --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Jurisdiction.java @@ -0,0 +1,86 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import lombok.*; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class Jurisdiction { + + @SafeHtml + private String id; + + @SafeHtml + @NotNull + @Size(min=2, max=100) + private String hierarchy; + + @SafeHtml + @NotNull + @Size(min=2, max=100) + private String boundary; + + @SafeHtml + @NotNull + @Size(max=256) + private String boundaryType; + + @SafeHtml + private String tenantId; + + private AuditDetails auditDetails; + + private Boolean isActive; + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/ReactivationDetails.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/ReactivationDetails.java new file mode 100644 index 00000000000..a5cb0c1a3c4 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/ReactivationDetails.java @@ -0,0 +1,45 @@ +package org.egov.hrms.model; + +import lombok.*; +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class ReactivationDetails { + + @SafeHtml + private String id; + + @SafeHtml + @NotNull + private String reasonForReactivation; + + @SafeHtml + private String orderNo; + + @SafeHtml + private String remarks; + + @NotNull + private Long effectiveFrom; + + @SafeHtml + private String tenantId; + + private AuditDetails auditDetails; + + + + +} + + diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Role.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Role.java new file mode 100644 index 00000000000..6ab3212b245 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/Role.java @@ -0,0 +1,72 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import lombok.*; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +@Builder +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +public class Role { + + + @NotNull + @Size(min=2, max=100) + private String name; + + @Size(min=2, max=100) + private String code; + + @Size(max=256) + private String description; + + @Size(max = 256) + private String tenantId; + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/SMSRequest.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/SMSRequest.java new file mode 100644 index 00000000000..31c92e38ef7 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/SMSRequest.java @@ -0,0 +1,19 @@ +package org.egov.hrms.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + + +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@ToString +public class SMSRequest { + private String mobileNumber; + private String message; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/ServiceHistory.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/ServiceHistory.java new file mode 100644 index 00000000000..56bdb6e2ca9 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/ServiceHistory.java @@ -0,0 +1,85 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model; + +import lombok.*; + +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.constraints.SafeHtml; +import org.springframework.validation.annotation.Validated; + +@Validated +@EqualsAndHashCode(exclude = {"auditDetails"}) +@Builder +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +public class ServiceHistory { + + @SafeHtml + private String id; + + @SafeHtml + private String serviceStatus; + + private Long serviceFrom; + + private Long serviceTo; + + @SafeHtml + private String orderNo; + + @SafeHtml + private String location; + + @SafeHtml + private String tenantId; + + private Boolean isCurrentPosition; + + private AuditDetails auditDetails; + + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/DeactivationType.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/DeactivationType.java new file mode 100644 index 00000000000..3b632fc1e03 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/DeactivationType.java @@ -0,0 +1,31 @@ +package org.egov.hrms.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + + +public enum DeactivationType { + SUSPENSION("SUSPENSION"), DEATH("DEATH"), RETIRED("RETIRED"); + + private String value; + + DeactivationType(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return name(); + } + + @JsonCreator + public static DeactivationType fromValue(String passedValue) { + for (DeactivationType obj : DeactivationType.values()) { + if (String.valueOf(obj.value).equals(passedValue.toUpperCase())) { + return obj; + } + } + return null; + } +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/EmployeeDocumentReferenceType.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/EmployeeDocumentReferenceType.java new file mode 100644 index 00000000000..f18fcd65a4d --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/EmployeeDocumentReferenceType.java @@ -0,0 +1,31 @@ +package org.egov.hrms.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum EmployeeDocumentReferenceType { + HEADER("HEADER"), ASSIGNMENT("ASSIGNMENT"), JURISDICTION("JURISDICTION"), SERVICE("SERVICE"), + EDUCATION("EDUCATION"), TEST("TEST"), DEACTIVATION("DEACTIVATION"); + + private String value; + + EmployeeDocumentReferenceType(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return name(); + } + + @JsonCreator + public static EmployeeDocumentReferenceType fromValue(String passedValue) { + for (EmployeeDocumentReferenceType obj : EmployeeDocumentReferenceType.values()) { + if (String.valueOf(obj.value).equals(passedValue.toUpperCase())) { + return obj; + } + } + return null; + } +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/Gender.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/Gender.java new file mode 100644 index 00000000000..7ab9adf1c8d --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/Gender.java @@ -0,0 +1,70 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum Gender { + MALE("MALE"), FEMALE("FEMALE"), OTHERS("OTHERS"); + + private String value; + + Gender(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return name(); + } + + @JsonCreator + public static Gender fromValue(String passedValue) { + for (Gender obj : Gender.values()) { + if (String.valueOf(obj.value).equals(passedValue.toUpperCase())) { + return obj; + } + } + return null; + } +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/GuardianRelation.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/GuardianRelation.java new file mode 100644 index 00000000000..dead1f98b69 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/GuardianRelation.java @@ -0,0 +1,5 @@ +package org.egov.hrms.model.enums; + +public enum GuardianRelation { + FATHER, MOTHER, HUSBAND, OTHER; +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/UserType.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/UserType.java new file mode 100644 index 00000000000..153e5db53cd --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/model/enums/UserType.java @@ -0,0 +1,70 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.model.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum UserType { + EMPLOYEE("EMPLOYEE"), CITIZEN("CITIZEN"), SYSTEM("SYSTEM"); + + private String value; + + UserType(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return name(); + } + + @JsonCreator + public static UserType fromValue(String passedValue) { + for (UserType obj : UserType.values()) { + if (String.valueOf(obj.value).equals(passedValue.toUpperCase())) { + return obj; + } + } + return null; + } +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/producer/HRMSProducer.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/producer/HRMSProducer.java new file mode 100644 index 00000000000..8521e631b1b --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/producer/HRMSProducer.java @@ -0,0 +1,19 @@ +package org.egov.hrms.producer; + +import lombok.extern.slf4j.Slf4j; +import org.egov.tracer.kafka.CustomKafkaTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class HRMSProducer { + + @Autowired + private CustomKafkaTemplate kafkaTemplate; + + public void push(String topic, Object value) { + log.info("Topic: "+topic); + kafkaTemplate.send(topic, value); + } +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeCountRowMapper.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeCountRowMapper.java new file mode 100644 index 00000000000..2266e24695f --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeCountRowMapper.java @@ -0,0 +1,58 @@ +package org.egov.hrms.repository; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.egov.hrms.model.*; +import org.egov.hrms.model.enums.EmployeeDocumentReferenceType; +import org.egov.hrms.web.contract.User; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class EmployeeCountRowMapper implements ResultSetExtractor> { + + @Autowired + private ObjectMapper mapper; + + @Override + /** + * Maps ResultSet to Employee POJO. + */ + public Map extractData(ResultSet rs) throws SQLException, DataAccessException { + Map response = new HashMap<>(); + int totalEmployee = 0; + int activeEmployee = 0; + int inactiveEmployee = 0; + while(rs.next()) { + if(rs.getBoolean("active")) + activeEmployee = activeEmployee + rs.getInt("count"); + else + inactiveEmployee = inactiveEmployee + rs.getInt("count"); + totalEmployee = totalEmployee + rs.getInt("count"); + } + if(totalEmployee==0){ + response.put("activeEmployee","0"); + response.put("inactiveEmployee", "0"); + } + response.put("activeEmployee", String.valueOf(activeEmployee)); + response.put("inactiveEmployee", String.valueOf(inactiveEmployee)); + response.put("totalEmployee", String.valueOf(totalEmployee)); + return response; + } + + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueries.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueries.java new file mode 100644 index 00000000000..6b824692a34 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueries.java @@ -0,0 +1,57 @@ +package org.egov.hrms.repository; + +import org.springframework.stereotype.Component; + +@Component +public class EmployeeQueries { + + public static final String HRMS_GET_EMPLOYEES = "SELECT employee.id as employee_id, employee.uuid as employee_uuid, employee.code as employee_code, " + + "employee.dateOfAppointment as employee_doa, employee.employeestatus as employee_status, employeetype as employee_type, employee.active as employee_active, employee.reactivateemployee as employee_reactive, " + + "employee.tenantid as employee_tenantid, employee.createdby as employee_createdby, employee.createddate as employee_createddate, " + + "employee.lastmodifiedby as employee_lastmodifiedby, employee.lastmodifieddate as employee_lastmodifieddate, assignment.uuid as assignment_uuid, " + + "assignment.position as assignment_position, assignment.department as assignment_department, assignment.designation as assignment_designation, " + + "assignment.fromdate as assignment_fromdate, assignment.todate as assignment_todate, assignment.govtordernumber as assignment_govtordernumber, " + + "assignment.reportingto as assignment_reportingto, assignment.ishod as assignment_ishod, assignment.iscurrentassignment as assignment_iscurrentassignment, " + + "assignment.tenantid as assignment_tenantid, " + + "assignment.createdby as assignment_createdby, assignment.createddate as assignment_createddate, assignment.lastmodifiedby as assignment_lastmodifiedby, " + + "assignment.lastmodifieddate as assignment_lastmodifieddate, education.uuid as education_uuid, education.qualification as education_qualification, " + + "education.stream as education_stream, education.yearofpassing as education_yearofpassing, education.university as education_university, " + + "education.remarks as education_remarks,education.isactive as education_isactive ,education.tenantid as education_tenantid, education.createdby as education_createdby, " + + "education.createddate as education_createddate, education.lastmodifiedby as education_lastmodifiedby, education.lastmodifieddate as education_lastmodifieddate, " + + "depttest.uuid as depttest_uuid, depttest.test as depttest_test, depttest.yearofpassing as depttest_yearofpassing, depttest.remarks as depttest_remarks, " + + "depttest.isactive as depttest_isactive, depttest.tenantid as depttest_tenantid, depttest.createdby as depttest_createdby, depttest.createddate as depttest_createddate, " + + "depttest.lastmodifiedby as depttest_lastmodifiedby, depttest.lastmodifieddate as depttest_lastmodifieddate, docs.uuid as docs_uuid, " + + "docs.documentid as docs_documentid, docs.documentname as docs_documentname, docs.referencetype as docs_referencetype, " + + "docs.referenceid as docs_referenceid, docs.tenantid as docs_tenantid, docs.createdby as docs_createdby, docs.createddate as docs_createddate, " + + "docs.lastmodifiedby as docs_lastmodifiedby, docs.lastmodifieddate as docs_lastmodifieddate, jurisdiction.uuid as jurisdiction_uuid, " + + "jurisdiction.hierarchy as jurisdiction_hierarchy, jurisdiction.boundarytype as jurisdiction_boundarytype, jurisdiction.boundary as jurisdiction_boundary, " + + "jurisdiction.isactive as jurisdiction_isactive, jurisdiction.tenantid as jurisdiction_tenantid, jurisdiction.createdby as jurisdiction_createdby, jurisdiction.createddate as jurisdiction_createddate, " + + "jurisdiction.lastmodifiedby as jurisdiction_lastmodifiedby, jurisdiction.lastmodifieddate as jurisdiction_lastmodifieddate, history.uuid as history_uuid, " + + "history.servicestatus as history_servicestatus, history.servicefrom as history_servicefrom, history.serviceto as history_serviceto, " + + "history.ordernumber as history_ordernumber, history.iscurrentposition as history_iscurrentposition, history.location as history_location, " + + "history.tenantid as history_tenantid, history.createdby as history_createdby, history.createddate as history_createddate, " + + "history.lastmodifiedby as history_lastmodifiedby, history.lastmodifieddate as history_lastmodifieddate, deact.uuid as deact_uuid, " + + "deact.reasonfordeactivation as deact_reasonfordeactivation, deact.effectivefrom as deact_effectivefrom, deact.ordernumber as deact_ordernumber, " + + "deact.remarks as deact_remarks, deact.tenantid as deact_tenantid, deact.createdby as deact_createdby, " + + "deact.createddate as deact_createddate, deact.lastmodifiedby as deact_lastmodifiedby, deact.lastmodifieddate as deact_lastmodifieddate, " + + "react.uuid as react_uuid, react.reasonforreactivation as react_reasonforreactivation, react.effectivefrom as react_effectivefrom, react.ordernumber as react_ordernumber, " + + "react.remarks as react_remarks, react.tenantid as react_tenantid, react.createdby as react_createdby, " + + "react.createddate as react_createddate, react.lastmodifiedby as react_lastmodifiedby, react.lastmodifieddate as react_lastmodifieddate " + + "FROM eg_hrms_employee employee LEFT JOIN eg_hrms_assignment assignment ON employee.uuid = assignment.employeeid LEFT JOIN eg_hrms_educationaldetails education " + + "ON employee.uuid = education.employeeid LEFT JOIN eg_hrms_departmentaltests depttest ON employee.uuid = depttest.employeeid LEFT JOIN eg_hrms_empdocuments docs " + + "ON employee.uuid = docs.employeeid LEFT JOIN eg_hrms_servicehistory history ON employee.uuid = history.employeeid LEFT JOIN eg_hrms_jurisdiction jurisdiction " + + "ON employee.uuid = jurisdiction.employeeid LEFT JOIN eg_hrms_deactivationdetails deact ON employee.uuid = deact.employeeid LEFT JOIN eg_hrms_reactivationdetails react " + + "ON employee.uuid = react.employeeid WHERE "; + + public static final String HRMS_PAGINATION_WRAPPER = "SELECT * FROM " + + "(SELECT *, DENSE_RANK() OVER (ORDER BY employee_uuid) offset_ FROM " + "({})" + " result) result_offset " + + "WHERE offset_ > $offset AND offset_ <= $limit"; + + public static final String HRMS_POSITION_SEQ = "SELECT NEXTVAL('EG_HRMS_POSITION')"; + + public static final String HRMS_GET_ASSIGNMENT = "select distinct(employeeid) from eg_hrms_assignment assignment where assignment.tenantid notnull "; + + public static final String HRMS_COUNT_EMP_QUERY = "SELECT active, count(*) FROM eg_hrms_employee WHERE tenantid "; + + public static final String HRMS_GET_UNASSIGNED_EMPLOYEES = "SELECT employee.uuid from eg_hrms_employee employee LEFT JOIN eg_hrms_assignment assignment ON employee.uuid = assignment.employeeid where assignment.employeeid is null"; +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueryBuilder.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueryBuilder.java new file mode 100644 index 00000000000..4e5e5d7bdc4 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueryBuilder.java @@ -0,0 +1,168 @@ +package org.egov.hrms.repository; + +import org.apache.commons.lang3.StringUtils; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.web.contract.EmployeeSearchCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +public class EmployeeQueryBuilder { + + @Value("${egov.hrms.default.pagination.limit}") + private Integer defaultLimit; + + @Autowired + private PropertiesManager properties; + + /** + * Returns query for searching employees + * + * @param criteria + * @return + */ + public String getEmployeeSearchQuery(EmployeeSearchCriteria criteria,List preparedStmtList ) { + StringBuilder builder = new StringBuilder(EmployeeQueries.HRMS_GET_EMPLOYEES); + addWhereClause(criteria, builder, preparedStmtList); + return paginationClause(criteria, builder); + } + + public String getEmployeeCountQuery(String tenantId, List preparedStmtList ) { + StringBuilder builder = new StringBuilder(EmployeeQueries.HRMS_COUNT_EMP_QUERY); + if(tenantId.equalsIgnoreCase(properties.stateLevelTenantId)){ + builder.append("LIKE ? "); + preparedStmtList.add(tenantId+"%"); + } + else{ + builder.append("= ? "); + preparedStmtList.add(tenantId); + } + builder.append("GROUP BY active"); + return builder.toString(); + } + + public String getPositionSeqQuery() { + return EmployeeQueries.HRMS_POSITION_SEQ; + } + + /** + * Adds where clause to the query based on the requirement. + * @param criteria + * @param builder + * @param preparedStmtList + */ + public void addWhereClause(EmployeeSearchCriteria criteria, StringBuilder builder, List preparedStmtList) { + if(!StringUtils.isEmpty(criteria.getTenantId())) { + builder.append(" employee.tenantid = ?"); + preparedStmtList.add(criteria.getTenantId()); + } + else + builder.append(" employee.tenantid NOTNULL"); + + if(!CollectionUtils.isEmpty(criteria.getCodes())){ + List codes = criteria.getCodes().stream().map(String::toLowerCase).collect(Collectors.toList()); + builder.append(" and lower(employee.code) IN (").append(createQuery(codes)).append(")"); + addToPreparedStatement(preparedStmtList, codes); + } + if(!CollectionUtils.isEmpty(criteria.getIds())){ + builder.append(" and employee.id IN (").append(createQuery(criteria.getIds())).append(")"); + addToPreparedStatement(preparedStmtList, criteria.getIds()); + } + if(!CollectionUtils.isEmpty(criteria.getUuids())){ + builder.append(" and employee.uuid IN (").append(createQuery(criteria.getUuids())).append(")"); + addToPreparedStatement(preparedStmtList, criteria.getUuids()); + } + if(!CollectionUtils.isEmpty(criteria.getEmployeestatuses())){ + builder.append(" and employee.employeestatus IN (").append(createQuery(criteria.getEmployeestatuses())).append(")"); + addToPreparedStatement(preparedStmtList, criteria.getEmployeestatuses()); + } + if(!CollectionUtils.isEmpty(criteria.getEmployeetypes())){ + builder.append(" and employee.employeetype IN (").append(createQuery(criteria.getEmployeetypes())).append(")"); + addToPreparedStatement(preparedStmtList, criteria.getEmployeetypes()); + } + if(criteria.getIsActive() != null){ + builder.append(" and employee.active = ?"); + preparedStmtList.add(criteria.getIsActive()); + } + } + + public String paginationClause(EmployeeSearchCriteria criteria, StringBuilder builder) { + String pagination = EmployeeQueries.HRMS_PAGINATION_WRAPPER; + pagination = pagination.replace("{}", builder.toString()); + if(null != criteria.getOffset()) + pagination = pagination.replace("$offset", criteria.getOffset().toString()); + else + pagination = pagination.replace("$offset", "0"); + + if(null != criteria.getLimit()){ + Integer limit = criteria.getLimit() + criteria.getOffset(); + pagination = pagination.replace("$limit", limit.toString()); + } + else + pagination = pagination.replace("$limit", defaultLimit.toString()); + + return pagination; + } + + public String getAssignmentSearchQuery(EmployeeSearchCriteria criteria, List preparedStmtList) { + StringBuilder builder = new StringBuilder(EmployeeQueries.HRMS_GET_ASSIGNMENT); + addWhereClauseAssignment(criteria, builder, preparedStmtList); + return builder.toString(); + } + + private void addWhereClauseAssignment(EmployeeSearchCriteria criteria, StringBuilder builder, List preparedStmtList) { + if(!CollectionUtils.isEmpty(criteria.getDepartments())){ + builder.append(" and assignment.department IN (").append(createQuery(criteria.getDepartments())).append(")"); + addToPreparedStatement(preparedStmtList, criteria.getDepartments()); + } + if(!CollectionUtils.isEmpty(criteria.getDesignations())){ + builder.append(" and assignment.designation IN (").append(createQuery(criteria.getDesignations())+")"); + addToPreparedStatement(preparedStmtList,criteria.getDesignations()); + } + if(!CollectionUtils.isEmpty(criteria.getPositions())){ + builder.append(" and assignment.position IN (").append(createQuery(criteria.getPositions())+")"); + addToPreparedStatement(preparedStmtList,criteria.getPositions()); + } + if(null != criteria.getAsOnDate()) { + builder.append( " and case when assignment.todate is null then assignment.fromdate <= ? else assignment.fromdate <= ? and assignment.todate > ? end"); + preparedStmtList.add(criteria.getAsOnDate()); + preparedStmtList.add(criteria.getAsOnDate()); + preparedStmtList.add(criteria.getAsOnDate()); + } + + + } + + + private String createQuery(List ids) { + StringBuilder builder = new StringBuilder(); + int length = ids.size(); + for (int i = 0; i < length; i++) { + builder.append(" ?"); + if (i != length - 1) + builder.append(","); + } + return builder.toString(); + } + + private void addToPreparedStatement(List preparedStmtList, List ids) { + ids.forEach(id -> { + preparedStmtList.add(id); + }); + } + + public String getUnassignedEmployeesSearchQuery(EmployeeSearchCriteria criteria, List preparedStmtList) { + StringBuilder builder = new StringBuilder(EmployeeQueries.HRMS_GET_UNASSIGNED_EMPLOYEES); + addWhereClauseAssignment(criteria, builder, preparedStmtList); + return builder.toString(); + } + + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeRepository.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeRepository.java new file mode 100644 index 00000000000..20bb37a813e --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeRepository.java @@ -0,0 +1,141 @@ +package org.egov.hrms.repository; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.egov.common.contract.request.RequestInfo; +import org.egov.hrms.utils.HRMSUtils; +import org.egov.hrms.web.contract.EmployeeSearchCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import lombok.extern.slf4j.Slf4j; + +import org.egov.hrms.model.Employee; +import org.springframework.util.CollectionUtils; + +@Repository +@Slf4j +public class EmployeeRepository { + + @Autowired + private EmployeeQueryBuilder queryBuilder; + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private EmployeeRowMapper rowMapper; + + @Autowired + private EmployeeCountRowMapper countRowMapper; + + @Autowired + private HRMSUtils hrmsUtils; + + /** + * DB Repository that makes jdbc calls to the db and fetches employees. + * + * @param criteria + * @param requestInfo + * @return + */ + public List fetchEmployees(EmployeeSearchCriteria criteria, RequestInfo requestInfo){ + List employees = new ArrayList<>(); + List preparedStmtList = new ArrayList<>(); + if(hrmsUtils.isAssignmentSearchReqd(criteria)) { + List empUuids = fetchEmployeesforAssignment(criteria, requestInfo); + if (CollectionUtils.isEmpty(empUuids)) + return employees; + else { + if(!CollectionUtils.isEmpty(criteria.getUuids())) + criteria.setUuids(criteria.getUuids().stream().filter(empUuids::contains).collect(Collectors.toList())); + else + criteria.setUuids(empUuids); + } + } + if (criteria.getIncludeUnassigned() != null && criteria.getIncludeUnassigned()) { + List empUuids = fetchUnassignedEmployees(criteria, requestInfo); + criteria.setUuids(empUuids); + } + String query = queryBuilder.getEmployeeSearchQuery(criteria, preparedStmtList); + try { + employees = jdbcTemplate.query(query, preparedStmtList.toArray(),rowMapper); + }catch(Exception e) { + log.error("Exception while making the db call: ",e); + log.error("query; "+query); + } + return employees; + } + + private List fetchUnassignedEmployees(EmployeeSearchCriteria criteria, RequestInfo requestInfo) { + List employeesIds = new ArrayList<>(); + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getUnassignedEmployeesSearchQuery(criteria, preparedStmtList); + try { + employeesIds = jdbcTemplate.queryForList(query, preparedStmtList.toArray(),String.class); + }catch(Exception e) { + log.error("Exception while making the db call: ",e); + log.error("query; "+query); + } + return employeesIds; + } + + private List fetchEmployeesforAssignment(EmployeeSearchCriteria criteria, RequestInfo requestInfo) { + List employeesIds = new ArrayList<>(); + List preparedStmtList = new ArrayList<>(); + String query = queryBuilder.getAssignmentSearchQuery(criteria, preparedStmtList); + try { + + employeesIds = jdbcTemplate.queryForList(query, preparedStmtList.toArray(),String.class); + }catch(Exception e) { + log.error("Exception while making the db call: ",e); + log.error("query; "+query); + } + return employeesIds; + + } + + /** + * Fetches next value in the position seq table + * + * @return + */ + public Long fetchPosition(){ + String query = queryBuilder.getPositionSeqQuery(); + Long id = null; + try { + id = jdbcTemplate.queryForObject(query, Long.class); + }catch(Exception e) { + log.error("Exception while making the db call: ",e); + log.error("query; "+query); + } + return id; + } + + /** + * DB Repository that makes jdbc calls to the db and fetches employee count. + * + * @param tenantId + * @return + */ + public Map fetchEmployeeCount(String tenantId){ + Map response = new HashMap<>(); + List preparedStmtList = new ArrayList<>(); + + String query = queryBuilder.getEmployeeCountQuery(tenantId, preparedStmtList); + log.info("query; "+query); + try { + response=jdbcTemplate.query(query, preparedStmtList.toArray(),countRowMapper); + }catch(Exception e) { + log.error("Exception while making the db call: ",e); + log.error("query; "+query); + } + return response; + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeRowMapper.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeRowMapper.java new file mode 100644 index 00000000000..9d1ab4dd875 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeRowMapper.java @@ -0,0 +1,338 @@ +package org.egov.hrms.repository; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.egov.hrms.model.*; +import org.egov.hrms.model.enums.EmployeeDocumentReferenceType; +import org.egov.hrms.web.contract.User; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class EmployeeRowMapper implements ResultSetExtractor> { + + @Autowired + private ObjectMapper mapper; + + @Override + /** + * Maps ResultSet to Employee POJO. + */ + public List extractData(ResultSet rs) throws SQLException, DataAccessException { + Map employeeMap = new HashMap<>(); + while(rs.next()) { + String currentid = rs.getString("employee_uuid"); + Employee currentEmployee = employeeMap.get(currentid); + if(null == currentEmployee) { + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("employee_createdby")).createdDate(rs.getLong("employee_createddate")) + .lastModifiedBy(rs.getString("employee_lastmodifiedby")).lastModifiedDate(rs.getLong("employee_lastmodifieddate")).build(); + currentEmployee = Employee.builder().id(rs.getLong("employee_id")).uuid(rs.getString("employee_uuid")).tenantId(rs.getString("employee_tenantid")) + .code(rs.getString("employee_code")).dateOfAppointment(null == rs.getObject("employee_doa")? null : rs.getLong("employee_doa")).IsActive(rs.getBoolean("employee_active")) + .employeeStatus(rs.getString("employee_status")).employeeType(rs.getString("employee_type")).auditDetails(auditDetails).reActivateEmployee(rs.getBoolean("employee_reactive")) + .jurisdictions(new ArrayList()).assignments(new ArrayList()).user(new User()) + .build(); + } + addChildrenToEmployee(rs, currentEmployee); + employeeMap.put(currentid, currentEmployee); + } + + return new ArrayList<>(employeeMap.values()); + + } + + /** + * Adds all the children data to a employee object. + * + * @param rs + * @param currentEmployee + */ + public void addChildrenToEmployee(ResultSet rs, Employee currentEmployee) { + setAssignments(rs, currentEmployee); + setJurisdictions(rs, currentEmployee); + setEducationDetails(rs, currentEmployee); + setDeptTests(rs, currentEmployee); + setServiceHistory(rs, currentEmployee); + setDocuments(rs, currentEmployee); + setDeactivationDetails(rs, currentEmployee); + setReactivationDetails(rs, currentEmployee); + } + + /** + * Maps Assignments inside a ResultSet to the Assignment POJO inside employee object. + * + * @param rs + * @param currentEmployee + */ + public void setAssignments(ResultSet rs, Employee currentEmployee) { + try { + List assignments = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getAssignments())) + assignments = new ArrayList(); + else + assignments = currentEmployee.getAssignments(); + + List ids = assignments.stream().map(Assignment::getId).collect(Collectors.toList()); + if(!StringUtils.isEmpty(rs.getString("assignment_uuid")) && !ids.contains(rs.getString("assignment_uuid"))) { + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("assignment_createdby")).createdDate(rs.getLong("assignment_createddate")) + .lastModifiedBy(rs.getString("assignment_lastmodifiedby")).lastModifiedDate(rs.getLong("assignment_lastmodifieddate")).build(); + + Assignment assignment = Assignment.builder().id(rs.getString("assignment_uuid")).position(rs.getLong("assignment_position")).department(rs.getString("assignment_department")) + .designation(rs.getString("assignment_designation")).fromDate(rs.getLong("assignment_fromdate")).toDate(null == rs.getObject("assignment_todate")? null : rs.getLong("assignment_todate")) + .govtOrderNumber(rs.getString("assignment_govtordernumber")).reportingTo(rs.getString("assignment_reportingto")).isHOD(rs.getBoolean("assignment_ishod")) + .isCurrentAssignment(rs.getBoolean("assignment_iscurrentassignment")).tenantid(rs.getString("assignment_tenantid")).auditDetails(auditDetails).build(); + + assignments.add(assignment); + } + currentEmployee.setAssignments(assignments); + }catch(Exception e) { + log.error("Error in row mapper while mapping Assignments: ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping Assignments"); + } + } + + /** + * Maps Jurisdictions inside a ResultSet to the Jurisdiction POJO inside employee object. + * + * @param rs + * @param currentEmployee + */ + public void setJurisdictions(ResultSet rs, Employee currentEmployee) { + try { + List jurisdictions = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getJurisdictions())) + jurisdictions = new ArrayList(); + else + jurisdictions = currentEmployee.getJurisdictions(); + + List ids = jurisdictions.stream().map(Jurisdiction::getId).collect(Collectors.toList()); + Boolean isActive = rs.getBoolean("jurisdiction_isactive") !=false; + if(isActive && !StringUtils.isEmpty(rs.getString("jurisdiction_uuid")) && !ids.contains(rs.getString("jurisdiction_uuid"))) { + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("jurisdiction_createdby")).createdDate(rs.getLong("jurisdiction_createddate")) + .lastModifiedBy(rs.getString("jurisdiction_lastmodifiedby")).lastModifiedDate(rs.getLong("jurisdiction_lastmodifieddate")).build(); + + Jurisdiction jurisdiction = Jurisdiction.builder().id(rs.getString("jurisdiction_uuid")).hierarchy(rs.getString("jurisdiction_hierarchy")) + .boundary(rs.getString("jurisdiction_boundary")).boundaryType(rs.getString("jurisdiction_boundarytype")) + .tenantId(rs.getString("jurisdiction_tenantid")) + .isActive(null == rs.getObject("jurisdiction_isactive")?true:rs.getBoolean("jurisdiction_isactive")) + .auditDetails(auditDetails).build(); + + jurisdictions.add(jurisdiction); + } + currentEmployee.setJurisdictions(jurisdictions); + }catch(Exception e) { + log.error("Error in row mapper while mapping Jurisdictions: ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping Jurisdictions"); + } + } + + /** + * Maps EducationDetails inside a ResultSet to the EducationDetails POJO inside employee object. + * + * @param rs + * @param currentEmployee + */ + public void setEducationDetails(ResultSet rs, Employee currentEmployee) { + try { + List educationDetails = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getEducation())) + educationDetails = new ArrayList(); + else + educationDetails = currentEmployee.getEducation(); + List ids = educationDetails.stream().map(EducationalQualification::getId).collect(Collectors.toList()); + Boolean isActive =rs.getBoolean("education_isactive") !=false; + if( isActive &&!StringUtils.isEmpty( rs.getString("education_uuid")) && !ids.contains(rs.getString("education_uuid"))) { + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("education_createdby")).createdDate(rs.getLong("education_createddate")) + .lastModifiedBy(rs.getString("education_lastmodifiedby")).lastModifiedDate(rs.getLong("education_lastmodifieddate")).build(); + EducationalQualification education = EducationalQualification.builder().id(rs.getString("education_uuid")).qualification(rs.getString("education_qualification")).stream(rs.getString("education_stream")) + .yearOfPassing(rs.getLong("education_yearofpassing")).university(rs.getString("education_university")).remarks(rs.getString("education_remarks")) + .tenantId(rs.getString("education_tenantid")) + .isActive(null == rs.getObject("education_isactive")?true:rs.getBoolean("education_isactive")) + .auditDetails(auditDetails).build(); + + educationDetails.add(education); + } + currentEmployee.setEducation(educationDetails); + }catch(Exception e) { + log.error("Error in row mapper while mapping Educational Details: ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping Educational Details"); + } + } + + /** + * Maps Dept Tests inside a ResultSet to the DeptTest POJO inside employee object. + * + * @param rs + * @param currentEmployee + */ + public void setDeptTests(ResultSet rs, Employee currentEmployee) { + try { + List tests = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getTests())) + tests = new ArrayList(); + else + tests = currentEmployee.getTests(); + + List ids = tests.stream().map(DepartmentalTest::getId).collect(Collectors.toList()); + Boolean isActive = rs.getBoolean("depttest_isactive") !=false; + if(isActive && !StringUtils.isEmpty(rs.getString("depttest_uuid")) && !ids.contains(rs.getString("depttest_uuid"))) { + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("depttest_createdby")).createdDate(rs.getLong("depttest_createddate")) + .lastModifiedBy(rs.getString("depttest_lastmodifiedby")).lastModifiedDate(rs.getLong("depttest_lastmodifieddate")).build(); + + DepartmentalTest test = DepartmentalTest.builder().id(rs.getString("depttest_uuid")).test(rs.getString("depttest_test")).yearOfPassing(rs.getLong("depttest_yearofpassing")) + .remarks(rs.getString("depttest_remarks")).tenantId(rs.getString("depttest_tenantid")) + .isActive(null == rs.getObject("depttest_isactive")?true:rs.getBoolean("depttest_isactive")) + .auditDetails(auditDetails).build(); + + tests.add(test); + } + currentEmployee.setTests(tests); + }catch(Exception e) { + log.error("Error in row mapper while mapping Departmental Tests: ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping Departmental Tests"); + } + } + + /** + * Maps ServiceHistory inside a ResultSet to the ServiceHistory POJO inside employee object. + * + * @param rs + * @param currentEmployee + */ + public void setServiceHistory(ResultSet rs, Employee currentEmployee) { + try { + List history = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getServiceHistory())) + history = new ArrayList(); + else + history = currentEmployee.getServiceHistory(); + + List ids = history.stream().map(ServiceHistory::getId).collect(Collectors.toList()); + if(!StringUtils.isEmpty(rs.getString("history_uuid")) && !ids.contains(rs.getString("history_uuid"))) { + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("history_createdby")).createdDate(rs.getLong("history_createddate")) + .lastModifiedBy(rs.getString("history_lastmodifiedby")).lastModifiedDate(rs.getLong("history_lastmodifieddate")).build(); + + ServiceHistory service = ServiceHistory.builder().id(rs.getString("history_uuid")).serviceStatus(rs.getString("history_servicestatus")).serviceFrom(rs.getLong("history_servicefrom")) + .serviceTo(null == rs.getObject("history_serviceto")? null :rs.getLong("history_serviceto")).orderNo(rs.getString("history_ordernumber")).isCurrentPosition(rs.getBoolean("history_iscurrentposition")) + .location(rs.getString("history_location")).tenantId(rs.getString("history_tenantid")).auditDetails(auditDetails).build(); + + history.add(service); + } + currentEmployee.setServiceHistory(history); + }catch(Exception e) { + log.error("Error in row mapper while mapping Service History: ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping Service History"); + } + + } + + /** + * Maps Documents inside a ResultSet to the Document POJO inside employee object. + * + * @param rs + * @param currentEmployee + */ + public void setDocuments(ResultSet rs, Employee currentEmployee) { + try { + List documents = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getDocuments())) + documents = new ArrayList(); + else + documents = currentEmployee.getDocuments(); + + List ids = documents.stream().map(EmployeeDocument::getId).collect(Collectors.toList()); + if(!StringUtils.isEmpty(rs.getString("docs_uuid")) && !ids.contains(rs.getString("docs_uuid")) ) { + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("docs_createdby")).createdDate(rs.getLong("docs_createddate")) + .lastModifiedBy(rs.getString("docs_lastmodifiedby")).lastModifiedDate(rs.getLong("docs_lastmodifieddate")).build(); + EmployeeDocument document = EmployeeDocument.builder().id(rs.getString("docs_uuid")).documentId(rs.getString("docs_documentid")) + .documentName(rs.getString("docs_documentname")).referenceType(rs.getString("docs_referencetype") != null ? EmployeeDocumentReferenceType.valueOf(rs.getString("docs_referencetype")): null) + .referenceId(rs.getString("docs_referenceid")).tenantId(rs.getString("docs_tenantid")).auditDetails(auditDetails).build(); + + documents.add(document); + } + currentEmployee.setDocuments(documents); + }catch(Exception e) { + log.error("Error in row mapper while mapping document: ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping document"); + + } + } + + /** + * Maps DeactivationDetails inside a ResultSet to the DeactivationDetail POJO inside employee object. + * + * @param rs + * @param currentEmployee + */ + public void setDeactivationDetails(ResultSet rs, Employee currentEmployee) { + try { + List deactDetails = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getDeactivationDetails())) + deactDetails = new ArrayList(); + else + deactDetails = currentEmployee.getDeactivationDetails(); + + List ids = deactDetails.stream().map(DeactivationDetails::getId).collect(Collectors.toList()); + if(!StringUtils.isEmpty(rs.getString("deact_uuid")) && !ids.contains(rs.getString("deact_uuid")) ) { + if(rs.getString("deact_uuid")!=null){ + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("deact_createdby")).createdDate(rs.getLong("deact_createddate")) + .lastModifiedBy(rs.getString("deact_lastmodifiedby")).lastModifiedDate(rs.getLong("deact_lastmodifieddate")).build(); + + DeactivationDetails deactDetail = DeactivationDetails.builder().id(rs.getString("deact_uuid")).reasonForDeactivation(rs.getString("deact_reasonfordeactivation")) + .effectiveFrom(rs.getLong("deact_effectivefrom")).orderNo(rs.getString("deact_ordernumber")).remarks(rs.getString("deact_remarks")!= null ? (rs.getString("deact_remarks")) : null) + .tenantId(rs.getString("deact_tenantid")).auditDetails(auditDetails).build(); + + deactDetails.add(deactDetail); + } + } + currentEmployee.setDeactivationDetails(deactDetails); + + }catch(Exception e) { + log.error("Error in row mapper while mapping deactivation details: ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping deactivation details"); + } + } + + public void setReactivationDetails(ResultSet rs, Employee currentEmployee){ + try { + List reactDetails = new ArrayList<>(); + if(CollectionUtils.isEmpty(currentEmployee.getReactivationDetails())) + reactDetails = new ArrayList(); + else + reactDetails = currentEmployee.getReactivationDetails(); + + List ids = reactDetails.stream().map(ReactivationDetails::getId).collect(Collectors.toList()); + if(!StringUtils.isEmpty(rs.getString("react_uuid")) && !ids.contains(rs.getString("react_uuid")) ) { + if(rs.getString("react_uuid")!=null){ + AuditDetails auditDetails = AuditDetails.builder().createdBy(rs.getString("react_createdby")).createdDate(rs.getLong("react_createddate")) + .lastModifiedBy(rs.getString("react_lastmodifiedby")).lastModifiedDate(rs.getLong("react_lastmodifieddate")).build(); + + ReactivationDetails reactDetail = ReactivationDetails.builder().id(rs.getString("react_uuid")).reasonForReactivation(rs.getString("react_reasonforreactivation")) + .effectiveFrom(rs.getLong("react_effectivefrom")).orderNo(rs.getString("react_ordernumber")).remarks(rs.getString("react_remarks")!= null ? (rs.getString("react_remarks")) : null) + .tenantId(rs.getString("react_tenantid")).auditDetails(auditDetails).build(); + + reactDetails.add(reactDetail); + } + } + currentEmployee.setReactivationDetails(reactDetails); + + }catch(Exception e) { + log.error("Error in row mapper while mapping reactivation details ",e); + throw new CustomException("ROWMAPPER_ERROR","Error in row mapper while mapping reactivation details"); + } + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/RestCallRepository.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/RestCallRepository.java new file mode 100644 index 00000000000..596538863e5 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/repository/RestCallRepository.java @@ -0,0 +1,67 @@ +package org.egov.hrms.repository; + +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +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; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +import lombok.extern.slf4j.Slf4j; + +@Repository +@Slf4j +public class RestCallRepository { + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private ObjectMapper objectMapper; + + /** + * Fetches results from the given API and request and handles errors. + * + * @param requestInfo + * @param serviceReqSearchCriteria + * @return Object + * @author vishal + */ + public Object fetchResult(StringBuilder uri, Object request) { + Object response = null; + try { + response = restTemplate.postForObject(uri.toString(), request, Map.class); + } catch (HttpClientErrorException e) { + log.error("External Service threw an Exception: ", e); + if (!StringUtils.isEmpty(e.getResponseBodyAsString())) { + throw new ServiceCallException(e.getResponseBodyAsString()); + } + } catch (Exception e) { + log.error("Exception while fetching from searcher: ", e); + log.info("req: " + (request)); + } + + return response; + + } + + public T fetchResult(StringBuilder uri, Object request, Class + clazz) { + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + T response; + try { + response = restTemplate.postForObject(uri.toString(), request, clazz); + } catch (HttpClientErrorException e) { + throw new CustomException("HTTP_CLIENT_ERROR", + String.format("%s - %s", e.getMessage(), e.getResponseBodyAsString())); + } + return response; + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/service/DefaultUserService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/DefaultUserService.java new file mode 100644 index 00000000000..0b232ae6448 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/DefaultUserService.java @@ -0,0 +1,281 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.request.Role; +import org.egov.common.contract.request.User; +import org.egov.common.utils.MultiStateInstanceUtil; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.repository.RestCallRepository; +import org.egov.hrms.utils.HRMSConstants; +import org.egov.hrms.web.contract.UserRequest; +import org.egov.hrms.web.contract.UserResponse; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; + +import javax.annotation.PostConstruct; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +import static org.egov.hrms.utils.HRMSConstants.*; + +@Slf4j +@Setter +@Getter +public class DefaultUserService implements UserService { + + @Autowired + private PropertiesManager propertiesManager; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private RestCallRepository restCallRepository; + + @Autowired + private MultiStateInstanceUtil centralInstanceUtil; + + @Value("${egov.user.create.endpoint}") + private String userCreateEndpoint; + + @Value("${egov.user.search.endpoint}") + private String userSearchEndpoint; + + @Value("${egov.user.update.endpoint}") + private String userUpdateEndpoint; + + private String internalMicroserviceRoleUuid = null; + + @PostConstruct + void initalizeSystemuser(){ + log.info("initialising system user"); + RequestInfo requestInfo = new RequestInfo(); + StringBuilder uri = new StringBuilder(); + uri.append(propertiesManager.getUserHost()).append(propertiesManager.getUserSearchEndpoint()); // URL for user search call + Map userSearchRequest = new HashMap<>(); + userSearchRequest.put("RequestInfo", requestInfo); + userSearchRequest.put("tenantId", propertiesManager.getStateLevelTenantId()); + userSearchRequest.put("roleCodes", Collections.singletonList(INTERNALMICROSERVICEROLE_CODE)); + try { + LinkedHashMap responseMap = (LinkedHashMap) restCallRepository.fetchResult(uri, userSearchRequest); + List> users = (List>) responseMap.get("user"); + if(users.size()==0) + createInternalMicroserviceUser(requestInfo); + internalMicroserviceRoleUuid = (String) users.get(0).get("uuid"); + }catch (Exception e) { + throw new CustomException("EG_USER_SEARCH_ERROR", "Service returned null while fetching user"); + } + + } + + private void createInternalMicroserviceUser(RequestInfo requestInfo){ + Map userCreateRequest = new HashMap<>(); + //Creating role with INTERNAL_MICROSERVICE_ROLE + Role role = Role.builder() + .name(INTERNALMICROSERVICEROLE_NAME).code(INTERNALMICROSERVICEROLE_CODE) + .tenantId(propertiesManager.getStateLevelTenantId()).build(); + User user = User.builder().userName(INTERNALMICROSERVICEUSER_USERNAME) + .name(INTERNALMICROSERVICEUSER_NAME).mobileNumber(INTERNALMICROSERVICEUSER_MOBILENO) + .type(INTERNALMICROSERVICEUSER_TYPE).tenantId(propertiesManager.getStateLevelTenantId()) + .roles(Collections.singletonList(role)).id(0L).build(); + + userCreateRequest.put("RequestInfo", requestInfo); + userCreateRequest.put("user", user); + + StringBuilder uri = new StringBuilder(); + uri.append(propertiesManager.getUserHost()).append(propertiesManager.getUserCreateEndpoint()); // URL for user create call + + try { + LinkedHashMap responseMap = (LinkedHashMap) restCallRepository.fetchResult(uri, userCreateRequest); + List> users = (List>) responseMap.get("user"); + internalMicroserviceRoleUuid = (String) users.get(0).get("uuid"); + }catch (Exception e) { + throw new CustomException("EG_USER_CRETE_ERROR", "Service returned throws error while creating user"); + } + } + + @Override + public UserResponse createUser(UserRequest userRequest) { + StringBuilder uri = new StringBuilder(); + uri.append(propertiesManager.getUserHost()).append(propertiesManager.getUserCreateEndpoint()); + UserResponse userResponse = null; + try { + userResponse = userCall(userRequest,uri); + }catch(Exception e) { + log.error("User created failed: ",e); + } + + return userResponse; + } + + @Override + public UserResponse updateUser(UserRequest userRequest) { + StringBuilder uri = new StringBuilder(); + uri.append(propertiesManager.getUserHost()).append(propertiesManager.getUserUpdateEndpoint()); + UserResponse userResponse = null; + try { + userResponse = userCall(userRequest,uri); + }catch(Exception e) { + log.error("User created failed: ",e); + } + + return userResponse; + } + + @Override + public UserResponse getUser(RequestInfo requestInfo, Map userSearchCriteria) { + StringBuilder uri = new StringBuilder(); + Map userSearchReq = new HashMap<>(); + User userInfoCopy = requestInfo.getUserInfo(); + + if(propertiesManager.getIsDecryptionEnable()){ + User enrichedUserInfo = getEncrichedandCopiedUserInfo(String.valueOf(userSearchCriteria.get("tenantId"))); + requestInfo.setUserInfo(enrichedUserInfo); + } + + userSearchReq.put("RequestInfo", requestInfo); + userSearchReq.put(HRMSConstants.HRMS_USER_SERACH_CRITERIA_USERTYPE_CODE,HRMSConstants.HRMS_USER_SERACH_CRITERIA_USERTYPE); + for( String key: userSearchCriteria.keySet()) + userSearchReq.put(key, userSearchCriteria.get(key)); + uri.append(propertiesManager.getUserHost()).append(propertiesManager.getUserSearchEndpoint()); + UserResponse userResponse = new UserResponse(); + try { + userResponse = userCall(userSearchReq,uri); + }catch(Exception e) { + log.error("User search failed: ",e); + } + if(propertiesManager.getIsDecryptionEnable()) + requestInfo.setUserInfo(userInfoCopy); + + return userResponse; + } + + private User getEncrichedandCopiedUserInfo(String tenantId){ + //Creating role with INTERNAL_MICROSERVICE_ROLE + Role role = Role.builder() + .name(INTERNALMICROSERVICEROLE_NAME).code(INTERNALMICROSERVICEROLE_CODE) + .tenantId(centralInstanceUtil.getStateLevelTenant(tenantId)).build(); + + //Creating userinfo with uuid and role of internal micro service role + User userInfo = User.builder() + .uuid(internalMicroserviceRoleUuid) + .type(INTERNALMICROSERVICEUSER_TYPE) + .roles(Collections.singletonList(role)).id(0L).build(); + + return userInfo; + } + + + /** + * Returns UserDetailResponse by calling user service with given uri and object + * @param userRequest Request object for user service + * @param uri The address of the endpoint + * @return Response from user service as parsed as userDetailResponse + */ + @SuppressWarnings("all") + private UserResponse userCall(Object userRequest, StringBuilder uri) { + String dobFormat = null; + if(uri.toString().contains(userSearchEndpoint) || uri.toString().contains(userUpdateEndpoint)) + dobFormat="yyyy-MM-dd"; + else if(uri.toString().contains(userCreateEndpoint)) + dobFormat = "dd/MM/yyyy"; + try{ + LinkedHashMap responseMap = (LinkedHashMap) restCallRepository.fetchResult(uri, userRequest); + parseResponse(responseMap,dobFormat); + UserResponse userDetailResponse = objectMapper.convertValue(responseMap,UserResponse.class); + return userDetailResponse; + } + catch(IllegalArgumentException e) { + throw new CustomException("IllegalArgumentException","ObjectMapper not able to convertValue in userCall"); + } + } + + + /** + * Parses date formats to long for all users in responseMap + * @param responeMap LinkedHashMap got from user api response + * @param dobFormat dob format (required because dob is returned in different format's in search and create response in user service) + */ + @SuppressWarnings("all") + private void parseResponse(LinkedHashMap responeMap,String dobFormat){ + List users = (List)responeMap.get("user"); + String format1 = "dd-MM-yyyy HH:mm:ss"; + if(users!=null){ + users.forEach( map -> { + map.put("createdDate",dateTolong((String)map.get("createdDate"),format1)); + if((String)map.get("lastModifiedDate")!=null) + map.put("lastModifiedDate",dateTolong((String)map.get("lastModifiedDate"),format1)); + if((String)map.get("dob")!=null) + map.put("dob",dateTolong((String)map.get("dob"),dobFormat)); + if((String)map.get("pwdExpiryDate")!=null) + map.put("pwdExpiryDate",dateTolong((String)map.get("pwdExpiryDate"),format1)); + } + ); + } + } + + /** + * Converts date to long + * @param date date to be parsed + * @param format Format of the date + * @return Long value of date + */ + private Long dateTolong(String date,String format){ + SimpleDateFormat f = new SimpleDateFormat(format); + Date d = null; + try { + d = f.parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return d.getTime(); + } + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java new file mode 100644 index 00000000000..ec86d2452ce --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java @@ -0,0 +1,577 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.response.ResponseInfo; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.model.AuditDetails; +import org.egov.hrms.model.Employee; +import org.egov.hrms.model.enums.UserType; +import org.egov.hrms.producer.HRMSProducer; +import org.egov.hrms.repository.EmployeeRepository; +import org.egov.hrms.utils.ErrorConstants; +import org.egov.hrms.utils.HRMSConstants; +import org.egov.hrms.utils.HRMSUtils; +import org.egov.hrms.utils.ResponseInfoFactory; +import org.egov.hrms.web.contract.*; +import org.egov.tracer.kafka.LogAwareKafkaTemplate; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Data +@Slf4j +@Service +public class EmployeeService { + + + @Autowired + private UserService userService; + + @Autowired + private IdGenService idGenService; + + @Autowired + private ResponseInfoFactory factory; + + @Autowired + private LogAwareKafkaTemplate kafkaTemplate; + + @Autowired + private PropertiesManager propertiesManager; + + @Autowired + private HRMSProducer hrmsProducer; + + @Autowired + private EmployeeRepository repository; + + @Autowired + private HRMSUtils hrmsUtils; + + @Autowired + private NotificationService notificationService; + + @Autowired + private ObjectMapper objectMapper; + + /** + * Service method for create employee. Does following: + * 1. Sets ids to all the objects using idgen service. + * 2. Enriches the employee object with required parameters + * 3. Creates user in the egov-user service. + * 4. Sends notification upon successful creation + * + * @param employeeRequest + * @return + */ + public EmployeeResponse create(EmployeeRequest employeeRequest) { + RequestInfo requestInfo = employeeRequest.getRequestInfo(); + Map pwdMap = new HashMap<>(); + idGenService.setIds(employeeRequest); + employeeRequest.getEmployees().stream().forEach(employee -> { + enrichCreateRequest(employee, requestInfo); + createUser(employee, requestInfo); + pwdMap.put(employee.getUuid(), employee.getUser().getPassword()); + employee.getUser().setPassword(null); + }); + hrmsProducer.push(propertiesManager.getSaveEmployeeTopic(), employeeRequest); + notificationService.sendNotification(employeeRequest, pwdMap); + return generateResponse(employeeRequest); + } + + /** + * Searches employees on a given criteria. + * + * @param criteria + * @param requestInfo + * @return + */ + public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requestInfo) { + boolean userChecked = false; + /*if(null == criteria.getIsActive() || criteria.getIsActive()) + criteria.setIsActive(true); + else + criteria.setIsActive(false);*/ + Map mapOfUsers = new HashMap(); + if(!StringUtils.isEmpty(criteria.getPhone()) + || !CollectionUtils.isEmpty(criteria.getRoles()) + || !CollectionUtils.isEmpty(criteria.getCodes())) { + Map userSearchCriteria = new HashMap<>(); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID,criteria.getTenantId()); + if(!StringUtils.isEmpty(criteria.getPhone())) + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_MOBILENO,criteria.getPhone()); + if( !CollectionUtils.isEmpty(criteria.getRoles()) ) + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_ROLECODES,criteria.getRoles()); + if (!CollectionUtils.isEmpty(criteria.getCodes())) { + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_USERNAME, criteria.getCodes().get(0)); + } + UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria); + userChecked =true; + if(!CollectionUtils.isEmpty(userResponse.getUser())) { + mapOfUsers.putAll(userResponse.getUser().stream() + .collect(Collectors.toMap(User::getUuid, Function.identity()))); + } + List userUUIDs = userResponse.getUser().stream().map(User :: getUuid).collect(Collectors.toList()); + if(!CollectionUtils.isEmpty(criteria.getUuids())) + criteria.setUuids(criteria.getUuids().stream().filter(userUUIDs::contains).collect(Collectors.toList())); + else + criteria.setUuids(userUUIDs); + } + //checks if above criteria met and result is not null will check for name search if list of names are given as user search on name is not bulk api + + if(!((!CollectionUtils.isEmpty(criteria.getRoles()) || !StringUtils.isEmpty(criteria.getPhone())) && CollectionUtils.isEmpty(criteria.getUuids()))){ + if(!CollectionUtils.isEmpty(criteria.getNames())) { + List userUUIDs = new ArrayList<>(); + for(String name: criteria.getNames()) { + Map userSearchCriteria = new HashMap<>(); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID,criteria.getTenantId()); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_NAME,name); + UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria); + userChecked =true; + if(!CollectionUtils.isEmpty(userResponse.getUser())) { + mapOfUsers.putAll(userResponse.getUser().stream() + .collect(Collectors.toMap(User::getUuid, Function.identity()))); + } + List uuids = userResponse.getUser().stream().map(User :: getUuid).collect(Collectors.toList()); + userUUIDs.addAll(uuids); + } + if(!CollectionUtils.isEmpty(criteria.getUuids())) + criteria.setUuids(criteria.getUuids().stream().filter(userUUIDs::contains).collect(Collectors.toList())); + else + criteria.setUuids(userUUIDs); + } + } + if(userChecked) + criteria.setTenantId(null); + List employees = new ArrayList<>(); + if(!((!CollectionUtils.isEmpty(criteria.getRoles()) || !CollectionUtils.isEmpty(criteria.getNames()) || !StringUtils.isEmpty(criteria.getPhone())) && CollectionUtils.isEmpty(criteria.getUuids()))) + employees = repository.fetchEmployees(criteria, requestInfo); + List uuids = employees.stream().map(Employee :: getUuid).collect(Collectors.toList()); + if(!CollectionUtils.isEmpty(uuids)){ + Map userSearchCriteria = new HashMap<>(); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_UUID,uuids); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID, criteria.getTenantId()); + log.info("uuid is available {}", userSearchCriteria); + if(mapOfUsers.isEmpty()){ + log.info("searching in user service"); + UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria); + if(!CollectionUtils.isEmpty(userResponse.getUser())) { + mapOfUsers = userResponse.getUser().stream() + .collect(Collectors.toMap(User :: getUuid, Function.identity())); + } + } + for(Employee employee: employees){ + employee.setUser(mapOfUsers.get(employee.getUuid())); + } + } + return EmployeeResponse.builder().responseInfo(factory.createResponseInfoFromRequestInfo(requestInfo, true)) + .employees(employees).build(); + } + + + /** + * Creates user by making call to egov-user. + * + * @param employee + * @param requestInfo + */ + private void createUser(Employee employee, RequestInfo requestInfo) { + enrichUser(employee); + UserRequest request = UserRequest.builder().requestInfo(requestInfo).user(employee.getUser()).build(); + try { + UserResponse response = userService.createUser(request); + User user = response.getUser().get(0); + employee.setId(UUID.fromString(user.getUuid()).getMostSignificantBits()); + employee.setUuid(user.getUuid()); + employee.getUser().setId(user.getId()); + employee.getUser().setUuid(user.getUuid()); + employee.getUser().setUserServiceUuid(user.getUserServiceUuid()); + }catch(Exception e) { + log.error("Exception while creating user: ",e); + log.error("request: "+request); + throw new CustomException(ErrorConstants.HRMS_USER_CREATION_FAILED_CODE, ErrorConstants.HRMS_USER_CREATION_FAILED_MSG); + } + + } + + /** + * Enriches the user object. + * + * @param employee + */ + private void enrichUser(Employee employee) { + List pwdParams = new ArrayList<>(); + pwdParams.add(employee.getCode()); + pwdParams.add(employee.getUser().getMobileNumber()); + pwdParams.add(employee.getTenantId()); + pwdParams.add(employee.getUser().getName().toUpperCase()); + if (propertiesManager.isAutoGeneratePassword()) { + employee.getUser().setPassword(hrmsUtils.generatePassword(pwdParams)); + } + employee.getUser().setUserName(employee.getCode()); + employee.getUser().setActive(true); + employee.getUser().setType(UserType.EMPLOYEE.toString()); + } + + /** + * Enriches employee object by setting parent ids to all the child objects + * + * @param employee + * @param requestInfo + */ + private void enrichCreateRequest(Employee employee, RequestInfo requestInfo) { + + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(requestInfo.getUserInfo().getUuid()) + .createdDate(new Date().getTime()) + .build(); + + employee.getJurisdictions().stream().forEach(jurisdiction -> { + jurisdiction.setId(UUID.randomUUID().toString()); + jurisdiction.setAuditDetails(auditDetails); + if(null == jurisdiction.getIsActive()) + jurisdiction.setIsActive(true); + }); + if (employee.getAssignments() != null && !employee.getAssignments().isEmpty()) { + employee.getAssignments().stream().forEach(assignment -> { + assignment.setId(UUID.randomUUID().toString()); + assignment.setAuditDetails(auditDetails); + assignment.setPosition(getPosition()); + }); + } + if(!CollectionUtils.isEmpty(employee.getServiceHistory())) { + employee.getServiceHistory().stream().forEach(serviceHistory -> { + serviceHistory.setId(UUID.randomUUID().toString()); + serviceHistory.setAuditDetails(auditDetails); + if(null == serviceHistory.getIsCurrentPosition()) + serviceHistory.setIsCurrentPosition(false); + }); + } + if(!CollectionUtils.isEmpty(employee.getEducation())) { + employee.getEducation().stream().forEach(educationalQualification -> { + educationalQualification.setId(UUID.randomUUID().toString()); + educationalQualification.setAuditDetails(auditDetails); + if(null == educationalQualification.getIsActive()) + educationalQualification.setIsActive(true); + }); + } + if(!CollectionUtils.isEmpty(employee.getTests())) { + employee.getTests().stream().forEach(departmentalTest -> { + departmentalTest.setId(UUID.randomUUID().toString()); + departmentalTest.setAuditDetails(auditDetails); + if(null == departmentalTest.getIsActive()) + departmentalTest.setIsActive(true); + }); + } + if(!CollectionUtils.isEmpty(employee.getDocuments())) { + employee.getDocuments().stream().forEach(document -> { + document.setId(UUID.randomUUID().toString()); + document.setAuditDetails(auditDetails); + }); + } + employee.setAuditDetails(auditDetails); + employee.setIsActive(true); + } + + /** + * Fetches next value from the position sequence table + * @return + */ + public Long getPosition() { + return repository.fetchPosition(); + } + + /** + * Service method to update user. Performs the following: + * 1. Enriches the employee object with required parameters. + * 2. Updates user by making call to the user service. + * + * @param employeeRequest + * @return + */ + public EmployeeResponse update(EmployeeRequest employeeRequest) { + RequestInfo requestInfo = employeeRequest.getRequestInfo(); + List uuidList= new ArrayList<>(); + for(Employee employee: employeeRequest.getEmployees()) { + uuidList.add(employee.getUuid()); + } + EmployeeResponse existingEmployeeResponse = search(EmployeeSearchCriteria.builder().uuids(uuidList).build(),requestInfo); + List existingEmployees = existingEmployeeResponse.getEmployees(); + employeeRequest.getEmployees().stream().forEach(employee -> { + enrichUpdateRequest(employee, requestInfo, existingEmployees); + updateUser(employee, requestInfo); + }); + hrmsProducer.push(propertiesManager.getUpdateTopic(), employeeRequest); + //notificationService.sendReactivationNotification(employeeRequest); + return generateResponse(employeeRequest); + } + + /** + * Updates the user by making call to the user service. + * + * @param employee + * @param requestInfo + */ + private void updateUser(Employee employee, RequestInfo requestInfo) { + UserRequest request = UserRequest.builder().requestInfo(requestInfo).user(employee.getUser()).build(); + try { + userService.updateUser(request); + }catch(Exception e) { + log.error("Exception while updating user: ",e); + log.error("request: "+request); + throw new CustomException(ErrorConstants.HRMS_USER_UPDATION_FAILED_CODE, ErrorConstants.HRMS_USER_UPDATION_FAILED_MSG); + } + + } + + /** + * Enriches update request with required parameters. + * + * @param employee + * @param requestInfo + * @param existingEmployeesData + */ + private void enrichUpdateRequest(Employee employee, RequestInfo requestInfo, List existingEmployeesData) { + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(requestInfo.getUserInfo().getUserName()) + .createdDate(new Date().getTime()) + .build(); + Employee existingEmpData = existingEmployeesData.stream().filter(existingEmployee -> existingEmployee.getUuid().equals(employee.getUuid())).findFirst().get(); + + employee.getUser().setUserName(employee.getCode()); + if(!employee.getIsActive()) + employee.getUser().setActive(false); + else + employee.getUser().setActive(true); + + employee.getJurisdictions().stream().forEach(jurisdiction -> { + + if(null == jurisdiction.getIsActive()) + jurisdiction.setIsActive(true); + if(jurisdiction.getId()==null) { + jurisdiction.setId(UUID.randomUUID().toString()); + jurisdiction.setAuditDetails(auditDetails); + }else{ + if(!existingEmpData.getJurisdictions().stream() + .filter(jurisdictionData ->jurisdictionData.getId().equals(jurisdiction.getId() )) + .findFirst().orElse(null) + .equals(jurisdiction)){ + jurisdiction.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + jurisdiction.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + employee.getAssignments().stream().forEach(assignment -> { + if(assignment.getId()==null) { + assignment.setId(UUID.randomUUID().toString()); + assignment.setAuditDetails(auditDetails); + }else { + if(!existingEmpData.getAssignments().stream() + .filter(assignmentData -> assignmentData.getId().equals(assignment.getId())) + .findFirst().orElse(null) + .equals(assignment)){ + assignment.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + assignment.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + + if(employee.getServiceHistory()!=null){ + employee.getServiceHistory().stream().forEach(serviceHistory -> { + if(null == serviceHistory.getIsCurrentPosition()) + serviceHistory.setIsCurrentPosition(false); + if(serviceHistory.getId()==null) { + serviceHistory.setId(UUID.randomUUID().toString()); + serviceHistory.setAuditDetails(auditDetails); + }else { + if(!existingEmpData.getServiceHistory().stream() + .filter(serviceHistoryData -> serviceHistoryData.getId().equals(serviceHistory.getId())) + .findFirst().orElse(null) + .equals(serviceHistory)){ + serviceHistory.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + serviceHistory.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + + } + + if(employee.getEducation() != null){ + employee.getEducation().stream().forEach(educationalQualification -> { + if(null == educationalQualification.getIsActive()) + educationalQualification.setIsActive(true); + if(educationalQualification.getId()==null) { + educationalQualification.setId(UUID.randomUUID().toString()); + educationalQualification.setAuditDetails(auditDetails); + }else { + + if(!existingEmpData.getEducation().stream() + .filter(educationalQualificationData -> educationalQualificationData.getId().equals(educationalQualification.getId())) + .findFirst().orElse(null) + .equals(educationalQualification)){ + educationalQualification.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + educationalQualification.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + + } + + if(employee.getTests() != null){ + employee.getTests().stream().forEach(departmentalTest -> { + + if(null == departmentalTest.getIsActive()) + departmentalTest.setIsActive(true); + if(departmentalTest.getId()==null) { + departmentalTest.setId(UUID.randomUUID().toString()); + departmentalTest.setAuditDetails(auditDetails); + }else { + if(!existingEmpData.getTests().stream() + .filter(departmentalTestData -> departmentalTestData.getId().equals(departmentalTest.getId())) + .findFirst().orElse(null) + .equals(departmentalTest)){ + departmentalTest.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + departmentalTest.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + + } + + if(employee.getDocuments() != null){ + employee.getDocuments().stream().forEach(document -> { + if(document.getId()==null) { + document.setId(UUID.randomUUID().toString()); + document.setAuditDetails(auditDetails); + }else { + if(!existingEmpData.getDocuments().stream() + .filter(documentData -> documentData.getId().equals(document.getId())) + .findFirst().orElse(null) + .equals(document)){ + document.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + document.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + + } + + if(employee.getDeactivationDetails() != null){ + employee.getDeactivationDetails().stream().forEach(deactivationDetails -> { + if(deactivationDetails.getId()==null) { + deactivationDetails.setId(UUID.randomUUID().toString()); + deactivationDetails.setAuditDetails(auditDetails); + employee.getDocuments().forEach(employeeDocument -> { + employeeDocument.setReferenceId( deactivationDetails.getId()); + }); + }else { + if(!existingEmpData.getDeactivationDetails().stream() + .filter(deactivationDetailsData -> deactivationDetailsData.getId().equals(deactivationDetails.getId())) + .findFirst().orElse(null) + .equals(deactivationDetails)){ + deactivationDetails.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + deactivationDetails.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + + } + if(employee.getReactivationDetails() != null){ + employee.getReactivationDetails().stream().forEach(reactivationDetails -> { + if(reactivationDetails.getId() == null){ + reactivationDetails.setId(UUID.randomUUID().toString()); + reactivationDetails.setAuditDetails(auditDetails); + employee.getDocuments().forEach(employeeDocument -> { + employeeDocument.setReferenceId(reactivationDetails.getId()); + }); + } + else{ + if(!existingEmpData.getReactivationDetails().stream() + .filter(reactivationDetails1 -> reactivationDetails1.getId().equals(reactivationDetails.getId())) + .findFirst().orElse(null) + .equals(reactivationDetails)){ + reactivationDetails.getAuditDetails().setLastModifiedBy(requestInfo.getUserInfo().getUserName()); + reactivationDetails.getAuditDetails().setLastModifiedDate(new Date().getTime()); + } + } + }); + + } + + + } + + private EmployeeResponse generateResponse(EmployeeRequest employeeRequest) { + return EmployeeResponse.builder() + .responseInfo(factory.createResponseInfoFromRequestInfo(employeeRequest.getRequestInfo(), true)) + .employees(employeeRequest.getEmployees()).build(); + } + + public Map getEmployeeCountResponse(RequestInfo requestInfo, String tenantId){ + Map response = new HashMap<>(); + Map results = new HashMap<>(); + ResponseInfo responseInfo = factory.createResponseInfoFromRequestInfo(requestInfo, true); + + response.put("ResponseInfo",responseInfo); + results = repository.fetchEmployeeCount(tenantId); + + if(CollectionUtils.isEmpty(results) || results.get("totalEmployee").equalsIgnoreCase("0")){ + Map error = new HashMap<>(); + error.put("NO_RECORDS","No records found for the tenantId: "+tenantId); + throw new CustomException(error); + } + + response.put("EmployeCount",results); + return response; + } + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/service/IdGenService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/IdGenService.java new file mode 100644 index 00000000000..4e6420247ce --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/IdGenService.java @@ -0,0 +1,90 @@ +package org.egov.hrms.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.request.RequestInfo; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.model.Employee; +import org.egov.hrms.repository.RestCallRepository; +import org.egov.hrms.utils.ErrorConstants; +import org.egov.hrms.web.contract.EmployeeRequest; +import org.egov.hrms.web.contract.IdGenerationRequest; +import org.egov.hrms.web.contract.IdGenerationResponse; +import org.egov.hrms.web.contract.IdRequest; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class IdGenService { + + @Autowired + private RestCallRepository repository; + + @Autowired + private PropertiesManager properties; + + /** + * Sets ids to all the employee objects + * + * @param employeeRequest + */ + public void setIds(EmployeeRequest employeeRequest) { + String tenantId = employeeRequest.getEmployees().get(0).getTenantId(); + Integer employeesWithCode = employeeRequest.getEmployees().stream() + .filter(employee -> !StringUtils.isEmpty(employee.getCode())).collect(Collectors.toList()).size(); + if(employeesWithCode == employeeRequest.getEmployees().size()) + return; + IdGenerationResponse response = getId(employeeRequest.getRequestInfo(), tenantId, employeeRequest.getEmployees().size() - employeesWithCode, + properties.getHrmsIdGenKey(), properties.getHrmsIdGenFormat()); + if(null != response) { + int i = 0; + for(Employee employee: employeeRequest.getEmployees()) { + if(StringUtils.isEmpty(employee.getCode())) { + employee.setCode(response.getIdResponses().get(i).getId()); + i++; + } + } + } + } + + /** + * Makes call to the idgen service to fetch ids for the employee object. Format of the id configurable. + * + * @param requestInfo + * @param tenantId + * @param count + * @param name + * @param format + * @return + */ + public IdGenerationResponse getId(RequestInfo requestInfo, String tenantId, Integer count, String name, String format) { + StringBuilder uri = new StringBuilder(); + ObjectMapper mapper = new ObjectMapper(); + uri.append(properties.getIdGenHost()).append(properties.getIdGenEndpoint()); + List reqList = new ArrayList<>(); + for (int i = 0; i < count; i++) { + reqList.add(IdRequest.builder().idName(name).format(format).tenantId(tenantId).build()); + } + IdGenerationRequest request = IdGenerationRequest.builder().idRequests(reqList).requestInfo(requestInfo).build(); + IdGenerationResponse response = null; + try { + response = mapper.convertValue(repository.fetchResult(uri, request), IdGenerationResponse.class); + }catch(Exception e) { + log.error("Exception while generating ids: ",e); + log.error("Request: "+request); + throw new CustomException(ErrorConstants.HRMS_GENERATE_ID_ERROR_CODE,ErrorConstants.HRMS_GENERATE_ID_ERROR_MSG); + + } + return response; + } +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/service/IndividualService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/IndividualService.java new file mode 100644 index 00000000000..07b315bf1bc --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/IndividualService.java @@ -0,0 +1,251 @@ +package org.egov.hrms.service; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; +import java.util.UUID; +import java.util.stream.Collectors; + +import digit.models.coremodels.AuditDetails; +import digit.models.coremodels.user.enums.UserType; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.models.core.Role; +import org.egov.common.models.individual.Address; +import org.egov.common.models.individual.AddressType; +import org.egov.common.models.individual.Gender; +import org.egov.common.models.individual.Identifier; +import org.egov.common.models.individual.Individual; +import org.egov.common.models.individual.IndividualBulkResponse; +import org.egov.common.models.individual.IndividualRequest; +import org.egov.common.models.individual.IndividualResponse; +import org.egov.common.models.individual.IndividualSearch; +import org.egov.common.models.individual.IndividualSearchRequest; +import org.egov.common.models.individual.Name; +import org.egov.common.models.individual.UserDetails; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.repository.RestCallRepository; +import org.egov.hrms.utils.HRMSConstants; +import org.egov.hrms.web.contract.User; +import org.egov.hrms.web.contract.UserRequest; +import org.egov.hrms.web.contract.UserResponse; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.egov.hrms.utils.HRMSConstants.SYSTEM_GENERATED; + +@Slf4j +public class IndividualService implements UserService { + + private final PropertiesManager propertiesManager; + + private final RestCallRepository restCallRepository; + + @Autowired + public IndividualService(PropertiesManager propertiesManager, + RestCallRepository restCallRepository) { + this.propertiesManager = propertiesManager; + this.restCallRepository = restCallRepository; + } + + + @Override + public UserResponse createUser(UserRequest userRequest) { + IndividualRequest request = mapToIndividualRequest(userRequest); + StringBuilder uri = new StringBuilder(); + uri.append(propertiesManager.getIndividualHost()); + uri.append(propertiesManager.getIndividualCreateEndpoint()); + IndividualResponse response = restCallRepository + .fetchResult(uri, request, IndividualResponse.class); + UserResponse userResponse = null; + if (response != null && response.getIndividual() != null) { + log.info("response received from individual service"); + userResponse = mapToUserResponse(response); + } + return userResponse; + } + + @Override + public UserResponse updateUser(UserRequest userRequest) { + IndividualRequest request = mapToIndividualRequest(userRequest); + StringBuilder uri = new StringBuilder(); + uri.append(propertiesManager.getIndividualHost()); + uri.append(propertiesManager.getIndividualUpdateEndpoint()); + IndividualResponse response = restCallRepository + .fetchResult(uri, request, IndividualResponse.class); + UserResponse userResponse = null; + if (response != null && response.getIndividual() != null) { + log.info("response received from individual service"); + userResponse = mapToUserResponse(response); + } + return userResponse; + } + + @Override + public UserResponse getUser(RequestInfo requestInfo, Map userSearchCriteria ) { + IndividualSearchRequest request = IndividualSearchRequest.builder() + .requestInfo(requestInfo) + .individual(IndividualSearch.builder() + .mobileNumber((String) userSearchCriteria.get("mobileNumber")) + .id((List) userSearchCriteria.get("uuid")) + .roleCodes((List) userSearchCriteria.get("roleCodes")) + .username((String) userSearchCriteria.get(HRMSConstants.HRMS_USER_SEARCH_CRITERA_USERNAME)) + // given name + .individualName((String) userSearchCriteria + .get(HRMSConstants.HRMS_USER_SEARCH_CRITERA_NAME)) + .build()) + .build(); + IndividualBulkResponse response = getIndividualResponse((String) userSearchCriteria + .get(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID), + request); + UserResponse userResponse = new UserResponse(); + if (response != null && response.getIndividual() != null && !response.getIndividual().isEmpty()) { + log.info("response received from individual service"); + userResponse = mapToUserResponse(response); + } + return userResponse; + } + + private IndividualBulkResponse getIndividualResponse(String tenantId, IndividualSearchRequest individualSearchRequest) { + return restCallRepository.fetchResult( + new StringBuilder(propertiesManager.getIndividualHost() + + propertiesManager.getIndividualSearchEndpoint() + + "?limit=1000&offset=0&tenantId=" + tenantId), + individualSearchRequest, IndividualBulkResponse.class); + } + + + /** + * Converts a long value representing milliseconds since the epoch to a Date object in the format dd/MM/yyyy. + * + * @param milliseconds the long value representing milliseconds since the epoch. + * @return a Date object in the format dd/MM/yyyy. + */ + private static Date convertMillisecondsToDate(long milliseconds) { + SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); + formatter.setTimeZone(TimeZone.getTimeZone("UTC")); + String dateString = formatter.format(new Date(milliseconds)); + try { + return formatter.parse(dateString); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + private static IndividualRequest mapToIndividualRequest(UserRequest userRequest) { + Individual individual = Individual.builder() + .id(userRequest.getUser().getUuid()) + .userId(userRequest.getUser().getId() != null ? + String.valueOf(userRequest.getUser().getId()) : null) + .userUuid(userRequest.getUser().getUserServiceUuid()) + .isSystemUser(true) + .isSystemUserActive(userRequest.getUser().getActive()) + .name(Name.builder() + .givenName(userRequest.getUser().getName()) + .build()) + .gender(Gender.fromValue(userRequest.getUser().getGender())) + .email(userRequest.getUser().getEmailId()) + .mobileNumber(userRequest.getUser().getMobileNumber()) + .dateOfBirth(convertMillisecondsToDate(userRequest.getUser().getDob())) + .tenantId(userRequest.getUser().getTenantId()) + .address(Collections.singletonList(Address.builder() + .type(AddressType.CORRESPONDENCE) + .addressLine1(userRequest.getUser().getCorrespondenceAddress()) + .clientReferenceId(String.valueOf(UUID.randomUUID())) + .isDeleted(Boolean.FALSE) + .build())) + /* + * FIXME (HCM specific change) clientReferenceId is the primary key in the individual table of the FrontEnd Worker Application's local database. + */ + // Generating a unique client reference ID using UUID + .clientReferenceId(String.valueOf(UUID.randomUUID())) + // Creating a list of identifiers + .identifiers(Collections.singletonList( + // Building a unique identifier + Identifier.builder() + // Generating a unique client reference ID using UUID for the identifier + .clientReferenceId(String.valueOf(UUID.randomUUID())) + // Generating a unique identifier ID using UUID + .identifierId(String.valueOf(UUID.randomUUID())) + // Specifying the type of identifier as SYSTEM_GENERATED + .identifierType(SYSTEM_GENERATED) + .build())) + .userDetails(UserDetails.builder() + .username(userRequest.getUser().getUserName()) + .password(userRequest.getUser().getPassword()) + .tenantId(userRequest.getUser().getTenantId()) + .roles(userRequest.getUser().getRoles().stream().map(role -> Role.builder() + .code(role.getCode()) + .name(role.getName()) + .tenantId(userRequest.getUser().getTenantId()) + .description(role.getDescription()) + .build()).collect(Collectors.toList())) + .userType(UserType.fromValue(userRequest.getUser().getType())) + .build()) + .isDeleted(Boolean.FALSE) + .clientAuditDetails(AuditDetails.builder().createdBy(userRequest.getRequestInfo().getUserInfo().getUuid()).lastModifiedBy(userRequest.getRequestInfo().getUserInfo().getUuid()).build()) + .rowVersion(userRequest.getUser().getRowVersion()) + .build(); + return IndividualRequest.builder() + .requestInfo(userRequest.getRequestInfo()) + .individual(individual) + .build(); + } + + private static UserResponse mapToUserResponse(IndividualResponse response) { + UserResponse userResponse; + userResponse = UserResponse.builder() + .responseInfo(response.getResponseInfo()) + .user(Collections.singletonList(getUser(response.getIndividual()))) + .build(); + return userResponse; + } + + private static UserResponse mapToUserResponse(IndividualBulkResponse response) { + UserResponse userResponse; + userResponse = UserResponse.builder() + .responseInfo(response.getResponseInfo()) + .user(response.getIndividual().stream() + .map(IndividualService::getUser).collect(Collectors.toList())) + .build(); + return userResponse; + } + + + private static User getUser(Individual individual) { + return User.builder() + .id(individual.getUserId() != null ? Long.parseLong(individual.getUserId()) : null) + .mobileNumber(individual.getMobileNumber()) + .name(individual.getName().getGivenName()) + .uuid(individual.getId()) + .userServiceUuid(individual.getUserUuid()) + .active(individual.getIsSystemUserActive()) + .gender(individual.getGender() != null ? individual.getGender().name() : null) + .userName(individual.getUserDetails().getUsername()) + .emailId(individual.getEmail()) + .correspondenceAddress(individual.getAddress() != null && !individual.getAddress().isEmpty() + ? individual.getAddress().stream().filter(address -> address.getType() + .equals(AddressType.CORRESPONDENCE)).findFirst() + .orElse(Address.builder().build()) + .getAddressLine1() : null) + .dob(individual.getDateOfBirth().getTime()) + .tenantId(individual.getTenantId()) + .createdBy(individual.getAuditDetails().getCreatedBy()) + .createdDate(individual.getAuditDetails().getCreatedTime()) + .lastModifiedBy(individual.getAuditDetails().getLastModifiedBy()) + .lastModifiedDate(individual.getAuditDetails().getLastModifiedTime()) + .rowVersion(individual.getRowVersion()) + .roles(individual.getUserDetails() + .getRoles().stream().map(role -> org.egov.hrms.model.Role.builder() + .code(role.getCode()) + .tenantId(role.getTenantId()) + .name(role.getName()) + .build()).collect(Collectors.toList())) + + .build(); + } +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/service/MDMSService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/MDMSService.java new file mode 100644 index 00000000000..9b2d8df55c3 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/MDMSService.java @@ -0,0 +1,189 @@ +package org.egov.hrms.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.egov.common.contract.request.RequestInfo; +import org.egov.hrms.utils.HRMSConstants; +import org.egov.mdms.model.MasterDetail; +import org.egov.mdms.model.MdmsCriteria; +import org.egov.mdms.model.MdmsCriteriaReq; +import org.egov.mdms.model.MdmsResponse; +import org.egov.mdms.model.ModuleDetail; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.client.RestTemplate; + +import lombok.extern.slf4j.Slf4j; + +@Service +@Slf4j +public class MDMSService { + + @Autowired + private RestTemplate restTemplate; + + @Value("${egov.mdms.host}") + private String mdmsHost; + + @Value("${egov.mdms.search.endpoint}") + private String mdmsEndpoint; + + + /** + * Builds cache for MDMS data, this gets refreshed for every call. + * + * @param requestInfo + * @param tenantId + * @return + */ + public Map> getMDMSData(RequestInfo requestInfo, String tenantId){ + MdmsResponse response = fetchMDMSData(requestInfo, tenantId); + Map> masterData = new HashMap<>(); + Map> eachMasterMap = new HashMap<>(); + if(null != response) { + if(!CollectionUtils.isEmpty(response.getMdmsRes().keySet())) { + if(null != response.getMdmsRes().get(HRMSConstants.HRMS_MDMS_COMMON_MASTERS_CODE)){ + eachMasterMap = (Map) response.getMdmsRes().get(HRMSConstants.HRMS_MDMS_COMMON_MASTERS_CODE); + masterData.put(HRMSConstants.HRMS_MDMS_DEPT_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_DEPT_CODE)); + masterData.put(HRMSConstants.HRMS_MDMS_DESG_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_DESG_CODE)); + } + if(null != response.getMdmsRes().get(HRMSConstants.HRMS_MDMS_HR_MASTERS_CODE)) { + eachMasterMap = (Map) response.getMdmsRes().get(HRMSConstants.HRMS_MDMS_HR_MASTERS_CODE); + masterData.put(HRMSConstants.HRMS_MDMS_EMP_STATUS_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_EMP_STATUS_CODE)); + masterData.put(HRMSConstants.HRMS_MDMS_EMP_TYPE_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_EMP_TYPE_CODE)); + masterData.put(HRMSConstants.HRMS_MDMS_QUALIFICATION_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_QUALIFICATION_CODE)); + masterData.put(HRMSConstants.HRMS_MDMS_STREAMS_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_STREAMS_CODE)); + masterData.put(HRMSConstants.HRMS_MDMS_DEPT_TEST_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_DEPT_TEST_CODE)); + masterData.put(HRMSConstants.HRMS_MDMS_DEACT_REASON_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_DEACT_REASON_CODE)); + } + if(null != response.getMdmsRes().get(HRMSConstants.HRMS_AC_ROLES_MASTERS_CODE)) { + eachMasterMap = (Map) response.getMdmsRes().get(HRMSConstants.HRMS_AC_ROLES_MASTERS_CODE); + masterData.put(HRMSConstants.HRMS_MDMS_ROLES_CODE, eachMasterMap.get(HRMSConstants.HRMS_MDMS_ROLES_CODE)); + } + } + } + + return masterData; + + } + + + + /** + * Makes call to the MDMS service to fetch the MDMS data. + * + * @param requestInfo + * @param tenantId + * @return + */ + public MdmsResponse fetchMDMSData(RequestInfo requestInfo, String tenantId) { + StringBuilder uri = new StringBuilder(); + MdmsCriteriaReq request = prepareMDMSRequest(uri, requestInfo, tenantId); + MdmsResponse response = null; + try { + response = restTemplate.postForObject(uri.toString(), request, MdmsResponse.class); + }catch(Exception e) { + log.info("Exception while fetching from MDMS: ",e); + log.info("Request: "+ request); + } + return response; + } + + /** + * Makes call to the MDMS service to fetch the MDMS Boundary data. + * + * @param requestInfo + * @param tenantId + * @return + */ + public MdmsResponse fetchMDMSDataLoc(RequestInfo requestInfo, String tenantId) { + StringBuilder uri = new StringBuilder(); + MdmsCriteriaReq request = prepareMDMSRequestLoc(uri, requestInfo, tenantId); + MdmsResponse response = null; + try { + response = restTemplate.postForObject(uri.toString(), request, MdmsResponse.class); + }catch(Exception e) { + log.info("Exception while fetching from MDMS: ",e); + log.info("Request: "+ request); + } + return response; + } + + /** + * Prepares request for MDMS in order to fetch all the required masters for HRMS. + * + * @param uri + * @param requestInfo + * @param tenantId + * @return + */ + public MdmsCriteriaReq prepareMDMSRequest(StringBuilder uri, RequestInfo requestInfo, String tenantId) { + Map> mapOfModulesAndMasters = new HashMap<>(); + String[] hrMasters = {HRMSConstants.HRMS_MDMS_EMP_STATUS_CODE, HRMSConstants.HRMS_MDMS_EMP_TYPE_CODE, HRMSConstants.HRMS_MDMS_QUALIFICATION_CODE, + HRMSConstants.HRMS_MDMS_SERVICE_STATUS_CODE, HRMSConstants.HRMS_MDMS_STREAMS_CODE, HRMSConstants.HRMS_MDMS_DEACT_REASON_CODE, HRMSConstants.HRMS_MDMS_DEPT_TEST_CODE}; + String[] commonMasters = {HRMSConstants.HRMS_MDMS_DEPT_CODE, HRMSConstants.HRMS_MDMS_DESG_CODE, HRMSConstants.HRMS_MDMS_YEAR_CODE}; + String[] accessControlRoles = {HRMSConstants.HRMS_MDMS_ROLES_CODE}; + mapOfModulesAndMasters.put(HRMSConstants.HRMS_MDMS_COMMON_MASTERS_CODE, Arrays.asList(commonMasters)); + mapOfModulesAndMasters.put(HRMSConstants.HRMS_MDMS_HR_MASTERS_CODE, Arrays.asList(hrMasters)); + mapOfModulesAndMasters.put(HRMSConstants.HRMS_AC_ROLES_MASTERS_CODE, Arrays.asList(accessControlRoles)); + List moduleDetails = new ArrayList<>(); + for(String module: mapOfModulesAndMasters.keySet()) { + ModuleDetail moduleDetail = new ModuleDetail(); + moduleDetail.setModuleName(module); + List masterDetails = new ArrayList<>(); + for(String master: mapOfModulesAndMasters.get(module)) { + MasterDetail masterDetail=null; + if(module.equals(HRMSConstants.HRMS_AC_ROLES_MASTERS_CODE)) + masterDetail = MasterDetail.builder().name(master).filter(HRMSConstants.HRMS_MDMS_AC_ROLES_FILTER).build(); + else + masterDetail = MasterDetail.builder().name(master).filter("[?(@.active == true)].code").build(); + masterDetails.add(masterDetail); + } + moduleDetail.setMasterDetails(masterDetails); + moduleDetails.add(moduleDetail); + } + uri.append(mdmsHost).append(mdmsEndpoint); + MdmsCriteria mdmsCriteria = MdmsCriteria.builder().tenantId(tenantId).moduleDetails(moduleDetails).build(); + return MdmsCriteriaReq.builder().requestInfo(requestInfo).mdmsCriteria(mdmsCriteria).build(); + + } + + + /** + * Prepares request for MDMS in order to fetch all the required masters for Boundary Data. + * + * @param uri + * @param requestInfo + * @param tenantId + * @return + */ + public MdmsCriteriaReq prepareMDMSRequestLoc(StringBuilder uri, RequestInfo requestInfo, String tenantId) { + Map> mapOfModulesAndMasters = new HashMap<>(); + String[] egovLoccation = {HRMSConstants.HRMS_MDMS_TENANT_BOUNDARY_CODE}; + mapOfModulesAndMasters.put(HRMSConstants.HRMS_MDMS_EGOV_LOCATION_MASTERS_CODE, Arrays.asList(egovLoccation)); + List moduleDetails = new ArrayList<>(); + for(String module: mapOfModulesAndMasters.keySet()) { + ModuleDetail moduleDetail = new ModuleDetail(); + moduleDetail.setModuleName(module); + List masterDetails = new ArrayList<>(); + for(String master: mapOfModulesAndMasters.get(module)) { + MasterDetail masterDetail=null; + masterDetail = MasterDetail.builder().name(master).build(); + masterDetails.add(masterDetail); + } + moduleDetail.setMasterDetails(masterDetails); + moduleDetails.add(moduleDetail); + } + uri.append(mdmsHost).append(mdmsEndpoint); + MdmsCriteria mdmsCriteria = MdmsCriteria.builder().tenantId(tenantId).moduleDetails(moduleDetails).build(); + return MdmsCriteriaReq.builder().requestInfo(requestInfo).mdmsCriteria(mdmsCriteria).build(); + + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/service/NotificationService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/NotificationService.java new file mode 100644 index 00000000000..acb427e4ce7 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/NotificationService.java @@ -0,0 +1,196 @@ +package org.egov.hrms.service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.request.RequestInfo; +import org.egov.hrms.model.Employee; +import org.egov.hrms.model.SMSRequest; +import org.egov.hrms.producer.HRMSProducer; +import org.egov.hrms.repository.RestCallRepository; +import org.egov.hrms.utils.HRMSConstants; +import org.egov.hrms.web.contract.EmployeeRequest; +import org.egov.hrms.web.contract.RequestInfoWrapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.jayway.jsonpath.JsonPath; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.client.RestTemplate; + +@Service +@Slf4j +public class NotificationService { + + @Autowired + private HRMSProducer producer; + + @Autowired + private RestCallRepository repository; + + @Autowired + private RestTemplate restTemplate; + + @Value("${kafka.topics.notification.sms}") + private String smsTopic; + + @Value("${egov.hrms.employee.app.link}") + private String appLink; + + @Value("${egov.localization.host}") + private String localizationHost; + + @Value("${egov.localization.search.endpoint}") + private String localizationSearchEndpoint; + + @Value("${egov.otp.host}") + private String otpHost; + + @Value("${egov.otp.create.endpoint}") + private String otpCreateEndpoint; + + @Value("${egov.environment.domain}") + private String envHost; + + + + /** + * Sends notification by putting the sms content onto the core-sms topic + * + * @param request + * @param pwdMap + */ + public void sendNotification(EmployeeRequest request, Map pwdMap) { + String message = getMessage(request,HRMSConstants.HRMS_EMP_CREATE_LOCLZN_CODE); + if(StringUtils.isEmpty(message)) { + log.info("SMS content has not been configured for this case"); + return; + } + for(Employee employee: request.getEmployees()) { + message = buildMessage(employee, message, pwdMap); + SMSRequest smsRequest = SMSRequest.builder().mobileNumber(employee.getUser().getMobileNumber()).message(message).build(); + producer.push(smsTopic, smsRequest); + } + } + + public void sendReactivationNotification(EmployeeRequest request){ + String message = getMessage(request,HRMSConstants.HRMS_EMP_REACTIVATE_LOCLZN_CODE); + if(StringUtils.isEmpty(message)) { + log.info("SMS content has not been configured for this case"); + return; + } + RequestInfo requestInfo = request.getRequestInfo(); + for(Employee employee: request.getEmployees()) { + if(employee.getReactivationDetails()!=null && employee.getReActivateEmployee()){ + String OTP = getOTP(employee,requestInfo); + String link = envHost + "employee/user/otp"; + + message = message.replace("{Employee Name}",employee.getUser().getName()).replace("{Username}",employee.getCode()); + message = message.replace("{date}",(employee.getReactivationDetails().get(0).getEffectiveFrom()).toString()); + message = message.replace("{password}",OTP).replace("{link}",link); + + SMSRequest smsRequest = SMSRequest.builder().mobileNumber(employee.getUser().getMobileNumber()).message(message).build(); + log.info(message ); + producer.push(smsTopic, smsRequest); + } + + } + + } + + public String getOTP(Employee employee,RequestInfo requestInfo){ + Map OTPRequest= new HashMap<>(); + Map otp= new HashMap<>(); + otp.put("mobileNumber",employee.getUser().getMobileNumber()); + otp.put("type","passwordreset"); + otp.put("tenantId",employee.getTenantId()); + otp.put("userType","EMPLOYEE"); + otp.put("identity",employee.getUser().getMobileNumber()); + + OTPRequest.put("RequestInfo",requestInfo); + OTPRequest.put("otp",otp); + + Object response = null; + StringBuilder url = new StringBuilder(); + url.append(otpHost).append(otpCreateEndpoint); + try { + response = restTemplate.postForObject(url.toString(), OTPRequest, Map.class); + }catch(Exception e) { + log.error("Exception while creating user: ", e); + return null; + } + String result = JsonPath.read(response, "$.otp.otp"); + return result; + } + + /** + * Gets the message from localization + * + * @param request + * @return + */ + public String getMessage(EmployeeRequest request,String msgCode) { + String tenantId = request.getEmployees().get(0).getTenantId().split("\\.")[0]; + Map> localizedMessageMap = getLocalisedMessages(request.getRequestInfo(), tenantId, + HRMSConstants.HRMS_LOCALIZATION_ENG_LOCALE_CODE, HRMSConstants.HRMS_LOCALIZATION_MODULE_CODE); + return localizedMessageMap.get(HRMSConstants.HRMS_LOCALIZATION_ENG_LOCALE_CODE +"|"+tenantId).get(msgCode); + } + + /** + * Builds msg based on the format + * + * @param employee + * @param message + * @param pwdMap + * @return + */ + public String buildMessage(Employee employee, String message, Map pwdMap) { + message = message.replace("$username", employee.getCode()).replace("$password", pwdMap.get(employee.getUuid())) + .replace("$employeename", employee.getUser().getName()); + message = message.replace("$applink", appLink); + return message; + } + + /** + * Creates a cache for localization that gets refreshed at every call. + * + * @param requestInfo + * @param tenantId + * @param locale + * @param module + * @return + */ + public Map> getLocalisedMessages(RequestInfo requestInfo, String tenantId, String locale, String module) { + Map> localizedMessageMap = new HashMap<>(); + Map mapOfCodesAndMessages = new HashMap<>(); + StringBuilder uri = new StringBuilder(); + RequestInfoWrapper requestInfoWrapper = new RequestInfoWrapper(); + requestInfoWrapper.setRequestInfo(requestInfo); + tenantId = tenantId.split("\\.")[0]; + uri.append(localizationHost).append(localizationSearchEndpoint).append("?tenantId=" + tenantId) + .append("&module=" + module).append("&locale=" + locale); + List codes = null; + List messages = null; + Object result = null; + try { + result = repository.fetchResult(uri, requestInfoWrapper); + codes = JsonPath.read(result, HRMSConstants.HRMS_LOCALIZATION_CODES_JSONPATH); + messages = JsonPath.read(result, HRMSConstants.HRMS_LOCALIZATION_MSGS_JSONPATH); + } catch (Exception e) { + log.error("Exception while fetching from localization: " + e); + } + if (null != result) { + for (int i = 0; i < codes.size(); i++) { + mapOfCodesAndMessages.put(codes.get(i), messages.get(i)); + } + localizedMessageMap.put(locale + "|" + tenantId, mapOfCodesAndMessages); + } + + return localizedMessageMap; + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/service/UserService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/UserService.java new file mode 100644 index 00000000000..f1c7ee71a66 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/UserService.java @@ -0,0 +1,16 @@ +package org.egov.hrms.service; + +import org.egov.common.contract.request.RequestInfo; +import org.egov.hrms.web.contract.UserRequest; +import org.egov.hrms.web.contract.UserResponse; + +import java.util.Map; + +public interface UserService { + + UserResponse createUser(UserRequest userRequest); + + UserResponse updateUser(UserRequest userRequest); + + UserResponse getUser(RequestInfo requestInfo, Map userSearchCriteria); +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/ErrorConstants.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/ErrorConstants.java new file mode 100644 index 00000000000..1dccb2952f8 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/ErrorConstants.java @@ -0,0 +1,206 @@ +package org.egov.hrms.utils; + +import org.springframework.stereotype.Component; + +@Component +public class ErrorConstants { + + public static final String HRMS_USER_EXIST_MOB_CODE = "ERR_HRMS_USER_EXIST_MOB"; + public static final String HRMS_USER_EXIST_MOB_MSG = "User already exists for the entered mobile number. Use a different mobile number to proceed."; + + public static final String HRMS_USER_EXIST_USERNAME_CODE = "ERR_HRMS_USER_EXIST_USERNAME"; + public static final String HRMS_USER_EXIST_USERNAME_MSG = "User already exists for the entered user name."; + + public static final String HRMS_INVALID_MOB_NO_CODE = "ERR_HRMS_INVALID_MOB_NO"; + public static final String HRMS_INVALID_MOB_NO_MSG = "Invalid mobile number entered."; + + public static final String HRMS_MISSING_ROLES_CODE = "ERR_HRMS_MISSING_ROLES"; + public static final String HRMS_INVALID_ROLES_MSG = "Invalid mobile number entered."; + + public static final String HRMS_INVALID_ROLE_CODE = "ERR_HRMS_INVALID_ROLE"; + public static final String HRMS_INVALID_ROLE_MSG = "Invalid role assigned to the employee."; + + public static final String HRMS_INVALID_EMP_STATUS_CODE = "ERR_HRMS_INVALID_EMP_STATUS_ROLE"; + public static final String HRMS_INVALID_EMP_STATUS_MSG = "Invalid employment status entered."; + + public static final String HRMS_INVALID_EMP_TYPE_CODE = "ERR_HRMS_INVALID_EMP_TYPE"; + public static final String HRMS_INVALID_EMP_TYPE_MSG = "Invalid employee type entered."; + + public static final String HRMS_INVALID_DATE_OF_APPOINTMENT_CODE = "ERR_HRMS_INVALID_DATE_OF_APPOINTMENT"; + public static final String HRMS_INVALID_DATE_OF_APPOINTMENT_MSG = "Invalid employee date of appointment entered by the user."; + + public static final String HRMS_INVALID_DATE_OF_APPOINTMENT_DOB_CODE = "ERR_HRMS_INVALID_DATE_OF_APPOINTMENT_DOB"; + public static final String HRMS_INVALID_DATE_OF_APPOINTMENT_DOB_MSG = "Employee date of appointment can not be before date of birth."; + + public static final String HRMS_INVALID_DOB_CODE = "ERR_HRMS_INVALID_DOB"; + public static final String HRMS_INVALID_DOB_MSG = "Invalid date of birth entered."; + + public static final String HRMS_INVALID_CURRENT_ASSGN_CODE = "ERR_HRMS_INVALID_CURRENT_ASSGN"; + public static final String HRMS_INVALID_CURRENT_ASSGN_MSG = "There should be exactly one current assignment for the employee."; + + public static final String HRMS_OVERLAPPING_ASSGN_CODE = "ERR_HRMS_OVERLAPPING_ASSGN"; + public static final String HRMS_OVERLAPPING_ASSGN_MSG = "There should not be overlapping period of assignments for the employee."; + + public static final String HRMS_OVERLAPPING_ASSGN_CURRENT_CODE = "ERR_HRMS_OVERLAPPING_ASSGN_CURRENT"; + public static final String HRMS_OVERLAPPING_ASSGN_CURRENT_MSG = "Period of assignements of employee should not be after current assignment."; + + public static final String HRMS_INVALID_DEPT_CODE = "ERR_HRMS_INVALID_DEPT"; + public static final String HRMS_INVALID_DEPT_MSG = "Invalid department of employee entered."; + + public static final String HRMS_INVALID_DESG_CODE = "ERR_HRMS_INVALID_DESG"; + public static final String HRMS_INVALID_DESG_MSG = "Invalid designation of employee."; + + public static final String HRMS_INVALID_ASSIGNMENT_PERIOD_CODE = "ERR_HRMS_INVALID_ASSIGNMENT_PERIOD"; + public static final String HRMS_INVALID_ASSIGNMENT_PERIOD_MSG = "Invalid period of assignment (From date - To date)."; + + public static final String HRMS_INVALID_ASSIGNMENT_CURRENT_TO_DATE_CODE = "ERR_HRMS_INVALID_ASSIGNMENT_CURRENT_TO_DATE"; + public static final String HRMS_INVALID_ASSIGNMENT_CURRENT_TO_DATE_MSG = "To Date field should be blank for current assignment of the employee."; + + public static final String HRMS_OVERLAPPING_SERVICEHISTORY_CURRENT_CODE = "ERR_HRMS_OVERLAPPING_SERVICEHISTORY_CURRENT"; + public static final String HRMS_OVERLAPPING_SERVICEHISTORY_CURRENT_MSG = "Period of service details of employee should not be after current assignment!"; + + + public static final String HRMS_INVALID_ASSIGNMENT_NON_CURRENT_TO_DATE_CODE = "ERR_HRMS_INVALID_ASSIGNMENT_NOT_CURRENT_TO_DATE"; + public static final String HRMS_INVALID_ASSIGNMENT_NON_CURRENT_TO_DATE_MSG = "To date field should not be blank for non current assignment of the employee."; + + public static final String HRMS_INVALID_ASSIGNMENT_DATES_CODE = "ERR_HRMS_INVALID_ASSIGNMENT_DATES"; + public static final String HRMS_INVALID_ASSIGNMENT_DATES_MSG = "Employee period of assignment (From Date or To date) can not be before date of birth."; + + public static final String HRMS_INVALID_ASSIGNMENT_DATES_APPOINTMENT_CODE = "ERR_HRMS_INVALID_ASSIGNMENT_DATES_APPOINTMENT"; + public static final String HRMS_INVALID_ASSIGNMENT_DATES_APPOINTMENT_MSG = "Employee period of assignment (From Date or To date) can not be before date of appointment."; + + public static final String HRMS_INVALID_SERVICE_STATUS_CODE = "ERR_HRMS_INVALID_SERVICE_STATUS"; + public static final String HRMS_INVALID_SERVICE_STATUS_MSG = "Service stataus of employee is invalid."; + + public static final String HRMS_INVALID_SERVICE_PERIOD_CODE = "ERR_HRMS_INVALID_SERVICE_PERIOD"; + public static final String HRMS_INVALID_SERVICE_PERIOD_MSG = "Service period (From date or To date) of employee is invalid."; + + public static final String HRMS_INVALID_SERVICE_DATES_CODE = "ERR_HRMS_INVALID_SERVICE_DATES"; + public static final String HRMS_INVALID_SERVICE_DATES_MSG = "Employee service period (From date or To date) can not be before date of birth."; + + public static final String HRMS_INVALID_SERVICE_CURRENT_TO_DATE_CODE = "ERR_HRMS_INVALID_SERVICE_CURRENT_TO_DATE"; + public static final String HRMS_INVALID_SERVICE_CURRENT_TO_DATE_MSG = "To Date of service period should be blank for currently working employees."; + + public static final String HRMS_INVALID_SERVICE_NON_CURRENT_TO_DATE_CODE = "ERR_HRMS_INVALID_SERVICE_NOT_CURRENT_TO_DATE"; + public static final String HRMS_INVALID_SERVICE_NON_CURRENT_TO_DATE_MSG = "To Date of service period should not be blank for currently non working employees."; + + public static final String HRMS_INVALID_CURRENT_SERVICE_CODE = "ERR_HRMS_INVALID_SERVICE_ASSGN"; + public static final String HRMS_INVALID_CURRENT_SERVICE_MSG = "There should be maximum one currently working service for the employee."; + + public static final String HRMS_INVALID_QUALIFICATION_CODE = "ERR_HRMS_INVALID_QUALIFICATION"; + public static final String HRMS_INVALID_QUALIFICATION_MSG = "Qualification of the employee is invalid."; + + public static final String HRMS_INVALID_EDUCATIONAL_STREAM_CODE = "ERR_HRMS_INVALID_EDUCATIONAL_STREAM"; + public static final String HRMS_INVALID_EDUCATIONAL_STREAM_MSG = "Education stream of the employee is invalid."; + + public static final String HRMS_INVALID_EDUCATIONAL_PASSING_YEAR_CODE = "ERR_HRMS_INVALID_EDUCATIONAL_PASSING_YEAR"; + public static final String HRMS_INVALID_EDUCATIONAL_PASSING_YEAR_MSG = "Education year of passing of the employee can not be before date of birth."; + + public static final String HRMS_INVALID_DEPARTMENTAL_TEST_CODE = "ERR_HRMS_INVALID_DEPARTMENTAL_TEST"; + public static final String HRMS_INVALID_DEPARTMENTAL_TEST_MSG = "Departmental evaluation test of the employee is invalid."; + + public static final String HRMS_INVALID_DEPARTMENTAL_TEST_PASSING_YEAR_CODE = "ERR_HRMS_INVALID_DEPARTMENTAL_TEST_PASSING_YEAR"; + public static final String HRMS_INVALID_DEPARTMENTAL_TEST_PASSING_YEAR_MSG = "Departmental evaluation test passing year of the employee can not be before date of birth."; + + public static final String HRMS_INVALID_DEACT_REQUEST_CODE = "ERR_HRMS_INVALID_DEACT_REQUEST"; + public static final String HRMS_INVALID_DEACT_REQUEST_MSG = "Employee active flag should be set as false during deactivation."; + + public static final String HRMS_INVALID_DEACT_REASON_CODE = "ERR_HRMS_INVALID_DEACT_REASON"; + public static final String HRMS_INVALID_DEACT_REASON_MSG = "Employee deactivation reason is invalid."; + + public static final String HRMS_UPDATE_JURISDICTION_INCOSISTENT_CODE = "ERR_HRMS_UPDATE_JURISDICTION_INCOSISTENT"; + public static final String HRMS_UPDATE_JURISDICTION_INCOSISTENT_MSG = "Jurisdiction data in an update request should contain all previously entered data."; + + public static final String HRMS_UPDATE_ASSIGNEMENT_INCOSISTENT_CODE = "ERR_HRMS_UPDATE_ASSIGNEMENT_INCOSISTENT"; + public static final String HRMS_UPDATE_ASSIGNEMENT_INCOSISTENT_MSG = "Assignment data in an update request should contain all previously entered data."; + + public static final String HRMS_UPDATE_TESTS_INCOSISTENT_CODE = "ERR_HRMS_UPDATE_TESTS_INCOSISTENT"; + public static final String HRMS_UPDATE_TESTS_INCOSISTENT_MSG = "Employee evaluation test data in an update request should contain all previously entered data."; + + public static final String HRMS_UPDATE_EDUCATION_INCOSISTENT_CODE = "ERR_HRMS_UPDATE_EDUCATION_INCOSISTENT"; + public static final String HRMS_UPDATE_EDUCATION_INCOSISTENT_MSG = "Education data in an update request should contain all previously entered data."; + + public static final String HRMS_UPDATE_SERVICE_HISTORY_INCOSISTENT_CODE = "ERR_HRMS_UPDATE_SERVICE_HISTORY_INCOSISTENT"; + public static final String HRMS_UPDATE_SERVICE_HISTORY_INCOSISTENT_MSG = "Service history data in an update request should contain all previously entered data."; + + public static final String HRMS_UPDATE_DOCUMENT_INCOSISTENT_CODE = "ERR_HRMS_UPDATE_DOCUMENT_INCOSISTENT"; + public static final String HRMS_UPDATE_DOCUMENT_INCOSISTENT_MSG = "Employee document data in an update request should contain all previously entered data."; + + public static final String HRMS_UPDATE_DEACT_DETAILS_INCOSISTENT_CODE = "ERR_HRMS_UPDATE_DEACT_DETAILS_INCOSISTENT"; + public static final String HRMS_UPDATE_DEACT_DETAILS_INCOSISTENT_MSG = "Employee deactivation data in an update request should contain all previously entered data."; + + public static final String HRMS_UPDATE_NULL_ID_CODE = "ERR_HRMS_UPDATE_NULL_ID"; + public static final String HRMS_UPDATE_NULL_ID_MSG = "Employee ID in an update request should not be null."; + + public static final String HRMS_UPDATE_NULL_CODE_CODE = "ERR_HRMS_UPDATE_NULL"; + public static final String HRMS_UPDATE_NULL_CODE_MSG = "Employee Code in an update request should not be null."; + + public static final String HRMS_UPDATE_NULL_UUID_CODE = "ERR_HRMS_UPDATE_NULL_UUID"; + public static final String HRMS_UPDATE_NULL_UUID_MSG = "Employee UUID in an update request should not be null."; + + public static final String HRMS_USER_CREATION_FAILED_CODE = "ERR_HRMS_USER_CREATION_FAILED"; + public static final String HRMS_USER_CREATION_FAILED_MSG = "User creation failed at the user service."; + + public static final String HRMS_USER_UPDATION_FAILED_CODE = "ERR_HRMS_USER_UPDATION_FAILED"; + public static final String HRMS_USER_UPDATION_FAILED_MSG = "User updation failed at the user service."; + + public static final String HRMS_INVALID_SEARCH_REQ_CODE = "ERR_HRMS_INVALID_SEARCH_REQ"; + public static final String HRMS_INVALID_SEARCH_REQ_MSG = "Open search is disabled for this user."; + + public static final String HRMS_INVALID_JURISDICTION_HEIRARCHY_CODE = "ERR_HRMS_INVALID_JURISDICTION_HEIRARCHY"; + public static final String HRMS_INVALID_JURISDICTION_HEIRARCHY_MSG = "Jurisiction hierarchy value is invalid."; + + public static final String HRMS_INVALID_JURISDICTION_BOUNDARY_TYPE_CODE = "ERR_HRMS_INVALID_BOUNDARY_TYPE_HEIRARCHY"; + public static final String HRMS_INVALID_JURISDICTION_BOUNDARY_TYPE_MSG = "Jurisiction boundary type value is invalid."; + + public static final String HRMS_INVALID_JURISDICTION_BOUNDARY_CODE = "ERR_HRMS_INVALID_JURISDICTION_BOUNDARY"; + public static final String HRMS_INVALID_JURISDICTION_BOUNDARY_MSG = "Jurisiction boundary value is invalid."; + + public static final String HRMS_INVALID_JURISDICTION_ACTIIEV_NULL_CODE = "ERR_HRMS_INVALID_JURISDICTION_ACTIIEV_NULL"; + public static final String HRMS_INVALID_JURISDICTION_ACTIIEV_NULL_MSG = "Jurisiction should have atleast 1 active data"; + + public static final String HRMS_INVALID_SEARCH_AOD_CODE = "ERR_HRMS_INVALID_SEARCH_AOD"; + public static final String HRMS_INVALID_SEARCH_AOD_MSG = "Along with as on date, atleast one department and designation need to be passed as search criteria."; + + public static final String HRMS_INVALID_SEARCH_ROLES_CODE = "ERR_HRMS_INVALID_SEARCH_ROLES"; + public static final String HRMS_INVALID_SEARCH_ROLES_MSG = "For search based on roles, passing of tenant id is mandatory."; + + public static final String HRMS_INVALID_SEARCH_USER_CODE = "ERR_HRMS_INVALID_SEARCH_USER"; + public static final String HRMS_INVALID_SEARCH_USER_MSG = "For search based on phone number and name, passing of tenant id is mandatory."; + + public static final String HRMS_UPDATE_EMPLOYEE_CODE_CHANGE_CODE = "ERR_HRMS_UPDATE_EMPLOYEE_CODE_CHANGE"; + public static final String HRMS_UPDATE_EMPLOYEE_CODE_CHANGE_MSG = "Employee code can not be changed in an update request."; + public static final String HRMS_UPDATE_EMPLOYEE_NOT_EXIST_CODE = "ERR_HRMS_UPDATE_EMPLOYEE_NOT_EXIST_CODE"; + public static final String HRMS_UPDATE_EMPLOYEE_NOT_EXIST_MSG = "No employee found for given UUID."; + + public static final String HRMS_UPDATE_EXISTING_MOBNO_CODE = "ERR_HRMS_UPDATE_EXISTING_MOBNO"; + public static final String HRMS_UPDATE_EXISTING_MOBNO_MSG = "User exist for given mobile no"; + + public static final String HRMS_BULK_CREATE_DUPLICATE_MOBILE_CODE = "ERR_HRMS_BULK_CREATE_DUPLICATE_MOBILE"; + public static final String HRMS_BULK_CREATE_DUPLICATE_MOBILE_MSG = "Bulk request has duplicate mobile number "; + + public static final String HRMS_BULK_CREATE_DUPLICATE_EMPCODE_CODE = "ERR_HRMS_BULK_CREATE_DUPLICATE_EMPCODE"; + public static final String HRMS_BULK_CREATE_DUPLICATE_EMPCODE_MSG = "Bulk request has duplicate employee code "; + + public static final String HRMS_UPDATE_DEACT_DETAILS_INCORRECT_EFFECTIVEFROM_CODE = "ERR_HRMS_UPDATE_DEACT_DETAILS_INCORRECT_EFFECTIVEFROM"; + public static final String HRMS_UPDATE_DEACT_DETAILS_INCORRECT_EFFECTIVEFROM_MSG = "Employee deactivation effective date should be current date only."; + + public static final String HRMS_GENERATE_ID_ERROR_CODE = "ERR_HRMS_GENERATE_ID_ERROR"; + public static final String HRMS_GENERATE_ID_ERROR_MSG = "Unable to create ids " ; + + public static final String HRMS_EMPLOYEE_COUNT_ERROR_CODE = "ERR_HRMS_COUNT_EMP"; + public static final String HRMS_EMPLOYEE_COUNT_ERROR_MSG = "Please provide tenantid to get count of the employee"; + + public static final String HRMS_UPDATE_REACT_DETAILS_INCORRECT_EFFECTIVEFROM_CODE = "ERR_HRMS_UPDATE_REACT_DETAILS_INCORRECT_EFFECTIVEFROM"; + public static final String HRMS_UPDATE_REACT_DETAILS_INCORRECT_EFFECTIVEFROM_MSG = "Employee reactivation effective date should be between deactivation date and current date."; + + public static final String CITIZEN_TYPE_CODE = "CITIZEN"; + + public static final String HRMS_INVALID_SEARCH_CITIZEN_CODE = "ERR_HRMS_INVALID_SEARCH_CITIZEN"; + public static final String HRMS_INVALID_SEARCH_CITIZEN_MSG = "Citizen are not allowed to access employee search with Ids."; + + public static final String HRMS_PASSWORD_REQUIRED = "ERR_HRMS_PASSWORD_REQUIRED"; + + public static final String HRMS_PASSWORD_REQUIRED_MSG = "Password is required"; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/HRMSConstants.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/HRMSConstants.java new file mode 100644 index 00000000000..0d01b642d97 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/HRMSConstants.java @@ -0,0 +1,64 @@ +package org.egov.hrms.utils; + +import org.springframework.stereotype.Component; + +@Component +public class HRMSConstants { + + public static final String HRMS_MDMS_COMMON_MASTERS_CODE = "common-masters"; + public static final String HRMS_MDMS_HR_MASTERS_CODE = "egov-hrms"; + public static final String HRMS_AC_ROLES_MASTERS_CODE = "ACCESSCONTROL-ROLES"; + public static final String HRMS_MDMS_EGOV_LOCATION_MASTERS_CODE = "egov-location"; + + public static final String HRMS_MDMS_DEPT_CODE = "Department"; + public static final String HRMS_MDMS_DESG_CODE = "Designation"; + public static final String HRMS_MDMS_EMP_STATUS_CODE = "EmployeeStatus"; + public static final String HRMS_MDMS_EMP_TYPE_CODE = "EmployeeType"; + public static final String HRMS_MDMS_SERVICE_STATUS_CODE = "ServiceStatus"; + public static final String HRMS_MDMS_ROLES_CODE = "roles"; + public static final String HRMS_MDMS_QUALIFICATION_CODE = "Degree"; + public static final String HRMS_MDMS_STREAMS_CODE = "Specalization"; + public static final String HRMS_MDMS_YEAR_CODE = "Year"; + public static final String HRMS_MDMS_DEPT_TEST_CODE = "EmploymentTest"; + public static final String HRMS_MDMS_DEACT_REASON_CODE = "DeactivationReason"; + public static final String HRMS_MDMS_TENANT_BOUNDARY_CODE = "TenantBoundary"; + + public static final String HRMS_LOCALIZATION_CODES_JSONPATH = "$.messages.*.code"; + public static final String HRMS_LOCALIZATION_MSGS_JSONPATH = "$.messages.*.message"; + + + public static final String HRMS_EMP_CREATE_LOCLZN_CODE = "hrms.employee.create.notification"; + public static final String HRMS_EMP_REACTIVATE_LOCLZN_CODE = "hrms.employee.reactivation.notification"; + public static final String HRMS_LOCALIZATION_MODULE_CODE = "egov-hrms"; + public static final String HRMS_LOCALIZATION_ENG_LOCALE_CODE = "en_IN"; + public static final String HRMS_TENANTBOUNDARY_HIERARCHY_JSONPATH = "$.TenantBoundary[?(@.boundary.code ==\"%s\")].hierarchyType.code"; + public static final String HRMS_TENANTBOUNDARY_BOUNDARY_TYPE_JSONPATH ="$.TenantBoundary[?(@.hierarchyType.name==\"%1$s\" && @.boundary.code ==\"%2$s\")]..label"; + public static final String HRMS_TENANTBOUNDARY_BOUNDARY_VALUE_JSONPATH ="$.TenantBoundary[?(@.hierarchyType.name==\"%1$s\" && @.boundary.code ==\"%2$s\")]..code"; + + public static final String HRMS_MDMS_AC_ROLES_FILTER = "[?(@.code != \"CITIZEN\")].code"; + public static final String HRMS_MDMS_CODE_FLITER = "[?(@.active == true)].code"; + + public static final String HRMS_USER_SEARCH_CRITERA_UUID = "uuid"; + public static final String HRMS_USER_SEARCH_CRITERA_ROLECODES = "roleCodes"; + public static final String HRMS_USER_SEARCH_CRITERA_TENANTID = "tenantId"; + public static final String HRMS_USER_SEARCH_CRITERA_MOBILENO = "mobileNumber"; + public static final String HRMS_USER_SEARCH_CRITERA_NAME = "name"; + public static final String HRMS_USER_SEARCH_CRITERA_USERNAME = "UserName"; + public static final String HRMS_USER_SERACH_CRITERIA_USERTYPE = "EMPLOYEE"; + public static final String HRMS_USER_SERACH_CRITERIA_USERTYPE_CODE = "userType"; + + public static final String INTERNALMICROSERVICEROLE_NAME = "Internal Microservice Role"; + + public static final String INTERNALMICROSERVICEROLE_CODE = "INTERNAL_MICROSERVICE_ROLE"; + + public static final String INTERNALMICROSERVICEUSER_NAME = "Internal Microservice User"; + + public static final String INTERNALMICROSERVICEUSER_USERNAME = "INTERNAL_USER"; + + public static final String INTERNALMICROSERVICEUSER_MOBILENO = "9999999999"; + + public static final String INTERNALMICROSERVICEUSER_TYPE = "SYSTEM"; + + public static final String SYSTEM_GENERATED = "SYSTEM_GENERATED"; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/HRMSUtils.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/HRMSUtils.java new file mode 100644 index 00000000000..014a7a2c005 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/HRMSUtils.java @@ -0,0 +1,72 @@ +package org.egov.hrms.utils; + +import java.security.SecureRandom; +import java.util.List; +import java.util.Random; + +import org.egov.hrms.web.contract.EmployeeSearchCriteria; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Service +public class HRMSUtils { + + @Value("${egov.hrms.default.pwd.length}") + private Integer pwdLength; + + @Value("${egov.pwd.allowed.special.characters}") + private String allowedPasswordSpecialCharacters; + + /** + * Generates random password for the user to login. Process: + * 1. Takes a list of parameters for password + * 2. Applies a random select logic and generates a password of constant length. + * 3. The length of the password is configurable. + * + * @param params + * @return + */ + public String generatePassword(List params) { + StringBuilder password = new StringBuilder(); + SecureRandom random = new SecureRandom(); + params.add(allowedPasswordSpecialCharacters); + try { + for(int i = 0; i < params.size(); i++) { + String param = params.get(i); + String val; + if(param.length() == 1) + val = param; + else + val = param.split("")[random.nextInt(param.length() - 1)]; + if(val.equals(".") || val.equals("-") || val.equals(" ")) + password.append("x"); + else + password.append(val); + if(password.length() == pwdLength) + break; + else { + if(i == params.size() - 1) + i = 0; + } + } + }catch(Exception e) { + password.append("123456"); + } + + return password.toString().replaceAll("\\s+", ""); + } + + public boolean isAssignmentSearchReqd(EmployeeSearchCriteria criteria) { + return (! CollectionUtils.isEmpty(criteria.getPositions()) || null != criteria.getAsOnDate() + || !CollectionUtils.isEmpty(criteria.getDepartments()) || !CollectionUtils.isEmpty(criteria.getDesignations())); + } + + public String generateMobileNumber() { + Random random = new Random(); + int min = 100000000; + int max = 999999999; + int mobileNumber = random.nextInt(max - min + 1) + min; + return Integer.toString(mobileNumber); + } +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/ResponseInfoFactory.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/ResponseInfoFactory.java new file mode 100644 index 00000000000..e82744a00c0 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/ResponseInfoFactory.java @@ -0,0 +1,26 @@ +package org.egov.hrms.utils; + + +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.response.ResponseInfo; +import org.springframework.stereotype.Component; + +@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 resMsgId = "uief87324"; // FIXME : Hard-coded + final String msgId = requestInfo != null ? requestInfo.getMsgId() : ""; + final String responseStatus = success ? "successful" : "failed"; + + return ResponseInfo.builder().apiId(apiId).ver(ver).ts(ts).resMsgId(resMsgId).msgId(msgId).resMsgId(resMsgId) + .status(responseStatus).build(); + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeRequest.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeRequest.java new file mode 100644 index 00000000000..87b2b42d207 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeRequest.java @@ -0,0 +1,76 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.web.contract; + +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +import org.egov.common.contract.request.RequestInfo; +import org.egov.hrms.model.Employee; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.validation.annotation.Validated; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Validated +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EmployeeRequest { + + @NotNull + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + + @Valid + @NotEmpty + @JsonProperty("Employees") + private List employees; + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeResponse.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeResponse.java new file mode 100644 index 00000000000..6fb5141aeed --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeResponse.java @@ -0,0 +1,72 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.web.contract; + +import java.util.List; + +import org.egov.common.contract.response.ResponseInfo; +import org.egov.hrms.model.Employee; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +@Builder +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +public class EmployeeResponse { + + @JsonProperty("ResponseInfo") + private ResponseInfo responseInfo; + + @JsonProperty("Employees") + private List employees; + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeSearchCriteria.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeSearchCriteria.java new file mode 100644 index 00000000000..f5a3f9dfca6 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeSearchCriteria.java @@ -0,0 +1,75 @@ +package org.egov.hrms.web.contract; + +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.CollectionUtils; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import javax.validation.constraints.Size; + + +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class EmployeeSearchCriteria { + + public List codes; + + public List names; + + public List departments; + + public List designations; + + public Long asOnDate; + + public List roles; + + public List ids; + + public List employeestatuses; + + public List employeetypes; + + public List uuids; + + public List positions; + + public Boolean isActive; + + @Size(max = 250) + public String tenantId; + + public String phone; + + public Integer offset; + + public Integer limit; + + private Boolean includeUnassigned = false; + + + public boolean isCriteriaEmpty(EmployeeSearchCriteria criteria) { + if(CollectionUtils.isEmpty(criteria.getCodes()) && CollectionUtils.isEmpty(criteria.getNames()) + && CollectionUtils.isEmpty(criteria.getDepartments()) && CollectionUtils.isEmpty(criteria.getDesignations()) + && CollectionUtils.isEmpty(criteria.getIds()) && CollectionUtils.isEmpty(criteria.getEmployeestatuses()) + && CollectionUtils.isEmpty(criteria.getEmployeetypes()) && CollectionUtils.isEmpty(criteria.getUuids()) + && CollectionUtils.isEmpty(criteria.getPositions()) && StringUtils.isEmpty(criteria.getTenantId()) + && CollectionUtils.isEmpty(criteria.getRoles()) && null == criteria.getAsOnDate()) { + return true; + }else { + return false; + } + } + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdGenerationRequest.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdGenerationRequest.java new file mode 100644 index 00000000000..9116d5835f3 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdGenerationRequest.java @@ -0,0 +1,64 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) <2015> eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ +package org.egov.hrms.web.contract; + +import java.util.List; + +import org.egov.common.contract.request.RequestInfo; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class IdGenerationRequest { + + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + + private List idRequests; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdGenerationResponse.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdGenerationResponse.java new file mode 100644 index 00000000000..3bcb4d1a7f3 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdGenerationResponse.java @@ -0,0 +1,65 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) <2015> eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ +package org.egov.hrms.web.contract; + +import java.util.List; + +import org.egov.common.contract.response.ResponseInfo; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@AllArgsConstructor +@NoArgsConstructor +public class IdGenerationResponse { + + private ResponseInfo responseInfo; + + private ResponseInfo ResponseInfo; + + private List idResponses; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdRequest.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdRequest.java new file mode 100644 index 00000000000..cc3ac543675 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdRequest.java @@ -0,0 +1,63 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) <2015> eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ +package org.egov.hrms.web.contract; + +import javax.validation.constraints.NotNull; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class IdRequest { + + @NotNull + private String idName; + + @NotNull + private String tenantId; + + private String format; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdResponse.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdResponse.java new file mode 100644 index 00000000000..ac167a59ddd --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/IdResponse.java @@ -0,0 +1,57 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) <2015> eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ +package org.egov.hrms.web.contract; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@AllArgsConstructor +@NoArgsConstructor +public class IdResponse { + + private String id; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/RequestInfoWrapper.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/RequestInfoWrapper.java new file mode 100644 index 00000000000..ada1794cd4f --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/RequestInfoWrapper.java @@ -0,0 +1,64 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.web.contract; + +import javax.validation.constraints.NotNull; + +import org.egov.common.contract.request.RequestInfo; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RequestInfoWrapper { + + @NotNull + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/User.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/User.java new file mode 100644 index 00000000000..b0a004a6ae9 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/User.java @@ -0,0 +1,186 @@ +package org.egov.hrms.web.contract; + +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.egov.hrms.model.Role; +import org.egov.hrms.model.enums.GuardianRelation; +import org.springframework.validation.annotation.Validated; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Validated +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +@JsonIgnoreProperties( + ignoreUnknown = true +) +public class User { + + @JsonProperty("id") + private Long id; + + @Size(max=64) + @JsonProperty("uuid") + private String uuid; + + @Size(max=64) + @JsonProperty("userServiceUuid") + private String userServiceUuid; + + @Size(max=180) + @JsonProperty("userName") + private String userName; + + @Size(max=64) + @JsonProperty("password") + private String password; + + @Size(max = 5) + @JsonProperty("salutation") + private String salutation; + + @NotNull + @Size(max=250) + @JsonProperty("name") + private String name; + + @JsonProperty("gender") + private String gender; + + @Pattern(regexp = "^[0-9]{9,10}$", message = "MobileNumber should be either 9 or 10 digit number") + @JsonProperty("mobileNumber") + private String mobileNumber; + + @Size(max=128) + @JsonProperty("emailId") + private String emailId; + + @Size(max=50) + @JsonProperty("altContactNumber") + private String altContactNumber; + + @Size(max=10) + @JsonProperty("pan") + private String pan; + + @Pattern(regexp = "^[0-9]{12}$", message = "AdharNumber should be 12 digit number") + @JsonProperty("aadhaarNumber") + private String aadhaarNumber; + + @Size(max=300) + @JsonProperty("permanentAddress") + private String permanentAddress; + + @Size(max=300) + @JsonProperty("permanentCity") + private String permanentCity; + + @Size(max=10) + @JsonProperty("permanentPinCode") + private String permanentPincode; + + @Size(max=300) + @JsonProperty("correspondenceCity") + private String correspondenceCity; + + @Size(max=10) + @JsonProperty("correspondencePinCode") + private String correspondencePincode; + + @Size(max=300) + @JsonProperty("correspondenceAddress") + private String correspondenceAddress; + + @JsonProperty("active") + private Boolean active; + + @NotNull + @JsonProperty("dob") + private Long dob; + + @JsonProperty("pwdExpiryDate") + private Long pwdExpiryDate; + + @Size(max=16) + @JsonProperty("locale") + private String locale; + + @Size(max=50) + @JsonProperty("type") + private String type; + + @Size(max=36) + @JsonProperty("signature") + private String signature; + + @JsonProperty("accountLocked") + private Boolean accountLocked; + + @JsonProperty("roles") + @Valid + private List roles; + + @Size(max=100) + @JsonProperty("fatherOrHusbandName") + private String fatherOrHusbandName; + + @JsonProperty("relationship") + private GuardianRelation relationship; + + @Size(max=32) + @JsonProperty("bloodGroup") + private String bloodGroup; + + @Size(max=300) + @JsonProperty("identificationMark") + private String identificationMark; + + @Size(max=36) + @JsonProperty("photo") + private String photo; + + @Size(max=64) + @JsonProperty("createdBy") + private String createdBy; + + @JsonProperty("createdDate") + private Long createdDate; + + @Size(max=64) + @JsonProperty("lastModifiedBy") + private String lastModifiedBy; + + @JsonProperty("lastModifiedDate") + private Long lastModifiedDate; + + @JsonProperty("otpReference") + private String otpReference; + + @Size(max=256) + @JsonProperty("tenantId") + private String tenantId; + + @JsonProperty("rowVersion") + private Integer rowVersion; + + +} diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/UserRequest.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/UserRequest.java new file mode 100644 index 00000000000..699dc079614 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/UserRequest.java @@ -0,0 +1,74 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.web.contract; + +import javax.validation.constraints.NotNull; + +import org.egov.common.contract.request.RequestInfo; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class UserRequest { + + @NotNull + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + + @NotNull + @JsonProperty("User") + private User user; + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/UserResponse.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/UserResponse.java new file mode 100644 index 00000000000..285964a0a87 --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/UserResponse.java @@ -0,0 +1,69 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.web.contract; + +import java.util.ArrayList; +import java.util.List; + +import lombok.Builder; +import org.egov.common.contract.response.ResponseInfo; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +@Builder +public class UserResponse { + + private ResponseInfo responseInfo; + + private List user = new ArrayList(); + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/controller/EmployeeController.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/controller/EmployeeController.java new file mode 100644 index 00000000000..0b780a74f6a --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/controller/EmployeeController.java @@ -0,0 +1,135 @@ +/* + * eGov suite of products aim to improve the internal efficiency,transparency, + * accountability and the service delivery of the government organizations. + * + * Copyright (C) 2016 eGovernments Foundation + * + * The updated version of eGov suite of products as by eGovernments Foundation + * is available at http://www.egovernments.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ or + * http://www.gnu.org/licenses/gpl.html . + * + * In addition to the terms of the GPL license to be adhered to in using this + * program, the following additional terms are to be complied with: + * + * 1) All versions of this program, verbatim or modified must carry this + * Legal Notice. + * + * 2) Any misrepresentation of the origin of the material is prohibited. It + * is required that all modified versions of this material be marked in + * reasonable ways as different from the original version. + * + * 3) This license does not grant any rights to any user of the program + * with regards to rights under trademark law for use of the trade names + * or trademarks of eGovernments Foundation. + * + * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. + */ + +package org.egov.hrms.web.controller; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.contract.request.RequestInfo; +import org.egov.hrms.service.EmployeeService; +import org.egov.hrms.web.contract.EmployeeRequest; +import org.egov.hrms.web.contract.EmployeeResponse; +import org.egov.hrms.web.contract.EmployeeSearchCriteria; +import org.egov.hrms.web.contract.RequestInfoWrapper; +import org.egov.hrms.web.validator.EmployeeValidator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@RestController +@RequestMapping("/employees") +public class EmployeeController { + + @Autowired + private EmployeeService employeeService; + + @Autowired + private EmployeeValidator validator; + + + /** + * Maps Post Requests for _create & returns ResponseEntity of either + * EmployeeResponse type or ErrorResponse type + * + * @param employeeRequest + * @param bindingResult + * @return ResponseEntity + */ + @PostMapping(value = "/_create") + @ResponseBody + public ResponseEntity create(@RequestBody @Valid EmployeeRequest employeeRequest) { + validator.validateCreateEmployee(employeeRequest); + EmployeeResponse employeeResponse = employeeService.create(employeeRequest); + return new ResponseEntity<>(employeeResponse, HttpStatus.ACCEPTED); + } + + + /** + * Maps Post Requests for _update & returns ResponseEntity of either + * EmployeeResponse type or ErrorResponse type + * + * @param employeeRequest + * @param bindingResult + * @return ResponseEntity + */ + @PostMapping(value = "/_update") + @ResponseBody + public ResponseEntity update(@RequestBody @Valid EmployeeRequest employeeRequest) { + validator.validateUpdateEmployee(employeeRequest); + EmployeeResponse employeeResponse = employeeService.update(employeeRequest); + return new ResponseEntity<>(employeeResponse, HttpStatus.ACCEPTED); + } + + + /** + * Maps Post Requests for _search & returns ResponseEntity of either + * EmployeeResponse type or ErrorResponse type + * + * @param criteria + * @param bindingResult + * @return ResponseEntity + */ + @PostMapping(value = "/_search") + @ResponseBody + public ResponseEntity search(@RequestBody @Valid RequestInfoWrapper requestInfoWrapper, @ModelAttribute @Valid EmployeeSearchCriteria criteria) { + validator.validateSearchRequest(requestInfoWrapper.getRequestInfo(), criteria); + log.info(criteria.toString()); + EmployeeResponse employeeResponse = employeeService.search(criteria, requestInfoWrapper.getRequestInfo()); + return new ResponseEntity<>(employeeResponse,HttpStatus.OK); + } + + @PostMapping("_count") + @ResponseBody + private ResponseEntity count(@RequestParam("tenantId") String tenantId, @RequestBody RequestInfo requestInfo) { + + Map response = new HashMap<>(); + validator.validateEmployeeCountRequest(tenantId); + response = employeeService.getEmployeeCountResponse(requestInfo,tenantId); + return new ResponseEntity<>(response,HttpStatus.OK); + } + + +} \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/validator/EmployeeValidator.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/validator/EmployeeValidator.java new file mode 100644 index 00000000000..1494f83bdbc --- /dev/null +++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/validator/EmployeeValidator.java @@ -0,0 +1,817 @@ +package org.egov.hrms.web.validator; + +import java.util.*; +import java.util.stream.Collectors; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.Date; + +import com.jayway.jsonpath.JsonPath; +import org.apache.commons.lang3.StringUtils; +import org.egov.common.contract.request.RequestInfo; +import org.egov.common.contract.request.Role; +import org.egov.hrms.config.PropertiesManager; +import org.egov.hrms.model.*; +import org.egov.hrms.service.EmployeeService; +import org.egov.hrms.service.MDMSService; +import org.egov.hrms.service.UserService; +import org.egov.hrms.utils.ErrorConstants; +import org.egov.hrms.utils.HRMSConstants; +import org.egov.hrms.utils.HRMSUtils; +import org.egov.hrms.web.contract.EmployeeRequest; +import org.egov.hrms.web.contract.EmployeeResponse; +import org.egov.hrms.web.contract.EmployeeSearchCriteria; +import org.egov.hrms.web.contract.UserResponse; +import org.egov.mdms.model.MdmsResponse; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import lombok.extern.slf4j.Slf4j; + +import static org.egov.hrms.utils.ErrorConstants.CITIZEN_TYPE_CODE; + +@Service +@Slf4j +public class EmployeeValidator { + + @Autowired + private MDMSService mdmsService; + + @Autowired + private EmployeeService employeeService; + + @Autowired + private UserService userService; + + @Autowired + private PropertiesManager propertiesManager; + + @Autowired + private HRMSUtils hrmsUtils; + + /** + * Validates employee request for create. Validations include: + * 1. Validating MDMS codes + * 2. Performing data sanity checks + * + * @param request + */ + public void validateCreateEmployee(EmployeeRequest request) { + Map errorMap = new HashMap<>(); + validateExistingDuplicates(request ,errorMap); + validatePassword(request, errorMap); + if(!CollectionUtils.isEmpty(errorMap.keySet())) + throw new CustomException(errorMap); + Map> boundaryMap = getBoundaryList(request.getRequestInfo(),request.getEmployees().get(0)); + Map> mdmsData = mdmsService.getMDMSData(request.getRequestInfo(), request.getEmployees().get(0).getTenantId()); + if(!CollectionUtils.isEmpty(mdmsData.keySet())){ + request.getEmployees().stream().forEach(employee -> validateMdmsData(employee, errorMap, mdmsData,boundaryMap)); + } + if(!CollectionUtils.isEmpty(errorMap.keySet())) + throw new CustomException(errorMap); + } + + private void validatePassword(EmployeeRequest request, Map errorMap) { + List employees = request.getEmployees(); + if (!propertiesManager.isAutoGeneratePassword()) { + employees.forEach(employee -> { + if (StringUtils.isEmpty(employee.getUser().getPassword())) + errorMap.put(ErrorConstants.HRMS_PASSWORD_REQUIRED, ErrorConstants.HRMS_PASSWORD_REQUIRED_MSG); + }); + } + } + + public Map> getBoundaryList(RequestInfo requestInfo,Employee employee){ + List boundarytList = new ArrayList<>(); + Map> eachMasterMap = new HashMap<>(); + Map> masterData = new HashMap<>(); + if(!CollectionUtils.isEmpty(employee.getJurisdictions())){ + for(Jurisdiction jurisdiction: employee.getJurisdictions()){ + if(!boundarytList.contains(jurisdiction.getBoundary())) + boundarytList.add(jurisdiction.getBoundary()); + } + if(CollectionUtils.isEmpty(boundarytList)) + boundarytList.add(employee.getTenantId()); + } + + List boundaryResponseList = new ArrayList<>(); + for(String boundary: boundarytList){ + MdmsResponse responseLoc = mdmsService.fetchMDMSDataLoc(requestInfo, boundary); + if(!CollectionUtils.isEmpty(responseLoc.getMdmsRes())) + boundaryResponseList.add(responseLoc); + } + + if(!CollectionUtils.isEmpty(boundaryResponseList)){ + List tenantBoundaryData = new ArrayList<>(); + for(MdmsResponse responseLoc : boundaryResponseList){ + if(!CollectionUtils.isEmpty(responseLoc.getMdmsRes().keySet())) { + if(null != responseLoc.getMdmsRes().get(HRMSConstants.HRMS_MDMS_EGOV_LOCATION_MASTERS_CODE)) { + eachMasterMap = (Map) responseLoc.getMdmsRes().get(HRMSConstants.HRMS_MDMS_EGOV_LOCATION_MASTERS_CODE); + tenantBoundaryData.addAll(eachMasterMap.get(HRMSConstants.HRMS_MDMS_TENANT_BOUNDARY_CODE)); + } + } + } + if(!CollectionUtils.isEmpty(tenantBoundaryData)) + masterData.put(HRMSConstants.HRMS_MDMS_TENANT_BOUNDARY_CODE,tenantBoundaryData); + } + return masterData; + } + + /** + * Validates search request. Checks the following: + * 1. If a user who doesn't have access to open search is making an open search call. + * + * @param requestInfo + * @param criteria + */ + public void validateSearchRequest(RequestInfo requestInfo, EmployeeSearchCriteria criteria) { + Map errorMap = new HashMap<>(); + + if(requestInfo.getUserInfo() != null && requestInfo.getUserInfo().getType().equalsIgnoreCase(CITIZEN_TYPE_CODE) && !CollectionUtils.isEmpty(criteria.getIds())) + errorMap.put(ErrorConstants.HRMS_INVALID_SEARCH_CITIZEN_CODE, ErrorConstants.HRMS_INVALID_SEARCH_CITIZEN_MSG); + + if(criteria.isCriteriaEmpty(criteria)) { + String[] roles = propertiesManager.getOpenSearchEnabledRoles().split(","); + List reqroles = requestInfo.getUserInfo().getRoles().stream().map(Role::getCode).collect(Collectors.toList()); + boolean check = false; + for(String role : reqroles) { + if(Arrays.asList(roles).contains(role)) { + check = true; + break; + } + } + if(!check) { + errorMap.put(ErrorConstants.HRMS_INVALID_SEARCH_REQ_CODE, ErrorConstants.HRMS_INVALID_SEARCH_REQ_MSG); + } + } + if(null != criteria.getAsOnDate()) { + if(CollectionUtils.isEmpty(criteria.getDepartments()) || CollectionUtils.isEmpty(criteria.getDesignations())) + errorMap.put(ErrorConstants.HRMS_INVALID_SEARCH_AOD_CODE, ErrorConstants.HRMS_INVALID_SEARCH_AOD_MSG); + } + + if(!CollectionUtils.isEmpty( criteria.getRoles()) && StringUtils.isEmpty(criteria.getTenantId())) { + errorMap.put(ErrorConstants.HRMS_INVALID_SEARCH_ROLES_CODE, ErrorConstants.HRMS_INVALID_SEARCH_ROLES_MSG); + } + + if((!StringUtils.isEmpty(criteria.getPhone()) || !CollectionUtils.isEmpty(criteria.getNames())) && + StringUtils.isEmpty(criteria.getTenantId())) { + errorMap.put(ErrorConstants.HRMS_INVALID_SEARCH_USER_CODE, ErrorConstants.HRMS_INVALID_SEARCH_USER_MSG); + } + if(!CollectionUtils.isEmpty(errorMap.keySet())) + throw new CustomException(errorMap); + } + + /** + * Checks if the employee being created is duplicate with the following: + * 1. Validating mobile number + * 2. Validating username + * + * @param request + * @param errorMap + */ + private void validateExistingDuplicates(EmployeeRequest request, Map errorMap) { + List employees = request.getEmployees(); + validateDataUniqueness(employees,errorMap); + validateUserMobile(employees,errorMap,request.getRequestInfo()); + validateUserName(employees,errorMap,request.getRequestInfo()); + } + + /** + * Checks duplicate occurance of mobileNumber and code for bulk request + * + * @param employees + * @param errorMap + */ + private void validateDataUniqueness(List employees, Map errorMap) { + HashSet < String> codes = new HashSet<>(); + employees.forEach(employee -> { + if(null != employee.getCode()){ + if (codes.contains(employee.getCode())) + errorMap.put(ErrorConstants.HRMS_BULK_CREATE_DUPLICATE_EMPCODE_CODE,ErrorConstants.HRMS_BULK_CREATE_DUPLICATE_EMPCODE_MSG); + else + codes.add(employee.getCode()); + } + }); + } + + /** + * Checks if the mobile number used in the request is duplicate. + * + * @param employees + * @param errorMap + * @param requestInfo + */ + private void validateUserMobile(List employees, Map errorMap, RequestInfo requestInfo) { + HashSet < String> mobileNos = new HashSet<>(); + employees.forEach(employee -> { + boolean autoGenerateMobileNumber = employee.getUser().getMobileNumber() == null || + employee.getUser().getMobileNumber().isEmpty(); + int maxRetryCount = 5; + if (autoGenerateMobileNumber) { + int retryCount = 0; + String generatedMobileNumber = hrmsUtils.generateMobileNumber(); + while ((retryCount < maxRetryCount) && mobileNos.contains(generatedMobileNumber)) { + generatedMobileNumber = hrmsUtils.generateMobileNumber(); + retryCount++; + } + employee.getUser().setMobileNumber(generatedMobileNumber); + } + if(mobileNos.contains(employee.getUser().getMobileNumber())) + errorMap.put(ErrorConstants.HRMS_BULK_CREATE_DUPLICATE_MOBILE_CODE, ErrorConstants.HRMS_BULK_CREATE_DUPLICATE_MOBILE_MSG ); + else + mobileNos.add(employee.getUser().getMobileNumber()); + Map userSearchCriteria = new HashMap<>(); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID,employee.getTenantId()); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_MOBILENO,employee.getUser().getMobileNumber()); + UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria); + if (autoGenerateMobileNumber && !CollectionUtils.isEmpty(userResponse.getUser())) { + int retryCount = 0; + String generatedMobileNumber = hrmsUtils.generateMobileNumber(); + while ((retryCount < maxRetryCount) && !CollectionUtils.isEmpty(userResponse.getUser())) { + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_MOBILENO,generatedMobileNumber); + userResponse = userService.getUser(requestInfo, userSearchCriteria); + retryCount++; + } + employee.getUser().setMobileNumber(generatedMobileNumber); + } + if(!CollectionUtils.isEmpty(userResponse.getUser())){ + errorMap.put(ErrorConstants.HRMS_USER_EXIST_MOB_CODE, + ErrorConstants.HRMS_USER_EXIST_MOB_MSG); + } + }); + } + + /** + * Checks if the username is duplicate + * + * @param employees + * @param errorMap + * @param requestInfo + */ + private void validateUserName(List employees, Map errorMap, RequestInfo requestInfo) { + employees.forEach(employee -> { + if(!StringUtils.isEmpty(employee.getCode())){ + Map userSearchCriteria = new HashMap<>(); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID,employee.getTenantId()); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_USERNAME,employee.getCode()); + UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria); + if(!CollectionUtils.isEmpty(userResponse.getUser())){ + errorMap.put(ErrorConstants.HRMS_USER_EXIST_USERNAME_CODE, + ErrorConstants.HRMS_USER_EXIST_USERNAME_MSG); + } + } + }); + } + + /** + * Validates MDMS codes of the request. + * + * @param employee + * @param errorMap + * @param mdmsData + */ + private void validateMdmsData(Employee employee, Map errorMap, Map> mdmsData, Map> boundaryMap) { + validateEmployee(employee, errorMap, mdmsData); + validateAssignments(employee, errorMap, mdmsData); + validateServiceHistory(employee, errorMap, mdmsData); + validateJurisdicton(employee, errorMap, mdmsData, boundaryMap); + validateEducationalDetails(employee, errorMap, mdmsData); + validateDepartmentalTest(employee, errorMap, mdmsData); + } + + + /** + * Performs checks for maintaining data consistency + * @param employee + * @param errorMap + * @param mdmsData + * @param existingEmp + * @param requestInfo + */ + public void validateDataConsistency(Employee employee, Map errorMap, Map> mdmsData, Employee existingEmp, RequestInfo requestInfo) { + validateUserData(existingEmp,employee,errorMap, requestInfo); + validateConsistencyAssignment(existingEmp,employee,errorMap); + validateConsistencyJurisdiction(existingEmp,employee,errorMap); + validateConsistencyDepartmentalTest(existingEmp,employee,errorMap); + validateConsistencyEducationalDetails(existingEmp,employee,errorMap); + validateConsistencyServiceHistory(existingEmp, employee, errorMap); + validateConsistencyEmployeeDocument(existingEmp, employee, errorMap); + validateConsistencyDeactivationDetails(existingEmp, employee, errorMap); + if(!employee.getIsActive()) + validateDeactivationDetails(existingEmp, employee, errorMap, mdmsData); + if(employee.getIsActive() && employee.getReActivateEmployee()) + validateReactivationDetails(existingEmp, employee, errorMap, mdmsData); + } + + /** + * Check whether employee code has changed + * @param existingEmp + * @param employee + * @param errorMap + * @param requestInfo + */ + private void validateUserData(Employee existingEmp, Employee employee, Map errorMap, RequestInfo requestInfo) { + if(!employee.getCode().equals(existingEmp.getCode())) + errorMap.put(ErrorConstants.HRMS_UPDATE_EMPLOYEE_CODE_CHANGE_CODE,ErrorConstants.HRMS_UPDATE_EMPLOYEE_CODE_CHANGE_MSG); + if(!employee.getUser().getMobileNumber().equals(existingEmp.getUser().getMobileNumber())){ + Map userSearchCriteria = new HashMap<>(); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID,employee.getTenantId()); + userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_MOBILENO,employee.getUser().getMobileNumber()); + UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria); + if(!CollectionUtils.isEmpty(userResponse.getUser())){ + if(!employee.getUser().getUuid().equals(userResponse.getUser().get(0).getUuid())){ + errorMap.put(ErrorConstants.HRMS_UPDATE_EXISTING_MOBNO_CODE,ErrorConstants.HRMS_UPDATE_EXISTING_MOBNO_MSG); + } + } + + + } + + } + + /** + * Checks the following: + * 1. Whether the mobile number is valid + * 2. Whether the roles are valid + * 3. Whether the employee status mentioned is valid. + * 4. Whether the employee type mentioned is valid + * 5. Whether the date of appointment of the employee is valid. + * + * @param employee + * @param errorMap + * @param mdmsData + */ + private void validateEmployee(Employee employee, Map errorMap, Map> mdmsData) { + + if(employee.getUser().getMobileNumber().length() != 10 && employee.getUser().getMobileNumber().length() != 9) { + errorMap.put(ErrorConstants.HRMS_INVALID_MOB_NO_CODE, ErrorConstants.HRMS_INVALID_MOB_NO_MSG); + } + + if(CollectionUtils.isEmpty(employee.getUser().getRoles())) + errorMap.put(ErrorConstants.HRMS_MISSING_ROLES_CODE, ErrorConstants.HRMS_INVALID_ROLES_MSG); + else { + for(org.egov.hrms.model.Role role: employee.getUser().getRoles()) { + if(!mdmsData.get(HRMSConstants.HRMS_MDMS_ROLES_CODE).contains(role.getCode())) + errorMap.put(ErrorConstants.HRMS_INVALID_ROLE_CODE, ErrorConstants.HRMS_INVALID_ROLE_MSG ); + } + } + /*if(!mdmsData.get(HRMSConstants.HRMS_MDMS_EMP_STATUS_CODE).contains(employee.getEmployeeStatus())) + errorMap.put(ErrorConstants.HRMS_INVALID_EMP_STATUS_CODE, ErrorConstants.HRMS_INVALID_EMP_STATUS_MSG);*/ + if(!mdmsData.get(HRMSConstants.HRMS_MDMS_EMP_TYPE_CODE).contains(employee.getEmployeeType())) + errorMap.put(ErrorConstants.HRMS_INVALID_EMP_TYPE_CODE, ErrorConstants.HRMS_INVALID_EMP_TYPE_MSG); + if(null != employee.getDateOfAppointment() && employee.getDateOfAppointment() > new Date().getTime()) + errorMap.put(ErrorConstants.HRMS_INVALID_DATE_OF_APPOINTMENT_CODE, ErrorConstants.HRMS_INVALID_DATE_OF_APPOINTMENT_MSG); + if(null != employee.getUser().getDob()) { + if(employee.getUser().getDob() >= new Date().getTime()) + errorMap.put(ErrorConstants.HRMS_INVALID_DOB_CODE, ErrorConstants.HRMS_INVALID_DOB_MSG); + if(null != employee.getDateOfAppointment() && employee.getDateOfAppointment() < employee.getUser().getDob()) + errorMap.put(ErrorConstants.HRMS_INVALID_DATE_OF_APPOINTMENT_DOB_CODE, ErrorConstants.HRMS_INVALID_DATE_OF_APPOINTMENT_DOB_MSG); + } + } + + /** + * Checks the following: + * 1. If there is more than one current assignment. + * 2. if period of assignment of any of the assignments overlap with that of others. + * 3. if the Department code is valid + * 4. If the Designation code is valid + * 5. If the assignment dates are valid + * + * @param employee + * @param errorMap + * @param mdmsData + */ + private void validateAssignments(Employee employee, Map errorMap, Map> mdmsData) { + if (employee.getAssignments() != null && !employee.getAssignments().isEmpty()) { + List currentAssignments = employee.getAssignments().stream().filter(assignment -> assignment.getIsCurrentAssignment()).collect(Collectors.toList()); + if (currentAssignments.size() != 1) { + errorMap.put(ErrorConstants.HRMS_INVALID_CURRENT_ASSGN_CODE, ErrorConstants.HRMS_INVALID_CURRENT_ASSGN_MSG); + } + employee.getAssignments().sort(new Comparator() { + @Override + public int compare(Assignment assignment1, Assignment assignment2) { + return assignment1.getFromDate().compareTo(assignment2.getFromDate()); + } + }); + int length = employee.getAssignments().size(); + boolean overlappingCheck = false; + for (int i = 0; i < length - 1; i++) { + if (null != employee.getAssignments().get(i).getToDate() && employee.getAssignments().get(i).getToDate() > employee.getAssignments().get(i + 1).getFromDate()) + overlappingCheck = true; + } + if (overlappingCheck) + errorMap.put(ErrorConstants.HRMS_OVERLAPPING_ASSGN_CODE, ErrorConstants.HRMS_OVERLAPPING_ASSGN_MSG); + + for (Assignment assignment : employee.getAssignments()) { + if (!assignment.getIsCurrentAssignment() && !CollectionUtils.isEmpty(currentAssignments) && null != assignment.getToDate() && currentAssignments.get(0).getFromDate() < assignment.getToDate()) + errorMap.put(ErrorConstants.HRMS_OVERLAPPING_ASSGN_CURRENT_CODE, ErrorConstants.HRMS_OVERLAPPING_ASSGN_CURRENT_MSG); + if (!mdmsData.get(HRMSConstants.HRMS_MDMS_DEPT_CODE).contains(assignment.getDepartment())) + errorMap.put(ErrorConstants.HRMS_INVALID_DEPT_CODE, ErrorConstants.HRMS_INVALID_DEPT_MSG); + /*if (!assignment.getDesignation().equalsIgnoreCase("undefined") && + !mdmsData.get(HRMSConstants.HRMS_MDMS_DESG_CODE).contains(assignment.getDesignation())) + errorMap.put(ErrorConstants.HRMS_INVALID_DESG_CODE, ErrorConstants.HRMS_INVALID_DESG_MSG);*/ + if (assignment.getIsCurrentAssignment() && null != assignment.getToDate()) + errorMap.put(ErrorConstants.HRMS_INVALID_ASSIGNMENT_CURRENT_TO_DATE_CODE, ErrorConstants.HRMS_INVALID_ASSIGNMENT_CURRENT_TO_DATE_MSG); + if (!assignment.getIsCurrentAssignment() && null == assignment.getToDate()) + errorMap.put(ErrorConstants.HRMS_INVALID_ASSIGNMENT_NON_CURRENT_TO_DATE_CODE, ErrorConstants.HRMS_INVALID_ASSIGNMENT_NON_CURRENT_TO_DATE_MSG); + if (null != assignment.getToDate() && assignment.getFromDate() > assignment.getToDate()) + errorMap.put(ErrorConstants.HRMS_INVALID_ASSIGNMENT_PERIOD_CODE, ErrorConstants.HRMS_INVALID_ASSIGNMENT_PERIOD_MSG); + if (employee.getUser().getDob() != null) + if (assignment.getFromDate() < employee.getUser().getDob() || (null != assignment.getToDate() && assignment.getToDate() < employee.getUser().getDob())) + errorMap.put(ErrorConstants.HRMS_INVALID_ASSIGNMENT_DATES_CODE, ErrorConstants.HRMS_INVALID_ASSIGNMENT_DATES_MSG); + if (null != employee.getDateOfAppointment() && assignment.getFromDate() < employee.getDateOfAppointment()) + errorMap.put(ErrorConstants.HRMS_INVALID_ASSIGNMENT_DATES_APPOINTMENT_CODE, ErrorConstants.HRMS_INVALID_ASSIGNMENT_DATES_APPOINTMENT_MSG); + + } + } + + } + + /** + * Checks the follwing: + * 1. If the status of service is valid. + * 2. If the service period is valid. + * 3. If the service dates is valid. + * 4. If there is more than 1 current Positions. + * 5. If service end date is null for current position + * + * @param employee + * @param errorMap + * @param mdmsData + */ + private void validateServiceHistory(Employee employee, Map errorMap, Map> mdmsData) { + if(!CollectionUtils.isEmpty(employee.getServiceHistory())){ + List currentService = employee.getServiceHistory().stream().filter(serviceHistory -> null!= serviceHistory.getIsCurrentPosition() && serviceHistory.getIsCurrentPosition()).collect(Collectors.toList()); + if(currentService.size() > 1){ + errorMap.put(ErrorConstants.HRMS_INVALID_CURRENT_SERVICE_CODE, ErrorConstants.HRMS_INVALID_CURRENT_SERVICE_MSG); + } + for(ServiceHistory history: employee.getServiceHistory()) { + if( (null== history.getIsCurrentPosition() || !history.getIsCurrentPosition()) && !CollectionUtils.isEmpty(currentService) && null != currentService.get(0).getServiceFrom() && null != history.getServiceTo() && currentService.get(0).getServiceFrom() new Date().getTime()) || (null != history.getServiceTo() && history.getServiceTo() > new Date().getTime()) + || (null != history.getServiceFrom() && null != history.getServiceTo() && history.getServiceFrom() > history.getServiceTo())) + errorMap.put(ErrorConstants.HRMS_INVALID_SERVICE_PERIOD_CODE, ErrorConstants.HRMS_INVALID_SERVICE_PERIOD_MSG); + if(employee.getUser().getDob()!=null ) + if((null != history.getServiceFrom() && history.getServiceFrom() < employee.getUser().getDob()) || (null != history.getServiceTo() && history.getServiceTo() < employee.getUser().getDob())) + errorMap.put(ErrorConstants.HRMS_INVALID_SERVICE_DATES_CODE, ErrorConstants.HRMS_INVALID_SERVICE_DATES_MSG); + } + } + } + + /** + * Checks the following: + * 1. If the qualification is valid. + * 2. If the specialization provided is valid. + * 3. If the year of passing is valid. + * + * @param employee + * @param errorMap + * @param mdmsData + */ + private void validateEducationalDetails(Employee employee, Map errorMap, Map> mdmsData) { + if(!CollectionUtils.isEmpty(employee.getEducation())){ + for(EducationalQualification education : employee.getEducation()) { + if(null!= education.getQualification() && !mdmsData.get(HRMSConstants.HRMS_MDMS_QUALIFICATION_CODE).contains(education.getQualification())) + errorMap.put(ErrorConstants.HRMS_INVALID_QUALIFICATION_CODE, ErrorConstants.HRMS_INVALID_QUALIFICATION_MSG); + if(null != education.getStream() && !mdmsData.get(HRMSConstants.HRMS_MDMS_STREAMS_CODE).contains(education.getStream())) + errorMap.put(ErrorConstants.HRMS_INVALID_EDUCATIONAL_STREAM_CODE, ErrorConstants.HRMS_INVALID_EDUCATIONAL_STREAM_MSG); + if(null != education.getYearOfPassing() && education.getYearOfPassing() > new Date().getTime()){ + errorMap.put(ErrorConstants.HRMS_INVALID_EDUCATIONAL_PASSING_YEAR_CODE, ErrorConstants.HRMS_INVALID_EDUCATIONAL_PASSING_YEAR_MSG); + } + } + } + } + + /** + * 1. Checks if there is atleast 1 active jurisdiction + * 2. If hierarchy is valid + * 3. If boundaryType is valid + * 4. If boundary is valid + * + * @param employee + * @param errorMap + * @param mdmsData + */ + private void validateJurisdicton(Employee employee, Map errorMap, Map> mdmsData,Map> boundaryMap) { + if(CollectionUtils.isEmpty(employee.getJurisdictions().stream().filter(jurisdiction -> null == jurisdiction.getIsActive() || jurisdiction.getIsActive() && jurisdiction.getIsActive() ).collect(Collectors.toList()))){ + errorMap.put(ErrorConstants.HRMS_INVALID_JURISDICTION_ACTIIEV_NULL_CODE,ErrorConstants.HRMS_INVALID_JURISDICTION_ACTIIEV_NULL_MSG); + } + for(Jurisdiction jurisdiction: employee.getJurisdictions()) { + String hierarchy_type_path = String.format(HRMSConstants.HRMS_TENANTBOUNDARY_HIERARCHY_JSONPATH,jurisdiction.getBoundary()); + String boundary_type_path = String.format(HRMSConstants.HRMS_TENANTBOUNDARY_BOUNDARY_TYPE_JSONPATH,jurisdiction.getHierarchy(),jurisdiction.getBoundary()); + String boundary_value_path = String.format(HRMSConstants.HRMS_TENANTBOUNDARY_BOUNDARY_VALUE_JSONPATH,jurisdiction.getHierarchy(),jurisdiction.getBoundary()); + List hierarchyTypes = JsonPath.read(boundaryMap,hierarchy_type_path); + List boundaryTypes = JsonPath.read(boundaryMap,boundary_type_path); + List boundaryValues = JsonPath.read(boundaryMap,boundary_value_path); + if(!hierarchyTypes.contains(jurisdiction.getHierarchy())) + errorMap.put(ErrorConstants.HRMS_INVALID_JURISDICTION_HEIRARCHY_CODE, ErrorConstants.HRMS_INVALID_JURISDICTION_HEIRARCHY_MSG); + if(!boundaryTypes.contains(jurisdiction.getBoundaryType())) + errorMap.put(ErrorConstants.HRMS_INVALID_JURISDICTION_BOUNDARY_TYPE_CODE, ErrorConstants.HRMS_INVALID_JURISDICTION_BOUNDARY_TYPE_MSG); + if(!boundaryValues.contains(jurisdiction.getBoundary())) + errorMap.put(ErrorConstants.HRMS_INVALID_JURISDICTION_BOUNDARY_CODE, ErrorConstants.HRMS_INVALID_JURISDICTION_BOUNDARY_MSG); + } + + + } + + + /** + * Checks the follwing: + * 1. If the dept test is valid. + * 2. If the year of passing is valid. + * + * @param employee + * @param errorMap + * @param mdmsData + */ + private void validateDepartmentalTest(Employee employee, Map errorMap, Map> mdmsData) { + if(!CollectionUtils.isEmpty(employee.getTests())) { + for (DepartmentalTest test : employee.getTests()) { + if (null!=test.getTest() && !mdmsData.get(HRMSConstants.HRMS_MDMS_DEPT_TEST_CODE).contains(test.getTest())) + errorMap.put(ErrorConstants.HRMS_INVALID_DEPARTMENTAL_TEST_CODE, ErrorConstants.HRMS_INVALID_DEPARTMENTAL_TEST_MSG ); + if (null!= test.getYearOfPassing() && test.getYearOfPassing() > new Date().getTime()) { + errorMap.put(ErrorConstants.HRMS_INVALID_DEPARTMENTAL_TEST_PASSING_YEAR_CODE, ErrorConstants.HRMS_INVALID_DEPARTMENTAL_TEST_PASSING_YEAR_MSG); + } + + } + } + } + + /** + * Validates if the deactivation details are provided every time an employee is deactivated. + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + * @param mdmsData + */ + private void validateDeactivationDetails(Employee existingEmp, Employee updatedEmployeeData, Map errorMap, Map> mdmsData){ + if(!CollectionUtils.isEmpty(updatedEmployeeData.getDeactivationDetails())) { + Date date = new Date(); + Date currentDateStartTime = Date.from(date.toInstant().atZone(ZoneId.systemDefault()) + .truncatedTo(ChronoUnit.DAYS).toInstant()); + for (DeactivationDetails deactivationDetails : updatedEmployeeData.getDeactivationDetails()) { + if (deactivationDetails.getId()==null){ + if(updatedEmployeeData.getIsActive()){ + errorMap.put(ErrorConstants.HRMS_INVALID_DEACT_REQUEST_CODE, ErrorConstants.HRMS_INVALID_DEACT_REQUEST_MSG); + } + } + if(deactivationDetails.getEffectiveFrom() > new Date().getTime()) + errorMap.put(ErrorConstants.HRMS_UPDATE_DEACT_DETAILS_INCORRECT_EFFECTIVEFROM_CODE, ErrorConstants.HRMS_UPDATE_DEACT_DETAILS_INCORRECT_EFFECTIVEFROM_MSG); + + if(deactivationDetails.getEffectiveFrom() < currentDateStartTime.getTime()) + errorMap.put(ErrorConstants.HRMS_UPDATE_DEACT_DETAILS_INCORRECT_EFFECTIVEFROM_CODE, ErrorConstants.HRMS_UPDATE_DEACT_DETAILS_INCORRECT_EFFECTIVEFROM_MSG); + + if (! mdmsData.get(HRMSConstants.HRMS_MDMS_DEACT_REASON_CODE).contains(deactivationDetails.getReasonForDeactivation())) + errorMap.put(ErrorConstants.HRMS_INVALID_DEACT_REASON_CODE, ErrorConstants.HRMS_INVALID_DEACT_REASON_MSG); + } + } + } + + private void validateReactivationDetails(Employee existingEmp, Employee updatedEmployeeData, Map errorMap, Map> mdmsData){ + if(!CollectionUtils.isEmpty(updatedEmployeeData.getReactivationDetails())) { + for (ReactivationDetails reactivationDetails : updatedEmployeeData.getReactivationDetails()) { + Boolean isValidDetails = existingEmp.getDeactivationDetails().get(0).getEffectiveFrom() <= reactivationDetails.getEffectiveFrom() + && reactivationDetails.getEffectiveFrom() <= new Date().getTime(); + if(!isValidDetails) + errorMap.put(ErrorConstants.HRMS_UPDATE_REACT_DETAILS_INCORRECT_EFFECTIVEFROM_CODE, ErrorConstants.HRMS_UPDATE_REACT_DETAILS_INCORRECT_EFFECTIVEFROM_MSG); + + } + } + } + + /** + * Validates the employee request for update. Validates the following: + * 1. MDMS codes in the request + * 2. Performs data consistency checks. + * + * @param request + */ + public void validateUpdateEmployee(EmployeeRequest request) { + Map errorMap = new HashMap<>(); + Map> boundaryMap = getBoundaryList(request.getRequestInfo(),request.getEmployees().get(0)); + Map> mdmsData = mdmsService.getMDMSData(request.getRequestInfo(), request.getEmployees().get(0).getTenantId()); + List uuidList = request.getEmployees().stream().map(Employee :: getUuid).collect(Collectors.toList()); + EmployeeResponse existingEmployeeResponse = employeeService.search(EmployeeSearchCriteria.builder().uuids(uuidList) + .tenantId(request.getEmployees().get(0).getTenantId()) + .build(),request.getRequestInfo()); + List existingEmployees = existingEmployeeResponse.getEmployees(); + for(Employee employee: request.getEmployees()){ + if(validateEmployeeForUpdate(employee, errorMap)){ + if(!existingEmployees.isEmpty()){ + Employee existingEmp = existingEmployees.stream().filter(existingEmployee -> existingEmployee.getUuid().equals(employee.getUuid())).findFirst().get(); + validateDataConsistency(employee, errorMap, mdmsData, existingEmp, request.getRequestInfo()); + } + else + errorMap.put(ErrorConstants.HRMS_UPDATE_EMPLOYEE_NOT_EXIST_CODE, ErrorConstants.HRMS_UPDATE_EMPLOYEE_NOT_EXIST_MSG); + } + validateMdmsData(employee, errorMap, mdmsData,boundaryMap); + } + if(!CollectionUtils.isEmpty(errorMap.keySet())) { + throw new CustomException(errorMap); + } + + + } + + /** + * Checks if the ID, UUID and Code are present in the update request + * + * @param employee + * @param errorMap + * @return + */ + private boolean validateEmployeeForUpdate(Employee employee, Map errorMap) { + boolean isvalid = true; + if(employee.getId() == null){ + errorMap.put(ErrorConstants.HRMS_UPDATE_NULL_ID_CODE, ErrorConstants.HRMS_UPDATE_NULL_ID_MSG); + isvalid=false; + } + if(StringUtils.isEmpty(employee.getCode())){ + errorMap.put(ErrorConstants.HRMS_UPDATE_NULL_CODE_CODE, ErrorConstants.HRMS_UPDATE_NULL_CODE_MSG); + isvalid=false; + } + if(StringUtils.isEmpty(employee.getUuid())){ + errorMap.put(ErrorConstants.HRMS_UPDATE_NULL_UUID_CODE, ErrorConstants.HRMS_UPDATE_NULL_UUID_MSG); + isvalid=false; + } + + return isvalid; + + } + + /** + * Juridictions once created in the system cannot be deleted, they can however be changed. Validates that condition + * + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + */ + private void validateConsistencyJurisdiction(Employee existingEmp, Employee updatedEmployeeData, Map errorMap) { + boolean check = + updatedEmployeeData.getJurisdictions().stream() + .map(jurisdiction -> jurisdiction.getId()) + .collect(Collectors.toList()) + .containsAll(existingEmp.getJurisdictions().stream() + .map(jurisdiction -> jurisdiction.getId()) + .collect(Collectors.toList())); + if(!check){ + errorMap.put(ErrorConstants.HRMS_UPDATE_JURISDICTION_INCOSISTENT_CODE, ErrorConstants.HRMS_UPDATE_JURISDICTION_INCOSISTENT_MSG); + } + + } + + /** + * Assignments once created in the system cannot be deleted, they can however be changed. Validates that condition + * + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + */ + private void validateConsistencyAssignment(Employee existingEmp, Employee updatedEmployeeData, Map errorMap) { + if (updatedEmployeeData.getAssignments() != null && existingEmp.getAssignments() != null) { + boolean check = + updatedEmployeeData.getAssignments().stream() + .map(assignment -> assignment.getId()) + .collect(Collectors.toList()) + .containsAll(existingEmp.getAssignments().stream() + .map(assignment -> assignment.getId()) + .collect(Collectors.toList())); + if (!check) { + errorMap.put(ErrorConstants.HRMS_UPDATE_ASSIGNEMENT_INCOSISTENT_CODE, ErrorConstants.HRMS_UPDATE_ASSIGNEMENT_INCOSISTENT_MSG); + } + } + } + + /** + * Dept Test details once created in the system cannot be deleted, they can however be changed. Validates that condition + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + */ + private void validateConsistencyDepartmentalTest(Employee existingEmp, Employee updatedEmployeeData, Map errorMap){ + if(!CollectionUtils.isEmpty(updatedEmployeeData.getTests())){ + boolean check = + updatedEmployeeData.getTests().stream() + .map(test -> test.getId()) + .collect(Collectors.toList()) + .containsAll(existingEmp.getTests().stream() + .map(test -> test.getId()) + .collect(Collectors.toList())); + if(!check){ + errorMap.put(ErrorConstants.HRMS_UPDATE_TESTS_INCOSISTENT_CODE, ErrorConstants.HRMS_UPDATE_TESTS_INCOSISTENT_MSG); + } + } + + } + + /** + * Education Details once created in the system cannot be deleted, they can however be changed. Validates that condition + * + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + */ + private void validateConsistencyEducationalDetails(Employee existingEmp, Employee updatedEmployeeData, Map errorMap){ + if(!CollectionUtils.isEmpty(updatedEmployeeData.getEducation())){ + boolean check = + updatedEmployeeData.getEducation().stream() + .map(educationalQualification -> educationalQualification.getId()) + .collect(Collectors.toList()) + .containsAll(existingEmp.getEducation().stream() + .map(educationalQualification -> educationalQualification.getId()) + .collect(Collectors.toList())); + if(!check){ + errorMap.put(ErrorConstants.HRMS_UPDATE_EDUCATION_INCOSISTENT_CODE, ErrorConstants.HRMS_UPDATE_EDUCATION_INCOSISTENT_MSG); + } + } + } + + /** + * Service History once created in the system cannot be deleted, they can however be changed. Validates that condition + * + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + */ + private void validateConsistencyServiceHistory(Employee existingEmp, Employee updatedEmployeeData, Map errorMap){ + if(!CollectionUtils.isEmpty(updatedEmployeeData.getServiceHistory())){ + boolean check = + updatedEmployeeData.getServiceHistory().stream() + .map(serviceHistory -> serviceHistory.getId()) + .collect(Collectors.toList()) + .containsAll(existingEmp.getServiceHistory().stream() + .map(serviceHistory -> serviceHistory.getId()) + .collect(Collectors.toList())); + if(!check){ + errorMap.put(ErrorConstants.HRMS_UPDATE_SERVICE_HISTORY_INCOSISTENT_CODE, ErrorConstants.HRMS_UPDATE_SERVICE_HISTORY_INCOSISTENT_MSG); + } + + } + + } + + /** + * Documents once created in the system cannot be deleted, they can however be changed. Validates that condition + * + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + */ + private void validateConsistencyEmployeeDocument(Employee existingEmp, Employee updatedEmployeeData, Map errorMap){ + if(!CollectionUtils.isEmpty(updatedEmployeeData.getDocuments())){ + boolean check = + updatedEmployeeData.getDocuments().stream() + .map(employeeDocument -> employeeDocument.getId()) + .collect(Collectors.toList()) + .containsAll(existingEmp.getDocuments().stream() + .map(employeeDocument -> employeeDocument.getId()) + .collect(Collectors.toList())); + if (!check) { + errorMap.put(ErrorConstants.HRMS_UPDATE_DOCUMENT_INCOSISTENT_CODE, ErrorConstants.HRMS_UPDATE_DOCUMENT_INCOSISTENT_MSG); + } + } + + } + + /** + * Deactivation Details once created in the system cannot be deleted, they can however be changed. Validates that condition + * + * @param existingEmp + * @param updatedEmployeeData + * @param errorMap + */ + private void validateConsistencyDeactivationDetails(Employee existingEmp, Employee updatedEmployeeData, Map errorMap){ + if(!CollectionUtils.isEmpty(updatedEmployeeData.getDeactivationDetails())){ + boolean check = + updatedEmployeeData.getDeactivationDetails().stream() + .map(deactivationDetails -> deactivationDetails.getId()) + .collect(Collectors.toList()) + .containsAll(existingEmp.getDeactivationDetails().stream() + .map(employeeDocument -> employeeDocument.getId()) + .collect(Collectors.toList())); + if (!check) { + errorMap.put(ErrorConstants.HRMS_UPDATE_DEACT_DETAILS_INCOSISTENT_CODE, ErrorConstants.HRMS_UPDATE_DEACT_DETAILS_INCOSISTENT_MSG); + } + } + + } + + public void validateEmployeeCountRequest(String tenantId){ + Map errorMap = new HashMap<>(); + if(StringUtils.isEmpty(tenantId)) + errorMap.put(ErrorConstants.HRMS_EMPLOYEE_COUNT_ERROR_CODE, ErrorConstants.HRMS_EMPLOYEE_COUNT_ERROR_MSG); + + if(!CollectionUtils.isEmpty(errorMap.keySet())) { + throw new CustomException(errorMap); + } + } + +} diff --git a/core-services/egov-hrms/src/main/resources/application.properties b/core-services/egov-hrms/src/main/resources/application.properties new file mode 100644 index 00000000000..ece32eba711 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/application.properties @@ -0,0 +1,118 @@ +#---------------------------- DATABASE CONFIGURATIONS -----------------------------# +spring.datasource.driver-class-name=org.postgresql.Driver +spring.datasource.url=jdbc:postgresql://localhost:5432/egov_hrms +spring.datasource.username=postgres +spring.datasource.password=postgres + +#----------------------------- FLYWAY CONFIGURATIONS ------------------------------# +spring.flyway.url=jdbc:postgresql://localhost:5432/egov_hrms +spring.flyway.user=postgres +spring.flyway.password=postgres +#spring.flyway.table=hr_employee_schema_version +spring.flyway.baseline-on-migrate=true +spring.flyway.outOfOrder=true +spring.flyway.locations=classpath:/db/migration/main,db/migration/seed +spring.flyway.enabled=true + +#--------------------------- PATH & PORT CONFIGURATIONS ---------------------------# +server.contextPath=/egov-hrms +server.servlet.context-path=/egov-hrms +server.port=9999 + +#---------------------------- TIMEZONE CONFIGURATIONS -----------------------------# +app.timezone=UTC + +#-------------------------- EXTERNAL API CONFIGURATIONS ---------------------------# + + +egov.services.data_sync_employee.required = false + + +#mdms urls +egov.mdms.host=https://dev.digit.org +egov.mdms.search.endpoint=/egov-mdms-service/v1/_search +#egov.mdms.search.endpoint=/egov-mdms-service-test/v1/_search + +#filestore urls +egov.filestore.host=https://dev.digit.org +egov.filestore.url.endpoint=/filestore/v1/files/url + +#localization urls +egov.localization.host=https://dev.digit.org +egov.localization.search.endpoint=/localization/messages/v1/_search + +#egov-otp urls +egov.otp.host=http://egov-otp.egov:8080/ +egov.otp.create.endpoint=otp/v1/_create + +egov.environment.domain=https://dev.digit.org/ + +#user +egov.user.host=https://dev.digit.org +egov.user.search.endpoint=/user/v1/_search +egov.user.create.endpoint=/user/users/_createnovalidate +egov.user.update.endpoint=/user/users/_updatenovalidate + +#idgen configs +#egov.idgen.host=http://egov-idgen:8080/ +egov.idgen.host=https://dev.digit.org/ +egov.idgen.path=egov-idgen/id/_generate +egov.idgen.ack.name=hrms.employeecode +egov.idgen.ack.format=EMP-[city]-[SEQ_EG_HRMS_EMP_CODE] + + +egov.individual.host=https://health-dev.digit.org +egov.individual.create.endpoint=/individual/v1/_create +egov.individual.update.endpoint=/individual/v1/_update +egov.individual.search.endpoint=/individual/v1/_search + +# use qualifier as "defaultUserService" to integrate with egov-user module +# use qualifier as "individualService" to integrate with individual module +egov.hrms.user.service.qualifier=individualService + + +#user +egov.hrms.employee.app.link=https://mseva.lgpunjab.gov.in/employee/user/login + + +#CONFIGS +egov.hrms.default.pagination.limit=200 +egov.hrms.default.pwd.length=8 +open.search.enabled.roles=SUPERUSER +egov.pwd.allowed.special.characters=@#$% +parent.level.tenant.id=pb +decryption.abac.enable=false + +#------------------------------ KAFKA CONFIGURATIONS ------------------------------# +# KAFKA SERVER CONFIGURATIONS +spring.kafka.bootstrap.servers=localhost:9092 +spring.kafka.consumer.properties.spring.json.use.type.headers=false + +# SPRING KAFKA CONSUMER CONFIGURATIONS +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=employee-group1 + +# SPRING KAFKA PRODUCER CONFIGURATIONS +spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer +spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer + +# KAFKA TOPIC CONFIGURATIONS +kafka.topics.save.service=save-hrms-employee +kafka.topics.update.service=update-hrms-employee +kafka.topics.notification.sms=egov.core.notification.sms +kafka.topics.hrms.updateData= egov-hrms-update + +spring.kafka.listener.missing-topics-fatal=false + +#------------------------------ TRACER CONFIGURATIONS -----------------------------# +# tracer.detailed.tracing.enabled=false + +#------------------------------ LOGGER CONFIGURATIONS -----------------------------# +logging.pattern.console=%clr(%X{CORRELATION_ID:-}) %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + +log4j.logger.org.springframework.jdbc.core = TRACE + +state.level.tenant.id=default + +egov.hrms.auto.generate.password=true \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/config/application-config.properties b/core-services/egov-hrms/src/main/resources/config/application-config.properties new file mode 100644 index 00000000000..8ade6ea4997 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/config/application-config.properties @@ -0,0 +1,17 @@ +#----------------------- DEFAULT PAGINATION CONFIGURATIONS ------------------------# +egov.services.emp.search.pagesize.default=200 +egov.services.emp.search.pageno.max=50 +egov.services.emp.search.pagesize.max=500 + + +#------------------------- CODE & SEQUENCE CONFIGURATIONS -------------------------# + +# Already configured in ApplicationConfiguration file but right now not being used. Instead using enum. +egov.services.emp.seq.assignment=seq_egeis_assignment +egov.services.emp.seq.departmentaltest=seq_egeis_departmentaltest +egov.services.emp.seq.educationalqualification=seq_egeis_educationalqualification +egov.services.emp.seq.hoddepartment=seq_egeis_hoddepartment +egov.services.emp.seq.probation=seq_egeis_probation +egov.services.emp.seq.regularisation=seq_egeis_regularisation +egov.services.emp.seq.servicehistory=seq_egeis_servicehistory +egov.services.emp.seq.technicalqualification=seq_egeis_technicalqualification diff --git a/core-services/egov-hrms/src/main/resources/config/hrm-employee-update-persister.yml b/core-services/egov-hrms/src/main/resources/config/hrm-employee-update-persister.yml new file mode 100644 index 00000000000..1f57cc0719c --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/config/hrm-employee-update-persister.yml @@ -0,0 +1,265 @@ +serviceMaps: + serviceName: HRMS + mappings: + - version: 1.0 + name: hrms + description: Persists employee details in the table + fromTopic: update-hrms-employee + isTransaction: true + queryMaps: + + - query: DELETE from eg_hrms_employee WHERE uuid=? on + + basePath: Employees.* + jsonMaps: + + -jsonPath: $.Employees.*.uuid + + + + - query: INSERT INTO eg_hrms_employee(tenantid, id, uuid, code, phone, name, dateOfAppointment, employeestatus, employeetype, active, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.* + jsonMaps: + + + - jsonPath: $.Employees.*.tenantId + + - jsonPath: $.Employees.*.id + + - jsonPath: $.Employees.*.uuid + + - jsonPath: $.Employees.*.code + + - jsonPath: $.Employees.*.user.mobileNumber + + - jsonPath: $.Employees.*.user.name + + - jsonPath: $.Employees.*.dateOfAppointment + + - jsonPath: $.Employees.*.employeeStatus + + - jsonPath: $.Employees.*.employeeType + + - jsonPath: $.Employees.*.active + + - jsonPath: $.Employees.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.auditDetails.lastModifiedDate + + + + - query: INSERT INTO eg_hrms_assignment(tenantid, uuid, position, department, designation, fromdate, todate, govtordernumber, reportingto, isHOD, employeeid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.assignments.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.assignments[*].id)].tenantId + + - jsonPath: $.Employees.*.assignments.*.id + + - jsonPath: $.Employees.*.assignments.*.position + + - jsonPath: $.Employees.*.assignments.*.department + + - jsonPath: $.Employees.*.assignments.*.designation + + - jsonPath: $.Employees.*.assignments.*.fromDate + + - jsonPath: $.Employees.*.assignments.*.toDate + + - jsonPath: $.Employees.*.assignments.*.govtOrderNumber + + - jsonPath: $.Employees.*.assignments.*.reportingTo + + - jsonPath: $.Employees.*.assignments.*.isHOD + + - jsonPath: $.Employees[*][?({id} in @.assignments[*].id)].uuid + + - jsonPath: $.Employees.*.assignments.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.assignments.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.assignments.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.assignments.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_educationaldetails(tenantid, uuid, employeeid, qualification, stream, yearofpassing, university, remarks, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.education.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.education[*].id)].tenantId + + - jsonPath: $.Employees.*.education.*.id + + - jsonPath: $.Employees[*][?({id} in @.education[*].id)].uuid + + - jsonPath: $.Employees.*.education.*.qualification + + - jsonPath: $.Employees.*.education.*.stream + + - jsonPath: $.Employees.*.education.*.yearOfPassing + + - jsonPath: $.Employees.*.education.*.university + + - jsonPath: $.Employees.*.education.*.remarks + + - jsonPath: $.Employees.*.education.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.education.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.education.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.education.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_departmentaltests(tenantid, uuid, employeeid, test, yearofpassing, remarks, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.tests.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.tests[*].id)].tenantId + + - jsonPath: $.Employees.*.tests.*.id + + - jsonPath: $.Employees[*][?({id} in @.tests[*].id)].uuid + + - jsonPath: $.Employees.*.tests.*.test + + - jsonPath: $.Employees.*.tests.*.yearOfPassing + + - jsonPath: $.Employees.*.tests.*.remarks + + - jsonPath: $.Employees.*.tests.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.tests.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.tests.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.tests.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_empdocuments(tenantid, uuid, employeeid, documentid, documentname, referencetype, referenceid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.documents.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.documents[*].id)].tenantId + + - jsonPath: $.Employees.*.documents.*.id + + - jsonPath: $.Employees[*][?({id} in @.documents[*].id)].uuid + + - jsonPath: $.Employees.*.documents.*.documentId + + - jsonPath: $.Employees.*.documents.*.documentName + + - jsonPath: $.Employees.*.documents.*.referenceType + + - jsonPath: $.Employees.*.documents.*.referenceId + + - jsonPath: $.Employees.*.documents.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.documents.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.documents.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.documents.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_servicehistory(tenantid, uuid, employeeid, servicestatus, servicefrom, serviceto, ordernumber, isCurrentPosition, location, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.serviceHistory.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.serviceHistory[*].id)].tenantId + + - jsonPath: $.Employees.*.serviceHistory.*.id + + - jsonPath: $.Employees[*][?({id} in @.serviceHistory[*].id)].uuid + + - jsonPath: $.Employees.*.serviceHistory.*.serviceStatus + + - jsonPath: $.Employees.*.serviceHistory.*.serviceFrom + + - jsonPath: $.Employees.*.serviceHistory.*.serviceTo + + - jsonPath: $.Employees.*.serviceHistory.*.orderNo + + - jsonPath: $.Employees.*.serviceHistory.*.isCurrentPosition + + - jsonPath: $.Employees.*.serviceHistory.*.location + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.lastModifiedDate + + -query: INSERT INTO eg_hrms_jurisdiction (uuid, employeeid, hierarchy, boundarytype, boundary, tenantid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.jurisdictions.* + jsonMaps: + + - jsonPath: $.Employees.*.jurisdictions.*.id + + - jsonPath: $.Employees[*][?({id} in @.jurisdictions[*].id)].uuid + + - jsonPath: $.Employees.*.jurisdictions.*.hierarchy + + - jsonPath: $.Employees.*.jurisdictions.*.boundaryType + + - jsonPath: $.Employees.*.jurisdictions.*.boundary + + - jsonPath: $.Employees[*][?({id} in @.jurisdictions[*].id)].tenantId + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.lastModifiedDate + + + + - query: INSERT INTO eg_hrms_deactivationdetails(uuid, employeeid, reasonfordeactivation, effectivefrom, ordernumber, typeOfDeactivation, tenantid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.deactivationDetails.* + jsonMaps: + + - jsonPath: $.Employees.*.deactivationDetails.*.id + + - jsonPath: $.Employees[*][?({id} in @.deactivationDetails[*].id)].uuid + + - jsonPath: $.Employees.*.deactivationDetails.*.reasonForDeactivation + + - jsonPath: $.Employees.*.deactivationDetails.*.effectiveFrom + + - jsonPath: $.Employees.*.deactivationDetails.*.orderNo + + - jsonPath: $.Employees.*.deactivationDetails.*.typeOfDeactivation + + - jsonPath: $.Employees[*][?({id} in @.deactivationDetails[*].id)].tenantId + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.lastModifiedDate + diff --git a/core-services/egov-hrms/src/main/resources/config/hrms-employee-persister.yml b/core-services/egov-hrms/src/main/resources/config/hrms-employee-persister.yml new file mode 100644 index 00000000000..74dbd1940ef --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/config/hrms-employee-persister.yml @@ -0,0 +1,501 @@ +serviceMaps: + serviceName: HRMS + mappings: + - version: 1.0 + name: hrms + description: Persists employee details in the table + fromTopic: save-hrms-employee + isTransaction: true + queryMaps: + - query: INSERT INTO eg_hrms_employee(tenantid, id, uuid, code, dateOfAppointment, employeestatus, employeetype, active, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.* + jsonMaps: + + + - jsonPath: $.Employees.*.tenantId + + - jsonPath: $.Employees.*.id + + - jsonPath: $.Employees.*.uuid + + - jsonPath: $.Employees.*.code + + - jsonPath: $.Employees.*.dateOfAppointment + + - jsonPath: $.Employees.*.employeeStatus + + - jsonPath: $.Employees.*.employeeType + + - jsonPath: $.Employees.*.isActive + + - jsonPath: $.Employees.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.auditDetails.lastModifiedDate + + + + - query: INSERT INTO eg_hrms_assignment(tenantid, uuid, position, department, designation, fromdate, todate, govtordernumber, reportingto, isHOD, iscurrentassignment, employeeid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.assignments.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.assignments[*].id)].tenantId + + - jsonPath: $.Employees.*.assignments.*.id + + - jsonPath: $.Employees.*.assignments.*.position + + - jsonPath: $.Employees.*.assignments.*.department + + - jsonPath: $.Employees.*.assignments.*.designation + + - jsonPath: $.Employees.*.assignments.*.fromDate + + - jsonPath: $.Employees.*.assignments.*.toDate + + - jsonPath: $.Employees.*.assignments.*.govtOrderNumber + + - jsonPath: $.Employees.*.assignments.*.reportingTo + + - jsonPath: $.Employees.*.assignments.*.isHOD + + - jsonPath: $.Employees.*.assignments.*.isCurrentAssignment + + - jsonPath: $.Employees[*][?({id} in @.assignments[*].id)].uuid + + - jsonPath: $.Employees.*.assignments.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.assignments.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.assignments.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.assignments.*.auditDetails.lastModifiedDate + + + + + - query: INSERT INTO eg_hrms_educationaldetails(tenantid, uuid, employeeid, qualification, stream, yearofpassing, university, remarks, isactive, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.education.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.education[*].id)].tenantId + + - jsonPath: $.Employees.*.education.*.id + + - jsonPath: $.Employees[*][?({id} in @.education[*].id)].uuid + + - jsonPath: $.Employees.*.education.*.qualification + + - jsonPath: $.Employees.*.education.*.stream + + - jsonPath: $.Employees.*.education.*.yearOfPassing + + - jsonPath: $.Employees.*.education.*.university + + - jsonPath: $.Employees.*.education.*.remarks + + - jsonPath: $.Employees.*.education.*.isActive + + - jsonPath: $.Employees.*.education.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.education.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.education.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.education.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_departmentaltests(tenantid, uuid, employeeid, test, yearofpassing, remarks, isactive, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.tests.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.tests[*].id)].tenantId + + - jsonPath: $.Employees.*.tests.*.id + + - jsonPath: $.Employees[*][?({id} in @.tests[*].id)].uuid + + - jsonPath: $.Employees.*.tests.*.test + + - jsonPath: $.Employees.*.tests.*.yearOfPassing + + - jsonPath: $.Employees.*.tests.*.remarks + + - jsonPath: $.Employees.*.tests.*.isActive + + - jsonPath: $.Employees.*.tests.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.tests.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.tests.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.tests.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_empdocuments(tenantid, uuid, employeeid, documentid, documentname, referencetype, referenceid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.documents.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.documents[*].id)].tenantId + + - jsonPath: $.Employees.*.documents.*.id + + - jsonPath: $.Employees[*][?({id} in @.documents[*].id)].uuid + + - jsonPath: $.Employees.*.documents.*.documentId + + - jsonPath: $.Employees.*.documents.*.documentName + + - jsonPath: $.Employees.*.documents.*.referenceType + + - jsonPath: $.Employees.*.documents.*.referenceId + + - jsonPath: $.Employees.*.documents.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.documents.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.documents.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.documents.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_servicehistory(tenantid, uuid, employeeid, servicestatus, servicefrom, serviceto, ordernumber, isCurrentPosition, location, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.serviceHistory.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.serviceHistory[*].id)].tenantId + + - jsonPath: $.Employees.*.serviceHistory.*.id + + - jsonPath: $.Employees[*][?({id} in @.serviceHistory[*].id)].uuid + + - jsonPath: $.Employees.*.serviceHistory.*.serviceStatus + + - jsonPath: $.Employees.*.serviceHistory.*.serviceFrom + + - jsonPath: $.Employees.*.serviceHistory.*.serviceTo + + - jsonPath: $.Employees.*.serviceHistory.*.orderNo + + - jsonPath: $.Employees.*.serviceHistory.*.isCurrentPosition + + - jsonPath: $.Employees.*.serviceHistory.*.location + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_jurisdiction (uuid, employeeid, hierarchy, boundarytype, boundary, tenantid, isActive, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.jurisdictions.* + jsonMaps: + + - jsonPath: $.Employees.*.jurisdictions.*.id + + - jsonPath: $.Employees[*][?({id} in @.jurisdictions[*].id)].uuid + + - jsonPath: $.Employees.*.jurisdictions.*.hierarchy + + - jsonPath: $.Employees.*.jurisdictions.*.boundaryType + + - jsonPath: $.Employees.*.jurisdictions.*.boundary + + - jsonPath: $.Employees[*][?({id} in @.jurisdictions[*].id)].tenantId + + - jsonPath: $.Employees.*.jurisdictions.*.isActive + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.lastModifiedDate + + + + + - version: 1.0 + name: hrms + description: Persists employee details in the table + fromTopic: update-hrms-employee + isTransaction: true + queryMaps: + - query: DELETE from eg_hrms_employee WHERE uuid=? + + basePath: Employees.* + jsonMaps: + + - jsonPath: $.Employees.*.uuid + + - query: INSERT INTO eg_hrms_employee(tenantid, id, uuid, code, dateOfAppointment, employeestatus, employeetype, active, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.* + jsonMaps: + + + - jsonPath: $.Employees.*.tenantId + + - jsonPath: $.Employees.*.id + + - jsonPath: $.Employees.*.uuid + + - jsonPath: $.Employees.*.code + + - jsonPath: $.Employees.*.dateOfAppointment + + - jsonPath: $.Employees.*.employeeStatus + + - jsonPath: $.Employees.*.employeeType + + - jsonPath: $.Employees.*.isActive + + - jsonPath: $.Employees.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.auditDetails.lastModifiedDate + + + + - query: INSERT INTO eg_hrms_assignment(tenantid, uuid, position, department, designation, fromdate, todate, govtordernumber, reportingto, isHOD, iscurrentassignment, employeeid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.assignments.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.assignments[*].id)].tenantId + + - jsonPath: $.Employees.*.assignments.*.id + + - jsonPath: $.Employees.*.assignments.*.position + + - jsonPath: $.Employees.*.assignments.*.department + + - jsonPath: $.Employees.*.assignments.*.designation + + - jsonPath: $.Employees.*.assignments.*.fromDate + + - jsonPath: $.Employees.*.assignments.*.toDate + + - jsonPath: $.Employees.*.assignments.*.govtOrderNumber + + - jsonPath: $.Employees.*.assignments.*.reportingTo + + - jsonPath: $.Employees.*.assignments.*.isHOD + + - jsonPath: $.Employees.*.assignments.*.isCurrentAssignment + + - jsonPath: $.Employees[*][?({id} in @.assignments[*].id)].uuid + + - jsonPath: $.Employees.*.assignments.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.assignments.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.assignments.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.assignments.*.auditDetails.lastModifiedDate + + + + + - query: INSERT INTO eg_hrms_educationaldetails(tenantid, uuid, employeeid, qualification, stream, yearofpassing, university, remarks, isactive, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.education.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.education[*].id)].tenantId + + - jsonPath: $.Employees.*.education.*.id + + - jsonPath: $.Employees[*][?({id} in @.education[*].id)].uuid + + - jsonPath: $.Employees.*.education.*.qualification + + - jsonPath: $.Employees.*.education.*.stream + + - jsonPath: $.Employees.*.education.*.yearOfPassing + + - jsonPath: $.Employees.*.education.*.university + + - jsonPath: $.Employees.*.education.*.remarks + + - jsonPath: $.Employees.*.education.*.isActive + + - jsonPath: $.Employees.*.education.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.education.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.education.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.education.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_departmentaltests(tenantid, uuid, employeeid, test, yearofpassing, remarks, isactive, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.tests.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.tests[*].id)].tenantId + + - jsonPath: $.Employees.*.tests.*.id + + - jsonPath: $.Employees[*][?({id} in @.tests[*].id)].uuid + + - jsonPath: $.Employees.*.tests.*.test + + - jsonPath: $.Employees.*.tests.*.yearOfPassing + + - jsonPath: $.Employees.*.tests.*.remarks + + - jsonPath: $.Employees.*.tests.*.isActive + + - jsonPath: $.Employees.*.tests.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.tests.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.tests.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.tests.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_empdocuments(tenantid, uuid, employeeid, documentid, documentname, referencetype, referenceid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.documents.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.documents[*].id)].tenantId + + - jsonPath: $.Employees.*.documents.*.id + + - jsonPath: $.Employees[*][?({id} in @.documents[*].id)].uuid + + - jsonPath: $.Employees.*.documents.*.documentId + + - jsonPath: $.Employees.*.documents.*.documentName + + - jsonPath: $.Employees.*.documents.*.referenceType + + - jsonPath: $.Employees.*.documents.*.referenceId + + - jsonPath: $.Employees.*.documents.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.documents.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.documents.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.documents.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_servicehistory(tenantid, uuid, employeeid, servicestatus, servicefrom, serviceto, ordernumber, isCurrentPosition, location, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.serviceHistory.* + jsonMaps: + + + - jsonPath: $.Employees[*][?({id} in @.serviceHistory[*].id)].tenantId + + - jsonPath: $.Employees.*.serviceHistory.*.id + + - jsonPath: $.Employees[*][?({id} in @.serviceHistory[*].id)].uuid + + - jsonPath: $.Employees.*.serviceHistory.*.serviceStatus + + - jsonPath: $.Employees.*.serviceHistory.*.serviceFrom + + - jsonPath: $.Employees.*.serviceHistory.*.serviceTo + + - jsonPath: $.Employees.*.serviceHistory.*.orderNo + + - jsonPath: $.Employees.*.serviceHistory.*.isCurrentPosition + + - jsonPath: $.Employees.*.serviceHistory.*.location + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.serviceHistory.*.auditDetails.lastModifiedDate + + + - query: INSERT INTO eg_hrms_jurisdiction (uuid, employeeid, hierarchy, boundarytype, boundary, tenantid, isActive, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.jurisdictions.* + jsonMaps: + + - jsonPath: $.Employees.*.jurisdictions.*.id + + - jsonPath: $.Employees[*][?({id} in @.jurisdictions[*].id)].uuid + + - jsonPath: $.Employees.*.jurisdictions.*.hierarchy + + - jsonPath: $.Employees.*.jurisdictions.*.boundaryType + + - jsonPath: $.Employees.*.jurisdictions.*.boundary + + - jsonPath: $.Employees[*][?({id} in @.jurisdictions[*].id)].tenantId + + - jsonPath: $.Employees.*.jurisdictions.*.isActive + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.jurisdictions.*.auditDetails.lastModifiedDate + + + + - query: INSERT INTO eg_hrms_deactivationdetails(uuid, employeeid, reasonfordeactivation, effectivefrom, ordernumber, remarks, tenantid, createdby, createddate, lastmodifiedby, lastModifiedDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + + basePath: Employees.*.deactivationDetails.* + jsonMaps: + + - jsonPath: $.Employees.*.deactivationDetails.*.id + + - jsonPath: $.Employees[*][?({id} in @.deactivationDetails[*].id)].uuid + + - jsonPath: $.Employees.*.deactivationDetails.*.reasonForDeactivation + + - jsonPath: $.Employees.*.deactivationDetails.*.effectiveFrom + + - jsonPath: $.Employees.*.deactivationDetails.*.orderNo + + - jsonPath: $.Employees.*.deactivationDetails.*.remarks + + - jsonPath: $.Employees[*][?({id} in @.deactivationDetails[*].id)].tenantId + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.createdBy + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.createdDate + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.lastModifiedBy + + - jsonPath: $.Employees.*.deactivationDetails.*.auditDetails.lastModifiedDate diff --git a/core-services/egov-hrms/src/main/resources/db/Dockerfile b/core-services/egov-hrms/src/main/resources/db/Dockerfile new file mode 100644 index 00000000000..a5699ff7d99 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/Dockerfile @@ -0,0 +1,9 @@ +FROM egovio/flyway:4.1.2 + +COPY ./migration/main /flyway/sql + +COPY migrate.sh /usr/bin/migrate.sh + +RUN chmod +x /usr/bin/migrate.sh + +CMD ["/usr/bin/migrate.sh"] diff --git a/core-services/egov-hrms/src/main/resources/db/migrate.sh b/core-services/egov-hrms/src/main/resources/db/migrate.sh new file mode 100644 index 00000000000..43960b25cdb --- /dev/null +++ b/core-services/egov-hrms/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 -ignoreMissingMigrations=true migrate \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190122152236__create_hrms_employee_table_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190122152236__create_hrms_employee_table_ddl.sql new file mode 100644 index 00000000000..ea38846f3b3 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190122152236__create_hrms_employee_table_ddl.sql @@ -0,0 +1,159 @@ +CREATE TABLE eg_hrms_employee ( + id BIGINT NOT NULL, + uuid CHARACTER VARYING(1024) NOT NULL, + code CHARACTER VARYING(250), + phone CHARACTER VARYING(250), + name CHARACTER VARYING(250), + dateOfAppointment BIGINT, + employeestatus CHARACTER VARYING(250), + employeetype CHARACTER VARYING(250), + active BOOLEAN, + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_employee PRIMARY KEY (uuid), + CONSTRAINT uk_eghrms_employee_code UNIQUE (code) +); + + + +CREATE TABLE eg_hrms_assignment ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + position BIGINT, + department CHARACTER VARYING(250), + designation CHARACTER VARYING(250), + fromdate BIGINT, + todate BIGINT, + govtordernumber CHARACTER VARYING(250), + reportingto CHARACTER VARYING(250), + isHOD BOOLEAN, + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_assignment PRIMARY KEY (uuid), + CONSTRAINT ck_eghrms_employee_fromTo CHECK (fromdate <= todate), + CONSTRAINT fk_eghrms_assignment_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + +); + + +CREATE TABLE eg_hrms_educationaldetails ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + qualification CHARACTER VARYING(250), + stream CHARACTER VARYING(250), + yearofpassing BIGINT, + university CHARACTER VARYING(250), + remarks CHARACTER VARYING(250), + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_educationaldetails PRIMARY KEY (uuid), + CONSTRAINT fk_eghrms_educationaldetails_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + +); + + +CREATE TABLE eg_hrms_departmentaltests ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + test CHARACTER VARYING(250), + yearofpassing BIGINT, + remarks CHARACTER VARYING(250), + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_departmentaltests PRIMARY KEY (uuid), + CONSTRAINT fk_eghrms_departmentaltests_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + +); + + +CREATE TABLE eg_hrms_empdocuments ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + documentid CHARACTER VARYING(250) NOT NULL, + documentname CHARACTER VARYING(250), + referencetype CHARACTER VARYING(250), + referenceid CHARACTER VARYING(250) NOT NULL, + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_empdocuments PRIMARY KEY (uuid), + CONSTRAINT fk_eghrms_empdocuments_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + +); + + +CREATE TABLE eg_hrms_servicehistory ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + servicestatus CHARACTER VARYING(250), + servicefrom BIGINT, + serviceto BIGINT, + ordernumber CHARACTER VARYING(250), + isCurrentPosition BOOLEAN, + location CHARACTER VARYING(250), + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_servicehistory PRIMARY KEY (uuid), + CONSTRAINT fk_eghrms_servicehistory_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + +); + +CREATE TABLE eg_hrms_jurisdiction ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + hierarchy CHARACTER VARYING(250) NOT NULL, + boundarytype CHARACTER VARYING(250) NOT NULL, + boundary CHARACTER VARYING(250) NOT NULL, + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_jurisdiction PRIMARY KEY (uuid), + CONSTRAINT fk_eghrms_jurisdiction_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + +); + +CREATE TABLE eg_hrms_deactivationdetails ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + reasonfordeactivation CHARACTER VARYING(250), + effectivefrom BIGINT, + ordernumber CHARACTER VARYING(250), + typeOfDeactivation CHARACTER VARYING(250), + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_deactivationdetails PRIMARY KEY (uuid), + CONSTRAINT fk_eghrms_deactivationdetails_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + +); + + diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190130120650__alter_assgnmt_add_currentassgmt_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190130120650__alter_assgnmt_add_currentassgmt_ddl.sql new file mode 100644 index 00000000000..cbf835475d0 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190130120650__alter_assgnmt_add_currentassgmt_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE eg_hrms_assignment ADD COLUMN iscurrentassignment BOOLEAN; \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204154948__create_position_sequence_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204154948__create_position_sequence_ddl.sql new file mode 100644 index 00000000000..9cd94842b9c --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204154948__create_position_sequence_ddl.sql @@ -0,0 +1 @@ +CREATE SEQUENCE EG_HRMS_POSITION; diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204163735__alter_deactivation_rename_remarks_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204163735__alter_deactivation_rename_remarks_ddl.sql new file mode 100644 index 00000000000..48fa186edf2 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204163735__alter_deactivation_rename_remarks_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE eg_hrms_deactivationdetails RENAME COLUMN typeOfDeactivation TO remarks; diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204172710__secondary_indexes_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204172710__secondary_indexes_ddl.sql new file mode 100644 index 00000000000..ad6f5458476 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190204172710__secondary_indexes_ddl.sql @@ -0,0 +1,4 @@ +CREATE INDEX code_idx ON eg_hrms_employee ("code"); +CREATE INDEX dept_idx ON eg_hrms_assignment ("department"); +CREATE INDEX posn_idx ON eg_hrms_assignment ("position"); +CREATE INDEX desg_idx ON eg_hrms_assignment ("designation"); \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190215120811__alter_uk_constraint_dml.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190215120811__alter_uk_constraint_dml.sql new file mode 100644 index 00000000000..06a6ebf8635 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190215120811__alter_uk_constraint_dml.sql @@ -0,0 +1,2 @@ +ALTER TABLE eg_hrms_employee DROP CONSTRAINT uk_eghrms_employee_code; +ALTER TABLE eg_hrms_employee ADD CONSTRAINT uk_eghrms_employee_code UNIQUE (code, tenantid); \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190219163221__alter_remove_phone_name_clm_dml.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190219163221__alter_remove_phone_name_clm_dml.sql new file mode 100644 index 00000000000..851d369e121 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190219163221__alter_remove_phone_name_clm_dml.sql @@ -0,0 +1,2 @@ +ALTER TABLE eg_hrms_employee DROP COLUMN phone; +ALTER TABLE eg_hrms_employee DROP COLUMN name; \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20190301154105__alter_add_isactive_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190301154105__alter_add_isactive_ddl.sql new file mode 100644 index 00000000000..9ddb8794f36 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20190301154105__alter_add_isactive_ddl.sql @@ -0,0 +1,6 @@ +ALTER TABLE eg_hrms_departmentaltests ADD COLUMN isActive BOOLEAN; +ALTER TABLE eg_hrms_educationaldetails ADD COLUMN isActive BOOLEAN; +ALTER TABLE eg_hrms_jurisdiction ADD COLUMN isActive BOOLEAN; +ALTER TABLE eg_hrms_assignment ADD COLUMN isActive BOOLEAN; +ALTER TABLE eg_hrms_deactivationdetails ADD COLUMN isActive BOOLEAN; +ALTER TABLE eg_hrms_servicehistory ADD COLUMN isActive BOOLEAN; \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20201005230836__eg_hrms_employee_index_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20201005230836__eg_hrms_employee_index_ddl.sql new file mode 100644 index 00000000000..b9b8017f1eb --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20201005230836__eg_hrms_employee_index_ddl.sql @@ -0,0 +1 @@ + CREATE index if not exists idx_eg_hrms_employee_tenantid ON eg_hrms_employee USING btree (tenantid); diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20201223230836__eg_hrms_employee_reactivation_details_index_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20201223230836__eg_hrms_employee_reactivation_details_index_ddl.sql new file mode 100644 index 00000000000..2c4b6633804 --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20201223230836__eg_hrms_employee_reactivation_details_index_ddl.sql @@ -0,0 +1,19 @@ + ALTER TABLE eg_hrms_employee ADD COLUMN reactivateemployee BOOLEAN; + + CREATE TABLE eg_hrms_reactivationdetails ( + uuid CHARACTER VARYING(1024) NOT NULL, + employeeid CHARACTER VARYING(1024) NOT NULL, + reasonforreactivation CHARACTER VARYING(250), + effectivefrom BIGINT, + ordernumber CHARACTER VARYING(250), + remarks CHARACTER VARYING(250), + tenantid CHARACTER VARYING(250) NOT NULL, + createdby CHARACTER VARYING(250) NOT NULL, + createddate BIGINT NOT NULL, + lastmodifiedby CHARACTER VARYING(250), + lastModifiedDate BIGINT, + + CONSTRAINT pk_eghrms_reactivationdetails PRIMARY KEY (uuid), + CONSTRAINT fk_eghrms_reactivationdetails_employeeid FOREIGN KEY (employeeid) REFERENCES eg_hrms_employee (uuid) ON DELETE CASCADE + + ); diff --git a/core-services/egov-hrms/src/main/resources/db/migration/main/V20201228172710__reactivation_indexes_ddl.sql b/core-services/egov-hrms/src/main/resources/db/migration/main/V20201228172710__reactivation_indexes_ddl.sql new file mode 100644 index 00000000000..96f05aae2ee --- /dev/null +++ b/core-services/egov-hrms/src/main/resources/db/migration/main/V20201228172710__reactivation_indexes_ddl.sql @@ -0,0 +1 @@ +CREATE INDEX reactivation_employeeid_idx ON eg_hrms_reactivationdetails ("employeeid"); \ No newline at end of file diff --git a/core-services/egov-hrms/src/main/resources/db/migration/seed/.gitkeep b/core-services/egov-hrms/src/main/resources/db/migration/seed/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/core-services/egov-hrms/src/test/resources/application.properties b/core-services/egov-hrms/src/test/resources/application.properties new file mode 100644 index 00000000000..f8216b1d92e --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/application.properties @@ -0,0 +1,108 @@ +#---------------------------- DATABASE CONFIGURATIONS -----------------------------# +spring.datasource.driver-class-name=org.postgresql.Driver +spring.datasource.url=jdbc:postgresql://localhost:5432/hr_employee_db +spring.datasource.username=postgres +spring.datasource.password=postgres + +#----------------------------- FLYWAY CONFIGURATIONS ------------------------------# +flyway.url=jdbc:postgresql://localhost:5432/hr_employee_db +flyway.user=postgres +flyway.password=postgres +flyway.table=hr_employee_schema_version +flyway.baseline-on-migrate=true +flyway.outOfOrder=true +flyway.locations=db/migration/main,db/migration/seed + +#--------------------------- PATH & PORT CONFIGURATIONS ---------------------------# +server.contextPath=/hr-employee-v2 +server.port=9999 + +#---------------------------- TIMEZONE CONFIGURATIONS -----------------------------# +app.timezone=UTC + +#-------------------------- EXTERNAL API CONFIGURATIONS ---------------------------# +egov.services.data_sync_employee.required = false + +# HR-EMPLOYEE (SELF) SERVICE PATH +egov.services.hr_employee_service.hostname=https://dev.digit.org +egov.services.hr_employee_service.basepath=/hr-employee-v2 +egov.services.hr_employee_service.employee.createpath=/employees/_create +egov.services.hr_employee_service.default.password=abcdefgh + +# USER SERVICE PATH +egov.services.users_service.hostname=https://dev.digit.org +egov.services.users_service.users.basepath=/user +egov.services.users_service.users.searchpath=/v1/_search +egov.services.users_service.users.createpath=/users/_createnovalidate +egov.services.users_service.users.updatepath=/users/_updatenovalidate + +# HR-MASTERS SERVICE PATH +egov.services.hr_masters_service.hostname=https://dev.digit.org +egov.services.hr_masters_service.basepath=/hr-masters-v2 +egov.services.hr_masters_service.positions.searchpath=/positions/_search +egov.services.hr_masters_service.designations.searchpath=/designations/_search +egov.services.hr_masters_service.hr_configurations.searchpath=/hrconfigurations/_search +egov.services.hr_masters_service.vacantpositions.searchpath=/vacantpositions/_search +egov.services.hr_masters_service.empstatus.searchpath=//hrstatuses/_search +egov.services.hr_masters_service.emptype.searchpath=/employeetypes/_search + +# HYBRID-DATA-SYNC SERVICE PATH +egov.services.data_sync_employee_service.hostname=http://dev.digit.org +egov.services.data_sync_employee_service.basepath=/data-sync-employee +egov.services.data_sync_employee_service.createpath=/datasync/_create + +# ID GENERATION SERVICE PATH +egov.services.egov_idgen.hostname=http://dev.digit.org +egov.services.egov_idgen.createpath=/egov-idgen/id/_generate +egov.services.egov_idgen.emp.code.name=employee.code +egov.services.egov_idgen.emp.code.format=EMP_[SEQ_EMPLOYEE_CODE] + +# COMMON-WORKFLOW SERVICE PATH +egov.services.common_workflows_service.hostname=http://dev.digit.org +egov.services.common_workflows_service.searchpath=/egov-common-workflows/tasks/_search + +# MDMS SERVICE PATH +egov.services.egov_mdms.hostname=https://dev.digit.org/ +egov.services.egov_mdms.searchpath=egov-mdms-service/v1/_search + +# ERP SERVICE PATH +egov.services.eis_service.hostname=http://dev.digit.org +egov.municipality.host=http://kurnool-pilot-services.egovernments.org/ +egov.services.eis_service.employeeposition.searchpath=employeepositions/_search + +#------------------------------ KAFKA CONFIGURATIONS ------------------------------# +# KAFKA SERVER CONFIGURATIONS +spring.kafka.bootstrap.servers=localhost:9092 + +# SPRING KAFKA CONSUMER CONFIGURATIONS +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=employee-group1 + +# SPRING KAFKA PRODUCER CONFIGURATIONS +spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer +spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer + +# KAFKA TOPIC CONFIGURATIONS +kafka.topics.notification.sms.name=egov.employee +kafka.topics.notification.sms.id=employee +kafka.topics.notification.sms.group=employee-group1 +kafka.topics.employee.savedb.name=egov.employee +kafka.topics.employee.savedb.key=employee-save +kafka.topics.employee.finance.name=egov.employee.finance +kafka.topics.employee.finance.key=employee-finance +kafka.topics.employee.updatedb.name=egov.employee.update +kafka.topics.nominee.savedb.name=hr-employee.nominee.save +kafka.topics.nominee.savedb.key=hr-employee.nominee.save.key +kafka.topics.nominee.updatedb.name=hr-employee.nominee.update +kafka.topics.nominee.updatedb.key=hr-employee.nominee.update.key +kafka.topics.assignment.update.name=hr-employee.assignment.update +kafka.topics.assignment.update.key=hr-employee.assignment.update.key + +#------------------------------ TRACER CONFIGURATIONS -----------------------------# +# tracer.detailed.tracing.enabled=false + +#------------------------------ LOGGER CONFIGURATIONS -----------------------------# +logging.pattern.console=%clr(%X{CORRELATION_ID:-}) %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + +log4j.logger.org.springframework.jdbc.core = TRACE \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/config/application-config.properties b/core-services/egov-hrms/src/test/resources/config/application-config.properties new file mode 100644 index 00000000000..8ade6ea4997 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/config/application-config.properties @@ -0,0 +1,17 @@ +#----------------------- DEFAULT PAGINATION CONFIGURATIONS ------------------------# +egov.services.emp.search.pagesize.default=200 +egov.services.emp.search.pageno.max=50 +egov.services.emp.search.pagesize.max=500 + + +#------------------------- CODE & SEQUENCE CONFIGURATIONS -------------------------# + +# Already configured in ApplicationConfiguration file but right now not being used. Instead using enum. +egov.services.emp.seq.assignment=seq_egeis_assignment +egov.services.emp.seq.departmentaltest=seq_egeis_departmentaltest +egov.services.emp.seq.educationalqualification=seq_egeis_educationalqualification +egov.services.emp.seq.hoddepartment=seq_egeis_hoddepartment +egov.services.emp.seq.probation=seq_egeis_probation +egov.services.emp.seq.regularisation=seq_egeis_regularisation +egov.services.emp.seq.servicehistory=seq_egeis_servicehistory +egov.services.emp.seq.technicalqualification=seq_egeis_technicalqualification diff --git a/core-services/egov-hrms/src/test/resources/db/Dockerfile b/core-services/egov-hrms/src/test/resources/db/Dockerfile new file mode 100644 index 00000000000..fcb806edf0c --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/Dockerfile @@ -0,0 +1,13 @@ +FROM egovio/flyway:4.1.2 + +COPY ./migration/main /flyway/sql + +COPY ./migration/seed /flyway/seed + +COPY ./migration/dev /flyway/dev + +COPY migrate.sh /usr/bin/migrate.sh + +RUN chmod +x /usr/bin/migrate.sh + +CMD ["/usr/bin/migrate.sh"] diff --git a/core-services/egov-hrms/src/test/resources/db/migrate.sh b/core-services/egov-hrms/src/test/resources/db/migrate.sh new file mode 100644 index 00000000000..54d07c0940a --- /dev/null +++ b/core-services/egov-hrms/src/test/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 -ignoreMissingMigrations=true migrate diff --git a/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170428152327__egeis_hremployee_sample_data_for_pgr.sql b/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170428152327__egeis_hremployee_sample_data_for_pgr.sql new file mode 100644 index 00000000000..ea1477e6cb5 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170428152327__egeis_hremployee_sample_data_for_pgr.sql @@ -0,0 +1,18 @@ +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'narasappa' and tenantid = 'default'), '658039', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'default'); +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'ramana' and tenantid = 'default'), '658040', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'default'); + +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658039' and tenantid = 'default'), +(select id from egeis_position where name = 'ENG_Assistant Engineer_1' and tenantid = 'default'), NULL, NULL, NULL, +(select id from eg_department where code = 'ADM' and tenantid = 'default'), +(select id from egeis_designation where code = 'SASST' and tenantid = 'default'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'default'); +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658040' and tenantid = 'default'), +(select id from egeis_position where name = 'Acc_Senior Account_1' and tenantid = 'default'), NULL, NULL, NULL, +(select id from eg_department where code = 'ACC' and tenantid = 'default'), +(select id from egeis_designation where code = 'AO' and tenantid = 'default'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'default'); + diff --git a/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170530010026__hr_employee_sample_data_for_panavel.sql b/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170530010026__hr_employee_sample_data_for_panavel.sql new file mode 100644 index 00000000000..0cc581ae74c --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170530010026__hr_employee_sample_data_for_panavel.sql @@ -0,0 +1,20 @@ +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'admin' and tenantid = 'panavel'), '658039', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'panavel'); + +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'ajay' and tenantid = 'panavel'), '658040', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'panavel'); + +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658039' and tenantid = 'panavel'), +(select id from egeis_position where name = 'ENG_Assistant Engineer_2' and tenantid = 'panavel'), NULL, NULL, NULL, +(select id from eg_department where code = 'ADM' and tenantid = 'panavel'), +(select id from egeis_designation where code = 'SASST' and tenantid = 'panavel'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'panavel'); +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658040' and tenantid = 'panavel'), +(select id from egeis_position where name = 'Acc_Senior Account_2' and tenantid = 'panavel'), NULL, NULL, NULL, +(select id from eg_department where code = 'ENG' and tenantid = 'panavel'), +(select id from egeis_designation where code = 'AO' and tenantid = 'panavel'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'panavel'); + + diff --git a/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170614093822__hr_employee_sample_data_for_default.sql b/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170614093822__hr_employee_sample_data_for_default.sql new file mode 100644 index 00000000000..833a0c4c030 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/dev/V20170614093822__hr_employee_sample_data_for_default.sql @@ -0,0 +1,9 @@ +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'ravi' and tenantid = 'default'), '658041', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'default'); + +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658041' and tenantid = 'default'), +(select id from egeis_position where name = 'ENG_Junior Assistant_1' and tenantid = 'default'), NULL, NULL, NULL, +(select id from eg_department where code = 'ENG' and tenantid = 'default'), +(select id from egeis_designation where code = 'JASST' and tenantid = 'default'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'default'); \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185601__hr_employee_employee.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185601__hr_employee_employee.sql new file mode 100644 index 00000000000..3d240ac08c8 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185601__hr_employee_employee.sql @@ -0,0 +1,45 @@ +CREATE TABLE egeis_employee ( + id BIGINT NOT NULL, + code CHARACTER VARYING(250), + dateOfAppointment DATE, + dateOfJoining DATE, + dateOfRetirement DATE, + employeeStatus CHARACTER VARYING(250), + recruitmentModeId BIGINT, + recruitmentTypeId BIGINT, + recruitmentQuotaId BIGINT, + retirementAge INTEGER, + dateOfResignation DATE, + dateOfTermination DATE, + employeeTypeId BIGINT, + motherTongueId BIGINT, + religionId BIGINT, + communityId BIGINT, + categoryId BIGINT, + physicallyDisabled BOOLEAN NOT NULL, + medicalReportProduced BOOLEAN NOT NULL, + maritalStatus CHARACTER VARYING(250), + passportNo CHARACTER VARYING(250) NOT NULL, + gpfNo CHARACTER VARYING(250) NOT NULL, + bankId BIGINT, + bankBranchId BIGINT, + bankAccount CHARACTER VARYING(20) NOT NULL, + groupId BIGINT, + placeOfBirth CHARACTER VARYING(200) NOT NULL, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_employee PRIMARY KEY (Id), + CONSTRAINT uk_egeis_employee_code UNIQUE (code), + CONSTRAINT ck_egeis_employee_retirementAge CHECK (retirementAge <= 100), + CONSTRAINT ck_egeis_employee_dateOfAppointment CHECK (dateOfAppointment <= dateOfJoining), + CONSTRAINT ck_egeis_employee_dateOfRetirement CHECK (dateOfRetirement >= dateOfJoining), + CONSTRAINT ck_egeis_employee_dateOfResignation CHECK (dateOfResignation >= dateOfJoining), + CONSTRAINT ck_egeis_employee_dateOfTermination CHECK (dateOfTermination >= dateOfJoining) +); + +CREATE SEQUENCE seq_egeis_employee + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185602__hr_employee_assignment.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185602__hr_employee_assignment.sql new file mode 100644 index 00000000000..8874bba64e9 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185602__hr_employee_assignment.sql @@ -0,0 +1,31 @@ +CREATE TABLE egeis_assignment ( + id BIGINT NOT NULL, + employeeId BIGINT, + positionId BIGINT NOT NULL, + fundId BIGINT, + functionaryId BIGINT, + functionId BIGINT, + departmentId BIGINT NOT NULL, + designationId BIGINT NOT NULL, + isPrimary BOOLEAN NOT NULL, + fromDate DATE NOT NULL, + toDate DATE NOT NULL, + gradeId BIGINT, + govtOrderNumber CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_assignment PRIMARY KEY (id), + CONSTRAINT fk_egeis_assignment_employeeId FOREIGN KEY (employeeId) + REFERENCES egeis_employee (id) +); + +CREATE SEQUENCE seq_egeis_assignment + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185603__hr_employee_educationalqualification.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185603__hr_employee_educationalqualification.sql new file mode 100644 index 00000000000..2628586d321 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185603__hr_employee_educationalqualification.sql @@ -0,0 +1,24 @@ +CREATE TABLE egeis_educationalQualification ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + qualification CHARACTER VARYING(250) NOT NULL, + majorSubject CHARACTER VARYING(250), + yearOfPassing INTEGER NOT NULL, + university CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_educationalQualification PRIMARY KEY (Id), + CONSTRAINT fk_egeis_educationalQualification_employeeId FOREIGN KEY (employeeId) + REFERENCES egeis_employee (id) +); + +CREATE SEQUENCE seq_egeis_educationalQualification + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185604__hr_employee_departmentaltest.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185604__hr_employee_departmentaltest.sql new file mode 100644 index 00000000000..60fbc452966 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185604__hr_employee_departmentaltest.sql @@ -0,0 +1,23 @@ +CREATE TABLE egeis_departmentalTest ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + test CHARACTER VARYING(250) NOT NULL, + yearOfPassing INTEGER NOT NULL, + remarks CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_departmentalTest PRIMARY KEY (Id), + CONSTRAINT fk_egeis_departmentalTest_employeeId FOREIGN KEY (employeeId) + REFERENCES egeis_employee (id) +); + +CREATE SEQUENCE seq_egeis_departmentalTest + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185605__hr_employee_employee_jurisdictions.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185605__hr_employee_employee_jurisdictions.sql new file mode 100644 index 00000000000..ef7e25e8fb8 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185605__hr_employee_employee_jurisdictions.sql @@ -0,0 +1,15 @@ +CREATE TABLE egeis_employeeJurisdictions ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + jurisdictionId BIGINT NOT NULL, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_employeeJurisdictions PRIMARY KEY (Id) +); + +CREATE SEQUENCE seq_egeis_employeeJurisdictions + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185606__hr_employee_hoddepartment.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185606__hr_employee_hoddepartment.sql new file mode 100644 index 00000000000..6eb5bf38ca0 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185606__hr_employee_hoddepartment.sql @@ -0,0 +1,17 @@ +CREATE TABLE egeis_hodDepartment ( + id BIGINT NOT NULL, + departmentId BIGINT NOT NULL, + assignmentId BIGINT NOT NULL, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_hodDepartment PRIMARY KEY (Id), + CONSTRAINT egeis_hodDepartment_assignmentId FOREIGN KEY (assignmentId) + REFERENCES egeis_assignment(id) +); + +CREATE SEQUENCE seq_egeis_hodDepartment + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185607__hr_employee_employee_languages.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185607__hr_employee_employee_languages.sql new file mode 100644 index 00000000000..370f6b49244 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185607__hr_employee_employee_languages.sql @@ -0,0 +1,15 @@ +CREATE TABLE egeis_employeeLanguages ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + languageId BIGINT NOT NULL, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_employee_languages PRIMARY KEY (Id) +); + +CREATE SEQUENCE seq_egeis_employeeLanguages + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185608__hr_employee_probation.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185608__hr_employee_probation.sql new file mode 100644 index 00000000000..9b5ac43cbb5 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185608__hr_employee_probation.sql @@ -0,0 +1,25 @@ +CREATE TABLE egeis_probation ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + designationId BIGINT NOT NULL, + declaredOn DATE NOT NULL, + orderNo CHARACTER VARYING(250), + orderDate DATE, + remarks CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_probation PRIMARY KEY (Id), + CONSTRAINT fk_egeis_probation_employeeId FOREIGN KEY (employeeId) + REFERENCES egeis_employee (id) +); + +CREATE SEQUENCE seq_egeis_probation + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185609__hr_employee_regularisation.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185609__hr_employee_regularisation.sql new file mode 100644 index 00000000000..04b15a7cdb8 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185609__hr_employee_regularisation.sql @@ -0,0 +1,25 @@ +CREATE TABLE egeis_regularisation ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + designationId BIGINT NOT NULL, + declaredOn DATE NOT NULL, + orderNo CHARACTER VARYING(250), + orderDate DATE NOT NULL, + remarks CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_regularisation PRIMARY KEY (Id), + CONSTRAINT fk_egeis_regularisation_employeeId FOREIGN KEY (employeeId) + REFERENCES egeis_employee (id) +); + +CREATE SEQUENCE seq_egeis_regularisation + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185610__hr_employee_servicehistory.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185610__hr_employee_servicehistory.sql new file mode 100644 index 00000000000..ed40fb8ba5a --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185610__hr_employee_servicehistory.sql @@ -0,0 +1,24 @@ +CREATE TABLE egeis_serviceHistory ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + serviceInfo CHARACTER VARYING(250) NOT NULL, + serviceFrom DATE NOT NULL, + remarks CHARACTER VARYING(250), + orderNo CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_serviceHistory PRIMARY KEY (Id), + CONSTRAINT fk_egeis_serviceHistory_employeeId FOREIGN KEY (employeeId) + REFERENCES egeis_employee (id) +); + +CREATE SEQUENCE seq_egeis_serviceHistory + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185611__hr_employee_technicalqualification.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185611__hr_employee_technicalqualification.sql new file mode 100644 index 00000000000..85a261a8551 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185611__hr_employee_technicalqualification.sql @@ -0,0 +1,24 @@ +CREATE TABLE egeis_technicalQualification ( + id BIGINT NOT NULL, + employeeID BIGINT NOT NULL, + skill CHARACTER VARYING(250) NOT NULL, + grade CHARACTER VARYING(250), + yearOfPassing INTEGER, + remarks CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_technicalQualification PRIMARY KEY (Id), + CONSTRAINT fk_egeis_technicalQualification_employeeId FOREIGN KEY (employeeId) + REFERENCES egeis_employee (id) +); + +CREATE SEQUENCE seq_egeis_technicalQualification + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185612__hr_employee_added_and_updated_foreign_key_constraints.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185612__hr_employee_added_and_updated_foreign_key_constraints.sql new file mode 100644 index 00000000000..d2674ce5141 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185612__hr_employee_added_and_updated_foreign_key_constraints.sql @@ -0,0 +1,8 @@ +ALTER TABLE egeis_employeeJurisdictions ADD CONSTRAINT fk_egeis_employeeJurisdictions_employeeId + FOREIGN KEY (employeeId) REFERENCES egeis_employee (id); + +ALTER TABLE egeis_employeeLanguages ADD CONSTRAINT fk_egeis_employeeLanguages_employeeId + FOREIGN KEY (employeeId) REFERENCES egeis_employee (id); + +ALTER TABLE egeis_hodDepartment RENAME CONSTRAINT egeis_hodDepartment_assignmentId + TO fk_egeis_hodDepartment_assignmentId; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185613__updated_null_checks_in_egeis_employee_table.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185613__updated_null_checks_in_egeis_employee_table.sql new file mode 100644 index 00000000000..4cc00f0605d --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185613__updated_null_checks_in_egeis_employee_table.sql @@ -0,0 +1,9 @@ +ALTER TABLE egeis_employee ALTER COLUMN code SET NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN employeeStatus SET NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN employeeTypeId SET NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN physicallyDisabled DROP NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN medicalReportProduced DROP NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN passportNo DROP NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN gpfNo DROP NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN bankAccount DROP NOT NULL; +ALTER TABLE egeis_employee ALTER COLUMN placeOfBirth DROP NOT NULL; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185614__updated_null_checks_in_egeis_regularisation_table.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185614__updated_null_checks_in_egeis_regularisation_table.sql new file mode 100644 index 00000000000..8c5e1be4db1 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185614__updated_null_checks_in_egeis_regularisation_table.sql @@ -0,0 +1 @@ +ALTER TABLE egeis_regularisation ALTER COLUMN orderDate DROP NOT NULL; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185615__hr_employee_employeedocuments.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185615__hr_employee_employeedocuments.sql new file mode 100644 index 00000000000..b0f7559dd17 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185615__hr_employee_employeedocuments.sql @@ -0,0 +1,18 @@ +CREATE TABLE egeis_employeeDocuments ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + document CHARACTER VARYING(1000) NOT NULL, + referenceType CHARACTER VARYING(25), + referenceId BIGINT, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_employeeDocuments PRIMARY KEY (Id), + CONSTRAINT uk_egeis_employeeDocuments_document UNIQUE (document) +); + +CREATE SEQUENCE seq_egeis_employeeDocuments + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185616__updated_unique_constraint_in_hr_employee.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185616__updated_unique_constraint_in_hr_employee.sql new file mode 100644 index 00000000000..99aa51c4de5 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185616__updated_unique_constraint_in_hr_employee.sql @@ -0,0 +1,7 @@ +TRUNCATE TABLE egeis_employee CASCADE; +TRUNCATE TABLE egeis_assignment CASCADE; + +-- EMPLOYEE TABLE CONSTRAINTS +ALTER TABLE egeis_employee ADD CONSTRAINT uk_egeis_employee_passportNo UNIQUE (passportNo); +ALTER TABLE egeis_employee ADD CONSTRAINT uk_egeis_employee_gpfNo UNIQUE (gpfNo); +ALTER TABLE egeis_employee ADD CONSTRAINT uk_egeis_employee_bankAccount UNIQUE (bankAccount); diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185617__updated_createdDate_and_lastModifiedDate_columns.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185617__updated_createdDate_and_lastModifiedDate_columns.sql new file mode 100644 index 00000000000..d16112e9c51 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185617__updated_createdDate_and_lastModifiedDate_columns.sql @@ -0,0 +1,20 @@ +ALTER TABLE egeis_assignment ALTER COLUMN createdDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (createdDate::TIMESTAMP WITHOUT TIME ZONE); +ALTER TABLE egeis_assignment ALTER COLUMN lastModifiedDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (lastModifiedDate::TIMESTAMP WITHOUT TIME ZONE); + +ALTER TABLE egeis_departmentaltest ALTER COLUMN createdDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (createdDate::TIMESTAMP WITHOUT TIME ZONE); +ALTER TABLE egeis_departmentaltest ALTER COLUMN lastModifiedDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (lastModifiedDate::TIMESTAMP WITHOUT TIME ZONE); + +ALTER TABLE egeis_educationalqualification ALTER COLUMN createdDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (createdDate::TIMESTAMP WITHOUT TIME ZONE); +ALTER TABLE egeis_educationalqualification ALTER COLUMN lastModifiedDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (lastModifiedDate::TIMESTAMP WITHOUT TIME ZONE); + +ALTER TABLE egeis_probation ALTER COLUMN createdDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (createdDate::TIMESTAMP WITHOUT TIME ZONE); +ALTER TABLE egeis_probation ALTER COLUMN lastModifiedDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (lastModifiedDate::TIMESTAMP WITHOUT TIME ZONE); + +ALTER TABLE egeis_regularisation ALTER COLUMN createdDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (createdDate::TIMESTAMP WITHOUT TIME ZONE); +ALTER TABLE egeis_regularisation ALTER COLUMN lastModifiedDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (lastModifiedDate::TIMESTAMP WITHOUT TIME ZONE); + +ALTER TABLE egeis_servicehistory ALTER COLUMN createdDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (createdDate::TIMESTAMP WITHOUT TIME ZONE); +ALTER TABLE egeis_servicehistory ALTER COLUMN lastModifiedDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (lastModifiedDate::TIMESTAMP WITHOUT TIME ZONE); + +ALTER TABLE egeis_technicalqualification ALTER COLUMN createdDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (createdDate::TIMESTAMP WITHOUT TIME ZONE); +ALTER TABLE egeis_technicalqualification ALTER COLUMN lastModifiedDate TYPE TIMESTAMP WITHOUT TIME ZONE USING (lastModifiedDate::TIMESTAMP WITHOUT TIME ZONE); diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185618__updated_combination_pk.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185618__updated_combination_pk.sql new file mode 100644 index 00000000000..efdce215e6f --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185618__updated_combination_pk.sql @@ -0,0 +1,89 @@ +---------------------------- DROP FOREIGN KEYS ---------------------------- + +ALTER TABLE egeis_assignment DROP CONSTRAINT fk_egeis_assignment_employeeid; +ALTER TABLE egeis_hoddepartment DROP CONSTRAINT fk_egeis_hoddepartment_assignmentid; +ALTER TABLE egeis_employeejurisdictions DROP CONSTRAINT fk_egeis_employeejurisdictions_employeeid; +ALTER TABLE egeis_employeelanguages DROP CONSTRAINT fk_egeis_employeelanguages_employeeid; +ALTER TABLE egeis_departmentaltest DROP CONSTRAINT fk_egeis_departmentaltest_employeeid; +ALTER TABLE egeis_educationalqualification DROP CONSTRAINT fk_egeis_educationalqualification_employeeid; +ALTER TABLE egeis_probation DROP CONSTRAINT fk_egeis_probation_employeeid; +ALTER TABLE egeis_regularisation DROP CONSTRAINT fk_egeis_regularisation_employeeid; +ALTER TABLE egeis_servicehistory DROP CONSTRAINT fk_egeis_servicehistory_employeeid; +ALTER TABLE egeis_technicalqualification DROP CONSTRAINT fk_egeis_technicalqualification_employeeid; + + +--------------------------- UPDATE PRIMARY KEYS --------------------------- + +-- EGEIS_EMPLOYEE TABLE +ALTER TABLE egeis_employee DROP CONSTRAINT uk_egeis_employee_bankaccount; +ALTER TABLE egeis_employee DROP CONSTRAINT pk_egeis_employee; +ALTER TABLE egeis_employee ADD CONSTRAINT pk_egeis_employee PRIMARY KEY (id, tenantId); + +-- EGEIS_ASSIGNMENT TABLE +ALTER TABLE egeis_assignment DROP CONSTRAINT pk_egeis_assignment; +ALTER TABLE egeis_assignment ADD CONSTRAINT pk_egeis_assignment PRIMARY KEY (id, tenantId); + +-- EGEIS_HODDEPARTMENT TABLE +ALTER TABLE egeis_hoddepartment DROP CONSTRAINT pk_egeis_hoddepartment; +ALTER TABLE egeis_hoddepartment ADD CONSTRAINT pk_egeis_hoddepartment PRIMARY KEY (id, tenantId); + +-- EGEIS_EMPLOYEEDOCUMENTS TABLE +ALTER TABLE egeis_employeedocuments DROP CONSTRAINT pk_egeis_employeedocuments; +ALTER TABLE egeis_employeedocuments ADD CONSTRAINT pk_egeis_employeedocuments PRIMARY KEY (id, tenantId); + +-- EGEIS_EMPLOYEEJURISDICTIONS TABLE +ALTER TABLE egeis_employeejurisdictions DROP CONSTRAINT pk_egeis_employeejurisdictions; +ALTER TABLE egeis_employeejurisdictions ADD CONSTRAINT pk_egeis_employeejurisdictions PRIMARY KEY (id, tenantId); + +-- EGEIS_EMPLOYEELANGUAGES TABLE +ALTER TABLE egeis_employeelanguages DROP CONSTRAINT pk_egeis_employee_languages; +ALTER TABLE egeis_employeelanguages ADD CONSTRAINT pk_egeis_employeelanguages PRIMARY KEY (id, tenantId); + +-- EGEIS_DEPARTMENTALTEST TABLE +ALTER TABLE egeis_departmentaltest DROP CONSTRAINT pk_egeis_departmentaltest; +ALTER TABLE egeis_departmentaltest ADD CONSTRAINT pk_egeis_departmentaltest PRIMARY KEY (id, tenantId); + +-- EGEIS_EDUCATIONALQUALIFICATION TABLE +ALTER TABLE egeis_educationalqualification DROP CONSTRAINT pk_egeis_educationalqualification; +ALTER TABLE egeis_educationalqualification ADD CONSTRAINT pk_egeis_educationalqualification PRIMARY KEY (id, tenantId); + +-- EGEIS_PROBATION TABLE +ALTER TABLE egeis_probation DROP CONSTRAINT pk_egeis_probation; +ALTER TABLE egeis_probation ADD CONSTRAINT pk_egeis_probation PRIMARY KEY (id, tenantId); + +-- EGEIS_REGULARISATION TABLE +ALTER TABLE egeis_regularisation DROP CONSTRAINT pk_egeis_regularisation; +ALTER TABLE egeis_regularisation ADD CONSTRAINT pk_egeis_regularisation PRIMARY KEY (id, tenantId); + +-- EGEIS_SERVICEHISTORY TABLE +ALTER TABLE egeis_servicehistory DROP CONSTRAINT pk_egeis_servicehistory; +ALTER TABLE egeis_servicehistory ADD CONSTRAINT pk_egeis_servicehistory PRIMARY KEY (id, tenantId); + +-- EGEIS_TECHNICALQUALIFICATION TABLE +ALTER TABLE egeis_technicalqualification DROP CONSTRAINT pk_egeis_technicalqualification; +ALTER TABLE egeis_technicalqualification ADD CONSTRAINT pk_egeis_technicalqualification PRIMARY KEY (id, tenantId); + + +-------------------------- RECREATE FOREIGN KEYS -------------------------- + +ALTER TABLE egeis_assignment ADD CONSTRAINT fk_egeis_assignment_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_hoddepartment ADD CONSTRAINT fk_egeis_hoddepartment_assignmentid FOREIGN KEY (assignmentid, tenantId) + REFERENCES egeis_assignment (id, tenantId); +ALTER TABLE egeis_employeejurisdictions ADD CONSTRAINT fk_egeis_employeejurisdictions_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_employeelanguages ADD CONSTRAINT fk_egeis_employeelanguages_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_departmentaltest ADD CONSTRAINT fk_egeis_departmentaltest_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_educationalqualification ADD CONSTRAINT fk_egeis_educationalqualification_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_probation ADD CONSTRAINT fk_egeis_probation_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_regularisation ADD CONSTRAINT fk_egeis_regularisation_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_servicehistory ADD CONSTRAINT fk_egeis_servicehistory_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); +ALTER TABLE egeis_technicalqualification ADD CONSTRAINT fk_egeis_technicalqualification_employeeid FOREIGN KEY (employeeid, tenantId) + REFERENCES egeis_employee (id, tenantId); + diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185619__updated_foreign_key_names.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185619__updated_foreign_key_names.sql new file mode 100644 index 00000000000..8e5fe900872 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170227185619__updated_foreign_key_names.sql @@ -0,0 +1,29 @@ +ALTER TABLE egeis_assignment + RENAME CONSTRAINT fk_egeis_assignment_employeeid TO fk_egeis_assignment_employeeid_tenantid; + +ALTER TABLE egeis_hoddepartment + RENAME CONSTRAINT fk_egeis_hoddepartment_assignmentid TO fk_egeis_hoddepartment_assignmentid_tenantid; + +ALTER TABLE egeis_employeejurisdictions + RENAME CONSTRAINT fk_egeis_employeejurisdictions_employeeid TO fk_egeis_employeejurisdictions_employeeid_tenantid; + +ALTER TABLE egeis_employeelanguages + RENAME CONSTRAINT fk_egeis_employeelanguages_employeeid TO fk_egeis_employeelanguages_employeeid_tenantid; + +ALTER TABLE egeis_departmentaltest + RENAME CONSTRAINT fk_egeis_departmentaltest_employeeid TO fk_egeis_departmentaltest_employeeid_tenantid; + +ALTER TABLE egeis_educationalqualification + RENAME CONSTRAINT fk_egeis_educationalqualification_employeeid TO fk_egeis_educationalqualification_employeeid_tenantid; + +ALTER TABLE egeis_probation + RENAME CONSTRAINT fk_egeis_probation_employeeid TO fk_egeis_probation_employeeid_tenantid; + +ALTER TABLE egeis_regularisation + RENAME CONSTRAINT fk_egeis_regularisation_employeeid TO fk_egeis_regularisation_employeeid_tenantid; + +ALTER TABLE egeis_servicehistory + RENAME CONSTRAINT fk_egeis_servicehistory_employeeid TO fk_egeis_servicehistory_employeeid_tenantid; + +ALTER TABLE egeis_technicalqualification + RENAME CONSTRAINT fk_egeis_technicalqualification_employeeid TO fk_egeis_technicalqualification_employeeid_tenantid; diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170420145502__update_combination_uk.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170420145502__update_combination_uk.sql new file mode 100644 index 00000000000..76cfc669407 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170420145502__update_combination_uk.sql @@ -0,0 +1,12 @@ +-------------------------UPDATE UNIQUE KEY CONSTRAINT------------------------ + +--EGEIS_EMPLOYEE + +ALTER TABLE egeis_employee DROP CONSTRAINT if exists uk_egeis_employee_code; +ALTER TABLE egeis_employee ADD CONSTRAINT uk_egeis_employee_code UNIQUE (code,tenantid); + +ALTER TABLE egeis_employee DROP CONSTRAINT if exists uk_egeis_employee_passportNo; +ALTER TABLE egeis_employee ADD CONSTRAINT uk_egeis_employee_passportNo UNIQUE (passportNo,tenantid); + +ALTER TABLE egeis_employee DROP CONSTRAINT if exists uk_egeis_employee_gpfNo; +ALTER TABLE egeis_employee ADD CONSTRAINT uk_egeis_employee_gpfNo UNIQUE (gpfNo,tenantid); \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170502150908__updated_employeestatus_column_datatype.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170502150908__updated_employeestatus_column_datatype.sql new file mode 100644 index 00000000000..4c856708382 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170502150908__updated_employeestatus_column_datatype.sql @@ -0,0 +1 @@ +ALTER TABLE egeis_employee ALTER COLUMN employeeStatus TYPE BIGINT USING (employeeStatus::BIGINT); diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170509104227__hr_employee_add_lastmodifieddate.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170509104227__hr_employee_add_lastmodifieddate.sql new file mode 100644 index 00000000000..03ce59abaa8 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170509104227__hr_employee_add_lastmodifieddate.sql @@ -0,0 +1,3 @@ +alter table egeis_employee add column lastmodifieddate TIMESTAMP WITHOUT TIME ZONE default now(); + +alter table egeis_employeejurisdictions add column lastmodifieddate TIMESTAMP WITHOUT TIME ZONE default now(); \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170509121707__hr_hoddepartment_add_lastmodifieddate.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170509121707__hr_hoddepartment_add_lastmodifieddate.sql new file mode 100644 index 00000000000..318e17addaa --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170509121707__hr_hoddepartment_add_lastmodifieddate.sql @@ -0,0 +1 @@ +alter table egeis_hoddepartment add column lastmodifieddate TIMESTAMP WITHOUT TIME ZONE default now(); diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170525144339__hr_employee_added_createdBy_createdDate_lastModifiedBy_lastModifiedDate_columns.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170525144339__hr_employee_added_createdBy_createdDate_lastModifiedBy_lastModifiedDate_columns.sql new file mode 100644 index 00000000000..e06605f3f10 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170525144339__hr_employee_added_createdBy_createdDate_lastModifiedBy_lastModifiedDate_columns.sql @@ -0,0 +1,7 @@ +ALTER TABLE egeis_employee DROP COLUMN IF EXISTS createdBy; +ALTER TABLE egeis_employee DROP COLUMN IF EXISTS createdDate; +ALTER TABLE egeis_employee DROP COLUMN IF EXISTS lastModifiedBy; + +ALTER TABLE egeis_employee ADD COLUMN createdBy BIGINT NOT NULL DEFAULT 1; +ALTER TABLE egeis_employee ADD COLUMN createdDate TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(); +ALTER TABLE egeis_employee ADD COLUMN lastModifiedBy BIGINT; diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170609165847__egeis_nominee_table.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170609165847__egeis_nominee_table.sql new file mode 100644 index 00000000000..ff10ad6733e --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170609165847__egeis_nominee_table.sql @@ -0,0 +1,30 @@ +CREATE TABLE egeis_nominee ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + name CHARACTER VARYING(100) NOT NULL, + gender CHARACTER VARYING(15) NOT NULL, + dateOfBirth BIGINT NOT NULL, + maritalStatus CHARACTER VARYING(15) NOT NULL, + relationship CHARACTER VARYING(20) NOT NULL, + bankId BIGINT, + bankBranchId BIGINT, + bankAccount CHARACTER VARYING(20), + nominated boolean NOT NULL, + employed boolean NOT NULL, + createdBy BIGINT NOT NULL, + createdDate BIGINT NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate BIGINT, + tenantId CHARACTER VARYING(250) NOT NULL, + + CONSTRAINT pk_egeis_nominee PRIMARY KEY (id, tenantId), + CONSTRAINT fk_egeis_nominee_employeeId FOREIGN KEY (employeeId, tenantId) + REFERENCES egeis_employee (id, tenantId) +); + +CREATE SEQUENCE seq_egeis_nominee + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170703101329__dropped_unique_document_constraint_from_egeis_employeedocuments.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170703101329__dropped_unique_document_constraint_from_egeis_employeedocuments.sql new file mode 100644 index 00000000000..f8e86ac0fbe --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170703101329__dropped_unique_document_constraint_from_egeis_employeedocuments.sql @@ -0,0 +1,2 @@ +-- Dropping since now the document attachments are already going to be UUID +ALTER TABLE egeis_employeeDocuments DROP CONSTRAINT uk_egeis_employeeDocuments_document; diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20170707184507__egeis_aprdetails_table.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170707184507__egeis_aprdetails_table.sql new file mode 100644 index 00000000000..fa3734d30bd --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20170707184507__egeis_aprdetails_table.sql @@ -0,0 +1,24 @@ +CREATE TABLE egeis_aprDetails ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + yearOfSubmission INTEGER NOT NULL, + detailsSubmitted BOOLEAN NOT NULL, + dateOfSubmission DATE, + remarks CHARACTER VARYING(1024), + createdBy BIGINT NOT NULL, + createdDate TIMESTAMP WITHOUT TIME ZONE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate TIMESTAMP WITHOUT TIME ZONE, + tenantId CHARACTER VARYING(256) NOT NULL, + + CONSTRAINT pk_egeis_aprDetails PRIMARY KEY (id, tenantId), + CONSTRAINT fk_egeis_aprDetails_employeeId FOREIGN KEY (employeeId, tenantId) + REFERENCES egeis_employee (id, tenantId) +); + +CREATE SEQUENCE seq_egeis_aprDetails + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20171023104634__hr_employee_add_ifsccode.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20171023104634__hr_employee_add_ifsccode.sql new file mode 100644 index 00000000000..668fcadfe25 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20171023104634__hr_employee_add_ifsccode.sql @@ -0,0 +1 @@ +alter table egeis_employee add column ifscCode CHARACTER VARYING(20); \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180310133312__hr_employee_disciplinary.ddl.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180310133312__hr_employee_disciplinary.ddl.sql new file mode 100644 index 00000000000..5523340f27f --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180310133312__hr_employee_disciplinary.ddl.sql @@ -0,0 +1,56 @@ + CREATE TABLE egeis_disciplinary ( + id BIGINT NOT NULL, + employeeId BIGINT NOT NULL, + gistCase CHARACTER VARYING(250) NOT NULL, + disciplinaryAuthority CHARACTER VARYING(250) NOT NULL, + orderNo CHARACTER VARYING(250) NOT NULL, + orderDate DATE NOT NULL, + memoNo CHARACTER VARYING(250) NOT NULL, + memoDate DATE NOT NULL, + memoServingDate DATE NOT NULL, + dateOfReceiptMemoDate DATE, + explanationAccepted BOOLEAN, + chargeMemoNo CHARACTER VARYING(250), + chargeMemoDate DATE, + dateOfReceiptToChargeMemoDate DATE, + accepted BOOLEAN, + dateOfAppointmentOfEnquiryOfficerDate DATE, + enquiryOfficerName CHARACTER VARYING(250), + dateOfAppointmentOfPresentingOfficer DATE , + presentingOfficerName CHARACTER VARYING(250), + findingsOfEO CHARACTER VARYING(250), + enquiryReportSubmittedDate DATE, + dateOfCommunicationOfER DATE, + dateOfSubmissionOfExplanationByCO DATE, + acceptanceOfExplanation BOOLEAN, + proposedPunishmentByDA CHARACTER VARYING(250), + showCauseNoticeNo CHARACTER VARYING(250), + showCauseNoticeDate DATE, + showCauseNoticeServingDate DATE, + explanationToShowCauseNotice CHARACTER VARYING(250), + explanationToShowCauseNoticeAccepted BOOLEAN, + punishmentAwarded CHARACTER VARYING(250) , + proceedingsNumber CHARACTER VARYING(250), + proceedingsDate DATE, + proceedingsServingDate DATE, + courtCase BOOLEAN, + courtOrderNo CHARACTER VARYING(250), + courtOrderDate DATE, + gistOfDirectionIssuedByCourt CHARACTER VARYING(250), + createdBy BIGINT NOT NULL, + createdDate DATE NOT NULL, + lastModifiedBy BIGINT, + lastModifiedDate DATE, + tenantId CHARACTER VARYING(250) NOT NULL, + CONSTRAINT pk_egeis_disciplinary PRIMARY KEY (id,tenantId), + CONSTRAINT fk_egeis_disciplinary_employeeId FOREIGN KEY (employeeId,tenantId) + REFERENCES egeis_employee (id,tenantId) +); + +CREATE SEQUENCE seq_egeis_disciplinary + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180310133625__hr_employee_disciplinary_documents.ddl.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180310133625__hr_employee_disciplinary_documents.ddl.sql new file mode 100644 index 00000000000..a561aa45ee8 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180310133625__hr_employee_disciplinary_documents.ddl.sql @@ -0,0 +1,15 @@ +CREATE TABLE egeis_disciplinaryDocuments ( + id BIGINT NOT NULL, + disciplinaryId BIGINT NOT NULL, + documentType CHARACTER VARYING(25) , + filestoreId CHARACTER VARYING NOT NULL, + tenantId CHARACTER VARYING (250) NOT NULL, + CONSTRAINT pk_egeis_disciplinaryDocuments PRIMARY KEY (id,tenantid) +); + +CREATE SEQUENCE seq_egeis_disciplinaryDocument + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180312150245__hr_employee_disciplinary_alter_add_column.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180312150245__hr_employee_disciplinary_alter_add_column.sql new file mode 100644 index 00000000000..ae5f0fd4adb --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180312150245__hr_employee_disciplinary_alter_add_column.sql @@ -0,0 +1,7 @@ +alter table egeis_disciplinary add column courtOrderType CHARACTER VARYING(250); + +alter table egeis_disciplinary add column presentingOfficerDesignation CHARACTER VARYING(250); + +alter table egeis_disciplinary add column enquiryOfficerDesignation CHARACTER VARYING(250); + +alter table egeis_disciplinary alter column memoServingDate drop NOT NULL; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180314134356__hr_employee_disciplinary_alter_length_modify.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180314134356__hr_employee_disciplinary_alter_length_modify.sql new file mode 100644 index 00000000000..c22578e6118 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180314134356__hr_employee_disciplinary_alter_length_modify.sql @@ -0,0 +1,14 @@ +ALTER TABLE egeis_disciplinary + ALTER COLUMN gistcase TYPE character varying(1000); + +ALTER TABLE egeis_disciplinary + ALTER COLUMN findingsofeo TYPE character varying(1000); + +ALTER TABLE egeis_disciplinary + ALTER COLUMN proposedpunishmentbyda TYPE character varying(1000); + +ALTER TABLE egeis_disciplinary + ALTER COLUMN explanationtoshowcausenotice TYPE character varying(1000); + +ALTER TABLE egeis_disciplinary + ALTER COLUMN gistofdirectionissuedbycourt TYPE character varying(1000); \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180315135946__hr_employee_disciplinary_alter_add_remove_columns.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180315135946__hr_employee_disciplinary_alter_add_remove_columns.sql new file mode 100644 index 00000000000..5d29e00d8d0 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180315135946__hr_employee_disciplinary_alter_add_remove_columns.sql @@ -0,0 +1,7 @@ +ALTER TABLE egeis_disciplinary DROP COLUMN orderno; + +ALTER TABLE egeis_disciplinary DROP COLUMN orderdate; + +alter table egeis_disciplinary add column punishmentimplemented BOOLEAN; + +alter table egeis_disciplinary add column enddateofpunishment DATE; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180316163101__hr_employee_servicehistory_add_column.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180316163101__hr_employee_servicehistory_add_column.sql new file mode 100644 index 00000000000..44e85f76af0 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180316163101__hr_employee_servicehistory_add_column.sql @@ -0,0 +1,8 @@ +alter table egeis_servicehistory +add column city CHARACTER VARYING(250), +add column department CHARACTER VARYING(250), +add column designation CHARACTER VARYING(250), +add column positionId BIGINT, +add column serviceTo DATE, +add column isAssignmentBased BOOLEAN NOT NULL DEFAULT false, +add column assignmentId BIGINT ; \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180416144447__hr_employee_department_alter_type.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180416144447__hr_employee_department_alter_type.sql new file mode 100644 index 00000000000..2986f83d677 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180416144447__hr_employee_department_alter_type.sql @@ -0,0 +1,3 @@ +ALTER TABLE egeis_assignment ALTER COLUMN departmentId TYPE varchar(256); + +ALTER TABLE egeis_hodDepartment ALTER COLUMN departmentId TYPE varchar(256); \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/main/V20180418144447__hr_employee_designation_alter_type.sql b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180418144447__hr_employee_designation_alter_type.sql new file mode 100644 index 00000000000..cf8dcea3f9b --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/main/V20180418144447__hr_employee_designation_alter_type.sql @@ -0,0 +1 @@ +ALTER TABLE egeis_assignment ALTER COLUMN designationid TYPE varchar(256); diff --git a/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170428152327__egeis_hremployee_sample_data_for_pgr.sql b/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170428152327__egeis_hremployee_sample_data_for_pgr.sql new file mode 100644 index 00000000000..ea1477e6cb5 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170428152327__egeis_hremployee_sample_data_for_pgr.sql @@ -0,0 +1,18 @@ +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'narasappa' and tenantid = 'default'), '658039', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'default'); +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'ramana' and tenantid = 'default'), '658040', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'default'); + +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658039' and tenantid = 'default'), +(select id from egeis_position where name = 'ENG_Assistant Engineer_1' and tenantid = 'default'), NULL, NULL, NULL, +(select id from eg_department where code = 'ADM' and tenantid = 'default'), +(select id from egeis_designation where code = 'SASST' and tenantid = 'default'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'default'); +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658040' and tenantid = 'default'), +(select id from egeis_position where name = 'Acc_Senior Account_1' and tenantid = 'default'), NULL, NULL, NULL, +(select id from eg_department where code = 'ACC' and tenantid = 'default'), +(select id from egeis_designation where code = 'AO' and tenantid = 'default'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'default'); + diff --git a/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170530010026__hr_employee_sample_data_for_panavel.sql b/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170530010026__hr_employee_sample_data_for_panavel.sql new file mode 100644 index 00000000000..0cc581ae74c --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170530010026__hr_employee_sample_data_for_panavel.sql @@ -0,0 +1,20 @@ +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'admin' and tenantid = 'panavel'), '658039', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'panavel'); + +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'ajay' and tenantid = 'panavel'), '658040', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'panavel'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'panavel'); + +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658039' and tenantid = 'panavel'), +(select id from egeis_position where name = 'ENG_Assistant Engineer_2' and tenantid = 'panavel'), NULL, NULL, NULL, +(select id from eg_department where code = 'ADM' and tenantid = 'panavel'), +(select id from egeis_designation where code = 'SASST' and tenantid = 'panavel'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'panavel'); +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658040' and tenantid = 'panavel'), +(select id from egeis_position where name = 'Acc_Senior Account_2' and tenantid = 'panavel'), NULL, NULL, NULL, +(select id from eg_department where code = 'ENG' and tenantid = 'panavel'), +(select id from egeis_designation where code = 'AO' and tenantid = 'panavel'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'panavel'); + + diff --git a/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170614093822__hr_employee_sample_data_for_default.sql b/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170614093822__hr_employee_sample_data_for_default.sql new file mode 100644 index 00000000000..833a0c4c030 --- /dev/null +++ b/core-services/egov-hrms/src/test/resources/db/migration/qa/V20170614093822__hr_employee_sample_data_for_default.sql @@ -0,0 +1,9 @@ +INSERT INTO egeis_employee (id, code, dateofappointment, dateofjoining, dateofretirement, employeestatus, recruitmentmodeid, recruitmenttypeid, recruitmentquotaid, retirementage, dateofresignation, dateoftermination, employeetypeid, mothertongueid, religionid, communityid, categoryid, physicallydisabled, medicalreportproduced, maritalstatus, passportno, gpfno, bankid, bankbranchid, bankaccount, groupid, placeofbirth, tenantid) +VALUES ((select id from eg_user where username = 'ravi' and tenantid = 'default'), '658041', NULL, NULL, NULL, (select id from egeis_hrstatus where code = 'EMPLOYED' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, +(select id from egeis_employeetype where name = 'Permanent' and tenantid = 'default'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'default'); + +INSERT INTO egeis_assignment (id, employeeid, positionid, fundid, functionaryid, functionid, departmentid, designationid, isprimary, fromdate, todate, gradeid, govtordernumber, createdby, createddate, lastmodifiedby, lastmodifieddate, tenantid) +VALUES (nextval('seq_egeis_assignment'), (select id from egeis_employee where code = '658041' and tenantid = 'default'), +(select id from egeis_position where name = 'ENG_Junior Assistant_1' and tenantid = 'default'), NULL, NULL, NULL, +(select id from eg_department where code = 'ENG' and tenantid = 'default'), +(select id from egeis_designation where code = 'JASST' and tenantid = 'default'), true, '2015-04-01', '2020-03-31', NULL, NULL, 1, now(), 1, NULL, 'default'); \ No newline at end of file diff --git a/core-services/egov-hrms/src/test/resources/db/migration/seed/.gitkeep b/core-services/egov-hrms/src/test/resources/db/migration/seed/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docs/health-api-specs/contracts/stock.yml b/docs/health-api-specs/contracts/stock.yml index d2df236940d..2ee5512df51 100644 --- a/docs/health-api-specs/contracts/stock.yml +++ b/docs/health-api-specs/contracts/stock.yml @@ -504,6 +504,7 @@ definitions: - LOST_IN_TRANSIT - DAMAGED_IN_STORAGE - DAMAGED_IN_TRANSIT + description: This field accepts values from enum and if an invalid value is provided, it will default to null. wayBillNumber: type: string minLength: 2 diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_create.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_create.puml new file mode 100644 index 00000000000..031f8b42e19 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_create.puml @@ -0,0 +1,140 @@ +@startuml +title HFReferral - Bulk Create +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/hf-referral/v1/bulk/_create +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: HFReferral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each hfReferral + alt record already exists + alt record found in cache + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 1 row + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Check if record already exists + activate db + db -> rm: 1 row + deactivate db + rm -> rc: Put data in cache using clientReferenceId/serverGeneratedId + activate rc + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + alt projectId invalid + rm -> ps: Check if projectId exists + activate ps + ps -> db: Check if projectId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectId exists + activate ps + ps -> db: Check if projectId exists + activate db + db -> ps: n row + deactivate db + ps -> rm: n row + deactivate ps + alt projectFacilityId invalid + rm -> ps: Check if projectFacilityId exists + activate ps + ps -> db: Check if projectFacilityId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectFacilityId exists + activate ps + ps -> db: Check if projectFacilityId exists + activate db + db -> ps: n row + deactivate db + ps -> rm: n row + deactivate ps + rm -> k: HFReferral Data /persist_topic + activate k + rm -> rc: Put HFReferral Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume HFReferral Data + activate prs + idx -> k: Consume HFReferral Data + activate idx + idx -> el: Store HFReferral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist HFReferral Data + activate db + deactivate db + deactivate prs + end + deactivate k +end + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_delete.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_delete.puml new file mode 100644 index 00000000000..0f8eab2fa9b --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_delete.puml @@ -0,0 +1,153 @@ +@startuml +title HFReferral - Bulk Delete +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/hf-referral/v1/bulk/_delete +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: HFReferral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each hfReferral + alt id is null + rm -> rm: Check if HFReferral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note + end + rm -> rm: Check if HFReferral id is not null + alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: HFReferral Data /error_topic + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note + end + alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc + end + rm -> rc: Fetch the existing record + activate rc + rc -> rm: 1 row + deactivate rc + alt Duplicate Entry is present [Unique entity validation failed] + rm -> rm: Check if HFReferral object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note + end + rm -> rm: Duplicate Entry is not present [Unique entity validation successful] + alt incorrect rowVersion + s -> s: Compare rowVersion between request and db + s -> s: Incorrect rowVersion [request: should be +1 only] + s -> k: HFReferral Data /error_topic + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note + end + s -> s: Compare rowVersion between request and db + s -> s: rowVersion in request = rowVersion in db + 1 + rm -> k: HFReferral Data /persist_topic + activate k + rm -> rc: Put HFReferral Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume HFReferral Data + activate prs + idx -> k: Consume HFReferral Data + activate idx + idx -> el: Store HFReferral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist HFReferral Data + activate db + deactivate db + deactivate prs + end + deactivate k +end +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_update.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_update.puml new file mode 100644 index 00000000000..693993065b6 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/bulk_update.puml @@ -0,0 +1,205 @@ +@startuml +title HFReferral - Bulk Update +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/hf-referral/v1/bulk/_update +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: HFReferral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each hfReferral + alt id is null + rm -> rm: Check if HFReferral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note + end + rm -> rm: Check if HFReferral id is not null + alt isDeleted is true + rm -> rm: Check if HFReferral object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note + end + rm -> rm: Check if HFReferral object isDeleted is not true + alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: HFReferral Data /error_topic + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note + end + alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: n row + deactivate db + rm -> rc: n record + activate rc + deactivate rc + end + rm -> rc: Fetch the existing record + activate rc + rc -> rm: n row + deactivate rc + alt projectId invalid + rm -> ps: Check if projectId exists + activate ps + ps -> db: Check if projectId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectId exists + activate ps + ps -> db: Check if projectId exists + activate db + db -> ps: n row + deactivate db + ps -> rm: n row + deactivate ps + alt projectFacilityId invalid + rm -> ps: Check if projectFacilityId exists + activate ps + ps -> db: Check if projectFacilityId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectFacilityId exists + activate ps + ps -> db: Check if projectFacilityId exists + activate db + db -> ps: n row + deactivate db + ps -> rm: n row + deactivate ps + alt Duplicate Entry is present [Unique entity validation failed] + rm -> rm: Check if HFReferral object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note + end + rm -> rm: Duplicate Entry is not present [Unique entity validation successful] + alt incorrect rowVersion + s -> s: Compare rowVersion between request and db + s -> s: Incorrect rowVersion [request: should be +1 only] + s -> k: HFReferral Data /error_topic + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note + end + s -> s: Compare rowVersion between request and db + s -> s: rowVersion in request = rowVersion in db + 1 + rm -> k: HFReferral Data /persist_topic + activate k + rm -> rc: Put HFReferral Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume HFReferral Data + activate prs + idx -> k: Consume HFReferral Data + activate idx + idx -> el: Store HFReferral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist HFReferral Data + activate db + deactivate db + deactivate prs + end + deactivate k +end +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/create.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/create.puml new file mode 100644 index 00000000000..b83117a4e43 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/create.puml @@ -0,0 +1,137 @@ +@startuml +title HFReferral - Create +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/hf-referral/v1/_create +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: HFReferral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt record already exists + alt record found in cache + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 1 row + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Check if record already exists + activate db + db -> rm: 1 row + deactivate db + rm -> rc: Put data in cache using clientReferenceId/serverGeneratedId + activate rc + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note +end +alt projectId invalid + rm -> ps: Check if projectId exists + activate ps + ps -> db: Check if projectId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectId exists +activate ps +ps -> db: Check if projectId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +alt projectFacilityId invalid + rm -> ps: Check if projectFacilityId exists + activate ps + ps -> db: Check if projectFacilityId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectFacilityId exists +activate ps +ps -> db: Check if projectFacilityId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +rm -> k: HFReferral Data /persist_topic +activate k +rm -> rc: Put HFReferral Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume HFReferral Data + activate prs + idx -> k: Consume HFReferral Data + activate idx + idx -> el: Store HFReferral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist HFReferral Data + activate db + deactivate db + deactivate prs +end +deactivate k +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/delete.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/delete.puml new file mode 100644 index 00000000000..e5d460e53b0 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/delete.puml @@ -0,0 +1,143 @@ +@startuml +title HFReferral - Delete +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/hf-referral/v1/_delete +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: HFReferral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt id is null + rm -> rm: Check if HFReferral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note +end +rm -> rm: Check if HFReferral id is not null +alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: HFReferral Data /error_topic + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note +end +alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc +end +rm -> rc: Fetch the existing record +activate rc +rc -> rm: 1 row +deactivate rc +alt incorrect rowVersion + s -> s: Compare rowVersion between request and db + s -> s: Incorrect rowVersion [request: should be +1 only] + s -> k: HFReferral Data /error_topic + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note +end +s -> s: Compare rowVersion between request and db +s -> s: rowVersion in request = rowVersion in db + 1 +rm -> k: HFReferral Data /persist_topic +activate k +rm -> rc: Put HFReferral Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume HFReferral Data + activate prs + idx -> k: Consume HFReferral Data + activate idx + idx -> el: Store HFReferral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist HFReferral Data + activate db + deactivate db + deactivate prs +end +deactivate k +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/update.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/update.puml new file mode 100644 index 00000000000..b9db19c7578 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/hfreferral/update.puml @@ -0,0 +1,196 @@ +@startuml +title HFReferral - Update +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/hf-referral/v1/_update +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: HFReferral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt id is null + rm -> rm: Check if HFReferral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note +end +rm -> rm: Check if HFReferral id is not null +alt isDeleted is true + rm -> rm: Check if HFReferral object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note +end +rm -> rm: Check if HFReferral object isDeleted is not true +alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: HFReferral Data /error_topic + activate k + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note +end +alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc +end +rm -> rc: Fetch the existing record +activate rc +rc -> rm: 1 row +deactivate rc +alt projectId invalid + rm -> ps: Check if projectId exists + activate ps + ps -> db: Check if projectId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectId exists +activate ps +ps -> db: Check if projectId exists +activate db +db -> ps: n row +deactivate db +ps -> rm: n row +deactivate ps +alt projectFacilityId invalid + rm -> ps: Check if projectFacilityId exists + activate ps + ps -> db: Check if projectFacilityId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectFacilityId exists +activate ps +ps -> db: Check if projectFacilityId exists +activate db +db -> ps: n row +deactivate db +ps -> rm: n row +deactivate ps +alt incorrect rowVersion + s -> s: Compare rowVersion between request and db + s -> s: Incorrect rowVersion [request: should be +1 only] + s -> k: HFReferral Data /error_topic + group async + es -> k: Consume HFReferral Data + activate es + deactivate k + es -> db: Persist HFReferral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note +end +s -> s: Compare rowVersion between request and db +s -> s: rowVersion in request = rowVersion in db + 1 +rm -> k: HFReferral Data /persist_topic +activate k +rm -> rc: Put HFReferral Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume HFReferral Data + activate prs + idx -> k: Consume HFReferral Data + activate idx + idx -> el: Store HFReferral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist HFReferral Data + activate db + deactivate db + deactivate prs +end +deactivate k + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_create.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_create.puml new file mode 100644 index 00000000000..ad7d70f7540 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_create.puml @@ -0,0 +1,204 @@ +@startuml +title Referral - Bulk Create +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/v1/bulk/_create +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Referral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each referral + alt record already exists + alt record found in cache + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 1 row + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Check if record already exists + activate db + db -> rm: 1 row + deactivate db + rm -> rc: Put data in cache using clientReferenceId/serverGeneratedId + activate rc + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 1 row + deactivate db + ps -> rm: 1 row + deactivate ps + alt referrerId invalid + rm -> us: Check if referrerId exists + activate us + us -> db: Check if referrerId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> us: Check if referrerId exists + activate us + us -> db: Check if referrerId exists + activate db + db -> us: 1 row + deactivate db + us -> rm: 1 row + deactivate us + alt recipientId invalid + alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + end + alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 0 rows + deactivate db + fs -> rm: 0 rows + deactivate fs + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 1 row + deactivate db + us -> rm: 1 row + deactivate us + end + alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 1 row + deactivate db + fs -> rm: 1 row + deactivate fs + end + alt sideEffectId invalid + rm -> db: Check if sideEffectId exists + activate db + db -> rm: 0 rows + deactivate db + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> db: Check if referrerId exists + activate db + db -> rm: 1 row + deactivate db + + rm -> k: Referral Data /persist_topic + activate k + rm -> rc: Put Referral Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume Referral Data + activate prs + idx -> k: Consume Referral Data + activate idx + idx -> el: Store Referral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Referral Data + activate db + deactivate db + deactivate prs + end + deactivate k +end + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_delete.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_delete.puml new file mode 100644 index 00000000000..38aae93d8b3 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_delete.puml @@ -0,0 +1,133 @@ +@startuml +title Referral - Bulk Delete +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/v1/bulk/_delete +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Referral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each referral + alt id is null + rm -> rm: Check if Referral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note + end + rm -> rm: Check if Referral id is not null + alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Referral Data /error_topic + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note + end + alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc + end + rm -> rc: Fetch the existing record + activate rc + rc -> rm: 1 row + deactivate rc + alt Duplicate Entry is present [Unique entity validation failed] + rm -> rm: Check if Side Effect object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note + end + rm -> rm: Duplicate Entry is not present [Unique entity validation successful] + rm -> k: Referral Data /persist_topic + activate k + rm -> rc: Put Referral Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume Referral Data + activate prs + idx -> k: Consume Referral Data + activate idx + idx -> el: Store Referral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Referral Data + activate db + deactivate db + deactivate prs + end + deactivate k +end +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_update.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_update.puml new file mode 100644 index 00000000000..10d2b662106 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/bulk_update.puml @@ -0,0 +1,245 @@ +@startuml +title Referral - Bulk Update +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/v1/bulk/_update +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Referral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each referral + alt id is null + rm -> rm: Check if Referral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note + end + rm -> rm: Check if Referral id is not null + alt isDeleted is true + rm -> rm: Check if Referral object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note + end + rm -> rm: Check if Referral object isDeleted is not true + alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Referral Data /error_topic + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note + end + alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc + end + rm -> rc: Fetch the existing record + activate rc + rc -> rm: 1 row + deactivate rc + alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 1 row + deactivate db + ps -> rm: 1 row + deactivate ps + alt referrerId invalid + rm -> us: Check if referrerId exists + activate us + us -> db: Check if referrerId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> us: Check if referrerId exists + activate us + us -> db: Check if referrerId exists + activate db + db -> us: 1 row + deactivate db + us -> rm: 1 row + deactivate us + alt recipientId invalid + alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + end + alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 0 rows + deactivate db + fs -> rm: 0 rows + deactivate fs + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 1 row + deactivate db + us -> rm: 1 row + deactivate us + end + alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 1 row + deactivate db + fs -> rm: 1 row + deactivate fs + end + alt sideEffectId invalid + rm -> db: Check if sideEffectId exists + activate db + db -> rm: 0 rows + deactivate db + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> db: Check if referrerId exists + activate db + db -> rm: 1 row + deactivate db + alt Duplicate Entry is present [Unique entity validation failed] + rm -> rm: Check if Side Effect object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note + end + rm -> rm: Duplicate Entry is not present [Unique entity validation successful] + rm -> k: Referral Data /persist_topic + activate k + rm -> rc: Put Referral Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume Referral Data + activate prs + idx -> k: Consume Referral Data + activate idx + idx -> el: Store Referral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Referral Data + activate db + deactivate db + deactivate prs + end + deactivate k +end +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/create.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/create.puml new file mode 100644 index 00000000000..b3437b4a49c --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/create.puml @@ -0,0 +1,201 @@ +@startuml +title Referral - Create +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/v1/_create +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Referral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt record already exists + alt record found in cache + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 1 row + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Check if record already exists + activate db + db -> rm: 1 row + deactivate db + rm -> rc: Put data in cache using clientReferenceId/serverGeneratedId + activate rc + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note +end +alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectBeneficiaryId exists +activate ps +ps -> db: Check if projectBeneficiaryId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +alt referrerId invalid + rm -> us: Check if referrerId exists + activate us + us -> db: Check if referrerId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> us: Check if referrerId exists +activate us +us -> db: Check if referrerId exists +activate db +db -> us: 1 row +deactivate db +us -> rm: 1 row +deactivate us +alt recipientId invalid + alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + end + alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 0 rows + deactivate db + fs -> rm: 0 rows + deactivate fs + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 1 row + deactivate db + us -> rm: 1 row + deactivate us +end +alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 1 row + deactivate db + fs -> rm: 1 row + deactivate fs +end +alt sideEffectId invalid + rm -> db: Check if sideEffectId exists + activate db + db -> rm: 0 rows + deactivate db + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> db: Check if referrerId exists +activate db +db -> rm: 1 row +deactivate db + +rm -> k: Referral Data /persist_topic +activate k +rm -> rc: Put Referral Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume Referral Data + activate prs + idx -> k: Consume Referral Data + activate idx + idx -> el: Store Referral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Referral Data + activate db + deactivate db + deactivate prs +end +deactivate k +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/delete.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/delete.puml new file mode 100644 index 00000000000..6e67539432a --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/delete.puml @@ -0,0 +1,124 @@ +@startuml +title Referral - Delete +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/v1/_delete +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Referral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt id is null + rm -> rm: Check if Referral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note +end +rm -> rm: Check if Referral id is not null +alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Referral Data /error_topic + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + s -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note +end +alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc +end +rm -> rc: Fetch the existing record +activate rc +rc -> rm: 1 row +deactivate rc + +rm -> k: Referral Data /persist_topic +activate k +rm -> rc: Put Referral Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume Referral Data + activate prs + idx -> k: Consume Referral Data + activate idx + idx -> el: Store Referral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Referral Data + activate db + deactivate db + deactivate prs +end +deactivate k +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/update.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/update.puml new file mode 100644 index 00000000000..e08b8b98607 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/referral/update.puml @@ -0,0 +1,237 @@ +@startuml +title Referral - Update +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant RedisCache as rc +queue Kafka as k +database Database as db +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant UserService as us +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el + +c -> rm : /referralmanagement/v1/_update +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Referral Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt id is null + rm -> rm: Check if Referral object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note +end +rm -> rm: Check if Referral id is not null +alt isDeleted is true + rm -> rm: Check if Referral object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note +end +rm -> rm: Check if Referral object isDeleted is not true +alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Referral Data /error_topic + activate k + group async + es -> k: Consume Referral Data + activate es + deactivate k + es -> db: Persist Referral Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note +end +alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc +end +rm -> rc: Fetch the existing record +activate rc +rc -> rm: 1 row +deactivate rc +alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectBeneficiaryId exists +activate ps +ps -> db: Check if projectBeneficiaryId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +alt referrerId invalid + rm -> us: Check if referrerId exists + activate us + us -> db: Check if referrerId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> us: Check if referrerId exists +activate us +us -> db: Check if referrerId exists +activate db +db -> us: 1 row +deactivate db +us -> rm: 1 row +deactivate us +alt recipientId invalid + alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 0 rows + deactivate db + us -> rm: 0 rows + deactivate us + end + alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 0 rows + deactivate db + fs -> rm: 0 rows + deactivate fs + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +alt recipientType is STAFF + rm -> us: Check if recipientId exists + activate us + us -> db: Check if recipientId exists + activate db + db -> us: 1 row + deactivate db + us -> rm: 1 row + deactivate us +end +alt recipientType is FACILITY + rm -> fs: Check if recipientId exists + activate fs + fs -> db: Check if recipientId exists + activate db + db -> fs: 1 row + deactivate db + fs -> rm: 1 row + deactivate fs +end +alt sideEffectId invalid + rm -> db: Check if sideEffectId exists + activate db + db -> rm: 0 rows + deactivate db + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> db: Check if referrerId exists +activate db +db -> rm: 1 row +deactivate db + +rm -> k: Referral Data /persist_topic +activate k +rm -> rc: Put Referral Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume Referral Data + activate prs + idx -> k: Consume Referral Data + activate idx + idx -> el: Store Referral Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Referral Data + activate db + deactivate db + deactivate prs +end +deactivate k + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_create.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_create.puml new file mode 100644 index 00000000000..9808045815c --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_create.puml @@ -0,0 +1,141 @@ +@startuml +title Side Effect - Bulk Create +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/side-effect/v1/bulk/_create +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Side Effect Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each side-effect + alt record already exists + alt record found in cache + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 1 row + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Check if record already exists + activate db + db -> rm: 1 row + deactivate db + rm -> rc: Put data in cache using clientReferenceId/serverGeneratedId + activate rc + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + alt projectTaskId invalid + rm -> ps: Check if projectTaskId exists + activate ps + ps -> db: Check if projectTaskId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note + end + rm -> ps: Check if projectTaskId exists + activate ps + ps -> db: Check if projectTaskId exists + activate db + db -> ps: 1 row + deactivate db + ps -> rm: 1 row + deactivate ps + alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 1 row + deactivate db + ps -> rm: 1 row + deactivate ps + rm -> k: Side Effect Data /persist_topic + activate k + rm -> rc: Put Side Effect Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume Side Effect Data + activate prs + idx -> k: Consume Side Effect Data + activate idx + idx -> el: Store Side Effect Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Side Effect Data + activate db + deactivate db + deactivate prs + end + deactivate k +end +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_delete.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_delete.puml new file mode 100644 index 00000000000..1d95721ab4c --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_delete.puml @@ -0,0 +1,125 @@ +@startuml +title Side Effect - Bulk Delete +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/side-effect/v1/bulk/_delete +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Side Effect Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each side-effect + alt id is null + rm -> rm: Check if Side Effect object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note + end + rm -> rm: Check if Side Effect id is not null + alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Side Effect Data /error_topic + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note + end + alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc + end + rm -> rc: Fetch the existing record + activate rc + rc -> rm: 1 row + deactivate rc + rm -> k: Side Effect Data /persist_topic + activate k + rm -> rc: Put Side Effect Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume Side Effect Data + activate prs + idx -> k: Consume Side Effect Data + activate idx + idx -> el: Store Side Effect Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Side Effect Data + activate db + deactivate db + deactivate prs + end + deactivate k +end + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_update.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_update.puml new file mode 100644 index 00000000000..85606389c27 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/bulk_update.puml @@ -0,0 +1,177 @@ +@startuml +title Side Effect - Bulk Update +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/side-effect/v1/bulk/_update +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Side Effect Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +loop for each side-effect + alt id is null + rm -> rm: Check if Side Effect object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note + end + rm -> rm: Check if Side Effect id is not null + alt isDeleted is true + rm -> rm: Check if Side Effect object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note + end + rm -> rm: Check if Side Effect object isDeleted is not true + alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Side Effect Data /error_topic + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note + end + alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc + end + rm -> rc: Fetch the existing record + activate rc + rc -> rm: 1 row + deactivate rc + alt projectTaskId invalid + rm -> ps: Check if projectTaskId exists + activate ps + ps -> db: Check if projectTaskId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note + end + rm -> ps: Check if projectTaskId exists + activate ps + ps -> db: Check if projectTaskId exists + activate db + db -> ps: 1 row + deactivate db + ps -> rm: 1 row + deactivate ps + alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note + end + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 1 row + deactivate db + ps -> rm: 1 row + deactivate ps + rm -> k: Side Effect Data /persist_topic + activate k + rm -> rc: Put Side Effect Data against clientReferenceId/serverGeneratedId in cache + activate rc + deactivate rc + group async + prs -> k: Consume Side Effect Data + activate prs + idx -> k: Consume Side Effect Data + activate idx + idx -> el: Store Side Effect Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Side Effect Data + activate db + deactivate db + deactivate prs + end + deactivate k +end + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/create.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/create.puml new file mode 100644 index 00000000000..94d0a3b95ca --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/create.puml @@ -0,0 +1,140 @@ +@startuml +title Side Effect - Create +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/side-effect/v1/_create +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Side Effect Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt record already exists + alt record found in cache + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 1 row + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note + end + rm -> rc: Check using clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Check if record already exists + activate db + db -> rm: 1 row + deactivate db + rm -> rc: Put data in cache using clientReferenceId/serverGeneratedId + activate rc + deactivate rc + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_ALREADY_EXISTS + end note +end +alt projectTaskId invalid + rm -> ps: Check if projectTaskId exists + activate ps + ps -> db: Check if projectTaskId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note +end +rm -> ps: Check if projectTaskId exists +activate ps +ps -> db: Check if projectTaskId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectBeneficiaryId exists +activate ps +ps -> db: Check if projectBeneficiaryId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +rm -> k: Side Effect Data /persist_topic +activate k +rm -> rc: Put Side Effect Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume Side Effect Data + activate prs + idx -> k: Consume Side Effect Data + activate idx + idx -> el: Store Side Effect Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Side Effect Data + activate db + deactivate db + deactivate prs +end +deactivate k + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/delete.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/delete.puml new file mode 100644 index 00000000000..77727af23d2 --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/delete.puml @@ -0,0 +1,123 @@ +@startuml +title Side Effect - Delete +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/side-effect/v1/_delete +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Side Effect Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt id is null + rm -> rm: Check if Side Effect object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note +end +rm -> rm: Check if Side Effect id is not null +alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Side Effect Data /error_topic + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note +end +alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc +end +rm -> rc: Fetch the existing record +activate rc +rc -> rm: 1 row +deactivate rc +rm -> k: Side Effect Data /persist_topic +activate k +rm -> rc: Put Side Effect Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume Side Effect Data + activate prs + idx -> k: Consume Side Effect Data + activate idx + idx -> el: Store Side Effect Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Side Effect Data + activate db + deactivate db + deactivate prs +end +deactivate k + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/update.puml b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/update.puml new file mode 100644 index 00000000000..896e5d40fbc --- /dev/null +++ b/docs/health-api-specs/sequence-diagrams/referralmanagement/side-effect/update.puml @@ -0,0 +1,175 @@ +@startuml +title Side Effect - Update +!theme vibrant +participant Client as c +participant ReferralManagement as rm +participant FacilityService as fs +participant HouseholdService as hs +participant IndividualService as inds +participant ProjectService as ps +participant RedisCache as rc +queue Kafka as k +participant PersisterService as prs +participant IndexerService as idx +participant ErrorService as es +participant ElasticSearch as el +database Database as db + +c -> rm : /referralmanagement/side-effect/v1/_update +activate rm +rm -> rm : Validate request body + +alt request validation fails + rm -> rm: Request validation failed + rm -> k: Side Effect Data /error_topic + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: REQUEST_VALIDATION_FAILED + end note +end +rm -> rm: Request validation successful +alt id is null + rm -> rm: Check if Side Effect object id is null + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: NULL_ID + end note +end +rm -> rm: Check if Side Effect id is not null +alt isDeleted is true + rm -> rm: Check if Side Effect object isDeleted is true + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: IS_DELETED_TRUE + end note +end +rm -> rm: Check if Side Effect object isDeleted is not true +alt record doesn't exist + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 0 row + deactivate db + note left + This will be marked as unrecoverable right away + and require manual intervention + end note + rm -> k: Side Effect Data /error_topic + activate k + group async + es -> k: Consume Side Effect Data + activate es + deactivate k + es -> db: Persist Side Effect Data /error_table + activate db + deactivate db + deactivate es + end + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: RECORD_NOT_FOUND + end note +end +alt record doesn't exists in cache + rm -> rc: Search record based on clientReferenceId/serverGeneratedId + activate rc + rc -> rm: 0 rows + deactivate rc + rm -> db: Search record based on clientReferenceId/serverGeneratedId + activate db + db -> rm: 1 row + deactivate db + rm -> rc: 1 record + activate rc + deactivate rc +end +rm -> rc: Fetch the existing record +activate rc +rc -> rm: 1 row +deactivate rc +alt projectTaskId invalid + rm -> ps: Check if projectTaskId exists + activate ps + ps -> db: Check if projectTaskId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: BAD_REQUEST + end note +end +rm -> ps: Check if projectTaskId exists +activate ps +ps -> db: Check if projectTaskId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +alt projectBeneficiaryId invalid + rm -> ps: Check if projectBeneficiaryId exists + activate ps + ps -> db: Check if projectBeneficiaryId exists + activate db + db -> ps: 0 rows + deactivate db + ps -> rm: 0 rows + deactivate ps + rm -> c: HttpStatus: 400 with appropriate error code + note left + Error Code: DEPENDENCY_ERROR + end note +end +rm -> ps: Check if projectBeneficiaryId exists +activate ps +ps -> db: Check if projectBeneficiaryId exists +activate db +db -> ps: 1 row +deactivate db +ps -> rm: 1 row +deactivate ps +rm -> k: Side Effect Data /persist_topic +activate k +rm -> rc: Put Side Effect Data against clientReferenceId/serverGeneratedId in cache +activate rc +deactivate rc +group async + prs -> k: Consume Side Effect Data + activate prs + idx -> k: Consume Side Effect Data + activate idx + idx -> el: Store Side Effect Data + activate el + deactivate el + deactivate idx + prs -> db: Persist Side Effect Data + activate db + deactivate db + deactivate prs +end +deactivate k + +rm -> c : HttpStatus: 202 ACCEPTED +deactivate rm + +@enduml \ No newline at end of file diff --git a/health-services/individual/CHANGELOG.md b/health-services/individual/CHANGELOG.md index 6e8364117b0..6aaf8693ede 100644 --- a/health-services/individual/CHANGELOG.md +++ b/health-services/individual/CHANGELOG.md @@ -1,5 +1,8 @@ All notable changes to this module will be documented in this file. +## 1.1.3 +- Added ability to search by user UUID for individual search. + ## 1.1.2 - upgraded version from beta diff --git a/health-services/individual/pom.xml b/health-services/individual/pom.xml index b0cd415b742..075230f0166 100644 --- a/health-services/individual/pom.xml +++ b/health-services/individual/pom.xml @@ -5,7 +5,7 @@ individual jar individual - 1.1.2 + 1.1.3 1.8 ${java.version} 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 4362e1f1811..eecf48c03d7 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 @@ -269,12 +269,21 @@ private String getQueryForIndividual(IndividualSearch searchObject, Integer limi query = query + "AND userId=:userId "; paramsMap.put("userId", String.valueOf(searchObject.getUserId())); } + + if (searchObject.getUserUuid() != null) { + query = query + "AND userUuid in (:userUuid) "; + paramsMap.put("userUuid", searchObject.getUserUuid()); + } + query = query + "ORDER BY id ASC LIMIT :limit OFFSET :offset"; paramsMap.put("tenantId", tenantId); paramsMap.put("isDeleted", includeDeleted); paramsMap.put("lastModifiedTime", lastChangedSince); paramsMap.put("limit", limit); paramsMap.put("offset", offset); + + log.info("query-------------------------->"); + log.info(query); return query; } diff --git a/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java b/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java index 397b60304ce..51dec55ace1 100644 --- a/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java +++ b/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java @@ -17,6 +17,7 @@ import javax.validation.Valid; import javax.validation.constraints.DecimalMax; import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.Size; import java.math.BigDecimal; import java.util.Date; import java.util.List; @@ -99,6 +100,11 @@ public class IndividualSearch { @JsonProperty("userId") private Long userId; + @Exclude + @JsonProperty("userUuid") + @Size(min = 1) + private List userUuid; + @Exclude @JsonProperty("latitude") @DecimalMin("-90") diff --git a/health-services/individual/src/test/java/org/egov/individual/helper/IndividualSearchTestBuilder.java b/health-services/individual/src/test/java/org/egov/individual/helper/IndividualSearchTestBuilder.java index 6db1b119462..ed10e84d6c5 100644 --- a/health-services/individual/src/test/java/org/egov/individual/helper/IndividualSearchTestBuilder.java +++ b/health-services/individual/src/test/java/org/egov/individual/helper/IndividualSearchTestBuilder.java @@ -53,7 +53,17 @@ public IndividualSearchTestBuilder byClientReferenceId(String... args) { this.builder.clientReferenceId(ids); return this; } + public IndividualSearchTestBuilder byUserUUID(String... args) { + ArrayList ids = new ArrayList<>(); + if (args != null && args.length > 0) { + ids.add(args[0]); + } else { + ids.add("some-user-uuid"); + } + this.builder.userUuid(ids); + return this; + } public IndividualSearchTestBuilder byName() { this.builder.name(Name.builder() diff --git a/health-services/individual/src/test/java/org/egov/individual/repository/IndividualRepositoryTest.java b/health-services/individual/src/test/java/org/egov/individual/repository/IndividualRepositoryTest.java index 3e73c932c08..8167285ff87 100644 --- a/health-services/individual/src/test/java/org/egov/individual/repository/IndividualRepositoryTest.java +++ b/health-services/individual/src/test/java/org/egov/individual/repository/IndividualRepositoryTest.java @@ -88,6 +88,7 @@ void shouldFindOtherParamsFromDbAndReturnAllTheDependentEntitiesAsWellIfPresent( IndividualSearch individualSearch = IndividualSearchTestBuilder.builder() .byId() .byClientReferenceId() + .byUserUUID() .byGender() .byName() .byDateOfBirth() @@ -145,6 +146,7 @@ void shouldFindOtherParamsAndIdentifierFromDbAndReturnAllTheDependentEntitiesAsW IndividualSearch individualSearch = IndividualSearchTestBuilder.builder() .byId() .byClientReferenceId() + .byUserUUID() .byGender() .byName() .byDateOfBirth() diff --git a/health-services/libraries/health-services-models/CHANGELOG.md b/health-services/libraries/health-services-models/CHANGELOG.md index 3f5b9c6ff4e..a09fe37f16c 100644 --- a/health-services/libraries/health-services-models/CHANGELOG.md +++ b/health-services/libraries/health-services-models/CHANGELOG.md @@ -1,5 +1,13 @@ All notable changes to this module will be documented in this file. + +## 1.0.19 - 2024-02-26 +- Updated project staff search to accept a list of staffIds +- Added senderId and receiverId fields to stock information. + +## 1.0.18 - 2024-02-13 +- Adding user uuid in individual search + ## 1.0.11 - 2023-11-15 - Client reference id added for member of household - revert of household search change diff --git a/health-services/libraries/health-services-models/pom.xml b/health-services/libraries/health-services-models/pom.xml index 683fa9392f1..3dafc7c24a0 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.11-SNAPSHOT + 1.0.19-SNAPSHOT 8 8 @@ -28,6 +28,11 @@ digit-models 1.0.0-SNAPSHOT + + org.egov.services + tracer + 2.1.4-SNAPSHOT + diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/validator/CustomIntegerDeserializer.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/validator/CustomIntegerDeserializer.java new file mode 100644 index 00000000000..b5cb00eac27 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/core/validator/CustomIntegerDeserializer.java @@ -0,0 +1,43 @@ +package org.egov.common.models.core.validator; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.egov.tracer.model.CustomException; + +// Custom deserializer for Integer values +public class CustomIntegerDeserializer extends StdDeserializer { + + public CustomIntegerDeserializer() { + this(null); + } + + public CustomIntegerDeserializer(Class vc) { + super(vc); + } + + @Override + public Integer deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + + // Read the JSON tree from the parser + JsonNode node = jsonParser.getCodec().readTree(jsonParser); + System.out.println(node.toString()); + if(node.asLong() > Integer.MAX_VALUE){ + throw new CustomException("INVALID_INPUT","Value must be an Integer"); + } + + // Parse the quantity as an integer + int quantity = node.asInt(); + + // Check if the parsed quantity matches the original string representation + if ((double) quantity != Double.parseDouble(node.asText())) { + throw new CustomException("INVALID_INPUT", "Quantity must be an integer"); + } + + // Return the parsed quantity + return quantity; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Field.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Field.java index e836f7dcc4b..78218ccbf63 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Field.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/facility/Field.java @@ -1,5 +1,8 @@ package org.egov.common.models.facility; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -8,9 +11,6 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - /** * Field */ @@ -30,7 +30,7 @@ public class Field { @JsonProperty("value") @NotNull - @Size(min = 2, max = 10000) + @Size(min = 1, max = 10000) private String value = null; 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 ba8246ab184..bb53d162286 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,5 +1,8 @@ package org.egov.common.models.household; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -8,9 +11,6 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - /** * Field */ @@ -22,23 +22,16 @@ @AllArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class Field { - @JsonProperty("key") - @NotNull - - - @Size(min=2,max=64) - +public class Field { + @JsonProperty("key") + @NotNull + @Size(min = 2, max = 64) private String key = null; - @JsonProperty("value") - @NotNull - - - @Size(min=2,max=10000) - + @JsonProperty("value") + @NotNull + @Size(min = 1, max = 10000) private String value = null; - } 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 62cc4f84377..b189fbe154e 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,5 +1,8 @@ package org.egov.common.models.individual; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -8,9 +11,6 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - /** * Field */ @@ -22,23 +22,16 @@ @AllArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class Field { - @JsonProperty("key") - @NotNull - - - @Size(min=2,max=64) - +public class Field { + @JsonProperty("key") + @NotNull + @Size(min = 2, max = 64) private String key = null; - @JsonProperty("value") - @NotNull - - - @Size(min=2,max=10000) - + @JsonProperty("value") + @NotNull + @Size(min = 1, max = 10000) private String value = null; - } diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualSearch.java index 7dff5b261d7..d4471a9e29e 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualSearch.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/individual/IndividualSearch.java @@ -11,6 +11,7 @@ import org.springframework.validation.annotation.Validated; import javax.validation.Valid; +import javax.validation.constraints.Size; import java.math.BigDecimal; import java.util.Date; import java.util.List; @@ -82,5 +83,9 @@ public class IndividualSearch { @JsonProperty("userId") private Long userId; + + @JsonProperty("userUuid") + @Size(min = 1) + private List userUuid; } 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 2c2f099f003..828a1cad303 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,5 +1,8 @@ package org.egov.common.models.product; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -8,9 +11,6 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - /** * Field */ @@ -22,23 +22,16 @@ @AllArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class Field { - @JsonProperty("key") - @NotNull - - - @Size(min=2,max=64) - +public class Field { + @JsonProperty("key") + @NotNull + @Size(min = 2, max = 64) private String key = null; - @JsonProperty("value") - @NotNull - - - @Size(min=2,max=10000) - + @JsonProperty("value") + @NotNull + @Size(min = 1, max = 10000) private String value = null; - } 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 33a82b187b7..c4f47fe7a7e 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,5 +1,8 @@ package org.egov.common.models.project; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -8,9 +11,6 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - /** * Field */ @@ -22,8 +22,7 @@ @AllArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class Field { - +public class Field { @JsonProperty("key") @NotNull @Size(min = 2, max = 64) @@ -31,7 +30,8 @@ public class Field { @JsonProperty("value") @NotNull - @Size(min = 2, max = 10000) + @Size(min = 1, max = 10000) private String value = null; + } diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffSearch.java index f32cc34aa7d..940ec9bfb63 100644 --- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffSearch.java +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectStaffSearch.java @@ -13,9 +13,9 @@ import java.util.List; /** -* This object defines the mapping of a system staff user to a project for a certain period. -*/ - @ApiModel(description = "This object defines the mapping of a system staff user to a project for a certain period.") + * This object defines the mapping of a system staff user to a project for a certain period. + */ +@ApiModel(description = "This object defines the mapping of a system staff user to a project for a certain period.") @Validated @javax.annotation.Generated(value = "org.egov.codegen.SpringBootCodegen", date = "2022-12-02T17:32:25.406+05:30") @@ -23,23 +23,23 @@ @NoArgsConstructor @AllArgsConstructor @Builder - @JsonIgnoreProperties(ignoreUnknown = true) -public class ProjectStaffSearch { +@JsonIgnoreProperties(ignoreUnknown = true) +public class ProjectStaffSearch { @JsonProperty("id") private List id = null; @JsonProperty("tenantId") - @Size(min=2,max=1000) + @Size(min = 2, max = 1000) private String tenantId = null; @JsonProperty("staffId") - @Size(min=2,max=64) - private String staffId = null; + @Size(min = 2, max = 64) + private List staffId = null; @JsonProperty("projectId") - @Size(min=2,max=64) + @Size(min = 2, max = 64) private String projectId = null; @JsonProperty("startDate") 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 new file mode 100644 index 00000000000..330b437df95 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferral.java @@ -0,0 +1,84 @@ +package org.egov.common.models.referralmanagement.hfreferral; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +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; +import lombok.NoArgsConstructor; +import org.egov.common.models.project.AdditionalFields; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HFReferral { + + @JsonProperty("id") + @Size(min = 2, max = 64) + private String id; + + @JsonProperty("clientReferenceId") + @Size(min = 2, max = 64) + private String clientReferenceId; + + @JsonProperty("tenantId") + @NotNull + @Size(min=2, max = 1000) + private String tenantId; + + @JsonProperty("projectId") + @Size(min = 2, max = 64) + private String projectId; + + @JsonProperty("projectFacilityId") + @Size(min = 2, max = 64) + private String projectFacilityId; + + @JsonProperty("symptom") + @NotNull + @Size(min = 2, max = 256) + private String symptom; + + @JsonProperty("symptomSurveyId") + @Size(min = 2, max = 100) + private String symptomSurveyId; + + @JsonProperty("beneficiaryId") + @Size(max=100) + private String beneficiaryId; + + @JsonProperty("referralCode") + @Size(max=100) + private String referralCode; + + @JsonProperty("nationalLevelId") + @Size(max=100) + private String nationalLevelId; + + @JsonProperty("isDeleted") + private Boolean isDeleted = Boolean.FALSE; + + @JsonProperty("rowVersion") + private Integer rowVersion; + + @JsonProperty("auditDetails") + @Valid + private AuditDetails auditDetails; + + @JsonProperty("clientAuditDetails") + @Valid + private AuditDetails clientAuditDetails; + + @JsonProperty("additionalFields") + @Valid + private AdditionalFields additionalFields; + + @JsonIgnore + private Boolean hasErrors = Boolean.FALSE; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkRequest.java new file mode 100644 index 00000000000..358cb03135c --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkRequest.java @@ -0,0 +1,46 @@ +package org.egov.common.models.referralmanagement.hfreferral; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +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 +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HFReferralBulkRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo; + + @JsonProperty("HFReferrals") + @NotNull + @Valid + @Size(min = 1) + private List hfReferrals; + + /** + * Add a HfReferral item to the list of HfReferrals in the bulk request. + * + * @param hfReferralItem The HfReferral item to add to the request. + * @return The updated HFReferralBulkRequest. + */ + public HFReferralBulkRequest addHFReferralItem(HFReferral hfReferralItem) { + if(Objects.isNull(hfReferrals)) + hfReferrals = new ArrayList<>(); + if(Objects.nonNull(hfReferralItem)) + hfReferrals.add(hfReferralItem); + 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 new file mode 100644 index 00000000000..a0f1c04b090 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralBulkResponse.java @@ -0,0 +1,44 @@ +package org.egov.common.models.referralmanagement.hfreferral; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.validation.Valid; +import javax.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.response.ResponseInfo; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HFReferralBulkResponse { + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo; + + @JsonProperty("HFReferrals") + @NotNull + @Valid + private List hfReferrals; + + /** + * Add a HfReferral item to the list of HfReferrals in the bulk response. + * + * @param hfReferralItem The HfReferral item to add to the response. + * @return The updated HFReferralBulkRequest. + */ + public HFReferralBulkResponse addReferralItem(HFReferral hfReferralItem) { + if(Objects.isNull(hfReferrals)) + hfReferrals = new ArrayList<>(); + if(Objects.nonNull(hfReferralItem)) + hfReferrals.add(hfReferralItem); + return this; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralRequest.java new file mode 100644 index 00000000000..3adc90053b6 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralRequest.java @@ -0,0 +1,27 @@ +package org.egov.common.models.referralmanagement.hfreferral; + +import javax.validation.Valid; +import javax.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.request.RequestInfo; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HFReferralRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo; + + @JsonProperty("HFReferral") + @NotNull + @Valid + private HFReferral hfReferral; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralResponse.java new file mode 100644 index 00000000000..24471207656 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralResponse.java @@ -0,0 +1,27 @@ +package org.egov.common.models.referralmanagement.hfreferral; + +import javax.validation.Valid; +import javax.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.response.ResponseInfo; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HFReferralResponse { + @JsonProperty("ResponseInfo") + @NotNull + @Valid + private ResponseInfo responseInfo; + + @JsonProperty("HFReferral") + @NotNull + @Valid + private HFReferral hfReferral; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralSearch.java new file mode 100644 index 00000000000..02dbfdf899a --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralSearch.java @@ -0,0 +1,45 @@ +package org.egov.common.models.referralmanagement.hfreferral; + +import java.util.List; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HFReferralSearch { + @JsonProperty("id") + private List id; + + @JsonProperty("clientReferenceId") + private List clientReferenceId; + + @JsonProperty("facilityId") + private List facilityId; + + @JsonProperty("projectId") + private String projectId; + + @JsonProperty("symptom") + private List symptom; + + @JsonProperty("symptomSurveyId") + private List symptomSurveyId; + + @JsonProperty("beneficiaryId") + private List beneficiaryId; + + @JsonProperty("referralCode") + private List referralCode; + + @JsonProperty("nationalLevelId") + private List nationalLevelId; +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralSearchRequest.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralSearchRequest.java new file mode 100644 index 00000000000..4784f9fbdad --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/hfreferral/HFReferralSearchRequest.java @@ -0,0 +1,26 @@ +package org.egov.common.models.referralmanagement.hfreferral; + +import javax.validation.Valid; +import javax.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.request.RequestInfo; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HFReferralSearchRequest { + @JsonProperty("RequestInfo") + @NotNull + @Valid + private RequestInfo requestInfo; + + @JsonProperty("HFReferral") + @Valid + private HFReferralSearch hfReferral; +} 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 73dab0bcb93..4994957dd27 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,5 +1,8 @@ package org.egov.common.models.stock; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; @@ -8,9 +11,6 @@ import lombok.NoArgsConstructor; import org.springframework.validation.annotation.Validated; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - /** * Field */ @@ -22,23 +22,16 @@ @AllArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class Field { - @JsonProperty("key") - @NotNull - - - @Size(min=2,max=64) - +public class Field { + @JsonProperty("key") + @NotNull + @Size(min = 2, max = 64) private String key = null; - @JsonProperty("value") - @NotNull - - - @Size(min=1,max=10000) - + @JsonProperty("value") + @NotNull + @Size(min = 1, max = 10000) private String value = null; - } diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/ReferenceIdType.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/ReferenceIdType.java new file mode 100644 index 00000000000..7b5943c3493 --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/ReferenceIdType.java @@ -0,0 +1,32 @@ +package org.egov.common.models.stock; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonValue; + +@JsonIgnoreProperties(ignoreUnknown = true) +public enum ReferenceIdType { + PROJECT("PROJECT"), + OTHER("OTHER"); + private String value; + + ReferenceIdType(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static ReferenceIdType fromValue(String text) { + for (ReferenceIdType b : ReferenceIdType.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } +} diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/SenderReceiverType.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/SenderReceiverType.java new file mode 100644 index 00000000000..e5b1924574a --- /dev/null +++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/stock/SenderReceiverType.java @@ -0,0 +1,34 @@ +package org.egov.common.models.stock; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonValue; + +@JsonIgnoreProperties(ignoreUnknown = true) +public enum SenderReceiverType { + WAREHOUSE("WAREHOUSE"), + + STAFF("STAFF"); + + private String value; + + SenderReceiverType(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static SenderReceiverType fromValue(String text) { + for (SenderReceiverType b : SenderReceiverType.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } +} 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 a08748daf49..c53164b370c 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,21 +1,21 @@ package org.egov.common.models.stock; import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -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 lombok.AllArgsConstructor; import lombok.Builder; import lombok.Builder.Default; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.validation.annotation.Validated; /** * Stock @@ -51,6 +51,8 @@ public class Stock { @JsonProperty("quantity") @NotNull + @Min(value = 1, message = "Minimum value cannot be less than 1") + @Max(value = Integer.MAX_VALUE, message = "Value exceeds maximum allowable limit") private Integer quantity; /* project id in-case of health */ @@ -58,12 +60,13 @@ public class Stock { private String referenceId; @JsonProperty("referenceIdType") - @Size(min=2, max=64) - private String referenceIdType; + @NotNull(message = "referenceIdType must be PROJECT or OTHER") + @Valid + private ReferenceIdType referenceIdType; // transaction fields @JsonProperty("transactionType") - @NotNull + @NotNull(message = "transactionType must be either RECEIVED or DISPATCHED") @Valid private TransactionType transactionType; @@ -77,9 +80,9 @@ public class Stock { private String senderId; @JsonProperty("senderType") - @NotNull - @Size(min=2, max=64) - private String senderType; + @NotNull(message = "Sender Type can be either WAREHOUSE or STAFF") + @Valid + private SenderReceiverType senderType; @JsonProperty("receiverId") @NotNull @@ -87,9 +90,9 @@ public class Stock { private String receiverId; @JsonProperty("receiverType") - @NotNull - @Size(min=2, max=64) - private String receiverType; + @NotNull(message = "Receiver Type can be either WAREHOUSE or STAFF") + @Valid + private SenderReceiverType receiverType; @JsonProperty("wayBillNumber") @Size(min = 2, max = 200) diff --git a/health-services/project/CHANGELOG.md b/health-services/project/CHANGELOG.md index df50f2ba974..3a1ba625f06 100644 --- a/health-services/project/CHANGELOG.md +++ b/health-services/project/CHANGELOG.md @@ -1,5 +1,9 @@ All notable changes to this module will be documented in this file. +## 1.1.2 - 2024-02-26 +- Implemented validation for updating project start date and end date. +- Added numberOfSessions field in additional details for attendance registry. + ## 1.1.1 - 2023-11-15 - Added tag in project beneficiary diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml index ebb223d7d6f..bc89832e98c 100644 --- a/health-services/project/pom.xml +++ b/health-services/project/pom.xml @@ -5,7 +5,7 @@ project jar project - 1.1.1 + 1.1.2 1.8 ${java.version} 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 fe9291ab137..34308dd587f 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 @@ -183,4 +183,7 @@ public class ProjectConfiguration { @Value("${egov.user.id.validator}") private String egovUserIdValidator; + @Value("${project.staff.attendance.topic}") + private String projectStaffAttendanceTopic; + } 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 3c299826c90..c1eee50ec6c 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 @@ -6,6 +6,7 @@ import org.egov.common.models.project.ProjectStaff; import org.egov.common.models.project.ProjectStaffBulkRequest; import org.egov.common.models.project.ProjectStaffRequest; +import org.egov.common.producer.Producer; import org.egov.common.service.IdGenService; import org.egov.common.service.UserService; import org.egov.common.utils.CommonUtils; @@ -26,7 +27,9 @@ 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; @@ -60,6 +63,8 @@ public class ProjectStaffService { private final List> validators; + private final Producer producer; + private final Predicate> isApplicableForCreate = validator -> validator.getClass().equals(PsUserIdValidator.class) || validator.getClass().equals(PsProjectIdValidator.class) @@ -86,7 +91,8 @@ public ProjectStaffService( ProjectService projectService, UserService userService, ProjectConfiguration projectConfiguration, - ProjectStaffEnrichmentService enrichmentService, List> validators) { + ProjectStaffEnrichmentService enrichmentService, + Producer producer, List> validators) { this.idGenService = idGenService; this.projectStaffRepository = projectStaffRepository; this.projectService = projectService; @@ -94,6 +100,7 @@ public ProjectStaffService( this.projectConfiguration = projectConfiguration; this.enrichmentService = enrichmentService; this.validators = validators; + this.producer = producer; } public ProjectStaff create(ProjectStaffRequest request) { @@ -117,6 +124,9 @@ public List create(ProjectStaffBulkRequest request, boolean isBulk if (!validEntities.isEmpty()) { log.info("processing {} valid entities", validEntities.size()); enrichmentService.create(validEntities, request); + // Pushing the data as ProjectStaffBulkRequest for Attendance Service Consumer + producer.push(projectConfiguration.getProjectStaffAttendanceTopic(), new ProjectStaffBulkRequest(request.getRequestInfo(),validEntities)); + // Pushing the data as list for persister consumer projectStaffRepository.save(validEntities, projectConfiguration.getCreateProjectStaffTopic()); log.info("successfully created project staff"); } 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 950985ac246..27300bff902 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 @@ -1,5 +1,10 @@ package org.egov.project.util; +import java.util.ArrayList; +import java.util.LinkedHashMap; +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; @@ -14,16 +19,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; - +import static org.egov.project.util.ProjectConstants.MASTER_ATTENDANCE_SESSION; import static org.egov.project.util.ProjectConstants.MASTER_DEPARTMENT; import static org.egov.project.util.ProjectConstants.MASTER_NATUREOFWORK; import static org.egov.project.util.ProjectConstants.MASTER_PROJECTTYPE; import static org.egov.project.util.ProjectConstants.MASTER_TENANTS; import static org.egov.project.util.ProjectConstants.MDMS_COMMON_MASTERS_MODULE_NAME; +import static org.egov.project.util.ProjectConstants.MDMS_HCM_ATTENDANCE_MODULE_NAME; import static org.egov.project.util.ProjectConstants.MDMS_TENANT_MODULE_NAME; @Component @@ -58,11 +60,13 @@ public MdmsCriteriaReq getMDMSRequest(RequestInfo requestInfo, String tenantId, ModuleDetail projectMDMSModuleDetail = getMDMSModuleRequestData(request); ModuleDetail projectDepartmentModuleDetail = getDepartmentModuleRequestData(request); ModuleDetail projectTenantModuleDetail = getTenantModuleRequestData(request); + ModuleDetail attendanceModuleDetail = getAttendanceModuleRequestData(request); List moduleDetails = new LinkedList<>(); moduleDetails.add(projectMDMSModuleDetail); moduleDetails.add(projectDepartmentModuleDetail); moduleDetails.add(projectTenantModuleDetail); + moduleDetails.add(attendanceModuleDetail); MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId) .build(); @@ -123,4 +127,19 @@ private ModuleDetail getTenantModuleRequestData(ProjectRequest request) { return tenantModuleDetail; } -} + private ModuleDetail getAttendanceModuleRequestData(ProjectRequest request) { + List attendanceMasterDetails = new ArrayList<>(); + + MasterDetail attendanceSessionsMasterDetails = MasterDetail.builder().name(MASTER_ATTENDANCE_SESSION) + .filter(filterCode) + .build(); + + attendanceMasterDetails.add(attendanceSessionsMasterDetails); + + ModuleDetail attendanceModuleDetail = ModuleDetail.builder().masterDetails(attendanceMasterDetails) + .moduleName(MDMS_HCM_ATTENDANCE_MODULE_NAME).build(); + + return attendanceModuleDetail; + } + +} \ 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 5a431833f41..b314eb59fbf 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 @@ -7,10 +7,12 @@ public class ProjectConstants { public static final String MASTER_TENANTS = "tenants"; public static final String MDMS_TENANT_MODULE_NAME = "tenant"; public static final String MDMS_COMMON_MASTERS_MODULE_NAME = "common-masters"; + public static final String MDMS_HCM_ATTENDANCE_MODULE_NAME = "HCM-ATTENDANCE"; public static final String MASTER_DEPARTMENT = "Department"; public static final String MASTER_PROJECTTYPE = "ProjectType"; //location public static final String MASTER_NATUREOFWORK = "NatureOfWork"; + public static final String MASTER_ATTENDANCE_SESSION = "AttendanceSessions"; public static final String CODE = "code"; //General public static final String SEMICOLON = ":"; @@ -19,6 +21,8 @@ public class ProjectConstants { public static final String TASK_NOT_ALLOWED = "TASK_NOT_ALLOWED"; public static final String TASK_NOT_ALLOWED_BENEFICIARY_REFUSED_RESOURCE_EMPTY_ERROR_MESSAGE = "Task not allowed as resources can not be provided when " + TaskStatus.BENEFICIARY_REFUSED; public static final String TASK_NOT_ALLOWED_RESOURCE_CANNOT_EMPTY_ERROR_MESSAGE = "Task not allowed as resources can not be empty when "; + public static final String NUMBER_OF_SESSIONS = "numberOfSessions"; + public enum TaskStatus { BENEFICIARY_REFUSED("BENEFICIARY_REFUSED"); private String value; 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 9082f5a36a8..754fbc26fbe 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 @@ -1,5 +1,17 @@ package org.egov.project.validator.project; +import java.time.Duration; +import java.time.Instant; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -13,23 +25,17 @@ import org.egov.project.util.MDMSUtils; import org.egov.tracer.model.CustomException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - +import static org.egov.project.util.ProjectConstants.MASTER_ATTENDANCE_SESSION; import static org.egov.project.util.ProjectConstants.MASTER_DEPARTMENT; import static org.egov.project.util.ProjectConstants.MASTER_NATUREOFWORK; import static org.egov.project.util.ProjectConstants.MASTER_PROJECTTYPE; import static org.egov.project.util.ProjectConstants.MASTER_TENANTS; import static org.egov.project.util.ProjectConstants.MDMS_COMMON_MASTERS_MODULE_NAME; +import static org.egov.project.util.ProjectConstants.MDMS_HCM_ATTENDANCE_MODULE_NAME; import static org.egov.project.util.ProjectConstants.MDMS_TENANT_MODULE_NAME; @Component @@ -45,6 +51,10 @@ public class ProjectValidator { @Autowired ProjectConfiguration config; + @Autowired + @Qualifier("objectMapper") + ObjectMapper mapper; + /* Validates create Project request body */ public void validateCreateProjectRequest(ProjectRequest request) { Map errorMap = new HashMap<>(); @@ -61,6 +71,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); //Get boundaries in list from all Projects in request body for validation Map> boundariesForValidation = getBoundaryForValidation(request.getProjects()); @@ -183,6 +194,11 @@ private void validateProjectRequest(List projects) { log.error("Start date should be less than end date"); errorMap.put("INVALID_DATE", "Start date should be less than end date"); } + if (project.getStartDate() != null && project.getEndDate() != null && project.getEndDate() != 0 + && project.getEndDate().compareTo(Instant.ofEpochMilli(project.getStartDate()).plus(Duration.ofDays(1)).toEpochMilli()) < 0) { + log.error("Start date and end date difference should at least be 1 day."); + errorMap.put("INVALID_DATE", "Start date and end date difference should at least be 1 day."); + } if (project.getAddress() != null && StringUtils.isNotBlank(project.getAddress().getBoundary()) && StringUtils.isBlank(project.getAddress().getBoundaryType()) ) { log.error("Boundary Type is mandatory if boundary is present in Project request body"); errorMap.put("BOUNDARY", "Boundary Type is mandatory if boundary is present in Project request body"); @@ -303,6 +319,51 @@ private void validateMDMSData(List projects, Object mdmsData, Map errorMap, String tenantId) { + String rootTenantId = tenantId.split("\\.")[0]; + ObjectMapper objectMapper = new ObjectMapper(); + String numberOfSessions = null; + + //Get MDMS data using create project request and tenantId + Object mdmsData = mdmsUtils.mDMSCall(projectRequest, rootTenantId); + final String jsonPathForAttendanceSession = "$.MdmsRes." + MDMS_HCM_ATTENDANCE_MODULE_NAME + "." + MASTER_ATTENDANCE_SESSION + ".*"; + List attendanceRes = null; + try { + attendanceRes = JsonPath.read(mdmsData, jsonPathForAttendanceSession); + } catch (Exception e) { + log.error(e.getMessage()); + throw new CustomException("JSONPATH_ERROR", "Failed to parse mdms response"); + } + + for (Project project : projectRequest.getProjects()) { + JsonNode additionalDetails = null; + try { + Object additionalDetailsObj = project.getAdditionalDetails(); + String additionalDetailsStr = objectMapper.writeValueAsString(additionalDetailsObj); + additionalDetails = objectMapper.readTree(additionalDetailsStr); + + JsonNode numberOfSessionsNode = additionalDetails.get("numberOfSessions"); + if (numberOfSessionsNode != null && numberOfSessionsNode.isTextual()) { + numberOfSessions = numberOfSessionsNode.asText(); + log.info("Number of sessions: " + numberOfSessions); + } else { + log.info("numberOfSessions field not found in project's additonal Details"); + } + + } catch (ClassCastException e) { + log.error("Not able to parse additional details object", e); + } catch (Exception e) { + log.error("An unexpected error occurred while getting AdditionalDetails", e); + } + + // Validate numberOfSessions + if (!StringUtils.isBlank(numberOfSessions) && !attendanceRes.contains(numberOfSessions)) { + log.error("The number of attendance sessions " + numberOfSessions + " is not present in MDMS"); + errorMap.put("INVALID_NUMBER_OF_ATTENDANCE_SESSIONS", "The number of attendance sessions: " + numberOfSessions + " is not present in MDMS"); + } + } + } + /* Validate Project Request MDMS data */ private void validateRequestMDMSData(ProjectRequest request, String tenantId, Map errorMap) { String rootTenantId = tenantId.split("\\.")[0]; @@ -350,7 +411,17 @@ public void validateUpdateAgainstDB(List projectsFromRequest, List p.getId().equals(project.getId())).findFirst().orElse(null); @@ -359,6 +430,8 @@ public void validateUpdateAgainstDB(List projectsFromRequest, List projectsFromRequest, List projects, List parent } log.info("Parent projects validated against DB"); } -} +} \ No newline at end of file diff --git a/health-services/project/src/main/java/org/egov/project/web/models/ProjectStaffSearch.java b/health-services/project/src/main/java/org/egov/project/web/models/ProjectStaffSearch.java index d5440bf84d5..c2279738914 100644 --- a/health-services/project/src/main/java/org/egov/project/web/models/ProjectStaffSearch.java +++ b/health-services/project/src/main/java/org/egov/project/web/models/ProjectStaffSearch.java @@ -37,8 +37,7 @@ public class ProjectStaffSearch { private String tenantId = null; @JsonProperty("staffId") - @Size(min=2,max=64) - private String staffId = null; + private List staffId = null; @JsonProperty("projectId") @Size(min=2,max=64) diff --git a/health-services/project/src/main/resources/application.properties b/health-services/project/src/main/resources/application.properties index 81fc4cd7f12..8364f5f71da 100644 --- a/health-services/project/src/main/resources/application.properties +++ b/health-services/project/src/main/resources/application.properties @@ -163,3 +163,7 @@ project.resource.consumer.bulk.delete.topic=delete-project-resource-bulk-topic project.mdms.module=HCM-PROJECT-TYPES egov.location.hierarchy.type=ADMIN + +#---------Attendance-----------# +project.staff.attendance.topic=project-staff-attendance-health-topic + 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 5f8a6461f88..522b79708d3 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 @@ -50,7 +50,7 @@ void shouldNotRaiseExceptionIfNoProjectStaffFound() throws Exception { any(Integer.class), any(String.class), eq(null), any(Boolean.class))) .thenReturn(Collections.emptyList()); ProjectStaffSearch projectStaffSearch = ProjectStaffSearch.builder() - .id(Collections.singletonList("ID101")).staffId("some-user-id").build(); + .id(Collections.singletonList("ID101")).staffId(Collections.singletonList("some-user-id")).build(); ProjectStaffSearchRequest projectStaffSearchRequest = ProjectStaffSearchRequest.builder() .projectStaff(projectStaffSearch).requestInfo(RequestInfoTestBuilder.builder() .withCompleteRequestInfo().build()).build(); diff --git a/health-services/referralmanagement/CHANGELOG.md b/health-services/referralmanagement/CHANGELOG.md index 266f4ddf3f5..55b1ba23b50 100644 --- a/health-services/referralmanagement/CHANGELOG.md +++ b/health-services/referralmanagement/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog All notable changes to this module will be documented in this file. +## 1.0.1 - 2024-02-28 +- Added functionality for referrals handled by health facilities, referred to as "hfreferral". + ## 1.0.0 - 2023-11-15 - Added Downsync Feature diff --git a/health-services/referralmanagement/pom.xml b/health-services/referralmanagement/pom.xml index 5ef135c8553..a13ab7a0182 100644 --- a/health-services/referralmanagement/pom.xml +++ b/health-services/referralmanagement/pom.xml @@ -6,7 +6,7 @@ referralmanagement jar referralmanagement - 1.0.0 + 1.0.1 1.8 ${java.version} @@ -50,7 +50,7 @@ org.egov.common health-services-models - 1.0.11-SNAPSHOT + 1.0.14-SNAPSHOT compile 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 7bd29b61cc1..f33a82c8bea 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 @@ -5,6 +5,8 @@ public interface Constants { String GET_SIDE_EFFECTS = "getSideEffects"; String SET_REFERRALS = "setReferrals"; String GET_REFERRALS = "getReferrals"; + String SET_HF_REFERRALS = "setHfReferrals"; + String GET_HF_REFERRALS = "getHfReferrals"; String VALIDATION_ERROR = "VALIDATION_ERROR"; String PROJECT_TYPES = "projectTypes"; String MDMS_RESPONSE = "MdmsRes"; 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 e529c27a4f2..1113ac58efb 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 @@ -61,9 +61,33 @@ public class ReferralManagementConfiguration { @Value("${referralmanagement.referral.consumer.bulk.delete.topic}") private String deleteReferralBulkTopic; + @Value("${referralmanagement.hfreferral.kafka.create.topic}") + private String createHFReferralTopic; + + @Value("${referralmanagement.hfreferral.kafka.update.topic}") + private String updateHFReferralTopic; + + @Value("${referralmanagement.hfreferral.kafka.delete.topic}") + private String deleteHFReferralTopic; + + @Value("${referralmanagement.hfreferral.consumer.bulk.create.topic}") + private String createHFReferralBulkTopic; + + @Value("${referralmanagement.hfreferral.consumer.bulk.update.topic}") + private String updateHFReferralBulkTopic; + + @Value("${referralmanagement.hfreferral.consumer.bulk.delete.topic}") + private String deleteHFReferralBulkTopic; + @Value("${egov.search.project.staff.url}") private String projectStaffSearchUrl; + @Value("${egov.search.project.facility.url}") + private String projectFacilitySearchUrl; + + @Value("${egov.search.project.url}") + private String projectSearchUrl; + @Value("${egov.facility.host}") private String facilityHost; diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/HFReferralConsumer.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/HFReferralConsumer.java new file mode 100644 index 00000000000..d4b4469df52 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/consumer/HFReferralConsumer.java @@ -0,0 +1,110 @@ +package org.egov.referralmanagement.consumer; + +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.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.referralmanagement.service.HFReferralService; +import org.egov.tracer.model.CustomException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +/** + * Kafka Consumer for handling HFReferral-related messages. + * Author: kanishq-egov + */ +@Component +@Slf4j +public class HFReferralConsumer { + + private final HFReferralService hfReferralService; + private final ObjectMapper objectMapper; + + @Autowired + public HFReferralConsumer(HFReferralService hfReferralService, + @Qualifier("objectMapper") ObjectMapper objectMapper) { + this.hfReferralService = hfReferralService; + this.objectMapper = objectMapper; + } + + /** + * Kafka listener method to handle bulk creation of HFReferrals. + * Author: kanishq-egov + * + * @param consumerRecord The Kafka message payload. + * @param topic The Kafka topic from which the message is received. + */ + @KafkaListener(topics = "${referralmanagement.hfreferral.consumer.bulk.create.topic}") + public void bulkCreate(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + // Convert the Kafka message payload to HFReferralBulkRequest + HFReferralBulkRequest request = objectMapper.convertValue(consumerRecord, HFReferralBulkRequest.class); + + // Invoke the HFReferralService to handle bulk creation + hfReferralService.create(request, true); + } catch (Exception exception) { + log.error("Error in HFReferral consumer bulk create", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + + // Throw a CustomException in case of an error during bulk creation + throw new CustomException("HCM_REFERRAL_MANAGEMENT_REFERRAL_CREATE", exception.getMessage()); + } + } + + /** + * Kafka listener method to handle bulk update of HFReferrals. + * Author: kanishq-egov + * + * @param consumerRecord The Kafka message payload. + * @param topic The Kafka topic from which the message is received. + */ + @KafkaListener(topics = "${referralmanagement.hfreferral.consumer.bulk.update.topic}") + public void bulkUpdate(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + // Convert the Kafka message payload to HFReferralBulkRequest + HFReferralBulkRequest request = objectMapper.convertValue(consumerRecord, HFReferralBulkRequest.class); + + // Invoke the HFReferralService to handle bulk update + hfReferralService.update(request, true); + } catch (Exception exception) { + log.error("Error in HFReferral consumer bulk update", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + + // Throw a CustomException in case of an error during bulk update + throw new CustomException("HCM_REFERRAL_MANAGEMENT_REFERRAL_UPDATE", exception.getMessage()); + } + } + + /** + * Kafka listener method to handle bulk deletion of HFReferrals. + * Author: kanishq-egov + * + * @param consumerRecord The Kafka message payload. + * @param topic The Kafka topic from which the message is received. + */ + @KafkaListener(topics = "${referralmanagement.hfreferral.consumer.bulk.delete.topic}") + public void bulkDelete(Map consumerRecord, + @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + try { + // Convert the Kafka message payload to HFReferralBulkRequest + HFReferralBulkRequest request = objectMapper.convertValue(consumerRecord, HFReferralBulkRequest.class); + + // Invoke the HFReferralService to handle bulk deletion + hfReferralService.delete(request, true); + } catch (Exception exception) { + log.error("Error in HFReferral consumer bulk delete", exception); + log.error("Exception trace: ", ExceptionUtils.getStackTrace(exception)); + + // Throw a CustomException in case of an error during bulk deletion + throw new CustomException("HCM_REFERRAL_MANAGEMENT_REFERRAL_DELETE", exception.getMessage()); + } + } +} 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 new file mode 100644 index 00000000000..f3b05004718 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/HFReferralRepository.java @@ -0,0 +1,151 @@ +package org.egov.referralmanagement.repository; + +import java.lang.reflect.Method; +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.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralSearch; +import org.egov.common.producer.Producer; +import org.egov.referralmanagement.repository.rowmapper.HFReferralRowMapper; +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.ReflectionUtils; + +import static org.egov.common.utils.CommonUtils.getIdMethod; + +/** + * Repository class for managing the persistence and retrieval of HFReferral entities. + * This class extends GenericRepository for common CRUD operations. + * + * @author kanishq-egov + */ +@Repository +@Slf4j +public class HFReferralRepository extends GenericRepository { + + @Autowired + private HFReferralRowMapper rowMapper; + + /** + * Constructor for HFReferralRepository. + * + * @param producer The producer for publishing messages. + * @param namedParameterJdbcTemplate JDBC template for named parameters. + * @param redisTemplate Template for Redis operations. + * @param selectQueryBuilder Builder for creating SELECT queries. + * @param rowMapper Mapper for converting rows to HFReferral objects. + */ + @Autowired + protected HFReferralRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, + RedisTemplate redisTemplate, SelectQueryBuilder selectQueryBuilder, + HFReferralRowMapper rowMapper) { + // Call the constructor of the GenericRepository with necessary parameters. + super(producer, namedParameterJdbcTemplate, redisTemplate, selectQueryBuilder, rowMapper, Optional.of("hf_referral")); + } + + /** + * Retrieves a list of HFReferrals based on the provided search criteria. + * + * @param searchObject The search criteria for filtering HFReferrals. + * @param limit The maximum number of records to retrieve. + * @param offset The offset for pagination. + * @param tenantId The tenant ID for filtering. + * @param lastChangedSince Timestamp for filtering records changed since this time. + * @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, + 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"; + Map paramsMap = new HashMap<>(); + + // Generate WHERE conditions based on non-null fields in the search object. + List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, + QueryFieldChecker.isNotNull, paramsMap); + + // Apply the WHERE conditions to the query. + query = GenericQueryBuilder.generateQuery(query, whereFields).toString(); + query = query.replace("id IN (:id)", "hf.id IN (:id)"); + query = query.replace("clientReferenceId IN (:clientReferenceId)", "hf.clientReferenceId IN (:clientReferenceId)"); + + // Add additional conditions based on tenant ID, includeDeleted, and lastChangedSince. + query = query + " and hf.tenantId=:tenantId "; + if (Boolean.FALSE.equals(includeDeleted)) { + query = query + "and hf.isDeleted=:isDeleted "; + } + + if (lastChangedSince != null) { + query = query + "and hf.lastModifiedTime>=:lastModifiedTime "; + } + + // Add ORDER BY, LIMIT, and OFFSET clauses to the query. + query = query + "ORDER BY hf.id ASC LIMIT :limit OFFSET :offset"; + paramsMap.put("tenantId", tenantId); + paramsMap.put("isDeleted", includeDeleted); + paramsMap.put("lastModifiedTime", lastChangedSince); + 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; + } + + /** + * Retrieves a list of HFReferrals based on a list of IDs. + * + * @param ids The list of IDs to search for. + * @param includeDeleted Flag indicating whether to include deleted records. + * @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) { + // Find objects in the cache based on the provided IDs. + List objFound = findInCache(ids).stream() + .filter(entity -> entity.getIsDeleted().equals(includeDeleted)) + .collect(Collectors.toList()); + + // If objects are found in the cache, check if there are any IDs remaining to be retrieved. + if (!objFound.isEmpty()) { + Method idMethod = getIdMethod(objFound, columnName); + ids.removeAll(objFound.stream() + .map(obj -> (String) ReflectionUtils.invokeMethod(idMethod, obj)) + .collect(Collectors.toList())); + + // If no IDs are remaining, return the objects found in the cache. + if (ids.isEmpty()) { + return objFound; + } + } + + // Generate a SELECT query based on the provided IDs and column name. + String query = String.format("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 WHERE hf.%s IN (:ids) ", columnName); + + // Add conditions to exclude deleted records if includeDeleted is false. + if (includeDeleted == null || !includeDeleted) { + query += " AND hf.isDeleted = false "; + } + + // Create parameter map for the query and execute it to retrieve HFReferral entities. + Map paramMap = new HashMap<>(); + paramMap.put("ids", ids); + List hfReferralList = this.namedParameterJdbcTemplate.query(query, paramMap, this.rowMapper); + + // Add the retrieved entities to the cache. + objFound.addAll(hfReferralList); + putInCache(objFound); + return objFound; + } +} 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 new file mode 100644 index 00000000000..3f9b5084872 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/repository/rowmapper/HFReferralRowMapper.java @@ -0,0 +1,78 @@ +package org.egov.referralmanagement.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 org.egov.common.models.project.AdditionalFields; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +/** + * RowMapper implementation for mapping ResultSet rows to HFReferral objects. + * This class is responsible for converting database query results into Java objects. + * + * @author kanishq-egov + */ +@Component +public class HFReferralRowMapper implements RowMapper { + + @Autowired + ObjectMapper objectMapper; + + /** + * Maps a ResultSet row to an HFReferral object. + * + * @param resultSet The result set containing the queried data. + * @param i The current row number. + * @return An HFReferral object mapped from the ResultSet row. + * @throws SQLException If there's an issue accessing ResultSet data. + */ + @Override + public HFReferral mapRow(ResultSet resultSet, int i) throws SQLException { + try { + // Create AuditDetails object from the ResultSet data. + AuditDetails auditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("createdBy")) + .createdTime(resultSet.getLong("createdTime")) + .lastModifiedBy(resultSet.getString("lastModifiedBy")) + .lastModifiedTime(resultSet.getLong("lastModifiedTime")) + .build(); + + // Create clientAuditDetails object from the ResultSet data. + AuditDetails clientAuditDetails = AuditDetails.builder() + .createdBy(resultSet.getString("clientCreatedBy")) + .createdTime(resultSet.getLong("clientCreatedTime")) + .lastModifiedBy(resultSet.getString("clientLastModifiedBy")) + .lastModifiedTime(resultSet.getLong("clientLastModifiedTime")) + .build(); + + // Build and return HFReferral object using ResultSet data and ObjectMapper for additionalFields. + return HFReferral.builder() + .id(resultSet.getString("id")) + .clientReferenceId(resultSet.getString("clientreferenceid")) + .tenantId(resultSet.getString("tenantid")) + .projectId(resultSet.getString("projectid")) + .projectFacilityId(resultSet.getString("projectfacilityid")) + .symptom(resultSet.getString("symptom")) + .symptomSurveyId(resultSet.getString("symptomsurveyid")) + .beneficiaryId(resultSet.getString("beneficiaryid")) + .referralCode(resultSet.getString("referralcode")) + .nationalLevelId(resultSet.getString("nationallevelid")) + .additionalFields(resultSet.getString("additionalDetails") == null ? null : objectMapper + .readValue(resultSet.getString("additionalDetails"), AdditionalFields.class)) + .rowVersion(resultSet.getInt("rowversion")) + .isDeleted(resultSet.getBoolean("isdeleted")) + .auditDetails(auditDetails) + .clientAuditDetails(clientAuditDetails) + .build(); + } catch (JsonProcessingException e) { + // Wrap JsonProcessingException as a RuntimeException for simplicity. + throw new RuntimeException(e); + } + } +} 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 new file mode 100644 index 00000000000..aaf317acafc --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/HFReferralService.java @@ -0,0 +1,263 @@ +package org.egov.referralmanagement.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.egov.common.ds.Tuple; +import org.egov.common.models.ErrorDetails; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralRequest; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralSearchRequest; +import org.egov.common.service.IdGenService; +import org.egov.common.utils.CommonUtils; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.Constants; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.referralmanagement.repository.HFReferralRepository; +import org.egov.referralmanagement.service.enrichment.HFReferralEnrichmentService; +import org.egov.referralmanagement.validator.hfreferral.HfrIsDeletedValidator; +import org.egov.referralmanagement.validator.hfreferral.HfrNonExistentEntityValidator; +import org.egov.referralmanagement.validator.hfreferral.HfrNullIdValidator; +import org.egov.referralmanagement.validator.hfreferral.HfrProjectFacilityIdValidator; +import org.egov.referralmanagement.validator.hfreferral.HfrProjectIdValidator; +import org.egov.referralmanagement.validator.hfreferral.HfrRowVersionValidator; +import org.egov.referralmanagement.validator.hfreferral.HfrUniqueEntityValidator; +import org.egov.tracer.model.CustomException; +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; + +/** + * Service class for handling operations related to HFReferral entities. + * Manages creation, updating, searching, and deletion of HFReferrals. + * Includes validation and enrichment of HFReferrals before interacting with the repository. + * Author: kanishq-egov + */ +@Service +@Slf4j +public class HFReferralService { + + private final IdGenService idGenService; + private final HFReferralRepository hfReferralRepository; + private final ReferralManagementConfiguration referralManagementConfiguration; + private final HFReferralEnrichmentService hfReferralEnrichmentService; + private final List> validators; + + // Predicates to determine which validators are applicable for create, update, and delete operations + private final Predicate> isApplicableForCreate = validator -> + validator.getClass().equals(HfrProjectIdValidator.class) + || validator.getClass().equals(HfrProjectFacilityIdValidator.class); + + private final Predicate> isApplicableForUpdate = validator -> + validator.getClass().equals(HfrProjectIdValidator.class) + || validator.getClass().equals(HfrProjectFacilityIdValidator.class) + || validator.getClass().equals(HfrNullIdValidator.class) + || validator.getClass().equals(HfrIsDeletedValidator.class) + || validator.getClass().equals(HfrUniqueEntityValidator.class) + || validator.getClass().equals(HfrNonExistentEntityValidator.class) + || validator.getClass().equals(HfrRowVersionValidator.class); + + private final Predicate> isApplicableForDelete = validator -> + validator.getClass().equals(HfrNullIdValidator.class) + || validator.getClass().equals(HfrNonExistentEntityValidator.class) + || validator.getClass().equals(HfrRowVersionValidator.class); + + /** + * Constructor to initialize the service with required dependencies. + * + * @param idGenService The IdGenService for generating IDs. + * @param hfReferralRepository The repository for HFReferral entities. + * @param referralManagementConfiguration The configuration for referral management. + * @param hfReferralEnrichmentService The service for enriching HFReferral entities. + * @param validators The list of validators for HFReferral entities. + */ + public HFReferralService(IdGenService idGenService, HFReferralRepository hfReferralRepository, + ReferralManagementConfiguration referralManagementConfiguration, + HFReferralEnrichmentService hfReferralEnrichmentService, + List> validators) { + this.idGenService = idGenService; + this.hfReferralRepository = hfReferralRepository; + this.referralManagementConfiguration = referralManagementConfiguration; + this.hfReferralEnrichmentService = hfReferralEnrichmentService; + this.validators = validators; + } + + // Method to create a single HFReferral + public HFReferral create(HFReferralRequest request) { + log.info("Received request to create a referral"); + HFReferralBulkRequest bulkRequest = HFReferralBulkRequest.builder().requestInfo(request.getRequestInfo()) + .hfReferrals(Collections.singletonList(request.getHfReferral())).build(); + log.info("Creating bulk request"); + return create(bulkRequest, false).get(0); + } + + // Method to create multiple HFReferrals in bulk + public List create(HFReferralBulkRequest hfReferralRequest, boolean isBulk) { + log.info("Received request to create bulk referrals"); + Tuple, Map> tuple = validate(validators, + isApplicableForCreate, hfReferralRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validReferrals = tuple.getX(); + + try { + if (!validReferrals.isEmpty()) { + log.info("Processing {} valid entities", validReferrals.size()); + hfReferralEnrichmentService.create(validReferrals, hfReferralRequest); + hfReferralRepository.save(validReferrals, + referralManagementConfiguration.getCreateHFReferralTopic()); + log.info("Successfully created referrals"); + } + } catch (Exception exception) { + log.error("Error occurred while creating referrals: {}", exception.getMessage()); + populateErrorDetails(hfReferralRequest, errorDetailsMap, validReferrals, + exception, Constants.SET_HF_REFERRALS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validReferrals; + } + + // Method to update a single HFReferral + public HFReferral update(HFReferralRequest request) { + log.info("Received request to update a referral"); + HFReferralBulkRequest bulkRequest = HFReferralBulkRequest.builder().requestInfo(request.getRequestInfo()) + .hfReferrals(Collections.singletonList(request.getHfReferral())).build(); + log.info("Creating bulk request"); + return update(bulkRequest, false).get(0); + } + + // Method to update multiple HFReferrals in bulk + public List update(HFReferralBulkRequest hfReferralRequest, boolean isBulk) { + log.info("Received request to update bulk referrals"); + Tuple, Map> tuple = validate(validators, + isApplicableForUpdate, hfReferralRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validReferrals = tuple.getX(); + + try { + if (!validReferrals.isEmpty()) { + log.info("Processing {} valid entities", validReferrals.size()); + hfReferralEnrichmentService.update(validReferrals, hfReferralRequest); + hfReferralRepository.save(validReferrals, + referralManagementConfiguration.getUpdateHFReferralTopic()); + log.info("Successfully updated bulk referrals"); + } + } catch (Exception exception) { + log.error("Error occurred while updating referrals", exception); + populateErrorDetails(hfReferralRequest, errorDetailsMap, validReferrals, + exception, Constants.SET_HF_REFERRALS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validReferrals; + } + + // Method to search for HFReferrals based on certain criteria + public List 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()); + + // If searching by ID only, fetch referrals with specified IDs + if (isSearchByIdOnly(referralSearchRequest.getHfReferral(), idFieldName)) { + log.info("Searching referrals by ID"); + List ids = (List) ReflectionUtils.invokeMethod(getIdMethod(Collections + .singletonList(referralSearchRequest.getHfReferral())), + referralSearchRequest.getHfReferral()); + log.info("Fetching referrals with IDs: {}", ids); + + return hfReferralRepository.findById(ids, includeDeleted, idFieldName).stream() + .filter(lastChangedSince(lastChangedSince)) + .filter(havingTenantId(tenantId)) + .filter(includeDeleted(includeDeleted)) + .collect(Collectors.toList()); + } + + log.info("Searching referrals using criteria"); + return hfReferralRepository.find(referralSearchRequest.getHfReferral(), + limit, offset, tenantId, lastChangedSince, includeDeleted); + } + + // Method to delete a single HFReferral + public HFReferral delete(HFReferralRequest hfReferralRequest) { + log.info("Received request to delete a referral"); + HFReferralBulkRequest bulkRequest = HFReferralBulkRequest.builder().requestInfo(hfReferralRequest.getRequestInfo()) + .hfReferrals(Collections.singletonList(hfReferralRequest.getHfReferral())).build(); + log.info("Creating bulk request"); + return delete(bulkRequest, false).get(0); + } + + // Method to delete multiple HFReferrals in bulk + public List delete(HFReferralBulkRequest hfReferralRequest, boolean isBulk) { + Tuple, Map> tuple = validate(validators, + isApplicableForDelete, hfReferralRequest, isBulk); + Map errorDetailsMap = tuple.getY(); + List validReferrals = tuple.getX(); + + try { + if (!validReferrals.isEmpty()) { + log.info("Processing {} valid entities", validReferrals.size()); + List referralIds = validReferrals.stream().map(entity -> entity.getId()).collect(Collectors.toSet()).stream().collect(Collectors.toList()); + List existingReferrals = hfReferralRepository + .findById(referralIds, false); + hfReferralEnrichmentService.delete(existingReferrals, hfReferralRequest); + hfReferralRepository.save(existingReferrals, + referralManagementConfiguration.getDeleteHFReferralTopic()); + log.info("Successfully deleted entities"); + } + } catch (Exception exception) { + log.error("Error occurred while deleting entities: {}", exception); + populateErrorDetails(hfReferralRequest, errorDetailsMap, validReferrals, + exception, Constants.SET_HF_REFERRALS); + } + handleErrors(errorDetailsMap, isBulk, Constants.VALIDATION_ERROR); + + return validReferrals; + } + + // Method to put HFReferrals in cache + public void putInCache(List hfReferrals) { + log.info("Putting {} HFReferrals in cache", hfReferrals.size()); + hfReferralRepository.putInCache(hfReferrals); + log.info("Successfully put HFReferrals in cache"); + } + + // Method to validate HFReferralBulkRequest + private Tuple, Map> validate( + List> validators, + Predicate> isApplicable, + HFReferralBulkRequest request, + boolean isBulk + ) { + log.info("Validating request"); + Map errorDetailsMap = CommonUtils.validate(validators, + isApplicable, request, + Constants.SET_HF_REFERRALS); + if (!errorDetailsMap.isEmpty() && !isBulk) { + log.error("Validation error occurred. Error details: {}", errorDetailsMap.values()); + throw new CustomException(Constants.VALIDATION_ERROR, errorDetailsMap.values().toString()); + } + List validReferrals = request.getHfReferrals().stream() + .filter(notHavingErrors()).collect(Collectors.toList()); + log.info("Validation successful, found valid referrals"); + return new Tuple<>(validReferrals, errorDetailsMap); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/HFReferralEnrichmentService.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/HFReferralEnrichmentService.java new file mode 100644 index 00000000000..158b17c126d --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/enrichment/HFReferralEnrichmentService.java @@ -0,0 +1,57 @@ +package org.egov.referralmanagement.service.enrichment; + +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.utils.CommonUtils; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.enrichForCreate; +import static org.egov.common.utils.CommonUtils.enrichForDelete; +import static org.egov.common.utils.CommonUtils.enrichForUpdate; +import static org.egov.common.utils.CommonUtils.getIdToObjMap; + +@Component +@Slf4j +public class HFReferralEnrichmentService { + + /** + * + * @param entities + * @param request + */ + public void create(List entities, HFReferralBulkRequest request) { + log.info("starting the enrichment for create hfReferrals"); + log.info("generating IDs using UUID"); + List idList = CommonUtils.uuidSupplier().apply(entities.size()); + log.info("enriching referrals with generated IDs"); + enrichForCreate(entities, idList, request.getRequestInfo()); + log.info("enrichment done"); + } + + /** + * + * @param entities + * @param request + */ + public void update(List entities, HFReferralBulkRequest request) { + log.info("starting the enrichment for create hfReferrals"); + Map referralMap = getIdToObjMap(entities); + enrichForUpdate(referralMap, entities, request); + log.info("enrichment done"); + } + + /** + * + * @param entities + * @param request + */ + public void delete(List entities, HFReferralBulkRequest request) { + log.info("starting the enrichment for delete hfReferrals"); + enrichForDelete(entities, request.getRequestInfo(), true); + log.info("enrichment done"); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrIsDeletedValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrIsDeletedValidator.java new file mode 100644 index 00000000000..92a2fcfdd53 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrIsDeletedValidator.java @@ -0,0 +1,45 @@ +package org.egov.referralmanagement.validator.hfreferral; + +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.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForIsDelete; + +/** + * Validator for checking the 'isDeleted' field in HFReferral entities. + * + * Author: kanishq-egov + */ +@Component +@Order(2) +@Slf4j +public class HfrIsDeletedValidator implements Validator { + + /** + * Validates the 'isDeleted' field for each HFReferral entity in the bulk request. + * + * @param request The HFReferralBulkRequest containing a list of HFReferral entities + * @return A Map containing HFReferral entities as keys and lists of errors as values + */ + @Override + public Map> validate(HFReferralBulkRequest request) { + log.info("validating isDeleted field"); + HashMap> errorDetailsMap = new HashMap<>(); + List validEntities = request.getHfReferrals(); + validEntities.stream().filter(HFReferral::getIsDeleted).forEach(hfReferral -> { + Error error = getErrorForIsDelete(); + populateErrorDetails(hfReferral, error, errorDetailsMap); + }); + return errorDetailsMap; + } +} 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 new file mode 100644 index 00000000000..515d37624a4 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNonExistentEntityValidator.java @@ -0,0 +1,80 @@ +package org.egov.referralmanagement.validator.hfreferral; + +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 com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.repository.HFReferralRepository; +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.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.getErrorForNonExistentEntity; +import static org.egov.referralmanagement.Constants.GET_ID; + +/** + * Validator for checking the existence of entities referred in HFReferral entities. + * + * Author: kanishq-egov + */ +@Component +@Order(value = 4) +@Slf4j +public class HfrNonExistentEntityValidator implements Validator { + + private final HFReferralRepository hfReferralRepository; + + private final ObjectMapper objectMapper; + + @Autowired + public HfrNonExistentEntityValidator(HFReferralRepository hfReferralRepository, ObjectMapper objectMapper) { + this.hfReferralRepository = hfReferralRepository; + this.objectMapper = objectMapper; + } + + /** + * Validates the existence of entities referred in HFReferral entities. + * + * @param request The HFReferralBulkRequest containing a list of HFReferral entities + * @return A Map containing HFReferral entities as keys and lists of errors as values + */ + @Override + public Map> validate(HFReferralBulkRequest request) { + log.info("validating for existence of entity"); + Map> errorDetailsMap = new HashMap<>(); + List hfReferrals = request.getHfReferrals(); + Class objClass = getObjClass(hfReferrals); + Method idMethod = getMethod(GET_ID, objClass); + Map iMap = getIdToObjMap(hfReferrals + .stream().filter(notHavingErrors()).collect(Collectors.toList()), idMethod); + if (!iMap.isEmpty()) { + List referralIds = new ArrayList<>(iMap.keySet()); + List existingReferrals = hfReferralRepository + .findById(referralIds, false, getIdFieldName(idMethod)); + List nonExistentReferrals = checkNonExistentEntities(iMap, + existingReferrals, idMethod); + nonExistentReferrals.forEach(sideEffect -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(sideEffect, error, errorDetailsMap); + }); + } + + return errorDetailsMap; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNullIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNullIdValidator.java new file mode 100644 index 00000000000..26defef4fa4 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrNullIdValidator.java @@ -0,0 +1,38 @@ +package org.egov.referralmanagement.validator.hfreferral; + +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; +import org.egov.common.models.Error; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +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.referralmanagement.Constants.GET_HF_REFERRALS; + +/** + * Validator for checking null id in HFReferral entities. + * + * Author: kanishq-egov + */ +@Component +@Order(value = 1) +@Slf4j +public class HfrNullIdValidator implements Validator { + + /** + * Validates if HFReferral entities have null ids. + * + * @param request The HFReferralBulkRequest containing a list of HFReferral entities + * @return A Map containing HFReferral entities as keys and lists of errors as values + */ + @Override + public Map> validate(HFReferralBulkRequest request) { + log.info("validating for null id"); + return validateForNullId(request, GET_HF_REFERRALS); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrProjectFacilityIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrProjectFacilityIdValidator.java new file mode 100644 index 00000000000..82ac9dba00a --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrProjectFacilityIdValidator.java @@ -0,0 +1,134 @@ +package org.egov.referralmanagement.validator.hfreferral; + +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.project.ProjectFacility; +import org.egov.common.models.project.ProjectFacilityBulkResponse; +import org.egov.common.models.project.ProjectFacilitySearch; +import org.egov.common.models.project.ProjectFacilitySearchRequest; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.tracer.model.CustomException; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; + +/** + * Validator for checking the existence of ProjectFacility entities based on their IDs in HFReferral objects. + * + * Author: kanishq-egov + */ +@Component +@Order(value = 3) +@Slf4j +public class HfrProjectFacilityIdValidator implements Validator { + + private final ServiceRequestClient serviceRequestClient; + private final ReferralManagementConfiguration referralManagementConfiguration; + + public HfrProjectFacilityIdValidator(ServiceRequestClient serviceRequestClient, ReferralManagementConfiguration referralManagementConfiguration) { + this.serviceRequestClient = serviceRequestClient; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + /** + * Validates whether project facilities exist in the database or not using project facility IDs for HFReferral objects. + * + * @param request The HFReferralBulkRequest containing a list of HFReferral entities + * @return A Map containing HFReferral entities as keys and lists of errors as values + */ + @Override + public Map> validate(HFReferralBulkRequest request) { + log.info("Validating project facility IDs"); + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getHfReferrals(); + + // Grouping HFReferrals by tenantId to fetch project facilities for each tenant + Map> tenantIdReferralMap = entities.stream().collect(Collectors.groupingBy(HFReferral::getTenantId)); + tenantIdReferralMap.forEach((tenantId, hfReferralList) -> { + // Get all the existing project facilities in the HFReferral list from Project Service + List existingProjectFacilities = getExistingProjects(tenantId, hfReferralList, request); + // Validate project facilities and populate error map if invalid entities are found + validateAndPopulateErrors(existingProjectFacilities, entities, errorDetailsMap); + }); + + return errorDetailsMap; + } + + // Helper method to add an item to a list if it is not null + private void addIgnoreNull(List list, String item) { + if(Objects.nonNull(item)) list.add(item); + } + + // Fetches existing project facilities from Project Service based on their IDs + private List getExistingProjects(String tenantId, List hfReferrals, HFReferralBulkRequest request) { + List existingProjectFacilities = new ArrayList<>(); + final List projectFacilityIdList = new ArrayList<>(); + + // Collecting project facility IDs from HFReferrals + hfReferrals.forEach(hfReferral -> { + addIgnoreNull(projectFacilityIdList, hfReferral.getProjectFacilityId()); + }); + + if(!projectFacilityIdList.isEmpty()) { + ProjectFacilitySearch projectFacilitySearch = ProjectFacilitySearch.builder() + .id(!projectFacilityIdList.isEmpty()? projectFacilityIdList : null) + .tenantId(tenantId) + .build(); + + try { + // Using project facility search and fetching the valid IDs. + ProjectFacilityBulkResponse projectFacilityBulkResponse = serviceRequestClient.fetchResult( + new StringBuilder(referralManagementConfiguration.getProjectHost() + + referralManagementConfiguration.getProjectFacilitySearchUrl() + +"?limit=" + hfReferrals.size() + + "&offset=0&tenantId=" + tenantId), + ProjectFacilitySearchRequest.builder() + .requestInfo(request.getRequestInfo()) + .projectFacility(projectFacilitySearch) + .build(), + ProjectFacilityBulkResponse.class + ); + existingProjectFacilities = projectFacilityBulkResponse.getProjectFacilities(); + } catch (Exception e) { + throw new CustomException("Project Facilities failed to fetch", "Exception : "+e.getMessage()); + } + } + + return existingProjectFacilities; + } + + // Validates project facilities and populates the error map if invalid entities are found + private void validateAndPopulateErrors(List existingProjectFacilities, List entities, Map> errorDetailsMap) { + final List existingProjectFacilityIds = new ArrayList<>(); + + // Extracting IDs from existing project facilities + existingProjectFacilities.forEach(projectFacility -> { + existingProjectFacilityIds.add(projectFacility.getId()); + }); + + // Filtering invalid entities + List invalidEntities = entities.stream().filter(notHavingErrors()).filter(entity -> + Objects.nonNull(entity.getProjectFacilityId()) && !existingProjectFacilityIds.contains(entity.getProjectFacilityId()) + ).collect(Collectors.toList()); + + // Populating error details for invalid entities + invalidEntities.forEach(hfReferral -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(hfReferral, error, errorDetailsMap); + }); + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrProjectIdValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrProjectIdValidator.java new file mode 100644 index 00000000000..78fc23289c4 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrProjectIdValidator.java @@ -0,0 +1,131 @@ +package org.egov.referralmanagement.validator.hfreferral; + +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.project.Project; +import org.egov.common.models.project.ProjectRequest; +import org.egov.common.models.project.ProjectResponse; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.tracer.model.CustomException; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.notHavingErrors; +import static org.egov.common.utils.CommonUtils.populateErrorDetails; +import static org.egov.common.utils.ValidatorUtils.getErrorForNonExistentEntity; + +/** + * Validator for checking the existence of Project entities based on their IDs in HFReferral objects. + * + * Author: kanishq-egov + */ +@Component +@Order(value = 3) +@Slf4j +public class HfrProjectIdValidator implements Validator { + + private final ServiceRequestClient serviceRequestClient; + private final ReferralManagementConfiguration referralManagementConfiguration; + + public HfrProjectIdValidator(ServiceRequestClient serviceRequestClient, ReferralManagementConfiguration referralManagementConfiguration) { + this.serviceRequestClient = serviceRequestClient; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + /** + * Validates whether projects exist in the database or not using project IDs for HFReferral objects. + * + * @param request The HFReferralBulkRequest containing a list of HFReferral entities + * @return A Map containing HFReferral entities as keys and lists of errors as values + */ + @Override + public Map> validate(HFReferralBulkRequest request) { + log.info("Validating project IDs"); + Map> errorDetailsMap = new HashMap<>(); + List entities = request.getHfReferrals(); + + // Grouping HFReferrals by tenantId to fetch projects for each tenant + Map> tenantIdReferralMap = entities.stream().collect(Collectors.groupingBy(HFReferral::getTenantId)); + tenantIdReferralMap.forEach((tenantId, hfReferralList) -> { + // Get all the existing projects in the hfReferral list from Project Service + List existingProjects = getExistingProjects(tenantId, hfReferralList, request); + // Validate projects and populate error map if invalid entities are found + validateAndPopulateErrors(existingProjects, entities, errorDetailsMap); + }); + + return errorDetailsMap; + } + + // Helper method to add an item to a list if it is not null + private void addIgnoreNull(List list, String item) { + if (Objects.nonNull(item)) list.add(item); + } + + // Fetches existing projects from Project Service based on their IDs + private List getExistingProjects(String tenantId, List hfReferrals, HFReferralBulkRequest request) { + List existingProjects = null; + final List projectIdList = new ArrayList<>(); + + // Collecting project IDs from HFReferrals + hfReferrals.forEach(hfReferral -> { + addIgnoreNull(projectIdList, hfReferral.getProjectId()); + }); + + if (!projectIdList.isEmpty()) { + List projects = new ArrayList<>(); + projectIdList.forEach(projectId -> projects.add(Project.builder().id(projectId).tenantId(tenantId).build())); + + try { + // Using project search and fetching the valid IDs. + ProjectResponse projectResponse = serviceRequestClient.fetchResult( + new StringBuilder(referralManagementConfiguration.getProjectHost() + + referralManagementConfiguration.getProjectSearchUrl() + + "?limit=" + hfReferrals.size() + + "&offset=0&tenantId=" + tenantId), + ProjectRequest.builder() + .requestInfo(request.getRequestInfo()) + .projects(projects) + .build(), + ProjectResponse.class + ); + existingProjects = projectResponse.getProject(); + } catch (Exception e) { + throw new CustomException("Projects failed to fetch", "Exception : " + e.getMessage()); + } + } + + return existingProjects; + } + + // Validates projects and populates the error map if invalid entities are found + private void validateAndPopulateErrors(List existingProjects, List entities, Map> errorDetailsMap) { + final List existingProjectIds = new ArrayList<>(); + + // Extracting IDs from existing projects + existingProjects.forEach(project -> { + existingProjectIds.add(project.getId()); + }); + + // Filtering invalid entities + List invalidEntities = entities.stream().filter(notHavingErrors()).filter(entity -> + Objects.nonNull(entity.getProjectId()) && !existingProjectIds.contains(entity.getProjectId()) + ).collect(Collectors.toList()); + + // Populating error details for invalid entities + invalidEntities.forEach(hfReferral -> { + Error error = getErrorForNonExistentEntity(); + populateErrorDetails(hfReferral, error, errorDetailsMap); + }); + } +} 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 new file mode 100644 index 00000000000..e5d62bfee0a --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrRowVersionValidator.java @@ -0,0 +1,74 @@ +package org.egov.referralmanagement.validator.hfreferral; + +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.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.referralmanagement.repository.HFReferralRepository; +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; + +/** + * + * Validator for checking row version mismatch in HFReferral entities during bulk processing. + * Ensures that the row version of existing entities matches the row version in the request. + * + * @author kanishq-egov + */ +@Component +@Order(value = 5) +@Slf4j +public class HfrRowVersionValidator implements Validator { + + private final HFReferralRepository hfReferralRepository; + + @Autowired + public HfrRowVersionValidator(HFReferralRepository hfReferralRepository) { + this.hfReferralRepository = hfReferralRepository; + } + + /** + * Validates row version for HFReferral entities in a bulk request. + * + * @param request The HFReferralBulkRequest containing a list of HFReferral entities + * @return A Map containing HFReferral entities as keys and lists of errors as values + */ + @Override + public Map> validate(HFReferralBulkRequest request) { + log.info("Validating row version"); + Map> errorDetailsMap = new HashMap<>(); + Method idMethod = getIdMethod(request.getHfReferrals()); + Map iMap = getIdToObjMap(request.getHfReferrals().stream() + .filter(notHavingErrors()) + .collect(Collectors.toList()), idMethod); + if (!iMap.isEmpty()) { + List hfReferralIds = new ArrayList<>(iMap.keySet()); + List existingHfReferrals = hfReferralRepository.findById(hfReferralIds, + false, getIdFieldName(idMethod)); + List entitiesWithMismatchedRowVersion = + getEntitiesWithMismatchedRowVersion(iMap, existingHfReferrals, idMethod); + entitiesWithMismatchedRowVersion.forEach(hfReferral -> { + Error error = getErrorForRowVersionMismatch(); + populateErrorDetails(hfReferral, error, errorDetailsMap); + }); + } + return errorDetailsMap; + } +} diff --git a/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrUniqueEntityValidator.java b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrUniqueEntityValidator.java new file mode 100644 index 00000000000..42c84640201 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/validator/hfreferral/HfrUniqueEntityValidator.java @@ -0,0 +1,65 @@ +package org.egov.referralmanagement.validator.hfreferral; + +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.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.validator.Validator; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +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.getErrorForUniqueEntity; + +/** + * + * Validator for checking uniqueness of HFReferral entities in a bulk request. + * Ensures that there are no duplicate entities based on their IDs. + * + * Author: kanishq-egov + */ +@Component +@Order(value = 2) +@Slf4j +public class HfrUniqueEntityValidator implements Validator { + + /** + * Validates the uniqueness of HFReferral entities based on their IDs. + * + * @param request The HFReferralBulkRequest containing a list of HFReferral entities + * @return A Map containing HFReferral entities as keys and lists of errors as values + */ + @Override + public Map> validate(HFReferralBulkRequest request) { + log.info("Validating unique entity"); + Map> errorDetailsMap = new HashMap<>(); + List validEntities = request.getHfReferrals() + .stream().filter(notHavingErrors()).collect(Collectors.toList()); + if (!validEntities.isEmpty()) { + // Create a map of entity IDs to HFReferral objects + Map eMap = getIdToObjMap(validEntities); + + // Check for duplicate IDs + if (eMap.keySet().size() != validEntities.size()) { + List duplicates = eMap.keySet().stream().filter(id -> + validEntities.stream() + .filter(entity -> entity.getId().equals(id)).count() > 1 + ).collect(Collectors.toList()); + + // Populate errors for duplicate entities + for (String key : duplicates) { + Error error = getErrorForUniqueEntity(); + populateErrorDetails(eMap.get(key), error, errorDetailsMap); + } + } + } + return errorDetailsMap; + } +} 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 new file mode 100644 index 00000000000..97650777201 --- /dev/null +++ b/health-services/referralmanagement/src/main/java/org/egov/referralmanagement/web/controllers/HFReferralApiController.java @@ -0,0 +1,193 @@ +package org.egov.referralmanagement.web.controllers; + +import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import io.swagger.annotations.ApiParam; +import org.egov.common.contract.response.ResponseInfo; +import org.egov.common.models.referralmanagement.hfreferral.HFReferral; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkRequest; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralBulkResponse; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralRequest; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralResponse; +import org.egov.common.models.referralmanagement.hfreferral.HFReferralSearchRequest; +import org.egov.common.producer.Producer; +import org.egov.common.utils.ResponseInfoFactory; +import org.egov.referralmanagement.config.ReferralManagementConfiguration; +import org.egov.referralmanagement.service.HFReferralService; +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; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * Controller class for managing HF Referrals. + * @author kanishq-egov + */ +@Controller +@RequestMapping("/hf-referral") +@Validated +public class HFReferralApiController { + private final HttpServletRequest httpServletRequest; + private final HFReferralService hfReferralService; + private final Producer producer; + private final ReferralManagementConfiguration referralManagementConfiguration; + + /** + * Constructor for HFReferralApiController. + * + * @param httpServletRequest The HTTP servlet request. + * @param hfReferralService The service for handling HFReferral operations. + * @param producer The Kafka producer. + * @param referralManagementConfiguration The configuration for referral management. + */ + public HFReferralApiController( + HttpServletRequest httpServletRequest, + HFReferralService hfReferralService, + Producer producer, + ReferralManagementConfiguration referralManagementConfiguration + ) { + this.httpServletRequest = httpServletRequest; + this.hfReferralService = hfReferralService; + this.producer = producer; + this.referralManagementConfiguration = referralManagementConfiguration; + } + + /** + * API endpoint to create a single HFReferral. + * + * @param request The HFReferralRequest containing referral details. + * @return ResponseEntity containing HFReferralResponse. + */ + @RequestMapping(value = "/v1/_create", method = RequestMethod.POST) + public ResponseEntity referralV1CreatePost(@ApiParam(value = "Capture details of HFReferral", required = true) @Valid @RequestBody HFReferralRequest request) { + + HFReferral hfReferral = hfReferralService.create(request); + HFReferralResponse response = HFReferralResponse.builder() + .hfReferral(hfReferral) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } + + /** + * API endpoint to create multiple HFReferrals in bulk. + * + * @param request The HFReferralBulkRequest containing bulk referral details. + * @return ResponseEntity containing ResponseInfo. + */ + @RequestMapping(value = "/v1/bulk/_create", method = RequestMethod.POST) + public ResponseEntity referralBulkV1CreatePost(@ApiParam(value = "Capture details of HFReferral", required = true) @Valid @RequestBody HFReferralBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + hfReferralService.putInCache(request.getHfReferrals()); + producer.push(referralManagementConfiguration.getCreateHFReferralBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } + + /** + * API endpoint to search for HFReferrals based on certain criteria. + * + * @param request The HFReferralSearchRequest containing search criteria. + * @param limit Pagination - limit records in response. + * @param offset Pagination - offset from which records should be returned in response. + * @param tenantId Unique id for a tenant. + * @param lastChangedSince Epoch of the time since when the changes on the object should be picked up. + * @param includeDeleted Used in search APIs to specify if (soft) deleted records should be included in search results. + * @return ResponseEntity containing HFReferralBulkResponse. + * @throws Exception + */ + @RequestMapping(value = "/v1/_search", method = RequestMethod.POST) + public ResponseEntity referralV1SearchPost(@ApiParam(value = "HFReferral Search.", required = true) @Valid @RequestBody HFReferralSearchRequest request, + @NotNull @Min(0) @Max(1000) @ApiParam(value = "Pagination - limit records in response", required = true) @Valid @RequestParam(value = "limit", required = true) Integer limit, + @NotNull @Min(0) @ApiParam(value = "Pagination - offset from which records should be returned in response", required = true) @Valid @RequestParam(value = "offset", required = true) Integer offset, + @NotNull @ApiParam(value = "Unique id for a tenant.", required = true) @Valid @RequestParam(value = "tenantId", required = true) String tenantId, + @ApiParam(value = "Epoch of the time since when the changes on the object should be picked up. Search results from this parameter should include both newly created objects since this time as well as any modified objects since this time. This criterion is included to help polling clients to get the changes in system since a last time they synchronized with the platform. ") @Valid @RequestParam(value = "lastChangedSince", required = false) Long lastChangedSince, + @ApiParam(value = "Used in search APIs to specify if (soft) deleted records should be included in search results.", defaultValue = "false") @Valid @RequestParam(value = "includeDeleted", required = false, defaultValue = "false") Boolean includeDeleted) throws Exception { + + List hfReferrals = hfReferralService.search(request, limit, offset, tenantId, lastChangedSince, includeDeleted); + HFReferralBulkResponse response = HFReferralBulkResponse.builder().responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)).hfReferrals(hfReferrals).build(); + + return ResponseEntity.status(HttpStatus.OK).body(response); + } + + /** + * API endpoint to update a single HFReferral. + * + * @param request The HFReferralRequest containing updated referral details. + * @return ResponseEntity containing HFReferralResponse. + */ + @RequestMapping(value = "/v1/_update", method = RequestMethod.POST) + public ResponseEntity referralV1UpdatePost(@ApiParam(value = "Capture details of Existing HFReferral", required = true) @Valid @RequestBody HFReferralRequest request) { + HFReferral hfReferral = hfReferralService.update(request); + + HFReferralResponse response = HFReferralResponse.builder() + .hfReferral(hfReferral) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } + + /** + * API endpoint to update multiple HFReferrals in bulk. + * + * @param request The HFReferralBulkRequest containing bulk updated referral details. + * @return ResponseEntity containing ResponseInfo. + */ + @RequestMapping(value = "/v1/bulk/_update", method = RequestMethod.POST) + public ResponseEntity referralV1BulkUpdatePost(@ApiParam(value = "Capture details of Existing HFReferral", required = true) @Valid @RequestBody HFReferralBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + producer.push(referralManagementConfiguration.getUpdateHFReferralBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } + + /** + * API endpoint to delete a single HFReferral. + * + * @param request The HFReferralRequest containing details of the referral to be deleted. + * @return ResponseEntity containing HFReferralResponse. + */ + @RequestMapping(value = "/v1/_delete", method = RequestMethod.POST) + public ResponseEntity referralV1DeletePost(@ApiParam(value = "Capture details of Existing HFReferral", required = true) @Valid @RequestBody HFReferralRequest request) { + HFReferral hfReferral = hfReferralService.delete(request); + + HFReferralResponse response = HFReferralResponse.builder() + .hfReferral(hfReferral) + .responseInfo(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)) + .build(); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(response); + } + + /** + * API endpoint to delete multiple HFReferrals in bulk. + * + * @param request The HFReferralBulkRequest containing details of the referrals to be deleted in bulk. + * @return ResponseEntity containing ResponseInfo. + */ + @RequestMapping(value = "/v1/bulk/_delete", method = RequestMethod.POST) + public ResponseEntity referralV1BulkDeletePost(@ApiParam(value = "Capture details of Existing HFReferral", required = true) @Valid @RequestBody HFReferralBulkRequest request) { + request.getRequestInfo().setApiId(httpServletRequest.getRequestURI()); + producer.push(referralManagementConfiguration.getDeleteHFReferralBulkTopic(), request); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body(ResponseInfoFactory + .createResponseInfo(request.getRequestInfo(), true)); + } +} diff --git a/health-services/referralmanagement/src/main/resources/application.properties b/health-services/referralmanagement/src/main/resources/application.properties index 22830c099f1..b7ac09656ac 100644 --- a/health-services/referralmanagement/src/main/resources/application.properties +++ b/health-services/referralmanagement/src/main/resources/application.properties @@ -97,10 +97,12 @@ egov.search.individual.url=/individual/v1/_search egov.user.id.validator=individual # PROJECT SERVICE -egov.project.host=http://localhost:8084 +egov.project.host=https://unified-dev.digit.org +egov.search.project.url=/project/v1/_search egov.search.project.task.url=/project/task/v1/_search egov.search.project.beneficiary.url=/project/beneficiary/v1/_search egov.search.project.staff.url=/project/staff/v1/_search +egov.search.project.facility.url=/project/facility/v1/_search # ADRM KAFKA CONFIG @@ -120,6 +122,14 @@ referralmanagement.referral.consumer.bulk.create.topic=save-referral-bulk-topic referralmanagement.referral.consumer.bulk.update.topic=update-referral-bulk-topic referralmanagement.referral.consumer.bulk.delete.topic=delete-referral-bulk-topic +referralmanagement.hfreferral.kafka.create.topic=save-hfreferral-topic +referralmanagement.hfreferral.kafka.update.topic=update-hfreferral-topic +referralmanagement.hfreferral.kafka.delete.topic=delete-hfreferral-topic + +referralmanagement.hfreferral.consumer.bulk.create.topic=save-hfreferral-bulk-topic +referralmanagement.hfreferral.consumer.bulk.update.topic=update-hfreferral-bulk-topic +referralmanagement.hfreferral.consumer.bulk.delete.topic=delete-hfreferral-bulk-topic + search.api.limit=1000 referralmanagement.default.offset=0 diff --git a/health-services/referralmanagement/src/main/resources/db/migration/main/V20231214113400__hf_referral_create_ddl.sql b/health-services/referralmanagement/src/main/resources/db/migration/main/V20231214113400__hf_referral_create_ddl.sql new file mode 100644 index 00000000000..0d4dfbd4dad --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/db/migration/main/V20231214113400__hf_referral_create_ddl.sql @@ -0,0 +1,25 @@ +CREATE table IF NOT EXISTS hf_referral ( + id character varying(64), + clientreferenceid character varying(64), + tenantid character varying(1000), + projectid character varying(64), + facilityId character varying(64), + symptom character varying(256), + symptomsurveyid character varying(100), + beneficiaryid character varying(100), + referralcode character varying(100), + nationallevelid character varying(100), + createdby character varying(64), + createdtime bigint, + lastmodifiedby character varying(64), + lastmodifiedtime bigint, + clientcreatedby character varying(64), + clientcreatedtime bigint, + clientlastmodifiedby character varying(64), + clientlastmodifiedtime bigint, + rowversion bigint, + isdeleted boolean, + additionaldetails jsonb, + CONSTRAINT uk_hf_referral_id PRIMARY KEY (id), + CONSTRAINT uk_hf_referral_clientReferenceId UNIQUE (clientReferenceId) +); \ No newline at end of file diff --git a/health-services/referralmanagement/src/main/resources/db/migration/main/V20240103142200__hf_referral_project_facility_rename_ddl.sql b/health-services/referralmanagement/src/main/resources/db/migration/main/V20240103142200__hf_referral_project_facility_rename_ddl.sql new file mode 100644 index 00000000000..f7a8fb9b884 --- /dev/null +++ b/health-services/referralmanagement/src/main/resources/db/migration/main/V20240103142200__hf_referral_project_facility_rename_ddl.sql @@ -0,0 +1 @@ +ALTER TABLE hf_referral RENAME COLUMN facilityid to projectfacilityid; \ No newline at end of file diff --git a/health-services/stock/CHANGELOG.md b/health-services/stock/CHANGELOG.md index c837b842a64..83d0dd54070 100644 --- a/health-services/stock/CHANGELOG.md +++ b/health-services/stock/CHANGELOG.md @@ -1,5 +1,8 @@ All notable changes to this module will be documented in this file. +## 1.1.2 - 2024-02-26 +- Enhance inventory flow with sender id and receiver id added. + ## 1.1.1 - 2023-11-15 - Enhanced inventory flow for last mile delivery with QR code diff --git a/health-services/stock/pom.xml b/health-services/stock/pom.xml index 383f790553d..a6d29a41ba7 100644 --- a/health-services/stock/pom.xml +++ b/health-services/stock/pom.xml @@ -5,7 +5,7 @@ stock jar stock - 1.1.1 + 1.1.2 1.8 ${java.version} @@ -49,7 +49,7 @@ org.egov.common health-services-models - 1.0.9-SNAPSHOT + 1.0.15-SNAPSHOT diff --git a/health-services/stock/src/main/java/org/egov/stock/config/MainConfiguration.java b/health-services/stock/src/main/java/org/egov/stock/config/MainConfiguration.java index e0d61ae0682..b067e1cb2ab 100644 --- a/health-services/stock/src/main/java/org/egov/stock/config/MainConfiguration.java +++ b/health-services/stock/src/main/java/org/egov/stock/config/MainConfiguration.java @@ -6,6 +6,8 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.databind.module.SimpleModule; +import org.egov.common.models.core.validator.CustomIntegerDeserializer; import org.egov.tracer.config.TracerConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -42,7 +44,12 @@ public void initialize() { @Bean public ObjectMapper objectMapper(){ - return new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).setTimeZone(TimeZone.getTimeZone(timeZone)); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + SimpleModule module = new SimpleModule(); + module.addDeserializer(Integer.class, new CustomIntegerDeserializer()); + objectMapper.registerModule(module); + return objectMapper.setTimeZone(TimeZone.getTimeZone(timeZone)); } @Bean 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 89471581084..d011f3301a4 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 @@ -4,6 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import digit.models.coremodels.AuditDetails; import org.egov.common.models.stock.AdditionalFields; +import org.egov.common.models.stock.ReferenceIdType; +import org.egov.common.models.stock.SenderReceiverType; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.TransactionReason; import org.egov.common.models.stock.TransactionType; @@ -33,6 +35,10 @@ public Stock mapRow(ResultSet resultSet, int i) throws SQLException { .lastModifiedTime(resultSet.getLong("clientLastModifiedTime")) .lastModifiedBy(resultSet.getString("clientLastModifiedBy")) .build(); + Long dateOfEntry = resultSet.getLong("dateOfEntry"); + if(resultSet.wasNull()){ + dateOfEntry = null; + } return Stock.builder() .id(resultSet.getString("id")) .clientReferenceId(resultSet.getString("clientReferenceId")) @@ -41,20 +47,20 @@ public Stock mapRow(ResultSet resultSet, int i) throws SQLException { .quantity(resultSet.getInt("quantity")) .wayBillNumber(resultSet.getString("wayBillNumber")) .referenceId(resultSet.getString("referenceId")) - .referenceIdType(resultSet.getString("referenceIdType")) + .referenceIdType(ReferenceIdType.fromValue(resultSet.getString("referenceIdType"))) .transactionType(TransactionType.fromValue(resultSet.getString("transactionType"))) .transactionReason(TransactionReason.fromValue(resultSet.getString("transactionReason"))) .senderId(resultSet.getString("senderId")) - .senderType(resultSet.getString("senderType")) + .senderType(SenderReceiverType.fromValue(resultSet.getString("senderType"))) .receiverId(resultSet.getString("receiverId")) - .receiverType(resultSet.getString("receiverType")) + .receiverType(SenderReceiverType.fromValue(resultSet.getString("receiverType"))) .additionalFields(resultSet.getString("additionalDetails") == null ? null : objectMapper .readValue(resultSet.getString("additionalDetails"), AdditionalFields.class)) .auditDetails(auditDetails) .clientAuditDetails(clientAuditDetails) .rowVersion(resultSet.getInt("rowVersion")) .isDeleted(resultSet.getBoolean("isDeleted")) - .dateOfEntry(resultSet.getLong("dateOfEntry")) + .dateOfEntry(dateOfEntry) .build(); } catch (JsonProcessingException e) { throw new SQLException(e); 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 068a26a99fb..5d93a0ecfdd 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 @@ -25,6 +25,7 @@ import org.egov.common.models.project.ProjectFacilityBulkResponse; import org.egov.common.models.project.ProjectFacilitySearch; import org.egov.common.models.project.ProjectFacilitySearchRequest; +import org.egov.common.models.stock.SenderReceiverType; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockReconciliation; import org.egov.stock.config.StockConfiguration; @@ -97,10 +98,10 @@ public Map> validateProjectFacilityMappings(List ent Stock stock = (Stock) entity; - if (stock.getSenderType().equalsIgnoreCase(WAREHOUSE)) { + if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType())) { facilityIds.add(stock.getSenderId()); } - if (stock.getReceiverType().equalsIgnoreCase(WAREHOUSE)) { + if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType())) { facilityIds.add(stock.getReceiverId()); } } 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 8bbbd72c065..7876d60ac63 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 @@ -34,6 +34,7 @@ import org.egov.stock.validator.stock.SProductVariantIdValidator; import org.egov.stock.validator.stock.SReferenceIdValidator; import org.egov.stock.validator.stock.SRowVersionValidator; +import org.egov.stock.validator.stock.SSenderIdReceiverIdEqualsValidator; import org.egov.stock.validator.stock.SUniqueEntityValidator; import org.egov.stock.validator.stock.StocktransferPartiesValidator; import org.egov.stock.web.models.StockSearchRequest; @@ -57,6 +58,7 @@ public class StockService { private final Predicate> isApplicableForCreate = validator -> validator.getClass().equals(SProductVariantIdValidator.class) + || validator.getClass().equals(SSenderIdReceiverIdEqualsValidator.class) || validator.getClass().equals(StocktransferPartiesValidator.class) || validator.getClass().equals(SReferenceIdValidator.class); @@ -68,11 +70,13 @@ public class StockService { || validator.getClass().equals(SRowVersionValidator.class) || validator.getClass().equals(SUniqueEntityValidator.class) || validator.getClass().equals(SReferenceIdValidator.class) + || validator.getClass().equals(SSenderIdReceiverIdEqualsValidator.class) || validator.getClass().equals(StocktransferPartiesValidator.class); private final Predicate> isApplicableForDelete = validator -> validator.getClass().equals(SNonExistentValidator.class) - || validator.getClass().equals(SNullIdValidator.class); + || validator.getClass().equals(SNullIdValidator.class) + || validator.getClass().equals(SRowVersionValidator.class); public StockService(StockRepository stockRepository, List> validators, StockConfiguration configuration, StockEnrichmentService enrichmentService) { this.stockRepository = stockRepository; 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 b39ad93699d..b46431fe018 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 @@ -21,6 +21,7 @@ import org.egov.common.contract.request.RequestInfo; import org.egov.common.ds.Tuple; import org.egov.common.models.Error; +import org.egov.common.models.stock.SenderReceiverType; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockReconciliation; import org.egov.common.service.UserService; @@ -64,17 +65,13 @@ public static Map> validateFacilityIds(R request, Map - * @param - * @param stockRequest + * Non-generic method used for validating sender/receiver (parties) against facility or staff based on the type + * + * @param requestInfo * @param errorDetailsMap - * @param validEntities - * @param getId + * @param validStockEntities * @param facilityService + * @param userService * @return */ public static Map> validateStockTransferParties(RequestInfo requestInfo, @@ -94,17 +91,14 @@ public static Map> validateStockTransferParties(RequestInf } /** - * validates the list of party-ids (facility and staff) against the respective - * APIs and enriches the invalid ids list for both parties - * - * @param - * @param stockRequest + * Validates the list of party-ids (facility and staff) against the respective APIs and enriches the invalid ids list for both parties. + * + * @param requestInfo * @param errorDetailsMap * @param validStockEntities * @param facilityService - * @param facilityIds - * @param InvalidStaffId - * @param invalidFacilityIds + * @param userService + * @return A tuple containing lists of invalid facility ids and invalid staff ids */ @SuppressWarnings("unchecked") private static Tuple, List> validateAndEnrichInvalidPartyIds(RequestInfo requestInfo, @@ -158,18 +152,18 @@ private static void enrichFaciltyAndStaffIdsFromStock(List validStockEnti for (Stock stock : validStockEntities) { - if (stock.getSenderType().equalsIgnoreCase(WAREHOUSE)) { + if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) && stock.getSenderId() != null) { facilityIds.add(stock.getSenderId()); - } - if (stock.getSenderType().equalsIgnoreCase(STAFF)) { + } else if (SenderReceiverType.STAFF.equals(stock.getSenderType()) && stock.getSenderId() != null) { staffIds.add(stock.getSenderId()); } - if (stock.getReceiverType().equalsIgnoreCase(WAREHOUSE)) { + + if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) && stock.getReceiverId() != null) { facilityIds.add(stock.getReceiverId()); - } - if (stock.getReceiverType().equalsIgnoreCase(STAFF)) { + } else if (SenderReceiverType.STAFF.equals(stock.getReceiverType()) && stock.getReceiverId() != null) { staffIds.add(stock.getReceiverId()); } + } } @@ -179,7 +173,7 @@ private static void enrichFaciltyAndStaffIdsFromStock(List validStockEnti * * @param errorDetailsMap * @param validStockEntities - * @param InvalidStaffId + * @param invalidStaffIds * @param invalidFacilityIds */ @SuppressWarnings("unchecked") @@ -195,16 +189,16 @@ private static void enrichErrorMapFromInvalidPartyIds(Map> er String senderId = stock.getSenderId(); String recieverId = stock.getReceiverId(); - if ((stock.getSenderType().equalsIgnoreCase(WAREHOUSE) && invalidFacilityIds.contains(senderId)) + if ((SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) && invalidFacilityIds.contains(senderId)) - || (stock.getSenderType().equalsIgnoreCase(STAFF) && invalidStaffIds.contains(senderId))) { + || (SenderReceiverType.STAFF.equals(stock.getSenderType()) && invalidStaffIds.contains(senderId))) { getIdForErrorFromMethod(errorDetailsMap, (T) stock, senderIdMethod); } - if ((stock.getReceiverType().equalsIgnoreCase(WAREHOUSE) && invalidFacilityIds.contains(recieverId)) + if ((SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) && invalidFacilityIds.contains(recieverId)) - || (stock.getReceiverType().equalsIgnoreCase(STAFF) && invalidStaffIds.contains(recieverId))) { + || (SenderReceiverType.STAFF.equals(stock.getReceiverType()) && invalidStaffIds.contains(recieverId))) { getIdForErrorFromMethod(errorDetailsMap, (T) stock, recieverIdMethod); } @@ -232,7 +226,7 @@ private static void getIdForErrorFromMethod(Map> errorDetails * @param request * @param errorDetailsMap * @param validEntities - * @param getId + * @param getReferenceId * @param facilityService * @return */ @@ -279,11 +273,11 @@ private static void enrichErrorForStock(List validEntities, List facilityIds = ProjectFacilityMappingOfIds.get(stock.getReferenceId()); if (!CollectionUtils.isEmpty(facilityIds)) { - if (stock.getSenderType().equalsIgnoreCase("WAREHOUSE") && !facilityIds.contains(senderId)) { + if (SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) && !facilityIds.contains(senderId)) { populateErrorForStock(stock, senderId, errorDetailsMap); } - if (stock.getReceiverType().equalsIgnoreCase("WAREHOUSE") && !facilityIds.contains(receiverId)) + if (SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) && !facilityIds.contains(receiverId)) populateErrorForStock(stock, receiverId, errorDetailsMap); } else { populateErrorForStock(stock, senderId + " and " + receiverId, errorDetailsMap); diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java index 47a17106727..ceab1dfb887 100644 --- a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SReferenceIdValidator.java @@ -2,6 +2,8 @@ import lombok.extern.slf4j.Slf4j; import org.egov.common.models.Error; +import org.egov.common.models.stock.ReferenceIdType; +import org.egov.common.models.stock.SenderReceiverType; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.StockBulkRequest; import org.egov.common.validator.Validator; @@ -37,11 +39,11 @@ public Map> validate(StockBulkRequest request) { List validEntities = request.getStock().stream() .filter(notHavingErrors()) - .filter(entity -> PROJECT.equals(entity.getReferenceIdType())) + .filter(entity -> ReferenceIdType.PROJECT.equals(entity.getReferenceIdType())) .collect(Collectors.toList()); - long countOfWareHouseInStock = request.getStock().stream().filter(stock -> - stock.getReceiverType().equalsIgnoreCase("WAREHOUSE") || stock.getSenderType().equalsIgnoreCase("WAREHOUSE") + long countOfWareHouseInStock = request.getStock().stream().filter(stock -> + SenderReceiverType.WAREHOUSE.equals(stock.getReceiverType()) || SenderReceiverType.WAREHOUSE.equals(stock.getSenderType()) ).count(); if(countOfWareHouseInStock == 0) return errorDetailsMap; diff --git a/health-services/stock/src/main/java/org/egov/stock/validator/stock/SSenderIdReceiverIdEqualsValidator.java b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SSenderIdReceiverIdEqualsValidator.java new file mode 100644 index 00000000000..4285d90d26d --- /dev/null +++ b/health-services/stock/src/main/java/org/egov/stock/validator/stock/SSenderIdReceiverIdEqualsValidator.java @@ -0,0 +1,75 @@ +package org.egov.stock.validator.stock; + +import java.util.ArrayList; +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.stock.Stock; +import org.egov.common.models.stock.StockBulkRequest; +import org.egov.common.validator.Validator; +import org.egov.tracer.model.CustomException; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import static org.egov.common.utils.CommonUtils.populateErrorDetails; + +/** + * Validator class to check if senderId and receiverId are equal in a list of Stock entities. + */ +@Component +@Order(value = 6) +@Slf4j +public class SSenderIdReceiverIdEqualsValidator implements Validator { + + /** + * Validates the list of Stock entities to ensure that senderId and receiverId are not equal. + * + * @param stockBulkRequest The bulk request containing a list of Stock entities. + * @return A map containing Stock entities with corresponding error details for entities with equal senderId and receiverId. + */ + @Override + public Map> validate(StockBulkRequest stockBulkRequest) { + Map> errorDetailsMap = new HashMap<>(); + List entities = stockBulkRequest.getStock(); + List invalidEntities = new ArrayList<>(); + log.info("validating whether sender id and receiver id are same"); + + // Iterate through each Stock entity in the list + entities.forEach(stock -> { + // Check if senderId and receiverId are equal using helper method + if (areSenderAndReceiverEqual(stock)) { + // If equal, add the entity to the list of invalid entities + invalidEntities.add(stock); + + // Create an error object for the entity + Error error = Error.builder() + .errorMessage("Sender Id and Receiver Id cannot be the same") + .errorCode("SENDER_RECEIVER_CANNOT_BE_EQUAL") + .type(Error.ErrorType.NON_RECOVERABLE) + .exception(new CustomException("SENDER_RECEIVER_CANNOT_BE_EQUAL", "Sender Id and Receiver Id cannot be the same")) + .build(); + + // Populate error details for the entity + populateErrorDetails(stock, error, errorDetailsMap); + } + }); + + return errorDetailsMap; + } + + /** + * Helper method to check if senderId and receiverId are equal. + * + * @param stock The Stock entity to check. + * @return True if senderId and receiverId are equal, false otherwise. + */ + private boolean areSenderAndReceiverEqual(Stock stock) { + return stock.getSenderType() == stock.getReceiverType() + && stock.getReceiverId() != null + && stock.getSenderId() != null + && stock.getReceiverId().equals(stock.getSenderId()); + } +} diff --git a/health-services/stock/src/test/java/org/egov/stock/TestConfiguration.java b/health-services/stock/src/test/java/org/egov/stock/TestConfiguration.java index 0d8d9758688..d507efd67c1 100644 --- a/health-services/stock/src/test/java/org/egov/stock/TestConfiguration.java +++ b/health-services/stock/src/test/java/org/egov/stock/TestConfiguration.java @@ -1,5 +1,11 @@ package org.egov.stock; +import java.util.TimeZone; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import org.egov.common.models.core.validator.CustomIntegerDeserializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.core.KafkaTemplate; @@ -13,4 +19,14 @@ public class TestConfiguration { public KafkaTemplate kafkaTemplate() { return mock(KafkaTemplate.class); } + + @Bean + public ObjectMapper objectMapper(){ + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + SimpleModule module = new SimpleModule(); + module.addDeserializer(Integer.class, new CustomIntegerDeserializer()); + objectMapper.registerModule(module); + return objectMapper.setTimeZone(TimeZone.getTimeZone("UTC")); + } } \ No newline at end of file diff --git a/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java b/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java index 90960baf5a3..fd83333e42e 100644 --- a/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java +++ b/health-services/stock/src/test/java/org/egov/stock/helper/StockTestBuilder.java @@ -1,6 +1,8 @@ package org.egov.stock.helper; import org.egov.common.helper.AuditDetailsTestBuilder; +import org.egov.common.models.stock.ReferenceIdType; +import org.egov.common.models.stock.SenderReceiverType; import org.egov.common.models.stock.Stock; import org.egov.common.models.stock.TransactionReason; import org.egov.common.models.stock.TransactionType; @@ -26,13 +28,16 @@ public StockTestBuilder withStock() { this.builder .senderId("sender-id") .receiverId("receiver-id") - .productVariantId("pv-id").quantity(0) + .productVariantId("pv-id") + .quantity(1) .referenceId("reference-id") - .referenceIdType("PROJECT").rowVersion(1).tenantId("default") + .referenceIdType(ReferenceIdType.PROJECT) + .rowVersion(1) + .tenantId("default") .transactionType(TransactionType.DISPATCHED) .transactionReason(TransactionReason.RECEIVED) - .senderType("WAREHOUSE") - .receiverType("STAFF") + .senderType(SenderReceiverType.WAREHOUSE) + .receiverType(SenderReceiverType.STAFF) .hasErrors(false) .isDeleted(Boolean.FALSE) .auditDetails(AuditDetailsTestBuilder.builder().withAuditDetails().build());