users = new ArrayList<>();
+
+ workflow.getAssignes().forEach(uuid -> {
+ User user = new User();
+ user.setUuid(uuid);
+ users.add(user);
+ });
+
+ processInstance.setAssignes(users);
+ }
+
+ if (!CollectionUtils.isEmpty(workflow.getDocuments())) {
+ processInstance.setDocuments(workflow.getDocuments());
+ }
+
+ return processInstance;
+ }
+
+ /**
+ * Method to integrate with workflow
+ *
+ * take the ProcessInstanceRequest as paramerter to call wf-service
+ *
+ * and return wf-response to sets the resultant status
+ */
+ private ProcessInstance callWorkFlow(ProcessInstanceRequest workflowReq) {
+
+ ProcessInstanceResponse response = null;
+ StringBuilder url = new StringBuilder(serviceConfiguration.getWfHost().concat(serviceConfiguration.getWfTransitionPath()));
+ Object optional = repository.fetchResult(url, workflowReq);
+ response = mapper.convertValue(optional, ProcessInstanceResponse.class);
+ return response.getProcessInstances().get(0);
+ }
+
+ /*
+ * Should return the applicable BusinessService for the given request
+ *
+ */
+ public BusinessService getBusinessService(MusterRollRequest musterRollRequest) {
+ String tenantId = musterRollRequest.getMusterRoll().getTenantId();
+ StringBuilder url = getSearchURLWithParams(tenantId, serviceConfiguration.getMusterRollWFBusinessService());
+ RequestInfo requestInfo = musterRollRequest.getRequestInfo();
+ Object result = repository.fetchResult(url, requestInfo);
+ BusinessServiceResponse response = null;
+ try {
+ response = mapper.convertValue(result, BusinessServiceResponse.class);
+ } catch (IllegalArgumentException e) {
+ throw new CustomException("PARSING ERROR", "Failed to parse response of workflow business service search");
+ }
+
+ if (CollectionUtils.isEmpty(response.getBusinessServices()))
+ throw new CustomException("BUSINESSSERVICE_DOESN'T_EXIST", "The businessService : " + serviceConfiguration.getMusterRollWFBusinessService() + " doesn't exist");
+
+ return response.getBusinessServices().get(0);
+ }
+
+ /**
+ * Creates url for search based on given tenantId and businessservices
+ *
+ * @param tenantId The tenantId for which url is generated
+ * @param businessService The businessService for which url is generated
+ * @return The search url
+ */
+
+ private StringBuilder getSearchURLWithParams(String tenantId, String businessService) {
+
+ StringBuilder url = new StringBuilder(serviceConfiguration.getWfHost());
+ url.append(serviceConfiguration.getWfBusinessServiceSearchPath());
+ url.append("?tenantId=");
+ url.append(tenantId);
+ url.append("&businessServices=");
+ url.append(businessService);
+ return url;
+ }
+
+ /*
+ * Should return the applicable processInstance for the given request
+ *
+ */
+ public ProcessInstance getProcessInstance(MusterRollRequest musterRollRequest) {
+ String tenantId = musterRollRequest.getMusterRoll().getTenantId();
+ String businessId = musterRollRequest.getMusterRoll().getMusterRollNumber();
+ StringBuilder url = getProcessSearchURLWithParams(tenantId, businessId);
+ RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(musterRollRequest.getRequestInfo()).build();
+ Object result = repository.fetchResult(url, requestInfoWrapper);
+ ProcessInstanceResponse response = null;
+ try {
+ response = mapper.convertValue(result, ProcessInstanceResponse.class);
+ } catch (IllegalArgumentException e) {
+ throw new CustomException("PARSING ERROR", "Failed to parse response of workflow business service search");
+ }
+
+ if (CollectionUtils.isEmpty(response.getProcessInstances()))
+ throw new CustomException("PROCESSINSTANCE_DOESN'T_EXIST", "The businessId : " + businessId + " doesn't exist");
+
+ return response.getProcessInstances().get(0);
+ }
+
+ /**
+ * Creates url for search based on given tenantId and businessId
+ *
+ * @param tenantId The tenantId for which url is generated
+ * @param businessId The businessId for which url is generated
+ * @return The search url
+ */
+
+ private StringBuilder getProcessSearchURLWithParams(String tenantId, String businessId) {
+
+ StringBuilder url = new StringBuilder(serviceConfiguration.getWfHost());
+ url.append(serviceConfiguration.getWfProcessInstanceSearchPath());
+ url.append("?tenantId=");
+ url.append(tenantId);
+ url.append("&businessIds=");
+ url.append(businessId);
+ url.append("&history=false");
+ return url;
+ }
+
+}
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/IdgenUtil.java b/health-services/muster-roll/src/main/java/org/egov/util/IdgenUtil.java
new file mode 100644
index 0000000000..7e0967e841
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/IdgenUtil.java
@@ -0,0 +1,56 @@
+package org.egov.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.egov.common.contract.idgen.IdGenerationRequest;
+import org.egov.common.contract.idgen.IdGenerationResponse;
+import org.egov.common.contract.idgen.IdResponse;
+import org.egov.common.contract.idgen.IdRequest;
+import org.egov.common.contract.request.RequestInfo;
+import org.egov.repository.ServiceRequestRepository;
+import org.egov.tracer.model.CustomException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Component
+public class IdgenUtil {
+
+ @Value("${egov.idgen.host}")
+ private String idGenHost;
+
+ @Value("${egov.idgen.path}")
+ private String idGenPath;
+
+ private final ObjectMapper mapper;
+
+ private final ServiceRequestRepository restRepo;
+
+ @Autowired
+ public IdgenUtil(ObjectMapper mapper, ServiceRequestRepository restRepo) {
+ this.mapper = mapper;
+ this.restRepo = restRepo;
+ }
+
+ public List getIdList(RequestInfo requestInfo, String tenantId, String idName, String idformat, Integer count) {
+ List reqList = new ArrayList<>();
+ for (int i = 0; i < count; i++) {
+ reqList.add(IdRequest.builder().idName(idName).format(idformat).tenantId(tenantId).build());
+ }
+
+ IdGenerationRequest request = IdGenerationRequest.builder().idRequests(reqList).requestInfo(requestInfo).build();
+ StringBuilder uri = new StringBuilder(idGenHost).append(idGenPath);
+ IdGenerationResponse response = mapper.convertValue(restRepo.fetchResult(uri, request), IdGenerationResponse.class);
+
+ List idResponses = response.getIdResponses();
+
+ if (CollectionUtils.isEmpty(idResponses))
+ throw new CustomException("IDGEN ERROR", "No ids returned from idgen Service");
+
+ return idResponses.stream().map(IdResponse::getId).collect(Collectors.toList());
+ }
+}
\ No newline at end of file
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/LocalizationUtil.java b/health-services/muster-roll/src/main/java/org/egov/util/LocalizationUtil.java
new file mode 100644
index 0000000000..7b428fc1a4
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/LocalizationUtil.java
@@ -0,0 +1,71 @@
+package org.egov.util;
+
+import com.jayway.jsonpath.JsonPath;
+import lombok.extern.slf4j.Slf4j;
+import org.egov.common.contract.models.RequestInfoWrapper;
+import org.egov.common.contract.request.RequestInfo;
+import org.egov.config.MusterRollServiceConfiguration;
+import org.egov.repository.ServiceRequestRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.egov.util.MusterRollServiceConstants.MUSTER_ROLL_MODULE_CODE;
+
+@Component
+@Slf4j
+public class LocalizationUtil {
+
+ private final MusterRollServiceConfiguration config;
+
+ private final ServiceRequestRepository restRepo;
+
+ @Autowired
+ public LocalizationUtil(MusterRollServiceConfiguration config, ServiceRequestRepository restRepo) {
+ this.config = config;
+ this.restRepo = restRepo;
+ }
+
+
+ /**
+ * Creates a cache for localization that gets refreshed at every call.
+ *
+ * @param requestInfo
+ * @param rootTenantId
+ * @param locale
+ * @param module
+ * @return
+ */
+ public Map> getLocalisedMessages(RequestInfo requestInfo, String rootTenantId, String locale, String module) {
+ Map> localizedMessageMap = new HashMap<>();
+ Map mapOfCodesAndMessages = new HashMap<>();
+ StringBuilder uri = new StringBuilder();
+ RequestInfoWrapper requestInfoWrapper = new RequestInfoWrapper();
+ requestInfoWrapper.setRequestInfo(requestInfo);
+ uri.append(config.getLocalizationServiceHost())
+ .append(config.getLocalizationServiceEndpoint()).append("?tenantId=" + rootTenantId)
+ .append("&module=" + module).append("&locale=" + locale);
+ List codes = null;
+ List messages = null;
+ Object result = null;
+ try {
+ result = restRepo.fetchResult(uri, requestInfoWrapper);
+ codes = JsonPath.read(result, MusterRollServiceConstants.MUSTER_ROLL_LOCALIZATION_CODE_JSONPATH);
+ messages = JsonPath.read(result, MusterRollServiceConstants.MUSTER_ROLL_LOCALIZATION_MESSAGE_JSONPATH);
+ } catch (Exception e) {
+ log.error("Exception while fetching from localization: " + e);
+ }
+ if (null != result) {
+ for (int i = 0; i < codes.size(); i++) {
+ mapOfCodesAndMessages.put(codes.get(i), messages.get(i));
+ }
+ localizedMessageMap.put(locale + "|" + rootTenantId, mapOfCodesAndMessages);
+ }
+
+ return localizedMessageMap;
+ }
+
+}
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/MdmsUtil.java b/health-services/muster-roll/src/main/java/org/egov/util/MdmsUtil.java
new file mode 100644
index 0000000000..354aad7026
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/MdmsUtil.java
@@ -0,0 +1,170 @@
+package org.egov.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.egov.common.contract.request.RequestInfo;
+import org.egov.config.MusterRollServiceConfiguration;
+import org.egov.mdms.model.MasterDetail;
+import org.egov.mdms.model.MdmsCriteria;
+import org.egov.mdms.model.MdmsCriteriaReq;
+import org.egov.mdms.model.ModuleDetail;
+import org.egov.repository.ServiceRequestRepository;
+import org.egov.web.models.MusterRollRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.egov.util.MusterRollServiceConstants.*;
+
+@Slf4j
+@Component
+public class MdmsUtil {
+
+ private final MusterRollServiceConfiguration config;
+
+ private final ServiceRequestRepository serviceRequestRepository;
+
+ @Autowired
+ public MdmsUtil(MusterRollServiceConfiguration config, ServiceRequestRepository serviceRequestRepository) {
+ this.config = config;
+ this.serviceRequestRepository = serviceRequestRepository;
+ }
+
+ /**
+ * Calls MDMS service to fetch works master data
+ *
+ * @param request
+ * @param tenantId
+ * @return
+ */
+ public Object mDMSCall(MusterRollRequest request, String tenantId) {
+ RequestInfo requestInfo = request.getRequestInfo();
+ MdmsCriteriaReq mdmsCriteriaReq = getMDMSRequest(requestInfo, tenantId);
+ return serviceRequestRepository.fetchResult(getMdmsV2SearchUrl(), mdmsCriteriaReq);
+ }
+
+ /**
+ * Calls MDMS service to fetch muster roll data
+ *
+ * @param request
+ * @param tenantId
+ * @return
+ */
+ public Object mDMSCallMuster(MusterRollRequest request, String tenantId) {
+ RequestInfo requestInfo = request.getRequestInfo();
+ MdmsCriteriaReq mdmsCriteriaReq = getMDMSRequestMuster(requestInfo, tenantId);
+ return serviceRequestRepository.fetchResult(getMdmsV2SearchUrl(), mdmsCriteriaReq);
+ }
+
+ public Object mDMSV2CallMuster(MusterRollRequest request, String tenantId) {
+ RequestInfo requestInfo = request.getRequestInfo();
+ MdmsCriteriaReq mdmsCriteriaReq = getMDMSRequestMusterV2(requestInfo, tenantId);
+ return serviceRequestRepository.fetchResult(getMdmsV2SearchUrl(), mdmsCriteriaReq);
+ }
+
+ public MdmsCriteriaReq getMDMSRequestMusterV2(RequestInfo requestInfo, String tenantId) {
+ ModuleDetail musterRollModuleDetail = getMusterRollModuleRequestDataV2();
+
+ List moduleDetails = new LinkedList<>();
+ moduleDetails.add(musterRollModuleDetail);
+
+ MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId)
+ .build();
+ return MdmsCriteriaReq.builder().mdmsCriteria(mdmsCriteria)
+ .requestInfo(requestInfo).build();
+ }
+
+ /**
+ * Returns mdms search criteria based on the tenantId
+ *
+ * @param requestInfo
+ * @param tenantId
+ * @param request
+ * @return
+ */
+ public MdmsCriteriaReq getMDMSRequest(RequestInfo requestInfo, String tenantId) {
+
+ ModuleDetail tenantModuleDetail = getTenantModuleRequestData();
+
+ List moduleDetails = new LinkedList<>();
+ moduleDetails.add(tenantModuleDetail);
+
+ MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId)
+ .build();
+
+ return MdmsCriteriaReq.builder().mdmsCriteria(mdmsCriteria)
+ .requestInfo(requestInfo).build();
+ }
+
+ /**
+ * Returns mdms search criteria based on the tenantId
+ *
+ * @param requestInfo
+ * @param tenantId
+ * @param request
+ * @return
+ */
+ public MdmsCriteriaReq getMDMSRequestMuster(RequestInfo requestInfo, String tenantId) {
+
+ ModuleDetail musterRollModuleDetail = getMusterRollModuleRequestData();
+
+ List moduleDetails = new LinkedList<>();
+ moduleDetails.add(musterRollModuleDetail);
+
+ MdmsCriteria mdmsCriteria = MdmsCriteria.builder().moduleDetails(moduleDetails).tenantId(tenantId)
+ .build();
+
+ return MdmsCriteriaReq.builder().mdmsCriteria(mdmsCriteria)
+ .requestInfo(requestInfo).build();
+ }
+
+ private ModuleDetail getTenantModuleRequestData() {
+ List musterRollTenantMasterDetails = new ArrayList<>();
+
+ MasterDetail tenantMasterDetails = MasterDetail.builder().name(MASTER_TENANTS)
+ .filter(FILTER_CODE).build();
+
+ musterRollTenantMasterDetails.add(tenantMasterDetails);
+
+ return ModuleDetail.builder().masterDetails(musterRollTenantMasterDetails)
+ .moduleName(MDMS_TENANT_MODULE_NAME).build();
+ }
+
+ private ModuleDetail getMusterRollModuleRequestData() {
+
+ List musterRollMasterDetails = new ArrayList<>();
+
+ MasterDetail musterAttendanceMasterDetails = MasterDetail.builder().name(MASTER_MUSTER_ROLL).build();
+ musterRollMasterDetails.add(musterAttendanceMasterDetails);
+
+ MasterDetail musterWageSeekerSkillsMasterDetails = MasterDetail.builder().name(MASTER_WAGER_SEEKER_SKILLS).build();
+ musterRollMasterDetails.add(musterWageSeekerSkillsMasterDetails);
+
+ return ModuleDetail.builder().masterDetails(musterRollMasterDetails)
+ .moduleName(MDMS_COMMON_MASTERS_MODULE_NAME).build();
+ }
+
+ private ModuleDetail getMusterRollModuleRequestDataV2() {
+
+ List musterRollMasterDetails = new ArrayList<>();
+ MasterDetail musterWageSeekerSkillMasterDetails = MasterDetail.builder().name("SOR").filter("[?(@.sorType=='L')]").build();
+ musterRollMasterDetails.add(musterWageSeekerSkillMasterDetails);
+ return ModuleDetail.builder().masterDetails(musterRollMasterDetails)
+ .moduleName("WORKS-SOR").build();
+ }
+
+ /**
+ * Returns the url for mdms search endpoint
+ *
+ * @return url for mdms search endpoint
+ */
+ public StringBuilder getMdmsSearchUrl() {
+ return new StringBuilder().append(config.getMdmsHost()).append(config.getMdmsEndPoint());
+ }
+ public StringBuilder getMdmsV2SearchUrl() {
+ return new StringBuilder().append(config.getMdmsV2Host()).append(config.getMdmsV2EndPoint());
+ }
+
+}
\ No newline at end of file
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/MusterRollServiceConstants.java b/health-services/muster-roll/src/main/java/org/egov/util/MusterRollServiceConstants.java
new file mode 100644
index 0000000000..f35a0da604
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/MusterRollServiceConstants.java
@@ -0,0 +1,37 @@
+package org.egov.util;
+
+public class MusterRollServiceConstants {
+
+ public static final String ACTION_REJECT = "REJECT";
+ public static final String MASTER_TENANTS = "tenants";
+ public static final String FILTER_CODE = "$.*.code";
+ public static final String MDMS_TENANT_MODULE_NAME = "tenant";
+ public static final String MDMS_COMMON_MASTERS_MODULE_NAME = "common-masters";
+ public static final String MASTER_MUSTER_ROLL = "MusterRoll";
+ public static final String MASTER_WAGER_SEEKER_SKILLS = "WageSeekerSkills";
+ public static final String HALF_DAY_NUM_HOURS = "HALF_DAY_NUM_HOURS";
+ public static final String FULL_DAY_NUM_HOURS = "FULL_DAY_NUM_HOURS";
+ public static final String ROUND_OFF_HOURS = "ROUND_OFF_HOURS";
+ public static final String ENTRY_EVENT = "ENTRY";
+ public static final String EXIT_EVENT = "EXIT";
+ public static final String STATUS_APPROVED = "APPROVED";
+ public static final String TENANT_ID = "tenantId";
+ public static final String CONTRACT_NUMBER = "contractNumber";
+ public static final String REQUEST_INFO = "RequestInfo";
+ public static final String ORG_ID_PATH = "$.contracts.*.orgId";
+ public static final String ID = "id";
+ public static final String ORG_NAME_PATH = "$.organisations.*.name";
+ public static final String CONTACT_NAME_PATH = "$.organisations.*.contactDetails.*.contactName";
+ public static final String CONTACT_MOBILE_NUMBER_PATH = "$.organisations.*.contactDetails.*.contactMobileNumber";
+ public static final String ORG_NAME = "orgName";
+ public static final String CONTACT_NAME = "contactName";
+ public static final String CONTACT_MOBILE_NUMBER = "contactMobileNumber";
+ public static final String MUSTER_ROLL_MODULE_CODE = "rainmaker-common-masters";
+ public static final String SEARCH_CRITERIA = "SearchCriteria";
+ public static final String MUSTER_ROLL_LOCALIZATION_CODE_JSONPATH = "$.messages.*.code";
+ public static final String MUSTER_ROLL_LOCALIZATION_MESSAGE_JSONPATH = "$.messages.*.message";
+ public static final String WF_SEND_BACK_TO_CBO_CODE = "SENDBACKTOCBO";
+ public static final String WF_APPROVE_CODE = "APPROVE";
+ public static final String CBO_NOTIFICATION_FOR_CORRECTION_LOCALIZATION_CODE = "MUSTER_ROLL_CBO_NOTIFICATION_FOR_CORRECTION";
+ public static final String CBO_NOTIFICATION_OF_APPROVAL_LOCALIZATION_CODE = "MUSTER_ROLL_CBO_NOTIFICATION_OF_APPROVAL";
+}
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/MusterRollServiceUtil.java b/health-services/muster-roll/src/main/java/org/egov/util/MusterRollServiceUtil.java
new file mode 100644
index 0000000000..0d150e8e43
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/MusterRollServiceUtil.java
@@ -0,0 +1,269 @@
+package org.egov.util;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.jayway.jsonpath.JsonPath;
+import org.egov.common.contract.models.AuditDetails;
+import org.egov.common.contract.models.RequestInfoWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.egov.common.contract.request.RequestInfo;
+import org.egov.common.models.individual.Identifier;
+import org.egov.common.models.individual.Individual;
+import org.egov.common.models.individual.Skill;
+import org.egov.config.MusterRollServiceConfiguration;
+import org.egov.tracer.model.CustomException;
+import org.egov.web.models.*;
+import org.egov.works.services.common.models.bankaccounts.BankAccount;
+import org.egov.works.services.common.models.bankaccounts.BankAccountDetails;
+import org.egov.works.services.common.models.musterroll.Status;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import static org.egov.util.MusterRollServiceConstants.*;
+
+@Component
+@Slf4j
+public class MusterRollServiceUtil {
+
+ private final ObjectMapper mapper;
+
+ private final RestTemplate restTemplate;
+
+ private final MusterRollServiceConfiguration config;
+ private static final String SKILL_CODE = "skillCode";
+
+ @Autowired
+ public MusterRollServiceUtil(ObjectMapper mapper, RestTemplate restTemplate, MusterRollServiceConfiguration config) {
+ this.mapper = mapper;
+ this.restTemplate = restTemplate;
+ this.config = config;
+ }
+
+ /**
+ * Method to return auditDetails for create/update flows
+ *
+ * @param by
+ * @param isCreate
+ * @return AuditDetails
+ */
+ public AuditDetails getAuditDetails(String by, MusterRoll musterRoll, Boolean isCreate) {
+ Long time = System.currentTimeMillis();
+ if (Boolean.TRUE.equals(isCreate))
+ return AuditDetails.builder().createdBy(by).lastModifiedBy(by).createdTime(time).lastModifiedTime(time)
+ .build();
+ else
+ return AuditDetails.builder().createdBy(musterRoll.getAuditDetails().getCreatedBy()).lastModifiedBy(by)
+ .createdTime(musterRoll.getAuditDetails().getCreatedTime()).lastModifiedTime(time).build();
+ }
+
+ /**
+ * Fetch the individual skill level from MDMS
+ *
+ * @param mdmsData
+ * @param individualEntry
+ * @param skillCode
+ *
+ */
+ public void populateAdditionalDetails(Object mdmsData, IndividualEntry individualEntry, String skillCode,
+ Individual matchedIndividual, BankAccount bankAccount, boolean isCreate) {
+ final String jsonPathForWorksMuster = "$.MdmsRes." + "WORKS-SOR" + "."
+ + "SOR" + ".*";
+ List> musterRes = null;
+
+ try {
+ musterRes = JsonPath.read(mdmsData, jsonPathForWorksMuster);
+
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ throw new CustomException("MusterRollServiceUtil::populateAdditionalDetails::JSONPATH_ERROR",
+ "Failed to parse mdms response");
+ }
+
+ String skillValue = "";
+ if (skillCode != null && !CollectionUtils.isEmpty(musterRes)) {
+ for (LinkedHashMap codeValueMap : musterRes) {
+ if (codeValueMap.get("id").equalsIgnoreCase(skillCode)) {
+ skillValue = codeValueMap.get("name");
+ break;
+ }
+ }
+ }
+
+ // populate individual details for estimate and create
+ log.info("MusterRollServiceUtil::populateAdditionalDetails::start");
+ JSONObject additionalDetails = new JSONObject();
+
+ additionalDetails.put("userId", matchedIndividual.getIndividualId());
+ additionalDetails.put("userName", matchedIndividual.getName().getGivenName());
+ additionalDetails.put("fatherName", matchedIndividual.getFatherName());
+ additionalDetails.put("mobileNo", matchedIndividual.getMobileNumber());
+ additionalDetails.put("gender",matchedIndividual.getGender());
+ Identifier aadhaar = matchedIndividual.getIdentifiers().stream()
+ .filter(identifier -> identifier.getIdentifierType().contains("AADHAAR")).findFirst().orElse(null);
+ if (aadhaar != null) {
+ additionalDetails.put("aadharNumber", aadhaar.getIdentifierId());
+ }
+
+ // populate individual's skill details in create and update (user selected skill
+ // will be set in additionalDetails)
+ if (isCreate) {
+ additionalDetails.put(SKILL_CODE, skillCode);
+ additionalDetails.put("skillValue", skillValue);
+ }
+
+ // populate list of skills of the individual in estimate additionalDetails
+ populateSkillsInEstimateDetails(isCreate,matchedIndividual,additionalDetails);
+
+ if (bankAccount != null) {
+ List bankAccountDetails = bankAccount.getBankAccountDetails();
+ if (!CollectionUtils.isEmpty(bankAccountDetails)) {
+ String accountNumber = bankAccountDetails.get(0).getAccountNumber();
+ String ifscCode = bankAccountDetails.get(0).getBankBranchIdentifier().getCode();
+ String accountHolderName = bankAccountDetails.get(0).getAccountHolderName();
+ String accountType = bankAccountDetails.get(0).getAccountType();
+ additionalDetails.put("bankDetails", accountNumber + "-" + ifscCode);
+ additionalDetails.put("accountHolderName", accountHolderName);
+ additionalDetails.put("accountType", accountType);
+ }
+ }
+
+ try {
+ individualEntry.setAdditionalDetails(mapper.readValue(additionalDetails.toString(), Object.class));
+ } catch (IOException e) {
+ throw new CustomException("MusterRollServiceUtil::populateAdditionalDetails::PARSING ERROR",
+ "Failed to set additionalDetail object");
+ }
+
+ }
+ private void populateSkillsInEstimateDetails(boolean isCreate,Individual matchedIndividual,JSONObject additionalDetails){
+ if (!isCreate && !CollectionUtils.isEmpty(matchedIndividual.getSkills())) {
+ List skillList = new ArrayList<>();
+ for (Skill skill : matchedIndividual.getSkills()) {
+ skillList.add(skill.getLevel());
+ }
+ additionalDetails.put(SKILL_CODE, skillList);
+ }
+ }
+
+ public void updateAdditionalDetails(Object mdmsData, IndividualEntry individualEntry, String skillCode) {
+ final String jsonPathForWorksMuster = "$.MdmsRes." + "WORKS-SOR" + "."
+ + "SOR" + ".*";
+ List> musterRes = null;
+
+ try {
+ musterRes = JsonPath.read(mdmsData, jsonPathForWorksMuster);
+
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ throw new CustomException("MusterRollServiceUtil::updateAdditionalDetails::JSONPATH_ERROR",
+ "Failed to parse mdms response");
+ }
+
+ String skillValue = "";
+ if (skillCode != null && !CollectionUtils.isEmpty(musterRes)) {
+ for (LinkedHashMap codeValueMap : musterRes) {
+ if (codeValueMap.get("id").equalsIgnoreCase(skillCode)) {
+ skillValue = codeValueMap.get("name");
+ break;
+ }
+ }
+ }
+
+ try {
+ JsonNode node = mapper.readTree(mapper.writeValueAsString(individualEntry.getAdditionalDetails()));
+ ((ObjectNode) node).put(SKILL_CODE, skillCode);
+ ((ObjectNode) node).put("skillValue", skillValue);
+ individualEntry.setAdditionalDetails(mapper.readValue(node.toString(), Object.class));
+
+ } catch (IOException e) {
+ log.info(
+ "MusterRollServiceUtil::updateAdditionalDetails::Failed to parse additionalDetail object from request"
+ + e);
+ throw new CustomException("PARSING ERROR",
+ "Failed to parse additionalDetail object from request on update");
+ }
+
+ }
+
+ /**
+ * Sets the attendanceLogId in additionalDetails of the attendanceEntry
+ *
+ * @param attendanceEntry
+ * @param entryAttendanceLogId
+ * @param exitAttendanceLogId
+ */
+ public void populateAdditionalDetailsAttendanceEntry(AttendanceEntry attendanceEntry, String entryAttendanceLogId,
+ String exitAttendanceLogId) {
+ JSONObject additionalDetails = new JSONObject();
+ additionalDetails.put("entryAttendanceLogId", entryAttendanceLogId);
+ additionalDetails.put("exitAttendanceLogId", exitAttendanceLogId);
+ try {
+ attendanceEntry.setAdditionalDetails(mapper.readValue(additionalDetails.toString(), Object.class));
+ } catch (IOException e) {
+ throw new CustomException("MusterRollServiceUtil::populateAdditionalDetailsAttendanceEntry::PARSING ERROR",
+ "Failed to set additionalDetail object");
+ }
+ }
+
+ /**
+ * Checks if the search is based only on tenantId
+ *
+ * @param searchCriteria
+ * @return
+ */
+ public boolean isTenantBasedSearch(MusterRollSearchCriteria searchCriteria) {
+ return (searchCriteria.getIds() == null || searchCriteria.getIds().isEmpty())
+ && StringUtils.isBlank(searchCriteria.getMusterRollNumber())
+ && StringUtils.isBlank(searchCriteria.getRegisterId()) && searchCriteria.getFromDate() == null
+ && searchCriteria.getToDate() == null && searchCriteria.getStatus() == null
+ && StringUtils.isBlank(searchCriteria.getMusterRollStatus())
+ && StringUtils.isNotBlank(searchCriteria.getTenantId());
+ }
+
+ public AttendanceRegisterResponse fetchAttendanceRegister(MusterRoll musterRoll, RequestInfo requestInfo) {
+ log.info("MusterRollValidator::Fetching attendance register with tenantId::" + musterRoll.getTenantId()
+ + " and register ID: " + musterRoll.getRegisterId());
+ String id = requestInfo.getUserInfo().getUuid();
+
+ StringBuilder uri = new StringBuilder();
+ uri.append(config.getAttendanceLogHost()).append(config.getAttendanceRegisterEndpoint());
+ UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(uri.toString())
+ .queryParam("tenantId", musterRoll.getTenantId()).queryParam("ids", musterRoll.getRegisterId())
+ .queryParam("status", Status.ACTIVE);
+ RequestInfoWrapper requestInfoWrapper = RequestInfoWrapper.builder().requestInfo(requestInfo).build();
+
+ AttendanceRegisterResponse attendanceRegisterResponse = null;
+
+ try {
+ attendanceRegisterResponse = restTemplate.postForObject(uriBuilder.toUriString(), requestInfoWrapper,
+ AttendanceRegisterResponse.class);
+ } catch (HttpClientErrorException | HttpServerErrorException httpClientOrServerExc) {
+ log.error("MusterRollValidator::Error thrown from attendance register service::"
+ + httpClientOrServerExc.getStatusCode());
+ throw new CustomException("ATTENDANCE_REGISTER_SERVICE_EXCEPTION",
+ "Error thrown from attendance register service::" + httpClientOrServerExc.getStatusCode());
+ }
+
+ if (attendanceRegisterResponse == null
+ || CollectionUtils.isEmpty(attendanceRegisterResponse.getAttendanceRegister())) {
+ log.error("MusterRollValidator::User with id::" + id + " is not enrolled in the attendance register::"
+ + musterRoll.getRegisterId());
+ throw new CustomException("ACCESS_EXCEPTION",
+ "User is not enrolled in the attendance register and not authorized to fetch it");
+ }
+ return attendanceRegisterResponse;
+ }
+}
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/NotificationUtil.java b/health-services/muster-roll/src/main/java/org/egov/util/NotificationUtil.java
new file mode 100644
index 0000000000..1afa015b48
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/NotificationUtil.java
@@ -0,0 +1,163 @@
+package org.egov.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.jayway.jsonpath.JsonPath;
+import lombok.extern.slf4j.Slf4j;
+import net.minidev.json.JSONArray;
+import org.egov.common.contract.request.RequestInfo;
+import org.egov.config.MusterRollServiceConfiguration;
+import org.egov.repository.ServiceRequestRepository;
+import org.egov.tracer.model.CustomException;
+import org.egov.web.models.MusterRollRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.egov.util.MusterRollServiceConstants.*;
+
+@Component
+@Slf4j
+public class NotificationUtil {
+
+ private final MusterRollServiceConfiguration config;
+
+ private final ServiceRequestRepository restRepo;
+
+ private final ObjectMapper mapper;
+
+ @Autowired
+ public NotificationUtil(MusterRollServiceConfiguration config, ServiceRequestRepository restRepo, ObjectMapper mapper) {
+ this.config = config;
+ this.restRepo = restRepo;
+ this.mapper = mapper;
+ }
+
+ public Map getCBOContactPersonDetails(MusterRollRequest musterRollRequest){
+ String orgId = fetchOrgId(musterRollRequest);
+ return fetchCBODetails(musterRollRequest, orgId);
+ }
+ public String fetchOrgId(MusterRollRequest musterRollRequest){
+ StringBuilder url = getOrgIdWithContractIdUrl();
+ Object contractSearchRequest = getOrgIdWithContractIdRequest(musterRollRequest);
+ final Object contractRes = restRepo.fetchResult(url, contractSearchRequest);
+ String orgId;
+ try{
+ JSONArray jsonArray = JsonPath.read(contractRes, ORG_ID_PATH);
+ orgId = jsonArray.get(0).toString();
+ }catch (Exception e){
+ throw new CustomException("PARSING_CONTRACT_ERROR", "Failed to parse response from contract");
+ }
+
+ return orgId;
+ }
+
+ private StringBuilder getOrgIdWithContractIdUrl(){
+ StringBuilder builder = new StringBuilder(config.getContractServiceHost());
+ builder.append(config.getContractServiceEndpoint());
+ return builder;
+ }
+
+ private Object getOrgIdWithContractIdRequest(MusterRollRequest musterRollRequest){
+ RequestInfo requestInfo = musterRollRequest.getRequestInfo();
+ String contractNumber = musterRollRequest.getMusterRoll().getReferenceId();
+ String tenantId = musterRollRequest.getMusterRoll().getTenantId();
+
+ // Create request object
+ ObjectNode contractSearchCriteriaNode = mapper.createObjectNode();
+
+ contractSearchCriteriaNode.putPOJO(REQUEST_INFO, requestInfo);
+ contractSearchCriteriaNode.put(CONTRACT_NUMBER, contractNumber);
+ contractSearchCriteriaNode.put(TENANT_ID, tenantId);
+
+ return contractSearchCriteriaNode;
+ }
+
+ private Map fetchCBODetails(MusterRollRequest musterRollRequest, String orgId){
+ StringBuilder url = getCBODetailsFromOrgUrl();
+ Object orgSearchRequest = getCBODetailsRequest(musterRollRequest, orgId);
+
+ log.info("Organisation search request -> {}", orgSearchRequest);
+ Object orgRes = restRepo.fetchResult(url, orgSearchRequest);
+
+ Map orgDetails = new HashMap<>();
+ List orgName = null;
+ List contactName = null;
+ List contactMobileNumber = null;
+
+ try{
+ orgName = JsonPath.read(orgRes, ORG_NAME_PATH);
+ contactName = JsonPath.read(orgRes, CONTACT_NAME_PATH);
+ contactMobileNumber = JsonPath.read(orgRes, CONTACT_MOBILE_NUMBER_PATH);
+ } catch (Exception e){
+ throw new CustomException("PARSING_ORG_ERROR", "Failed to parse response from organisation");
+ }
+
+ orgDetails.put(ORG_NAME, orgName.get(0));
+ orgDetails.put(CONTACT_NAME, contactName.get(0));
+ orgDetails.put(CONTACT_MOBILE_NUMBER,contactMobileNumber.get(0));
+
+ return orgDetails;
+ }
+
+ private StringBuilder getCBODetailsFromOrgUrl(){
+ StringBuilder builder = new StringBuilder(config.getOrganisationServiceHost());
+ builder.append(config.getOrganisationServiceEndpoint());
+ return builder;
+ }
+
+ private Object getCBODetailsRequest(MusterRollRequest musterRollRequest, String orgId){
+ RequestInfo requestInfo = musterRollRequest.getRequestInfo();
+ String tenantId = musterRollRequest.getMusterRoll().getTenantId();
+
+ ObjectNode orgSearchRequestNode = mapper.createObjectNode();
+ ArrayNode ids = mapper.createArrayNode();
+ ids.add(orgId);
+
+ ObjectNode orgObjNode = mapper.createObjectNode();
+ orgObjNode.put(TENANT_ID, tenantId);
+ orgObjNode.putPOJO(ID, ids);
+
+ orgSearchRequestNode.putPOJO(REQUEST_INFO, requestInfo);
+ orgSearchRequestNode.putPOJO(SEARCH_CRITERIA,orgObjNode);
+
+ return orgSearchRequestNode;
+ }
+
+ public String getExpenseAmount(MusterRollRequest musterRollRequest){
+ StringBuilder url = getExpenseUrl();
+ Object expenseSearchRequest = getExpenseRequest(musterRollRequest);
+ final Object expenseRes = restRepo.fetchResult(url, expenseSearchRequest);
+ Integer amount = null;
+ try {
+ amount = JsonPath.read(expenseRes, "$.calculation.totalAmount");
+ }catch (Exception e){
+ throw new CustomException("EXPENSE_PARSING_ERROR", "Error while parsing expense object");
+ }
+ return amount.toString();
+ }
+ public StringBuilder getExpenseUrl(){
+ return new StringBuilder(config.getExpenseCalculatorServiceHost())
+ .append(config.getExpenseCalculatorServiceEndpoint());
+ }
+
+ public Object getExpenseRequest(MusterRollRequest musterRollRequest){
+ ObjectNode expenseRequestObjNode = mapper.createObjectNode();
+ ArrayNode musterRollIds = mapper.createArrayNode();
+ ObjectNode criteriaObjNode = mapper.createObjectNode();
+
+ musterRollIds.add(musterRollRequest.getMusterRoll().getId());
+
+ criteriaObjNode.putPOJO("musterRollId", musterRollIds);
+ criteriaObjNode.put("tenantId", musterRollRequest.getMusterRoll().getTenantId());
+
+ expenseRequestObjNode.putPOJO(REQUEST_INFO, musterRollRequest.getRequestInfo());
+ expenseRequestObjNode.putPOJO("criteria", criteriaObjNode);
+ return expenseRequestObjNode;
+ }
+
+}
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/ResponseInfoCreator.java b/health-services/muster-roll/src/main/java/org/egov/util/ResponseInfoCreator.java
new file mode 100644
index 0000000000..e5f3751ce6
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/ResponseInfoCreator.java
@@ -0,0 +1,26 @@
+package org.egov.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.egov.common.contract.request.RequestInfo;
+import org.egov.common.contract.response.ResponseInfo;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class ResponseInfoCreator {
+
+ public ResponseInfo createResponseInfoFromRequestInfo(final RequestInfo requestInfo, final Boolean success) {
+
+ final String apiId = requestInfo != null ? requestInfo.getApiId() : "";
+ final String ver = requestInfo != null ? requestInfo.getVer() : "";
+ Long ts = null;
+ if (requestInfo != null)
+ ts = requestInfo.getTs();
+ final String resMsgId = "uief87324"; // TODO : Hard-coded
+ final String msgId = requestInfo != null ? requestInfo.getMsgId() : "";
+ final String responseStatus = Boolean.TRUE.equals(success) ? "successful" : "failed";
+
+ return ResponseInfo.builder().apiId(apiId).ver(ver).ts(ts).resMsgId(resMsgId).msgId(msgId).resMsgId(resMsgId)
+ .status(responseStatus).build();
+ }
+}
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/UrlShortenerUtil.java b/health-services/muster-roll/src/main/java/org/egov/util/UrlShortenerUtil.java
new file mode 100644
index 0000000000..66a1080de0
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/UrlShortenerUtil.java
@@ -0,0 +1,44 @@
+package org.egov.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+
+@Slf4j
+@Component
+public class UrlShortenerUtil {
+
+ private final RestTemplate restTemplate;
+
+ @Value("${egov.url.shortner.host}")
+ private String urlShortnerHost;
+
+ @Value("${egov.url.shortner.endpoint}")
+ private String urShortnerPath;
+
+ @Autowired
+ public UrlShortenerUtil(RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
+
+ public String getShortenedUrl(String url) {
+
+ HashMap body = new HashMap<>();
+ body.put("url", url);
+ StringBuilder builder = new StringBuilder(urlShortnerHost);
+ builder.append(urShortnerPath);
+ String res = restTemplate.postForObject(builder.toString(), body, String.class);
+
+ if (StringUtils.isEmpty(res)) {
+ log.error("URL_SHORTENING_ERROR", "Unable to shorten url: " + url);
+ return url;
+ } else return res;
+ }
+
+
+}
\ No newline at end of file
diff --git a/health-services/muster-roll/src/main/java/org/egov/util/UserUtil.java b/health-services/muster-roll/src/main/java/org/egov/util/UserUtil.java
new file mode 100644
index 0000000000..ee51c870e8
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/util/UserUtil.java
@@ -0,0 +1,143 @@
+package org.egov.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.egov.common.contract.request.Role;
+import org.egov.common.contract.request.User;
+import org.egov.common.contract.user.UserDetailResponse;
+import org.egov.repository.ServiceRequestRepository;
+import org.egov.tracer.model.CustomException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+@Component
+public class UserUtil {
+
+
+ private ObjectMapper mapper;
+
+ private ServiceRequestRepository serviceRequestRepository;
+
+ @Value("${egov.user.create.path}")
+ private String userCreateEndpoint;
+
+ @Value("${egov.user.search.path}")
+ private String userSearchEndpoint;
+
+ @Value("${egov.user.update.path}")
+ private String userUpdateEndpoint;
+ private static final String LAST_MODIFIED_DATE = "lastModifiedDate";
+ private static final String PWD_EXPIRY_DATE = "pwdExpiryDate";
+
+ @Autowired
+ public UserUtil(ObjectMapper mapper, ServiceRequestRepository serviceRequestRepository) {
+ this.mapper = mapper;
+ this.serviceRequestRepository = serviceRequestRepository;
+ }
+
+ /**
+ * Returns UserDetailResponse by calling user service with given uri and object
+ *
+ * @param userRequest Request object for user service
+ * @param uri The address of the endpoint
+ * @return Response from user service as parsed as userDetailResponse
+ */
+
+ public UserDetailResponse userCall(Object userRequest, StringBuilder uri) {
+ String dobFormat = null;
+ if (uri.toString().contains(userSearchEndpoint) || uri.toString().contains(userUpdateEndpoint))
+ dobFormat = "yyyy-MM-dd";
+ else if (uri.toString().contains(userCreateEndpoint))
+ dobFormat = "dd/MM/yyyy";
+ try {
+ LinkedHashMap responseMap = (LinkedHashMap) serviceRequestRepository.fetchResult(uri, userRequest);
+ parseResponse(responseMap, dobFormat);
+ return mapper.convertValue(responseMap, UserDetailResponse.class);
+ } catch (IllegalArgumentException e) {
+ throw new CustomException("IllegalArgumentException", "ObjectMapper not able to convertValue in userCall");
+ }
+ }
+
+
+ /**
+ * Parses date formats to long for all users in responseMap
+ *
+ * @param responeMap LinkedHashMap got from user api response
+ */
+
+ public void parseResponse(LinkedHashMap responeMap, String dobFormat) {
+ List users = (List) responeMap.get("user");
+ String format1 = "dd-MM-yyyy HH:mm:ss";
+ if (users != null) {
+ users.forEach(map -> {
+ map.put("createdDate", dateTolong((String) map.get("createdDate"), format1));
+ if ((String) map.get(LAST_MODIFIED_DATE) != null)
+ map.put(LAST_MODIFIED_DATE, dateTolong((String) map.get(LAST_MODIFIED_DATE), format1));
+ if ((String) map.get("dob") != null)
+ map.put("dob", dateTolong((String) map.get("dob"), dobFormat));
+ if ((String) map.get(PWD_EXPIRY_DATE) != null)
+ map.put(PWD_EXPIRY_DATE, dateTolong((String) map.get(PWD_EXPIRY_DATE), format1));
+ }
+ );
+ }
+ }
+
+ /**
+ * Converts date to long
+ *
+ * @param date date to be parsed
+ * @param format Format of the date
+ * @return Long value of date
+ */
+ private Long dateTolong(String date, String format) {
+ SimpleDateFormat f = new SimpleDateFormat(format);
+ Date d = null;
+ try {
+ d = f.parse(date);
+ } catch (ParseException e) {
+ throw new CustomException("INVALID_DATE_FORMAT", "Failed to parse date format in user");
+ }
+ return d.getTime();
+ }
+
+ /**
+ * enriches the userInfo with statelevel tenantId and other fields
+ *
+ * @param mobileNumber
+ * @param tenantId
+ * @param userInfo
+ */
+ public void addUserDefaultFields(String mobileNumber, String tenantId, User userInfo) {
+ Role role = getCitizenRole(tenantId);
+ userInfo.setRoles(Collections.singletonList(role));
+ userInfo.setType("CITIZEN");
+ userInfo.setUserName(mobileNumber);
+ userInfo.setTenantId(getStateLevelTenant(tenantId));
+ }
+
+ /**
+ * Returns role object for citizen
+ *
+ * @param tenantId
+ * @return
+ */
+ private Role getCitizenRole(String tenantId) {
+ Role role = new Role();
+ role.setCode("CITIZEN");
+ role.setName("Citizen");
+ role.setTenantId(getStateLevelTenant(tenantId));
+ return role;
+ }
+
+ public String getStateLevelTenant(String tenantId) {
+ return tenantId.split("\\.")[0];
+ }
+
+}
\ No newline at end of file
diff --git a/health-services/muster-roll/src/main/java/org/egov/validator/MusterRollValidator.java b/health-services/muster-roll/src/main/java/org/egov/validator/MusterRollValidator.java
new file mode 100644
index 0000000000..8a5d84e45e
--- /dev/null
+++ b/health-services/muster-roll/src/main/java/org/egov/validator/MusterRollValidator.java
@@ -0,0 +1,299 @@
+package org.egov.validator;
+
+import com.jayway.jsonpath.JsonPath;
+import org.egov.common.contract.models.RequestInfoWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.egov.common.contract.models.Workflow;
+import org.egov.common.contract.request.RequestInfo;
+import org.egov.config.MusterRollServiceConfiguration;
+import org.egov.tracer.model.CustomException;
+import org.egov.util.MdmsUtil;
+import org.egov.web.models.*;
+import org.egov.works.services.common.models.musterroll.Status;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.math.BigDecimal;
+import java.time.DayOfWeek;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.egov.util.MusterRollServiceConstants.*;
+
+@Component
+@Slf4j
+public class MusterRollValidator {
+
+ private final MusterRollServiceConfiguration serviceConfiguration;
+
+ private final MdmsUtil mdmsUtils;
+
+ private final RestTemplate restTemplate;
+
+ private static final String TENANT_ID = "TENANT_ID";
+ private static final String MUSTER_ROLL = "MUSTER_ROLL";
+ private static final String MUSTER_ROLL_IS_MANADATORY = "Muster roll is mandatory";
+ private static final String TENANT_ID_IS_MANADATORY = "TenantId is mandatory";
+
+ @Autowired
+ public MusterRollValidator(MusterRollServiceConfiguration serviceConfiguration, MdmsUtil mdmsUtils, RestTemplate restTemplate) {
+ this.serviceConfiguration = serviceConfiguration;
+ this.mdmsUtils = mdmsUtils;
+ this.restTemplate = restTemplate;
+ }
+
+ /**
+ * Validate muster roll in estimate service
+ * @param musterRollRequest
+ */
+ public void validateEstimateMusterRoll(MusterRollRequest musterRollRequest){
+ log.info("MusterRollValidator::validateEstimateMusterRoll");
+
+ Map errorMap = new HashMap<>();
+ MusterRoll musterRoll = musterRollRequest.getMusterRoll();
+ RequestInfo requestInfo = musterRollRequest.getRequestInfo();
+
+ validateRequestInfo(requestInfo);
+ validateEstimateMusterRollRequest(musterRoll);
+
+ //split the tenantId and validate tenantId
+ String tenantId = musterRoll.getTenantId();
+ Object mdmsData = mdmsUtils.mDMSCall(musterRollRequest, tenantId);
+ validateMDMSData(musterRoll, mdmsData, errorMap);
+
+ if (!errorMap.isEmpty()){
+ throw new CustomException(errorMap);
+ }
+
+ }
+
+ /**
+ * Validate muster roll in create service
+ * @param musterRollRequest
+ */
+ public void validateCreateMusterRoll(MusterRollRequest musterRollRequest) {
+ log.info("MusterRollValidator::validateCreateMusterRoll");
+
+ Map errorMap = new HashMap<>();
+ MusterRoll musterRoll = musterRollRequest.getMusterRoll();
+ RequestInfo requestInfo = musterRollRequest.getRequestInfo();
+ Workflow workflow = musterRollRequest.getWorkflow();
+
+ validateRequestInfo(requestInfo);
+ validateCreateMusterRollRequest(musterRoll);
+ validateWorkFlow(workflow, errorMap);
+
+ //split the tenantId and validate tenantId
+ String tenantId = musterRoll.getTenantId();
+ Object mdmsData = mdmsUtils.mDMSCall(musterRollRequest, tenantId);
+ validateMDMSData(musterRoll, mdmsData, errorMap);
+
+ //check if the user is enrolled in the attendance register
+ isValidUser(musterRoll, requestInfo);
+
+ if (!errorMap.isEmpty()){
+ throw new CustomException(errorMap);
+ }
+
+ }
+
+ /**
+ * Validate muster roll in update service
+ * @param musterRollRequest
+ */
+ public void validateUpdateMusterRoll(MusterRollRequest musterRollRequest) {
+ log.info("MusterRollValidator::validateUpdateMusterRoll");
+
+ Map errorMap = new HashMap<>();
+ MusterRoll musterRoll = musterRollRequest.getMusterRoll();
+ RequestInfo requestInfo = musterRollRequest.getRequestInfo();
+ Workflow workflow = musterRollRequest.getWorkflow();
+
+ validateRequestInfo(requestInfo);
+ validateWorkFlow(workflow, errorMap);
+ validateUpdateMusterRollRequest(musterRoll);
+
+ //split the tenantId and validate tenantId
+ String tenantId = musterRoll.getTenantId();
+ Object mdmsData = mdmsUtils.mDMSCall(musterRollRequest, tenantId);
+ validateMDMSData(musterRoll, mdmsData, errorMap);
+
+ if (!errorMap.isEmpty()){
+ throw new CustomException(errorMap);
+ }
+
+ }
+
+ /**
+ * Validate muster roll in search service
+ * @param requestInfoWrapper
+ * @param searchCriteria
+ */
+ public void validateSearchMuster(RequestInfoWrapper requestInfoWrapper, MusterRollSearchCriteria searchCriteria) {
+ log.info("MusterRollValidator::validateSearchMuster");
+
+ if (searchCriteria == null || requestInfoWrapper == null || requestInfoWrapper.getRequestInfo() == null) {
+ throw new CustomException("MUSTER_ROLL_SEARCH_CRITERIA_REQUEST", "Muster roll search criteria request is mandatory");
+ }
+ if (StringUtils.isBlank(searchCriteria.getTenantId())) {
+ throw new CustomException(TENANT_ID, "Tenant is mandatory");
+ }
+ }
+
+
+ private void validateRequestInfo(RequestInfo requestInfo) {
+ if (requestInfo == null) {
+ throw new CustomException("REQUEST_INFO", "Request info is mandatory");
+ }
+ if (requestInfo.getUserInfo() == null) {
+ throw new CustomException("USERINFO", "UserInfo is mandatory");
+ }
+ if (requestInfo.getUserInfo() != null && StringUtils.isBlank(requestInfo.getUserInfo().getUuid())) {
+ throw new CustomException("USERINFO_UUID", "UUID is mandatory");
+ }
+ }
+
+ private void validateCreateMusterRollRequest(MusterRoll musterRoll) {
+ if (musterRoll == null) {
+ throw new CustomException(MUSTER_ROLL,MUSTER_ROLL_IS_MANADATORY);
+ }
+ if (musterRoll.getTenantId() == null) {
+ throw new CustomException(TENANT_ID,TENANT_ID_IS_MANADATORY);
+ }
+ if (musterRoll.getRegisterId() == null) {
+ throw new CustomException("REGISTER_ID","RegisterId is mandatory");
+ }
+ if (musterRoll.getStartDate() == null) {
+ throw new CustomException("START_DATE_EMPTY","StartDate is mandatory");
+ }
+
+ //Check if the startDate is Monday - UI sends the epoch time in IST
+ LocalDate startDate = Instant.ofEpochMilli(musterRoll.getStartDate().longValue()).atZone(ZoneId.of(serviceConfiguration.getTimeZone())).toLocalDate();
+ if (startDate.getDayOfWeek() != DayOfWeek.MONDAY) {
+ throw new CustomException("START_DATE_MONDAY","StartDate should be Monday");
+ }
+ musterRoll.setStartDate(new BigDecimal(startDate.atStartOfDay(ZoneId.of(serviceConfiguration.getTimeZone())).toInstant().toEpochMilli()));
+
+ log.info("MusterRollValidator::validateCreateMusterRoll::startDate in epoch::"+musterRoll.getStartDate());
+ log.info("MusterRollValidator::validateCreateMusterRoll::startDate::"+startDate);
+ log.info("MusterRollValidator::validateCreateMusterRoll::endDate in epoch from request::"+musterRoll.getEndDate());
+
+ //Override the endDate as SUNDAY
+ LocalDate endDate = startDate.plusDays(6);
+ log.info("MusterRollValidator::validateCreateMusterRoll:: calculated endDate::"+endDate);
+ musterRoll.setEndDate(new BigDecimal(endDate.atStartOfDay(ZoneId.of(serviceConfiguration.getTimeZone())).toInstant().toEpochMilli()));
+
+ }
+
+ private void validateUpdateMusterRollRequest(MusterRoll musterRoll) {
+ if (musterRoll == null) {
+ throw new CustomException(MUSTER_ROLL,MUSTER_ROLL_IS_MANADATORY);
+ }
+ if (musterRoll.getTenantId() == null) {
+ throw new CustomException(TENANT_ID,TENANT_ID_IS_MANADATORY);
+ }
+ if (musterRoll.getId() == null) {
+ throw new CustomException("MUSTER_ROLL_ID","MusterRollId is mandatory");
+ }
+
+ }
+
+ private void validateEstimateMusterRollRequest(MusterRoll musterRoll) {
+ if (musterRoll == null) {
+ throw new CustomException(MUSTER_ROLL,MUSTER_ROLL_IS_MANADATORY);
+ }
+ if (musterRoll.getTenantId() == null) {
+ throw new CustomException(TENANT_ID,TENANT_ID_IS_MANADATORY);
+ }
+ if (musterRoll.getRegisterId() == null) {
+ throw new CustomException("REGISTER_ID","RegisterId is mandatory");
+ }
+ if (musterRoll.getStartDate() == null) {
+ throw new CustomException("START_DATE_EMPTY","StartDate is mandatory");
+ }
+ //endDate is required for /_estimate musterroll - The estimate will be shown for last few days in the week in view/edit screen
+ if (musterRoll.getEndDate() == null) {
+ throw new CustomException("END_DATE_EMPTY","EndDate is mandatory");
+ }
+
+ log.info("MusterRollValidator::validateEstimateMusterRoll::startDate in epoch::"+musterRoll.getStartDate());
+ log.info("MusterRollValidator::validateEstimateMusterRoll::endDate in epoch::"+musterRoll.getEndDate());
+
+ }
+
+ private void validateWorkFlow(Workflow workflow, Map errorMap) {
+ if (workflow == null) {
+ throw new CustomException("WORK_FLOW", "Work flow is mandatory");
+ }
+ if (StringUtils.isBlank(workflow.getAction())) {
+ errorMap.put("WORK_FLOW.ACTION", "Work flow's action is mandatory");
+ }
+ }
+
+ private void validateMDMSData(MusterRoll musterRoll, Object mdmsData, Map errorMap) {
+
+ final String jsonPathForTenants = "$.MdmsRes." + MDMS_TENANT_MODULE_NAME + "." + MASTER_TENANTS + ".*";
+ List