diff --git a/core-services/egov-hrms/pom.xml b/core-services/egov-hrms/pom.xml
index 0a0507aa5a4..ff717d747cc 100644
--- a/core-services/egov-hrms/pom.xml
+++ b/core-services/egov-hrms/pom.xml
@@ -39,11 +39,11 @@
org.flywaydb
flyway-core
- 9.22.3
org.postgresql
postgresql
+ 42.7.1
org.egov.services
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
index 1f0522f0d36..14e911985c0 100644
--- 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
@@ -82,7 +82,13 @@ public class PropertiesManager {
@Value("${egov.idgen.path}")
public String idGenEndpoint;
-
+
+ // Email
+ @Value("${kafka.topics.notification.email}")
+ private String emailNotifTopic;
+
+ @Value("${notification.email.enabled}")
+ private Boolean isEmailNotificationEnabled;
//Kafka Topics
@Value("${kafka.topics.save.service}")
@@ -96,7 +102,9 @@ public class PropertiesManager {
@Value("${kafka.topics.hrms.updateData}")
public String updateTopic;
-
+
+ @Value("${kafka.topics.hrms.email.notification}")
+ public String hrmsEmailNotifTopic;
//Variables
@Value("${egov.idgen.ack.name}")
@@ -140,4 +148,10 @@ public class PropertiesManager {
@Value("${egov.boundary.search.url}")
private String boundarySearchUrl;
+
+ @Value("${hrms.email.notification.implementation.partner}")
+ public String emailNotificationImplementationPartner;
+
+ @Value("${hrms.email.notification.website.link}")
+ public String emailNotificationWebsiteLink;
}
\ 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
index a4c33b0c096..74b2360cd73 100644
--- 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
@@ -32,12 +32,17 @@ public class HrmsConsumer {
@Autowired
private PropertiesManager propertiesManager;
- @KafkaListener(topics = {"${kafka.topics.hrms.updateData}"})
+ @KafkaListener(topics = {"${kafka.topics.hrms.updateData}", "${kafka.topics.hrms.email.notification}"})
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);
+
+ if(topic.equals(propertiesManager.getHrmsEmailNotifTopic())) {
+ notificationService.processEmailNotification(employeeRequest);
+ } else {
+ 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/service/EmployeeService.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java
index 2cecd5f5f71..c42d487fa2d 100644
--- 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
@@ -121,8 +121,12 @@ public EmployeeResponse create(EmployeeRequest employeeRequest) {
enrichCreateRequest(employee, requestInfo);
createUser(employee, requestInfo);
pwdMap.put(employee.getUuid(), employee.getUser().getPassword());
- employee.getUser().setPassword(null);
});
+ hrmsProducer.push(propertiesManager.getHrmsEmailNotifTopic(), employeeRequest);
+
+ // Setting password as null after sending employeeRequest to email notification topic to send email.
+ employeeRequest.getEmployees().forEach(employee -> employee.getUser().setPassword(null));
+
hrmsProducer.push(propertiesManager.getSaveEmployeeTopic(), employeeRequest);
notificationService.sendNotification(employeeRequest, pwdMap);
return generateResponse(employeeRequest);
@@ -137,6 +141,7 @@ public EmployeeResponse create(EmployeeRequest employeeRequest) {
*/
public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requestInfo) {
boolean userChecked = false;
+ Long totalCount = 0L;
/*if(null == criteria.getIsActive() || criteria.getIsActive())
criteria.setIsActive(true);
else
@@ -156,6 +161,7 @@ public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requ
userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_USERNAME, criteria.getCodes().get(0));
}
UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria);
+ totalCount = userResponse.getTotalCount();
userChecked =true;
if(!CollectionUtils.isEmpty(userResponse.getUser())) {
mapOfUsers.putAll(userResponse.getUser().stream()
@@ -178,6 +184,7 @@ public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requ
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);
+ totalCount = userResponse.getTotalCount();
userChecked =true;
if(!CollectionUtils.isEmpty(userResponse.getUser())) {
mapOfUsers.putAll(userResponse.getUser().stream()
@@ -191,6 +198,32 @@ public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requ
else
criteria.setUuids(userUUIDs);
}
+
+ if(!CollectionUtils.isEmpty(criteria.getUserServiceUuids())) {
+ List userUUIDs = new ArrayList<>();
+ Map userSearchCriteria = new HashMap<>();
+
+ userSearchCriteria.put(HRMSConstants.HRMS_USER_SERACH_CRITERIA_USERTYPE_CODE, HRMSConstants.HRMS_USER_SERACH_CRITERIA_USERTYPE);
+ userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_TENANTID, criteria.getTenantId());
+ userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_USER_SERVICE_UUIDS, criteria.getUserServiceUuids());
+ if(!CollectionUtils.isEmpty(criteria.getNames()))
+ userSearchCriteria.put(HRMSConstants.HRMS_USER_SEARCH_CRITERA_NAME, criteria.getNames().get(0));
+ UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria);
+ totalCount = userResponse.getTotalCount();
+ 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);
@@ -207,6 +240,7 @@ public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requ
if(mapOfUsers.isEmpty()){
log.info("searching in user service");
UserResponse userResponse = userService.getUser(requestInfo, userSearchCriteria);
+ totalCount = userResponse.getTotalCount();
if(!CollectionUtils.isEmpty(userResponse.getUser())) {
mapOfUsers = userResponse.getUser().stream()
.collect(Collectors.toMap(User :: getUuid, Function.identity()));
@@ -217,7 +251,8 @@ public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requ
}
}
return EmployeeResponse.builder().responseInfo(factory.createResponseInfoFromRequestInfo(requestInfo, true))
- .employees(employees).build();
+ .employees(employees)
+ .totalCount(totalCount).build();
}
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
index 6a967bf8cfb..40482914921 100644
--- 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
@@ -22,7 +22,6 @@
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.Name;
@@ -33,10 +32,12 @@
import org.egov.hrms.web.contract.User;
import org.egov.hrms.web.contract.UserRequest;
import org.egov.hrms.web.contract.UserResponse;
+import org.egov.hrms.web.models.IndividualBulkResponse;
import org.egov.hrms.web.models.IndividualSearch;
import org.egov.hrms.web.models.IndividualSearchRequest;
import org.springframework.beans.factory.annotation.Autowired;
+import static org.egov.hrms.utils.HRMSConstants.HRMS_USER_SEARCH_CRITERA_USER_SERVICE_UUIDS;
import static org.egov.hrms.utils.HRMSConstants.SYSTEM_GENERATED;
@Slf4j
@@ -210,6 +211,7 @@ public UserResponse getUser(RequestInfo requestInfo, Map userSea
mobileNumberList
)
.id((List) userSearchCriteria.get("uuid"))
+ .userUuid((List) userSearchCriteria.get(HRMS_USER_SEARCH_CRITERA_USER_SERVICE_UUIDS))
.roleCodes((List) userSearchCriteria.get("roleCodes"))
.username(usernameList)
// given name
@@ -331,6 +333,7 @@ private static UserResponse mapToUserResponse(IndividualBulkResponse response) {
.responseInfo(response.getResponseInfo())
.user(response.getIndividual().stream()
.map(IndividualService::getUser).collect(Collectors.toList()))
+ .totalCount(response.getTotalCount())
.build();
return userResponse;
}
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
index acb427e4ce7..a8915e3983c 100644
--- 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
@@ -11,30 +11,40 @@
import org.egov.hrms.producer.HRMSProducer;
import org.egov.hrms.repository.RestCallRepository;
import org.egov.hrms.utils.HRMSConstants;
+import org.egov.hrms.utils.NotificationUtil;
+import org.egov.hrms.web.contract.EmailRequest;
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.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
+import static org.egov.hrms.utils.HRMSConstants.HEALTH_HRMS_EMAIL_LOCALIZATION_CODE;
+
@Service
@Slf4j
public class NotificationService {
-
- @Autowired
+
private HRMSProducer producer;
-
- @Autowired
+
private RestCallRepository repository;
- @Autowired
private RestTemplate restTemplate;
+ private NotificationUtil notificationUtil;
+
+ public NotificationService(HRMSProducer producer, RestCallRepository repository, RestTemplate restTemplate, NotificationUtil notificationUtil) {
+ this.producer = producer;
+ this.repository = repository;
+ this.restTemplate = restTemplate;
+ this.notificationUtil = notificationUtil;
+ }
+
@Value("${kafka.topics.notification.sms}")
private String smsTopic;
@@ -193,4 +203,26 @@ public Map> getLocalisedMessages(RequestInfo request
return localizedMessageMap;
}
+ /**
+ * Creates and sends email notification to the employees whose details are provided in the employeeRequest.
+ *
+ * @param employeeRequest The employee request with employee details.
+ */
+ public void processEmailNotification(EmployeeRequest employeeRequest) {
+ if (employeeRequest == null || CollectionUtils.isEmpty(employeeRequest.getEmployees())) {
+ log.error("Invalid employee request received for email notification");
+ return;
+ }
+ try {
+ // Fetch localization messages and get email message template for HEALTH_HRMS_EMAIL_LOCALIZATION_CODE template code.
+ String localizationMessages = notificationUtil.getLocalizationMessages(employeeRequest);
+ String messageTemplate = notificationUtil.getMessageTemplate(HEALTH_HRMS_EMAIL_LOCALIZATION_CODE, localizationMessages);
+
+ // Create email requests from the employee details provided in the employeeRequest.
+ List emailRequests = notificationUtil.createEmailRequest(employeeRequest, messageTemplate);
+ notificationUtil.sendEmail(emailRequests);
+ } catch (Exception e) {
+ log.error("Error processing email notification for given employees");
+ }
+ }
}
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
index 0d01b642d97..34ef1076fdb 100644
--- 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
@@ -30,6 +30,8 @@ public class HRMSConstants {
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 HEALTH_HRMS_LOCALIZATION_MODULE_CODE = "rainmaker-hr";
+ public static final String HEALTH_HRMS_EMAIL_LOCALIZATION_CODE = "HEALTH_HRMS_EMAIL_CODE";
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";
@@ -39,6 +41,7 @@ public class HRMSConstants {
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_USER_SERVICE_UUIDS = "userServiceUuids";
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";
diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/NotificationUtil.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/NotificationUtil.java
new file mode 100644
index 00000000000..22b8ea41493
--- /dev/null
+++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/utils/NotificationUtil.java
@@ -0,0 +1,154 @@
+package org.egov.hrms.utils;
+
+import com.jayway.jsonpath.JsonPath;
+import lombok.extern.slf4j.Slf4j;
+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.producer.HRMSProducer;
+import org.egov.hrms.repository.RestCallRepository;
+import org.egov.hrms.web.contract.Email;
+import org.egov.hrms.web.contract.EmailRequest;
+import org.egov.hrms.web.contract.EmployeeRequest;
+import org.egov.hrms.web.contract.RequestInfoWrapper;
+import org.json.JSONObject;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.egov.hrms.utils.HRMSConstants.*;
+
+@Slf4j
+@Component
+public class NotificationUtil {
+
+ private RestCallRepository restCallRepository;
+
+ private PropertiesManager propertiesManager;
+
+ private HRMSProducer producer;
+
+ public NotificationUtil(RestCallRepository restCallRepository, PropertiesManager propertiesManager, HRMSProducer producer) {
+ this.restCallRepository = restCallRepository;
+ this.propertiesManager = propertiesManager;
+ this.producer = producer;
+ }
+
+ /**
+ * Extracts message for the specific code from the localization messages.
+ *
+ * @param notificationCode The code for which message is required.
+ * @param localizationMessage The localization messages.
+ * @return message for the specific code.
+ */
+ public String getMessageTemplate(String notificationCode, String localizationMessage) {
+ // Create the path to get the message for the provided notification code from localization messages.
+ String path = "$..messages[?(@.code==\"{}\")].message";
+ path = path.replace("{}", notificationCode);
+ String message = null;
+ try {
+ // Tries to get the message for the provided notificationCode.
+ List data = JsonPath.parse(localizationMessage).read(path);
+ if (!CollectionUtils.isEmpty(data))
+ message = data.get(0).toString();
+ else
+ log.error("Fetching from localization failed with code " + notificationCode);
+ } catch (Exception e) {
+ log.warn("Fetching from localization failed", e);
+ }
+ return message;
+ }
+
+ /**
+ * Fetches all the localization messages from localization service.
+ *
+ * @param employeeRequest The employee request
+ * @return Localization messages for the module
+ */
+ public String getLocalizationMessages(EmployeeRequest employeeRequest) {
+
+ RequestInfoWrapper requestInfoWrapper = new RequestInfoWrapper();
+ requestInfoWrapper.setRequestInfo(employeeRequest.getRequestInfo());
+
+ LinkedHashMap responseMap = (LinkedHashMap) restCallRepository.fetchResult(getUri(employeeRequest), requestInfoWrapper);
+ return new JSONObject(responseMap).toString();
+ }
+
+ /**
+ * Returns the search uri for the localization search to get localization messages from "rainmaker-hr" module.
+ *
+ * @param employeeRequest The employee request with locale code.
+ * @return The uri for localization search call.
+ */
+ public StringBuilder getUri(EmployeeRequest employeeRequest) {
+ String tenantId = employeeRequest.getEmployees().get(0).getTenantId().split("\\.")[0];
+
+ String locale = HRMS_LOCALIZATION_ENG_LOCALE_CODE;
+ if (!StringUtils.isEmpty(employeeRequest.getRequestInfo().getMsgId()) && employeeRequest.getRequestInfo().getMsgId().split("|").length >= 2)
+ locale = employeeRequest.getRequestInfo().getMsgId().split("\\|")[1];
+
+ StringBuilder uri = new StringBuilder();
+ uri.append(propertiesManager.getLocalizationHost()).append(propertiesManager.getLocalizationSearchEndpoint())
+ .append("?").append("locale=").append(locale).append("&tenantId=").append(tenantId).append("&module=").append(HEALTH_HRMS_LOCALIZATION_MODULE_CODE);
+
+ return uri;
+ }
+
+ /**
+ * Replaces the placeholders from the email template and creates an email request from the given employee request.
+ *
+ *
+ * @param employeeRequest The employee request
+ * @param emailTemplate the email template
+ * @return The list of email requests
+ */
+ public List createEmailRequest(EmployeeRequest employeeRequest, String emailTemplate) {
+ RequestInfo requestInfo = employeeRequest.getRequestInfo();
+
+ List emailRequest = new LinkedList<>();
+
+ // Iterate over each employee details and create email request for each employee.
+ for (Employee employee : employeeRequest.getEmployees()) {
+ String customizedMsg = emailTemplate.replace("{User's name}", employee.getUser().getName());
+ customizedMsg = customizedMsg.replace("{Username}", employee.getCode());
+ customizedMsg = customizedMsg.replace("{Password}", employee.getUser().getPassword());
+ customizedMsg = customizedMsg.replace("{website URL}", propertiesManager.getEmailNotificationWebsiteLink());
+ customizedMsg = customizedMsg.replace("{Implementation partner}", propertiesManager.getEmailNotificationImplementationPartner());
+
+ // Get email subject and email body from the provided email template.
+ String subject = customizedMsg.substring(customizedMsg.indexOf("")+4, customizedMsg.indexOf("
"));
+ String body = customizedMsg.substring(customizedMsg.indexOf("")+5);
+
+ // Create the email object with the employee's email id, subject and customized email body created.
+ Email emailObj = Email.builder().emailTo(Collections.singleton(employee.getUser().getEmailId())).isHTML(true).body(body).subject(subject).build();
+ EmailRequest email = new EmailRequest(requestInfo, emailObj);
+ emailRequest.add(email);
+ }
+ return emailRequest;
+ }
+
+ /**
+ * Pushes email request list into email notification topic if email notification is enabled.
+ *
+ * @param emailRequestList The list of emailRequests.
+ */
+ public void sendEmail(List emailRequestList) {
+ if (propertiesManager.getIsEmailNotificationEnabled()) {
+ if (CollectionUtils.isEmpty(emailRequestList)) {
+ log.error("No Emails Found!");
+ } else {
+ // Iterate over each email and push them into emailNotifTopic to send emails.
+ for (EmailRequest emailRequest : emailRequestList) {
+ producer.push(propertiesManager.getEmailNotifTopic(), emailRequest);
+ log.info("Email Request -> " + emailRequest.toString());
+ log.info("EMAIL notification sent!");
+ }
+ }
+ }
+ }
+}
diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/Email.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/Email.java
new file mode 100644
index 00000000000..68c6011e4e4
--- /dev/null
+++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/Email.java
@@ -0,0 +1,31 @@
+package org.egov.hrms.web.contract;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.*;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.Set;
+
+@Setter
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+@Builder
+public class Email {
+
+ @NotNull
+ @Size(min = 1, message = "At least one recipient is required")
+ private Set emailTo;
+
+ @NotBlank(message = "Subject is required")
+ private String subject;
+
+ @NotBlank(message = "Body is required")
+ private String body;
+ @JsonProperty("isHTML")
+ private boolean isHTML;
+
+}
diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmailRequest.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmailRequest.java
new file mode 100644
index 00000000000..015b31217b1
--- /dev/null
+++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmailRequest.java
@@ -0,0 +1,16 @@
+package org.egov.hrms.web.contract;
+
+import lombok.*;
+import org.egov.common.contract.request.RequestInfo;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Setter
+@Getter
+@ToString
+public class EmailRequest {
+
+ private RequestInfo requestInfo;
+ private Email email;
+}
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
index 6fb5141aeed..df8fb1538e5 100644
--- 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
@@ -54,6 +54,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
+
@Builder
@AllArgsConstructor
@EqualsAndHashCode
@@ -69,4 +70,8 @@ public class EmployeeResponse {
@JsonProperty("Employees")
private List employees;
+ @JsonProperty("TotalCount")
+ @Builder.Default
+ private Long totalCount = 0L;
+
}
\ 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
index f5a3f9dfca6..052f98a7072 100644
--- 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
@@ -23,38 +23,40 @@
@Builder
public class EmployeeSearchCriteria {
- public List codes;
+ private List codes;
- public List names;
+ private List names;
- public List departments;
+ private List departments;
- public List designations;
+ private List designations;
- public Long asOnDate;
+ private Long asOnDate;
- public List roles;
+ private List roles;
- public List ids;
+ private List ids;
- public List employeestatuses;
+ private List employeestatuses;
- public List employeetypes;
+ private List employeetypes;
- public List uuids;
+ private List uuids;
+
+ private List userServiceUuids;
- public List positions;
+ private List positions;
- public Boolean isActive;
+ private Boolean isActive;
@Size(max = 250)
- public String tenantId;
+ private String tenantId;
- public String phone;
+ private String phone;
- public Integer offset;
+ private Integer offset;
- public Integer limit;
+ private Integer limit;
private Boolean includeUnassigned = false;
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
index 285964a0a87..ea727df4cbd 100644
--- 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
@@ -43,6 +43,7 @@
import java.util.ArrayList;
import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Builder;
import org.egov.common.contract.response.ResponseInfo;
@@ -66,4 +67,8 @@ public class UserResponse {
private List user = new ArrayList();
+ @JsonIgnore
+ @Builder.Default
+ private Long totalCount = 0L;
+
}
\ No newline at end of file
diff --git a/core-services/egov-hrms/src/main/java/org/egov/hrms/web/models/IndividualBulkResponse.java b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/models/IndividualBulkResponse.java
new file mode 100644
index 00000000000..845d6cb72d0
--- /dev/null
+++ b/core-services/egov-hrms/src/main/java/org/egov/hrms/web/models/IndividualBulkResponse.java
@@ -0,0 +1,54 @@
+package org.egov.hrms.web.models;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.egov.common.contract.response.ResponseInfo;
+import org.egov.common.models.individual.Individual;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+/**
+ * IndividualBulkResponse
+ */
+@Validated
+
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class IndividualBulkResponse {
+
+ @JsonProperty("ResponseInfo")
+ @NotNull
+ @Valid
+ private ResponseInfo responseInfo = null;
+
+ @JsonProperty("TotalCount")
+ @Valid
+ @Builder.Default
+ private Long totalCount = 0L;
+
+ @JsonProperty("Individual")
+ @Valid
+ private List individual = null;
+
+ public IndividualBulkResponse addIndividualItem(Individual individualItem) {
+ if (this.individual == null) {
+ this.individual = new ArrayList<>();
+ }
+ this.individual.add(individualItem);
+ return this;
+ }
+
+}
diff --git a/core-services/egov-hrms/src/main/resources/application.properties b/core-services/egov-hrms/src/main/resources/application.properties
index dcece925352..6333f704295 100644
--- a/core-services/egov-hrms/src/main/resources/application.properties
+++ b/core-services/egov-hrms/src/main/resources/application.properties
@@ -65,6 +65,7 @@ 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
+egov.individual.delete.endpoint=/individual/v1/_delete
# use qualifier as "defaultUserService" to integrate with egov-user module
# use qualifier as "individualService" to integrate with individual module
@@ -101,7 +102,9 @@ spring.kafka.producer.value-serializer=org.springframework.kafka.support.seriali
kafka.topics.save.service=save-hrms-employee
kafka.topics.update.service=update-hrms-employee
kafka.topics.notification.sms=egov.core.notification.sms
+kafka.topics.notification.email=egov.core.notification.email
kafka.topics.hrms.updateData= egov-hrms-update
+kafka.topics.hrms.email.notification=hrms-send-email-notification
spring.kafka.listener.missing-topics-fatal=false
@@ -117,6 +120,12 @@ state.level.tenant.id=default
egov.hrms.auto.generate.password=true
+# EMAIL NOTIFICATION CONFIG
+notification.email.enabled=true
+
+hrms.email.notification.implementation.partner=NMCP Mozambique
+hrms.email.notification.website.link=https://unified-qa.digit.org/microplan-ui
+
# BOUNDARY SERVICE
egov.boundary.host=http://localhost:8081
egov.boundary.search.url=/boundary-service/boundary/_search
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 703b5521652..8b9ef49d763 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
@@ -98,7 +98,7 @@ public SearchResponse find(IndividualSearch searchObject, Integer li
return findByRadius(query, searchObject, includeDeleted, paramsMap);
}
if (searchObject.getIdentifier() == null) {
- String queryWithoutLimit = query.replace("ORDER BY id ASC LIMIT :limit OFFSET :offset", "");
+ String queryWithoutLimit = query.replace("ORDER BY createdtime DESC LIMIT :limit OFFSET :offset", "");
Long totalCount = constructTotalCountCTEAndReturnResult(queryWithoutLimit, paramsMap, this.namedParameterJdbcTemplate);
List individuals = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper);
if (!individuals.isEmpty()) {
@@ -226,7 +226,7 @@ private String getQueryForIndividual(IndividualSearch searchObject, Integer limi
query = query.replace(tableName + " AND", tableName + " WHERE ");
}
if (searchObject.getIndividualName() != null) {
- query = query + "AND givenname LIKE :individualName ";
+ query = query + "AND givenname ILIKE :individualName ";
paramsMap.put("individualName", "%"+searchObject.getIndividualName()+"%");
}
if (searchObject.getGender() != null) {