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..914982bbad3 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
@@ -103,6 +103,9 @@ public class EmployeeService {
@Autowired
private ObjectMapper objectMapper;
+ @Autowired
+ private IndividualService individualService;
+
/**
* Service method for create employee. Does following:
* 1. Sets ids to all the objects using idgen service.
@@ -121,8 +124,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 +144,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 +164,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 +187,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 +201,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 +243,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 +254,8 @@ public EmployeeResponse search(EmployeeSearchCriteria criteria, RequestInfo requ
}
}
return EmployeeResponse.builder().responseInfo(factory.createResponseInfoFromRequestInfo(requestInfo, true))
- .employees(employees).build();
+ .employees(employees)
+ .totalCount(totalCount).build();
}
@@ -231,7 +269,14 @@ 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);
+ UserResponse response;
+ if(userService instanceof IndividualService) {
+ String localityCode = (employee.getJurisdictions()!=null && !employee.getJurisdictions().isEmpty())? employee.getJurisdictions().get(0).getBoundary() : null;
+ response = individualService.createUserByLocality(request, localityCode);
+ }
+ else{
+ response = userService.createUser(request);
+ }
User user = response.getUser().get(0);
employee.setId(UUID.fromString(user.getUuid()).getMostSignificantBits());
employee.setUuid(user.getUuid());
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..17302f58b1f 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
@@ -17,26 +17,19 @@
import org.apache.commons.lang3.StringUtils;
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.Name;
-import org.egov.common.models.individual.UserDetails;
+import org.egov.common.models.individual.*;
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.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
@@ -56,7 +49,7 @@ public IndividualService(PropertiesManager propertiesManager,
@Override
public UserResponse createUser(UserRequest userRequest) {
- IndividualRequest request = mapToIndividualRequest(userRequest);
+ IndividualRequest request = mapToIndividualRequest(userRequest, null);
StringBuilder uri = new StringBuilder();
uri.append(propertiesManager.getIndividualHost());
uri.append(propertiesManager.getIndividualCreateEndpoint());
@@ -70,6 +63,21 @@ public UserResponse createUser(UserRequest userRequest) {
return userResponse;
}
+ public UserResponse createUserByLocality(UserRequest userRequest, String localityCode) {
+ IndividualRequest request = mapToIndividualRequest(userRequest,localityCode);
+ 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;
+ }
+
/**
* Updates a user by searching for the corresponding individual and updating their details.
*
@@ -210,6 +218,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
@@ -256,7 +265,7 @@ private static Date convertMillisecondsToDate(long milliseconds) {
}
}
- private static IndividualRequest mapToIndividualRequest(UserRequest userRequest) {
+ private static IndividualRequest mapToIndividualRequest(UserRequest userRequest, String localityCode) {
Individual individual = Individual.builder()
.id(userRequest.getUser().getUuid())
.userId(userRequest.getUser().getId() != null ?
@@ -276,6 +285,7 @@ private static IndividualRequest mapToIndividualRequest(UserRequest userRequest)
.type(AddressType.CORRESPONDENCE)
.addressLine1(userRequest.getUser().getCorrespondenceAddress())
.clientReferenceId(String.valueOf(UUID.randomUUID()))
+ .locality((localityCode!=null) ? Boundary.builder().code(localityCode).build() : null)
.isDeleted(Boolean.FALSE)
.build()))
/*
@@ -306,6 +316,9 @@ private static IndividualRequest mapToIndividualRequest(UserRequest userRequest)
.build()).collect(Collectors.toList()))
.userType(UserType.fromValue(userRequest.getUser().getType()))
.build())
+ .skills(userRequest.getUser().getRoles().stream().map(role -> Skill.builder()
+ .type(role.getCode()).level(role.getCode())
+ .build()).collect(Collectors.toList()))
.isDeleted(Boolean.FALSE)
.clientAuditDetails(AuditDetails.builder().createdBy(userRequest.getRequestInfo().getUserInfo().getUuid()).lastModifiedBy(userRequest.getRequestInfo().getUserInfo().getUuid()).build())
.rowVersion(userRequest.getUser().getRowVersion())
@@ -331,6 +344,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/household/CHANGELOG.md b/health-services/household/CHANGELOG.md
index 3b9cbec0526..d8d6e6d5019 100644
--- a/health-services/household/CHANGELOG.md
+++ b/health-services/household/CHANGELOG.md
@@ -1,5 +1,10 @@
All notable changes to this module will be documented in this file.
+## 1.1.5 - 2025-01-28
+
+- Added householdType column in household table
+- Upgraded to heath models 1.0.25
+
## 1.1.4 - 2024-08-29
- Added `ExistentEntityValidator` fixes
diff --git a/health-services/household/pom.xml b/health-services/household/pom.xml
index 798eba22c92..0ad08feb096 100644
--- a/health-services/household/pom.xml
+++ b/health-services/household/pom.xml
@@ -5,7 +5,7 @@
household
jar
household
- 1.1.4
+ 1.1.5
17
${java.version}
@@ -45,12 +45,12 @@
org.egov.common
health-services-common
- 1.0.18-SNAPSHOT
+ 1.0.19-SNAPSHOT
org.egov.common
health-services-models
- 1.0.20-SNAPSHOT
+ 1.0.25-dev-SNAPSHOT
compile
diff --git a/health-services/household/src/main/java/org/egov/household/config/HouseholdConfiguration.java b/health-services/household/src/main/java/org/egov/household/config/HouseholdConfiguration.java
index c906d52786f..6baa26b172d 100644
--- a/health-services/household/src/main/java/org/egov/household/config/HouseholdConfiguration.java
+++ b/health-services/household/src/main/java/org/egov/household/config/HouseholdConfiguration.java
@@ -42,4 +42,10 @@ public class HouseholdConfiguration {
@Value("${egov.boundary.search.url}")
private String boundarySearchUrl;
+
+ @Value("${household.type.same.validation}")
+ private boolean householdTypeSameValidation;
+
+ @Value("${household.type.community.creator.role}")
+ private String communityHouseholdCreatorRoleCode;
}
diff --git a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java
index 55a0cee69e1..e61717fce37 100644
--- a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java
+++ b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java
@@ -82,6 +82,10 @@ public SearchResponse find(HouseholdSearch searchObject, Integer limi
query = GenericQueryBuilder.generateQuery(query, whereFields).toString();
query = query.replace("id IN (:id)", "h.id IN (:id)");
query = query.replace("clientReferenceId IN (:clientReferenceId)", "h.clientReferenceId IN (:clientReferenceId)");
+ // To consider null values present in db as family if family parameter is passed
+ if (searchObject.getHouseholdType() != null && searchObject.getHouseholdType().equalsIgnoreCase("FAMILY")) {
+ query = query.replace("householdType=:householdType", "(householdType!='COMMUNITY' OR householdType IS NULL)");
+ }
if(CollectionUtils.isEmpty(whereFields)) {
query = query + " where h.tenantId=:tenantId ";
@@ -129,6 +133,10 @@ public SearchResponse findByRadius(HouseholdSearch searchObject, Inte
query = GenericQueryBuilder.generateQuery(query, whereFields).toString();
query = query.replace("id IN (:id)", "h.id IN (:id)");
query = query.replace("clientReferenceId IN (:clientReferenceId)", "h.clientReferenceId IN (:clientReferenceId)");
+ // To consider null values present in db as family if family parameter is passed
+ if (searchObject.getHouseholdType() != null && searchObject.getHouseholdType().equalsIgnoreCase("FAMILY")) {
+ query = query.replace("householdType=:householdType", "(householdType!='COMMUNITY' OR householdType IS NULL)");
+ }
if(CollectionUtils.isEmpty(whereFields)) {
query = query + " where h.tenantId=:tenantId ";
diff --git a/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdMemberRowMapper.java b/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdMemberRowMapper.java
index 79a762807ea..547312ec86c 100644
--- a/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdMemberRowMapper.java
+++ b/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdMemberRowMapper.java
@@ -5,7 +5,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import digit.models.coremodels.AuditDetails;
+import org.egov.common.contract.models.AuditDetails;
import org.egov.common.models.core.AdditionalFields;
import org.egov.common.models.household.HouseholdMember;
import org.springframework.jdbc.core.RowMapper;
diff --git a/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java b/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java
index be08e68e1d1..1cd6814ea73 100644
--- a/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java
+++ b/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java
@@ -5,11 +5,12 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import digit.models.coremodels.AuditDetails;
+import org.egov.common.contract.models.AuditDetails;
import org.egov.common.models.core.AdditionalFields;
import org.egov.common.models.household.Address;
import org.egov.common.models.household.AddressType;
import org.egov.common.models.core.Boundary;
+import org.egov.common.models.household.HouseHoldType;
import org.egov.common.models.household.Household;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
@@ -36,6 +37,7 @@ public Household mapRow(ResultSet resultSet, int i) throws SQLException {
Household household = Household.builder()
.id(resultSet.getString("id"))
.rowVersion(resultSet.getInt("rowVersion"))
+ .householdType(HouseHoldType.fromValue(resultSet.getString("householdType")))
.isDeleted(resultSet.getBoolean("isDeleted"))
.tenantId(resultSet.getString("tenantId"))
.memberCount(resultSet.getInt("numberOfMembers"))
diff --git a/health-services/household/src/main/java/org/egov/household/service/HouseholdEnrichmentService.java b/health-services/household/src/main/java/org/egov/household/service/HouseholdEnrichmentService.java
index a2ce8dc5e9d..b31ec077888 100644
--- a/health-services/household/src/main/java/org/egov/household/service/HouseholdEnrichmentService.java
+++ b/health-services/household/src/main/java/org/egov/household/service/HouseholdEnrichmentService.java
@@ -1,6 +1,6 @@
package org.egov.household.service;
-import digit.models.coremodels.AuditDetails;
+import org.egov.common.contract.models.AuditDetails;
import lombok.extern.slf4j.Slf4j;
import org.egov.common.models.household.Address;
import org.egov.common.models.household.Household;
diff --git a/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java b/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java
index c6f701b6eb0..9b7f35b8f93 100644
--- a/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java
+++ b/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java
@@ -14,13 +14,7 @@
import org.egov.common.validator.Validator;
import org.egov.household.config.HouseholdConfiguration;
import org.egov.household.repository.HouseholdRepository;
-import org.egov.household.validators.household.HExistentEntityValidator;
-import org.egov.household.validators.household.HBoundaryValidator;
-import org.egov.household.validators.household.HIsDeletedValidator;
-import org.egov.household.validators.household.HNonExistentEntityValidator;
-import org.egov.household.validators.household.HNullIdValidator;
-import org.egov.household.validators.household.HRowVersionValidator;
-import org.egov.household.validators.household.HUniqueEntityValidator;
+import org.egov.household.validators.household.*;
import org.egov.common.models.household.HouseholdSearch;
import org.egov.tracer.model.CustomException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,7 +22,6 @@
import org.springframework.util.ReflectionUtils;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
@@ -62,7 +55,9 @@ public class HouseholdService {
private final Predicate> isApplicableForCreate = validator ->
validator.getClass().equals(HBoundaryValidator.class)
- || validator.getClass().equals(HExistentEntityValidator.class);
+ || validator.getClass().equals(HExistentEntityValidator.class)
+ || validator.getClass().equals(HCommunityValidator.class)
+ || validator.getClass().equals(HCommunityTypeValidator.class);
private final Predicate> isApplicableForUpdate = validator ->
validator.getClass().equals(HNullIdValidator.class)
@@ -70,7 +65,10 @@ public class HouseholdService {
|| validator.getClass().equals(HIsDeletedValidator.class)
|| validator.getClass().equals(HUniqueEntityValidator.class)
|| validator.getClass().equals(HNonExistentEntityValidator.class)
- || validator.getClass().equals(HRowVersionValidator.class);
+ || validator.getClass().equals(HRowVersionValidator.class)
+ || validator.getClass().equals(HCommunityValidator.class)
+ || validator.getClass().equals(HCommunityTypeValidator.class)
+ || validator.getClass().equals(HHouseholdTypeChangeValidator.class);
private final Predicate> isApplicableForDelete = validator ->
validator.getClass().equals(HNullIdValidator.class)
diff --git a/health-services/household/src/main/java/org/egov/household/validators/household/HCommunityTypeValidator.java b/health-services/household/src/main/java/org/egov/household/validators/household/HCommunityTypeValidator.java
new file mode 100644
index 00000000000..9e76039121b
--- /dev/null
+++ b/health-services/household/src/main/java/org/egov/household/validators/household/HCommunityTypeValidator.java
@@ -0,0 +1,53 @@
+package org.egov.household.validators.household;
+
+import org.egov.common.models.Error;
+import org.egov.common.models.household.HouseHoldType;
+import org.egov.common.models.household.Household;
+import org.egov.common.models.household.HouseholdBulkRequest;
+import org.egov.common.validator.Validator;
+import org.egov.household.config.HouseholdConfiguration;
+import org.egov.tracer.model.CustomException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.egov.common.utils.CommonUtils.populateErrorDetails;
+
+public class HCommunityTypeValidator implements Validator {
+ private final HouseholdConfiguration configuration;
+
+ @Autowired
+ public HCommunityTypeValidator(HouseholdConfiguration configuration) {
+ this.configuration = configuration;
+ }
+ @Override
+ public Map> validate(HouseholdBulkRequest request) {
+ HashMap> errorDetailsMap = new HashMap<>();
+ if (configuration.isHouseholdTypeSameValidation()) {
+ // validate if request contains households of different householdTypes
+ List communityHouseholds = request.getHouseholds()
+ .stream()
+ .filter(household -> household.getHouseholdType() != null &&
+ household.getHouseholdType().equals(HouseHoldType.COMMUNITY))
+ .toList();
+
+ if (!CollectionUtils.isEmpty(communityHouseholds) &&
+ request.getHouseholds().size() != communityHouseholds.size()) {
+ communityHouseholds.forEach(household -> {
+ Error error = Error.builder()
+ .errorMessage("Community and Family household cannot be in same request")
+ .errorCode("COMMUNITY_AND_FAMILY_HOUSEHOLD_IN_SAME_REQUEST")
+ .type(Error.ErrorType.NON_RECOVERABLE)
+ .exception(new CustomException("COMMUNITY_AND_FAMILY_HOUSEHOLD_IN_SAME_REQUEST", "Community and Family household cannot be in same request"))
+ .build();
+ // Populate error details for the household
+ populateErrorDetails(household, error, errorDetailsMap);
+ });
+ }
+ }
+ return errorDetailsMap;
+ }
+}
diff --git a/health-services/household/src/main/java/org/egov/household/validators/household/HCommunityValidator.java b/health-services/household/src/main/java/org/egov/household/validators/household/HCommunityValidator.java
new file mode 100644
index 00000000000..005afb42e3c
--- /dev/null
+++ b/health-services/household/src/main/java/org/egov/household/validators/household/HCommunityValidator.java
@@ -0,0 +1,62 @@
+package org.egov.household.validators.household;
+
+import lombok.extern.slf4j.Slf4j;
+import org.egov.common.models.Error;
+import org.egov.common.models.household.HouseHoldType;
+import org.egov.common.models.household.Household;
+import org.egov.common.models.household.HouseholdBulkRequest;
+import org.egov.common.validator.Validator;
+import org.egov.household.config.HouseholdConfiguration;
+import org.egov.tracer.model.CustomException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.egov.common.utils.CommonUtils.populateErrorDetails;
+
+@Component
+@Order(value = 1)
+@Slf4j
+public class HCommunityValidator implements Validator {
+
+ private final HouseholdConfiguration configuration;
+
+ @Autowired
+ public HCommunityValidator(HouseholdConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ @Override
+ public Map> validate(HouseholdBulkRequest request) {
+ HashMap> errorDetailsMap = new HashMap<>();
+ List communityHouseholds = request.getHouseholds()
+ .stream()
+ .filter(household -> household.getHouseholdType() != null &&
+ household.getHouseholdType().equals(HouseHoldType.COMMUNITY))
+ .toList();
+
+ if (!CollectionUtils.isEmpty(communityHouseholds) &&
+ request.getRequestInfo().getUserInfo().getRoles()
+ .stream()
+ .noneMatch(role -> role.getCode().equals(configuration.getCommunityHouseholdCreatorRoleCode()))) {
+ communityHouseholds.forEach(household -> {
+ Error error = Error.builder()
+ .errorMessage("User doesn't have permission to create/update community household")
+ .errorCode("COMMUNITY_USER_ACCESS_DENIED")
+ .type(Error.ErrorType.NON_RECOVERABLE)
+ .exception(new CustomException("COMMUNITY_USER_ACCESS_DENIED", "User doesn't have permission to create/update community household"))
+ .build();
+ // Populate error details for the household
+ populateErrorDetails(household, error, errorDetailsMap);
+ });
+ }
+ return errorDetailsMap;
+ }
+
+
+}
diff --git a/health-services/household/src/main/java/org/egov/household/validators/household/HHouseholdTypeChangeValidator.java b/health-services/household/src/main/java/org/egov/household/validators/household/HHouseholdTypeChangeValidator.java
new file mode 100644
index 00000000000..483a11abba3
--- /dev/null
+++ b/health-services/household/src/main/java/org/egov/household/validators/household/HHouseholdTypeChangeValidator.java
@@ -0,0 +1,97 @@
+package org.egov.household.validators.household;
+
+import lombok.extern.slf4j.Slf4j;
+import org.egov.common.models.Error;
+import org.egov.common.models.household.Household;
+import org.egov.common.models.household.HouseholdBulkRequest;
+import org.egov.common.models.household.HouseholdSearch;
+import org.egov.common.validator.Validator;
+import org.egov.household.repository.HouseholdRepository;
+import org.egov.tracer.model.CustomException;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.egov.common.utils.CommonUtils.*;
+import static org.egov.common.utils.CommonUtils.notHavingErrors;
+
+@Slf4j
+@Component
+@Order(value = 3)
+public class HHouseholdTypeChangeValidator implements Validator {
+
+ private final HouseholdRepository householdRepository;
+
+ public HHouseholdTypeChangeValidator(HouseholdRepository householdRepository) {
+ this.householdRepository = householdRepository;
+ }
+
+ @Override
+ public Map> validate(HouseholdBulkRequest request) {
+ // Map to hold household entities and their error details
+ Map> errorDetailsMap = new HashMap<>();
+ // Get the list of household entities from the request
+ List entities = request.getHouseholds();
+ // Map to store entities by their IDs
+ Map eMap = entities.stream().filter(notHavingErrors()).collect(Collectors.toMap(Household::getId, household -> household));
+ // Lists to store IDs and client reference IDs
+ List idList = new ArrayList<>();
+ List clientReferenceIdList = new ArrayList<>();
+ // Extract IDs and client reference IDs from household entities
+ entities.forEach(household -> {
+ idList.add(household.getId());
+ clientReferenceIdList.add(household.getClientReferenceId());
+ });
+ // Check if the entity map is not empty
+ if (!eMap.isEmpty()) {
+ // Create a search object for querying existing entities
+ HouseholdSearch householdSearch = HouseholdSearch.builder()
+ .clientReferenceId(clientReferenceIdList)
+ .id(idList)
+ .build();
+
+ List existingEntities;
+ try {
+ // Query the repository to find existing entities
+ existingEntities = householdRepository.find(householdSearch, entities.size(), 0,
+ entities.get(0).getTenantId(), null, false).getResponse();
+ } catch (Exception e) {
+ // Handle query builder exception
+ log.error("Search failed for Household with error: {}", e.getMessage(), e);
+ throw new CustomException("HOUSEHOLD_SEARCH_FAILED", "Search Failed for Household, " + e.getMessage());
+ }
+ // Check for non-existent entities
+ List entitiesWithHouseholdTypeChange = changeInHouseholdType(eMap,
+ existingEntities);
+ // Populate error details for non-existent entities
+ entitiesWithHouseholdTypeChange.forEach(entity -> {
+ Error error = Error.builder().errorMessage("Household Type change").errorCode("HOUSEHOLD_TYPE_CHANGE")
+ .type(Error.ErrorType.NON_RECOVERABLE)
+ .exception(new CustomException("HOUSEHOLD_TYPE_CHANGE", "Household Type change")).build();
+ populateErrorDetails(entity, error, errorDetailsMap);
+ });
+ }
+
+ return errorDetailsMap;
+ }
+
+
+ private List changeInHouseholdType(Map eMap,
+ List existingEntities) {
+ List entitiesWithHouseholdTypeChange = new ArrayList<>();
+
+ for (Household existingEntity : existingEntities) {
+ if (eMap.containsKey(existingEntity.getId())) {
+ if (!existingEntity.getHouseholdType().equals(eMap.get(existingEntity.getId()).getHouseholdType())) {
+ entitiesWithHouseholdTypeChange.add(eMap.get(existingEntity.getId()));
+ }
+ }
+ }
+ return entitiesWithHouseholdTypeChange;
+ }
+}
diff --git a/health-services/household/src/main/resources/application.properties b/health-services/household/src/main/resources/application.properties
index dfd2b4f6937..c5fc6bdeaee 100644
--- a/health-services/household/src/main/resources/application.properties
+++ b/health-services/household/src/main/resources/application.properties
@@ -103,3 +103,7 @@ egov.individual.search.url=/individual/v1/_search
egov.boundary.host=http://localhost:8081
egov.boundary.search.url=/boundary-service/boundary/_search
egov.boundary.hierarchy=HCM-Moz-Hierarchy
+
+#Community Household Type
+household.type.same.validation=true
+household.type.community.creator.role=COMMUNITY_CREATOR
diff --git a/health-services/household/src/main/resources/db/migration/main/V20241114114225__household_type_ddl.sql b/health-services/household/src/main/resources/db/migration/main/V20241114114225__household_type_ddl.sql
new file mode 100644
index 00000000000..4f98c9fad80
--- /dev/null
+++ b/health-services/household/src/main/resources/db/migration/main/V20241114114225__household_type_ddl.sql
@@ -0,0 +1 @@
+ALTER TABLE HOUSEHOLD ADD COLUMN IF NOT EXISTS householdType character varying(64) DEFAULT 'FAMILY' NOT NULL;
\ No newline at end of file
diff --git a/health-services/household/src/main/resources/household-persister.yml b/health-services/household/src/main/resources/household-persister.yml
index f86a803b8ce..54e066b3e94 100644
--- a/health-services/household/src/main/resources/household-persister.yml
+++ b/health-services/household/src/main/resources/household-persister.yml
@@ -6,12 +6,13 @@ serviceMaps:
fromTopic: save-household-topic
isTransaction: true
queryMaps:
- - query: INSERT INTO HOUSEHOLD(id, tenantId, clientReferenceId, numberOfMembers, addressId, additionalDetails, createdBy, lastModifiedBy, createdTime, lastModifiedTime, rowVersion, isDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
+ - query: INSERT INTO HOUSEHOLD(id, tenantId, clientReferenceId, householdType, numberOfMembers, addressId, additionalDetails, createdBy, lastModifiedBy, createdTime, lastModifiedTime, rowVersion, isDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
basePath: $.*
jsonMaps:
- jsonPath: $.*.id
- jsonPath: $.*.tenantId
- jsonPath: $.*.clientReferenceId
+ - jsonPath: $.*.householdType
- jsonPath: $.*.memberCount
- jsonPath: $.*.address.id
- jsonPath: $.*.additionalFields
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) {
diff --git a/health-services/libraries/health-services-models/CHANGELOG.md b/health-services/libraries/health-services-models/CHANGELOG.md
index c7476cbe79b..e08569ca889 100644
--- a/health-services/libraries/health-services-models/CHANGELOG.md
+++ b/health-services/libraries/health-services-models/CHANGELOG.md
@@ -1,5 +1,11 @@
All notable changes to this module will be documented in this file.
+## 1.0.25 - 2025-01-03
+- Added BeneficiaryType Enum and update in ProjectType, Target models
+- Added HouseHoldType Enum and added in Household, HouseholdSearch models
+- Added DownsyncCLFHousehold, DownsyncCLFHouseholdResponse, HouseholdMemberMap
+- Updated DownsyncCriteria to include householdId
+
## 1.0.21 - 2024-08-07
- Added UserActionEnum, UserAction Entities, TaskStatus enum
- Added isCascadingProjectDateUpdate in ProjectRequest model
diff --git a/health-services/libraries/health-services-models/pom.xml b/health-services/libraries/health-services-models/pom.xml
index dc4e4c878ca..4a110e3b9a2 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.23-SNAPSHOT
+ 1.0.25-SNAPSHOT
17
${java.version}
@@ -84,4 +84,4 @@
https://nexus-repo.digit.org/nexus/content/repositories/snapshots/
-
\ No newline at end of file
+
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseHoldType.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseHoldType.java
new file mode 100644
index 00000000000..77948226c61
--- /dev/null
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseHoldType.java
@@ -0,0 +1,31 @@
+package org.egov.common.models.household;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public enum HouseHoldType {
+
+ FAMILY("FAMILY"),
+
+ COMMUNITY("COMMUNITY"),
+
+ OTHER("OTHER");
+
+ private String value;
+
+ HouseHoldType(String value) {
+ this.value = value;
+ }
+
+ @JsonCreator
+ public static HouseHoldType fromValue(String text) {
+ for (HouseHoldType b : HouseHoldType.values()) {
+ if (String.valueOf(b.value).equalsIgnoreCase(text)) {
+ return b;
+ }
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java
index 63c982ff07f..f43bc53e2f2 100644
--- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java
@@ -27,13 +27,16 @@ public class Household extends EgovOfflineModel {
@JsonProperty("memberCount")
@NotNull
- @Range(min = 0, max = 1000)
+// @Range(min = 0, max = 1000)
private Integer memberCount = null;
@JsonProperty("address")
@Valid
private Address address = null;
+ @JsonProperty("householdType")
+ private HouseHoldType householdType = null;
+
//TODO remove
@JsonProperty("isDeleted")
private Boolean isDeleted = Boolean.FALSE;
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearch.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearch.java
index 4ff5ccec51e..a6d754e3b99 100644
--- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearch.java
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearch.java
@@ -37,6 +37,9 @@ public class HouseholdSearch extends EgovOfflineSearchModel {
@DecimalMax("180")
private Double longitude = null;
+ @JsonProperty("householdType")
+ private String householdType = null;
+
/*
* @value unit of measurement in Kilometer
* */
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryType.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryType.java
new file mode 100644
index 00000000000..3836a8c5168
--- /dev/null
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryType.java
@@ -0,0 +1,35 @@
+package org.egov.common.models.project;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+
+public enum BeneficiaryType {
+
+ HOUSEHOLD("HOUSEHOLD"),
+
+ INDIVIDUAL("INDIVIDUAL");
+
+ private String value;
+
+ BeneficiaryType(String value) {
+ this.value = value;
+ }
+
+ @Override
+ @JsonValue
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ @JsonCreator
+ public static BeneficiaryType fromValue(String text) {
+ for(BeneficiaryType a:BeneficiaryType.values()){
+ if(String.valueOf(a.value).equalsIgnoreCase(text)){
+ return a;
+ }
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java
index 78445bed4a9..6f781df0f5a 100644
--- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/ProjectType.java
@@ -48,7 +48,7 @@ public class ProjectType {
private String group = null;
@JsonProperty("beneficiaryType")
- private String beneficiaryType = null;
+ private BeneficiaryType beneficiaryType = null;
@JsonProperty("eligibilityCriteria")
@Size(max=10)
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java
index e7152211048..187648724a6 100644
--- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java
@@ -31,7 +31,7 @@ public class Target {
private String projectid = null;
@JsonProperty("beneficiaryType")
- private String beneficiaryType = null;
+ private BeneficiaryType beneficiaryType = null;
@JsonProperty("totalNo")
private Integer totalNo = null;
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHousehold.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHousehold.java
new file mode 100644
index 00000000000..c0ccef312fe
--- /dev/null
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHousehold.java
@@ -0,0 +1,24 @@
+package org.egov.common.models.referralmanagement.beneficiarydownsync;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.egov.common.models.household.Household;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+
+public class DownsyncCLFHousehold {
+ @JsonProperty("HouseholdCountMap")
+ List householdMemberCountMap;
+
+ @JsonProperty("DownsyncCriteria")
+ DownsyncCriteria downsyncCriteria;
+}
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHouseholdResponse.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHouseholdResponse.java
new file mode 100644
index 00000000000..97a3023163e
--- /dev/null
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHouseholdResponse.java
@@ -0,0 +1,24 @@
+package org.egov.common.models.referralmanagement.beneficiarydownsync;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.egov.common.contract.response.ResponseInfo;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+
+public class DownsyncCLFHouseholdResponse {
+
+ @JsonProperty("ResponseInfo")
+ private ResponseInfo responseInfo;
+
+ @JsonProperty("Households")
+ private DownsyncCLFHousehold Households;
+}
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCriteria.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCriteria.java
index 71816f7849f..400de52948b 100644
--- a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCriteria.java
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCriteria.java
@@ -35,5 +35,7 @@ public class DownsyncCriteria {
private Integer limit = 50;
private Long totalCount;
+
+ private String householdId;
}
diff --git a/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/HouseholdMemberMap.java b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/HouseholdMemberMap.java
new file mode 100644
index 00000000000..ee6819f59ec
--- /dev/null
+++ b/health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/HouseholdMemberMap.java
@@ -0,0 +1,20 @@
+package org.egov.common.models.referralmanagement.beneficiarydownsync;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.egov.common.models.household.Household;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class HouseholdMemberMap {
+
+ private Household household;
+
+ private Integer numberOfMembers;
+
+
+}
\ No newline at end of file
diff --git a/health-services/project/CHANGELOG.md b/health-services/project/CHANGELOG.md
index 95369041416..c995b81daaf 100644
--- a/health-services/project/CHANGELOG.md
+++ b/health-services/project/CHANGELOG.md
@@ -1,5 +1,8 @@
All notable changes to this module will be documented in this file.
+## 1.1.6 - 2025-01-27
+- Added isAncestorProjectId param for search projects API to support search projects with ancestor project id as well
+
## 1.1.5 - 2024-08-07
- Added UserAction functionality with support for Location capture.
diff --git a/health-services/project/pom.xml b/health-services/project/pom.xml
index 9cb321d57d0..3333388355c 100644
--- a/health-services/project/pom.xml
+++ b/health-services/project/pom.xml
@@ -5,7 +5,7 @@
project
jar
project
- 1.1.5
+ 1.1.6
17
${java.version}
@@ -45,12 +45,12 @@
org.egov.common
health-services-common
- 1.0.20-dev-SNAPSHOT
+ 1.0.20-SNAPSHOT
org.egov.common
health-services-models
- 1.0.23-dev-SNAPSHOT
+ 1.0.25-SNAPSHOT
compile
diff --git a/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java b/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java
index ae7b4c9994b..31bd571cb77 100644
--- a/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java
+++ b/health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java
@@ -69,37 +69,44 @@ public ProjectRepository(Producer producer, NamedParameterJdbcTemplate namedPara
}
- public List getProjects(ProjectRequest project, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Boolean includeAncestors, Boolean includeDescendants, Long createdFrom, Long createdTo) {
+ /**
+ * @param isAncestorProjectId When true, treats the project IDs in the ProjectRequest as ancestor project IDs
+ */
+ public List getProjects(ProjectRequest project, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Boolean includeAncestors, Boolean includeDescendants, Long createdFrom, Long createdTo, boolean isAncestorProjectId) {
//Fetch Projects based on search criteria
- List projects = getProjectsBasedOnSearchCriteria(project.getProjects(), limit, offset, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo);
+ List projects = getProjectsBasedOnSearchCriteria(project.getProjects(), limit, offset, tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId);
Set projectIds = projects.stream().map(Project :: getId).collect(Collectors.toSet());
List ancestors = null;
List descendants = null;
- //Get Project ancestors if includeAncestors flag is true
- if (includeAncestors) {
- ancestors = getProjectAncestors(projects);
- if (ancestors != null && !ancestors.isEmpty()) {
- List ancestorProjectIds = ancestors.stream().map(Project :: getId).collect(Collectors.toList());
- projectIds.addAll(ancestorProjectIds);
+ List targets = new ArrayList<>();
+ List documents = new ArrayList<>();
+ if(!projectIds.isEmpty()) {
+ //Get Project ancestors if includeAncestors flag is true
+ if (includeAncestors) {
+ ancestors = getProjectAncestors(projects);
+ if (ancestors != null && !ancestors.isEmpty()) {
+ List ancestorProjectIds = ancestors.stream().map(Project :: getId).collect(Collectors.toList());
+ projectIds.addAll(ancestorProjectIds);
+ }
}
- }
- //Get Project descendants if includeDescendants flag is true
- if (includeDescendants) {
- descendants = getProjectDescendants(projects);
- if (descendants != null && !descendants.isEmpty()) {
- List descendantsProjectIds = descendants.stream().map(Project :: getId).collect(Collectors.toList());
- projectIds.addAll(descendantsProjectIds);
+ //Get Project descendants if includeDescendants flag is true
+ if (includeDescendants) {
+ descendants = getProjectDescendants(projects);
+ if (descendants != null && !descendants.isEmpty()) {
+ List descendantsProjectIds = descendants.stream().map(Project :: getId).collect(Collectors.toList());
+ projectIds.addAll(descendantsProjectIds);
+ }
}
- }
- //Fetch targets based on Project Ids
- List targets = getTargetsBasedOnProjectIds(projectIds);
+ //Fetch targets based on Project Ids
+ targets = getTargetsBasedOnProjectIds(projectIds);
- //Fetch documents based on Project Ids
- List documents = getDocumentsBasedOnProjectIds(projectIds);
+ //Fetch documents based on Project Ids
+ documents = getDocumentsBasedOnProjectIds(projectIds);
+ }
//Construct Project Objects with fetched projects, targets and documents using Project id
return buildProjectSearchResult(projects, targets, documents, ancestors, descendants);
@@ -114,28 +121,32 @@ public List getProjects(@NotNull @Valid ProjectSearch projectSearch, @V
List ancestors = null;
List descendants = null;
- //Get Project ancestors if includeAncestors flag is true
- if (urlParams.getIncludeAncestors()) {
- ancestors = getProjectAncestors(projects);
- if (ancestors != null && !ancestors.isEmpty()) {
- List ancestorProjectIds = ancestors.stream().map(Project :: getId).collect(Collectors.toList());
- projectIds.addAll(ancestorProjectIds);
+ List targets = new ArrayList<>();
+ List documents = new ArrayList<>();
+ if(!projectIds.isEmpty()) {
+ //Get Project ancestors if includeAncestors flag is true
+ if (urlParams.getIncludeAncestors()) {
+ ancestors = getProjectAncestors(projects);
+ if (ancestors != null && !ancestors.isEmpty()) {
+ List ancestorProjectIds = ancestors.stream().map(Project :: getId).toList();
+ projectIds.addAll(ancestorProjectIds);
+ }
}
- }
- //Get Project descendants if includeDescendants flag is true
- if (urlParams.getIncludeDescendants()) {
- descendants = getProjectDescendants(projects);
- if (descendants != null && !descendants.isEmpty()) {
- List descendantsProjectIds = descendants.stream().map(Project :: getId).collect(Collectors.toList());
- projectIds.addAll(descendantsProjectIds);
+ //Get Project descendants if includeDescendants flag is true
+ if (urlParams.getIncludeDescendants()) {
+ descendants = getProjectDescendants(projects);
+ if (descendants != null && !descendants.isEmpty()) {
+ List descendantsProjectIds = descendants.stream().map(Project :: getId).toList();
+ projectIds.addAll(descendantsProjectIds);
+ }
}
- }
- //Fetch targets based on Project Ids
- List targets = getTargetsBasedOnProjectIds(projectIds);
+ //Fetch targets based on Project Ids
+ targets = getTargetsBasedOnProjectIds(projectIds);
- //Fetch documents based on Project Ids
- List documents = getDocumentsBasedOnProjectIds(projectIds);
+ //Fetch documents based on Project Ids
+ documents = getDocumentsBasedOnProjectIds(projectIds);
+ }
//Construct Project Objects with fetched projects, targets and documents using Project id
return buildProjectSearchResult(projects, targets, documents, ancestors, descendants);
@@ -151,9 +162,9 @@ private List getProjectsBasedOnV2SearchCriteria(@NotNull @Valid Project
}
/* Fetch Projects based on search criteria */
- private List getProjectsBasedOnSearchCriteria(List projectsRequest, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo) {
+ private List getProjectsBasedOnSearchCriteria(List projectsRequest, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId) {
List