From 5a28f4b1082b3cfd552d2d34bdfec1dba011827b Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 26 Nov 2025 18:00:42 +0530 Subject: [PATCH 01/47] Update application.properties --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 18723465..a1135a2a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -373,4 +373,4 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent - +cors.allowed-origin = From ea12e3e16f68484da66a07f621e2fdccd0ca96d9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 26 Nov 2025 19:54:09 +0530 Subject: [PATCH 02/47] add column in create BeneficiaryModel --- .../com/iemr/common/model/beneficiary/BeneficiaryModel.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index e7a7a3de..5d42f275 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -118,7 +118,10 @@ public class BeneficiaryModel implements Comparable { private Boolean isMarried; @Expose - private Integer doYouHavechildren; + private boolean doYouHavechildren; + + @Expose + private Integer noOfchildren; @Expose private Integer noofAlivechildren; From 50c595288043614744079694c17d02749d4f1d5b Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:44:57 +0530 Subject: [PATCH 03/47] Elasticsearch implementation for Beneficiary Search (#324) * fix: implement functionality to search beneficiaries with Elasticsearch * fix: remove unwanted import * fix: update pom.xml * fix: change the response code --- pom.xml | 2 +- .../BeneficiaryRegistrationController.java | 58 +++++++++++++ .../beneficiary/IEMRSearchUserService.java | 2 + .../IEMRSearchUserServiceImpl.java | 31 ++++++- .../IdentityBeneficiaryService.java | 5 ++ .../IdentityBeneficiaryServiceImpl.java | 82 ++++++++++++++++++- src/main/resources/application.properties | 1 + 7 files changed, 178 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 11ad9f37..171ab162 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.0 + 3.6.1 war Common-API diff --git a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java index 8f573d6d..cdce13b0 100644 --- a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java +++ b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java @@ -36,6 +36,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @@ -70,6 +71,8 @@ import com.iemr.common.service.userbeneficiarydata.MaritalStatusService; import com.iemr.common.service.userbeneficiarydata.StatusService; import com.iemr.common.service.userbeneficiarydata.TitleService; +import com.iemr.common.utils.CookieUtil; +import com.iemr.common.utils.JwtUtil; import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.mapper.OutputMapper; import com.iemr.common.utils.response.OutputResponse; @@ -104,6 +107,10 @@ public class BeneficiaryRegistrationController { private GovtIdentityTypeService govtIdentityTypeService; + + @Autowired + private JwtUtil jwtUtil; + @Autowired public void setBenRelationshipTypeService(BenRelationshipTypeService benRelationshipTypeService) { this.benRelationshipTypeService = benRelationshipTypeService; @@ -342,6 +349,57 @@ public String searchUserByPhone( return response.toString(); } + @Operation(summary = "Provide the list of beneficiaries using Elasticsearch") + @RequestMapping(value = "/searchUser", method = RequestMethod.POST, headers = "Authorization") + public String searchUser( + @RequestBody String request, + @RequestHeader(value = "Authorization", required = false) String auth, HttpServletRequest httpRequest) { + + OutputResponse response = new OutputResponse(); + + try { + logger.info("Universal search request received"); + + JsonParser parser = new JsonParser(); + JsonObject requestObj = parser.parse(request).getAsJsonObject(); + + String searchQuery = null; + if (requestObj.has("search") && !requestObj.get("search").isJsonNull()) { + searchQuery = requestObj.get("search").getAsString(); + } + + if (searchQuery == null || searchQuery.trim().isEmpty()) { + response.setError(400, "Search query is required"); + return response.toString(); + } + + String jwtToken = CookieUtil.getJwtTokenFromCookie(httpRequest); + String userId = jwtUtil.getUserIdFromToken(jwtToken); + int userID=Integer.parseInt(userId); + + Boolean is1097 = false; + if (requestObj.has("is1097") && !requestObj.get("is1097").isJsonNull()) { + is1097 = requestObj.get("is1097").getAsBoolean(); + } + + logger.info("Searching with query: {}, userId: {}, is1097: {}", searchQuery, userID, is1097); + + String result = iemrSearchUserService.searchUser(searchQuery, userID, auth, is1097); + + if (result == null || result.trim().isEmpty()) { + response.setError(200, "No beneficiaries found"); + return response.toString(); + } + + return result; + + } catch (Exception e) { + logger.error("Error in universal search: {}", e.getMessage(), e); + response.setError(400, "Error searching beneficiaries: " + e.getMessage()); + return response.toString(); + } + } + @Operation(summary = "Provide the list of beneficiaries based on search criteria") @RequestMapping(value = "/searchBeneficiary", method = RequestMethod.POST, headers = "Authorization") public String searchBeneficiary( diff --git a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java index 6e7848cd..ab4c40fd 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java @@ -38,6 +38,8 @@ String findByBeneficiaryPhoneNo(BenPhoneMap benPhoneMap, Integer pageNo, Integer String findBeneficiary(BeneficiaryModel request, String auth) throws Exception; + String searchUser(String searchQuery, Integer userId, String auth, Boolean is1097) throws Exception; + List userExitsCheckWithId(String beneficiaryID, String auth, Boolean is1097) throws Exception; public List userExitsCheckWithHealthId_ABHAId(String healthID, String auth, Boolean is1097) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java index f67d7815..7c9bfc2d 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java @@ -25,6 +25,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import org.slf4j.Logger; @@ -76,7 +77,7 @@ import com.iemr.common.repository.userbeneficiarydata.MaritalStatusRepository; import com.iemr.common.repository.userbeneficiarydata.SexualOrientationRepository; import com.iemr.common.repository.userbeneficiarydata.TitleRepository; -import com.iemr.common.utils.mapper.OutputMapper; +import com.iemr.common.utils.exception.IEMRException; /** * @@ -322,6 +323,34 @@ private void setBeneficiaryGender(List iBeneficiary) { } + /** + Universal search using Elasticsearch + */ + @Override + public String searchUser(String searchQuery, Integer userId, String auth, Boolean is1097) throws Exception { + + try { + if (searchQuery == null || searchQuery.trim().isEmpty()) { + throw new IEMRException("Search query is required"); + } + + logger.info("Universal search with query: {}, userId: {}", searchQuery, userId); + + Map response = + identityBeneficiaryService.searchBeneficiariesUsingES( + searchQuery, userId, auth, is1097 + ); + + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(response); + + } catch (Exception e) { + logger.error("Error in universal search", e); + throw new Exception("Error searching beneficiaries: " + e.getMessage(), e); + } +} + + // Advance search @Override public String findBeneficiary(BeneficiaryModel i_beneficiary, String auth) throws Exception { diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java index 8b84bc8a..5ebe3b24 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.List; +import java.util.Map; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; @@ -69,4 +70,8 @@ public List getBeneficiaryListByFamilyId(String familyId, Stri public List getBeneficiaryListByGovId(String identity, String auth, Boolean is1097) throws IEMRException; + + public Map searchBeneficiariesUsingES(String query, Integer userId, String auth, Boolean is1097) throws IEMRException; + + } diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index f9ca6c96..0136c0f8 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -21,15 +21,20 @@ */ package com.iemr.common.service.beneficiary; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import com.google.gson.*; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.iemr.common.dto.identity.BeneficiariesDTO; @@ -43,6 +48,12 @@ import com.iemr.common.utils.mapper.OutputMapper; import com.iemr.common.utils.response.OutputResponse; +import org.springframework.beans.factory.annotation.Value; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + @Service public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryService { @@ -107,6 +118,75 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String return listBenDetailForOutboundDTO; } + /** + Call Identity API's Elasticsearch universal search + */ + @Override + public Map searchBeneficiariesUsingES(String query, Integer userId, String auth, Boolean is1097 ) throws IEMRException { + + Map response = new HashMap<>(); + + try { + HashMap headers = new HashMap<>(); + if (auth != null && !auth.isEmpty()) { + headers.put("Authorization", auth); + } + + String baseUrl = ConfigProperties + .getPropertyByName("identity-api-url-searchByES") + .replace( + IDENTITY_BASE_URL, + (Boolean.TRUE.equals(is1097)) ? identity1097BaseURL : identityBaseURL + ); + + StringBuilder url = new StringBuilder(baseUrl) + .append("?query=").append(URLEncoder.encode(query, StandardCharsets.UTF_8)); + + if (userId != null) { + url.append("&userId=").append(userId); + } + + logger.info("Calling Identity ES search URL: {}", url); + + String result = httpUtils.get(url.toString(), headers); + + if (result == null || result.isEmpty()) { + response.put("data", Collections.emptyList()); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + return response; + } + + ObjectMapper mapper = new ObjectMapper(); + + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false); + + JsonNode rootNode = mapper.readTree(result); + + if (rootNode.has("statusCode") && rootNode.get("statusCode").asInt() != 200) { + String errMsg = rootNode.has("errorMessage") + ? rootNode.get("errorMessage").asText() + : "Identity ES search failed"; + throw new IEMRException(errMsg); + } + + response.put("data", rootNode.path("data")); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + + return response; + + } catch (IEMRException e) { + throw e; + } catch (Exception e) { + logger.error("Error calling Identity ES search API", e); + throw new IEMRException("Error calling Identity ES search API"); + } +} + @Override public List getPartialBeneficiaryListByIDs(HashSet benIdList, String auth, Boolean is1097) throws IEMRException { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 18723465..8ab4669b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -118,6 +118,7 @@ identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity +identity-api-url-searchByES=IDENTITY_BASE_URL/beneficiary/search identity-api-url-getByFamilyId=IDENTITY_BASE_URL/id/searchByFamilyId?familyId= identity-api-url-getByGovIdentity=IDENTITY_BASE_URL/id/searchByGovIdentity?identity= From 1bc9298bf8783f400a022507782d4c5d91ddef34 Mon Sep 17 00:00:00 2001 From: Sachin Kadam <152252767+sac2kadam@users.noreply.github.com> Date: Wed, 31 Dec 2025 16:08:54 +0530 Subject: [PATCH 04/47] variable added --- src/main/environment/common_ci.properties | 1 + src/main/environment/common_docker.properties | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 0184b32f..9f54a35d 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -19,6 +19,7 @@ km-base-path=@env.KM_API_BASE_PATH@ km-root-path=/okm:personal/users/ km-guest-user=@env.KM_GUEST_USER@ km-guest-password=@env.KM_GUEST_PASSWORD@ +tempFilePath=@env.TEMP_FILE_PATH@ # CTI Config cti-server-ip=@env.CTI_SERVER_IP@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index a81ea62e..59cb580d 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -126,7 +126,7 @@ everwellRegisterBenficiary = ${COMMON_API_BASE_URL}/beneficiary/create ## LungAssessment credentials lungAssessmentEmail = ${SWAASA_EMAIL} lungAssessmentPassword =${SWAASA_PASSWORD} - +tempFilePath=${TEMP_FILE_PATH} ## SWASSA APIs lungAssessmentAdminLogin = ${SWAASA_BASE_URL}/api/adminLogin From c501e8037f967fa497d132a9780b8913452927e6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 7 Jan 2026 18:41:15 +0530 Subject: [PATCH 05/47] update language --- .../java/com/iemr/common/data/translation/Translation.java | 2 ++ .../common/service/dynamicForm/FormMasterServiceImpl.java | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/data/translation/Translation.java b/src/main/java/com/iemr/common/data/translation/Translation.java index 81a906fa..0dad116d 100644 --- a/src/main/java/com/iemr/common/data/translation/Translation.java +++ b/src/main/java/com/iemr/common/data/translation/Translation.java @@ -18,6 +18,8 @@ public class Translation { private String english; @Column(name = "hindi_translation") private String hindiTranslation; + @Column(name = "assamese_translation") + private String assameseTranslation; @Column(name = "is_active") private Boolean isActive; } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index df019de7..cfe643b3 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -122,8 +122,11 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { if (t != null) { if ("hi".equalsIgnoreCase(lang)) { translatedLabel = t.getHindiTranslation(); - } else { + } else if("am".equalsIgnoreCase(lang)){ + translatedLabel = t.getAssameseTranslation(); + }else if("en".equalsIgnoreCase(lang)){ translatedLabel = t.getEnglish(); + } } From ec3aac3557f4fec6c5bedcbada3195f17654b42a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 7 Jan 2026 18:50:37 +0530 Subject: [PATCH 06/47] update language --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index cfe643b3..98d93dbe 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -122,7 +122,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { if (t != null) { if ("hi".equalsIgnoreCase(lang)) { translatedLabel = t.getHindiTranslation(); - } else if("am".equalsIgnoreCase(lang)){ + } else if("as".equalsIgnoreCase(lang)){ translatedLabel = t.getAssameseTranslation(); }else if("en".equalsIgnoreCase(lang)){ translatedLabel = t.getEnglish(); From bafc8794a9afd5750b26ff74d61c3d1a7862d959 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 7 Jan 2026 23:15:36 +0530 Subject: [PATCH 07/47] Downgrade version from 3.6.1 to 3.6.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 171ab162..11ad9f37 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.1 + 3.6.0 war Common-API From 65efdc7362f558e6cadc8f735c7606cdec42fb28 Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Thu, 8 Jan 2026 09:26:07 +0530 Subject: [PATCH 08/47] Elastic Search Implementation for Advanced Search (#327) * fix: cherry-pick commits for advanced search * fix: cherry-pick commit for token issue - mobile application * fix: add the missing properties * fix: add function to retrieve userid * fix: move the fetch Userid to jwtUtil --- .../BeneficiaryRegistrationController.java | 74 ++++-- .../beneficiary/IEMRSearchUserService.java | 2 + .../IEMRSearchUserServiceImpl.java | 104 +++++++-- .../IdentityBeneficiaryService.java | 2 + .../IdentityBeneficiaryServiceImpl.java | 214 +++++++++++------- .../java/com/iemr/common/utils/JwtUtil.java | 55 +++++ .../iemr/common/utils/RestTemplateUtil.java | 7 +- .../utils/http/HTTPRequestInterceptor.java | 177 ++++++++------- src/main/resources/application.properties | 1 + 9 files changed, 423 insertions(+), 213 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java index cdce13b0..3784f3a9 100644 --- a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java +++ b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java @@ -106,9 +106,7 @@ public class BeneficiaryRegistrationController { private BeneficiaryOccupationService beneficiaryOccupationService; private GovtIdentityTypeService govtIdentityTypeService; - - - @Autowired + @Autowired private JwtUtil jwtUtil; @Autowired @@ -351,54 +349,51 @@ public String searchUserByPhone( @Operation(summary = "Provide the list of beneficiaries using Elasticsearch") @RequestMapping(value = "/searchUser", method = RequestMethod.POST, headers = "Authorization") - public String searchUser( - @RequestBody String request, - @RequestHeader(value = "Authorization", required = false) String auth, HttpServletRequest httpRequest) { - + public String searchUser(@RequestBody String request, HttpServletRequest httpRequest) { OutputResponse response = new OutputResponse(); - try { logger.info("Universal search request received"); - + JsonParser parser = new JsonParser(); JsonObject requestObj = parser.parse(request).getAsJsonObject(); - + String searchQuery = null; if (requestObj.has("search") && !requestObj.get("search").isJsonNull()) { searchQuery = requestObj.get("search").getAsString(); } - + if (searchQuery == null || searchQuery.trim().isEmpty()) { response.setError(400, "Search query is required"); return response.toString(); } - - String jwtToken = CookieUtil.getJwtTokenFromCookie(httpRequest); - String userId = jwtUtil.getUserIdFromToken(jwtToken); - int userID=Integer.parseInt(userId); - + + String auth = httpRequest.getHeader("Authorization"); + + Integer userID = jwtUtil.getUserIdFromRequest(httpRequest); + + logger.info("ES search for userId: {}", userID); + Boolean is1097 = false; if (requestObj.has("is1097") && !requestObj.get("is1097").isJsonNull()) { is1097 = requestObj.get("is1097").getAsBoolean(); } - + logger.info("Searching with query: {}, userId: {}, is1097: {}", searchQuery, userID, is1097); - String result = iemrSearchUserService.searchUser(searchQuery, userID, auth, is1097); - + if (result == null || result.trim().isEmpty()) { response.setError(200, "No beneficiaries found"); return response.toString(); } - + return result; - + } catch (Exception e) { logger.error("Error in universal search: {}", e.getMessage(), e); response.setError(400, "Error searching beneficiaries: " + e.getMessage()); return response.toString(); } - } + } @Operation(summary = "Provide the list of beneficiaries based on search criteria") @RequestMapping(value = "/searchBeneficiary", method = RequestMethod.POST, headers = "Authorization") @@ -422,6 +417,41 @@ public String searchBeneficiary( return output.toString(); } + /** + * Elasticsearch-based advanced search endpoint + */ + @Operation(summary = "Advanced search beneficiaries using Elasticsearch") + @RequestMapping(value = "/searchBeneficiaryES", method = RequestMethod.POST, headers = "Authorization") + public String searchBeneficiaryES( + @RequestBody BeneficiaryModel request, + HttpServletRequest httpRequest) { + + logger.info("searchBeneficiaryES request: {}", request); + OutputResponse output = new OutputResponse(); + + try { + + String auth = httpRequest.getHeader("Authorization"); + + Integer userID = jwtUtil.getUserIdFromRequest(httpRequest); + + logger.info("ES Advanced search for userId: {}", userID); + + String result = iemrSearchUserService.findBeneficiaryES(request, userID, auth); + + return result; + + } catch (NumberFormatException ne) { + logger.error("searchBeneficiaryES failed with number format error: {}", ne.getMessage(), ne); + output.setError(400, "Invalid number format in search criteria"); + return output.toString(); + } catch (Exception e) { + logger.error("searchBeneficiaryES failed with error: {}", e.getMessage(), e); + output.setError(500, "Error searching beneficiaries: " + e.getMessage()); + return output.toString(); + } + } + @Operation(summary = "Provide all common data list needed for beneficiary registration") @RequestMapping(value = "/getRegistrationData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String getRegistrationData() { diff --git a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java index ab4c40fd..e39cfcab 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java @@ -40,6 +40,8 @@ String findByBeneficiaryPhoneNo(BenPhoneMap benPhoneMap, Integer pageNo, Integer String searchUser(String searchQuery, Integer userId, String auth, Boolean is1097) throws Exception; + String findBeneficiaryES(BeneficiaryModel i_beneficiary, Integer userId, String auth) throws Exception; + List userExitsCheckWithId(String beneficiaryID, String auth, Boolean is1097) throws Exception; public List userExitsCheckWithHealthId_ABHAId(String healthID, String auth, Boolean is1097) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java index 7c9bfc2d..28d664c8 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java @@ -199,7 +199,7 @@ private void addCreatedDateToOtherFields(BeneficiaryModel beneficiaryModel) { JsonNode otherFieldsNode = objectMapper.readTree(beneficiaryModel.getOtherFields()); // Convert createdDate to a string - String createdDateString = beneficiaryModel.getCreatedDate().toString(); + String createdDateString = beneficiaryModel.getCreatedDate().toString(); // Add createdDate to the JSON node ((ObjectNode) otherFieldsNode).put("createdDate", createdDateString); @@ -220,10 +220,10 @@ public List userExitsCheckWithHealthId_ABHAId(String healthID, List beneficiaryList = new ArrayList(); // search patient by ben id, call Identity API List listBen = null; - if(healthID.contains("@")) { + if (healthID.contains("@")) { listBen = identityBeneficiaryService.getBeneficiaryListByHealthID_ABHAAddress(healthID, auth, is1097); - }else { + } else { String healthIdNumber = getHealthId(healthID); listBen = identityBeneficiaryService.getBeneficiaryListByHealthIDNo_ABHAIDNo(healthIdNumber, auth, is1097); } @@ -233,6 +233,7 @@ public List userExitsCheckWithHealthId_ABHAId(String healthID, } return beneficiaryList; } + private String getHealthId(String healthID) { String healthIdNumber = null; if (null != healthID) { @@ -250,6 +251,7 @@ private String getHealthId(String healthID) { } return healthIdNumber; } + // search patient by healthidNo / ABHA Id No @Override public List userExitsCheckWithHealthIdNo_ABHAIdNo(String healthIDNo, String auth, Boolean is1097) @@ -324,32 +326,88 @@ private void setBeneficiaryGender(List iBeneficiary) { } /** - Universal search using Elasticsearch - */ + * Universal search using Elasticsearch + */ @Override public String searchUser(String searchQuery, Integer userId, String auth, Boolean is1097) throws Exception { - try { - if (searchQuery == null || searchQuery.trim().isEmpty()) { - throw new IEMRException("Search query is required"); - } + try { + if (searchQuery == null || searchQuery.trim().isEmpty()) { + throw new IEMRException("Search query is required"); + } + + logger.info("Universal search with query: {}, userId: {}", searchQuery, userId); - logger.info("Universal search with query: {}, userId: {}", searchQuery, userId); + Map response = identityBeneficiaryService.searchBeneficiariesUsingES( + searchQuery, userId, auth, is1097); - Map response = - identityBeneficiaryService.searchBeneficiariesUsingES( - searchQuery, userId, auth, is1097 - ); + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(response); - ObjectMapper mapper = new ObjectMapper(); - return mapper.writeValueAsString(response); + } catch (Exception e) { + logger.error("Error in universal search", e); + throw new Exception("Error searching beneficiaries: " + e.getMessage(), e); + } + } - } catch (Exception e) { - logger.error("Error in universal search", e); - throw new Exception("Error searching beneficiaries: " + e.getMessage(), e); - } -} + /** + * Advanced search using Elasticsearch with multiple criteria + */ + + @Override + public String findBeneficiaryES( + BeneficiaryModel i_beneficiary, + Integer userId, + String auth) throws Exception { + + try { + IdentitySearchDTO identitySearchDTO = identityBenEditMapper.getidentitysearchModel(i_beneficiary); + + if (i_beneficiary.getDOB() != null) { + identitySearchDTO.setDob(i_beneficiary.getDOB()); + } + + if (i_beneficiary.getHouseHoldID() != null) { + identitySearchDTO.setHouseHoldID(i_beneficiary.getHouseHoldID()); + } + + if (i_beneficiary.getIsD2D() != null) { + identitySearchDTO.setIsD2D(i_beneficiary.getIsD2D()); + } + + if (i_beneficiary.getBenPhoneMaps() != null + && !i_beneficiary.getBenPhoneMaps().isEmpty()) { + identitySearchDTO.setContactNumber( + i_beneficiary.getBenPhoneMaps().get(0).getPhoneNo()); + } + + if (i_beneficiary.getBeneficiaryID() != null + && !i_beneficiary.getBeneficiaryID().isEmpty()) { + identitySearchDTO.setBeneficiaryId( + new BigInteger(i_beneficiary.getBeneficiaryID())); + } + + i_beneficiary.setIs1097(Boolean.TRUE.equals(i_beneficiary.getIs1097())); + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd") + .create(); + + String requestJson = gson.toJson(identitySearchDTO); + + Map response = identityBeneficiaryService.searchBeneficiaryListES( + requestJson, + auth, + i_beneficiary.getIs1097()); + + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(response); + + } catch (Exception e) { + logger.error("Error in ES advance search", e); + throw new Exception("Error searching beneficiaries using ES", e); + } + } // Advance search @Override @@ -393,7 +451,7 @@ public String findBeneficiary(BeneficiaryModel i_beneficiary, String auth) throw + (beneficiaryList != null ? beneficiaryList.size() : "No Beneficiary Found")); ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(beneficiaryList); - + } // get response mapper @@ -403,7 +461,7 @@ public List getBeneficiaryListFromMapper(List { BeneficiaryModel beneficiary = benCompleteMapper.benDetailForOutboundDTOToIBeneficiary(beneficiaryModel); - if(null != beneficiaryModel && null != beneficiaryModel.getBeneficiaryDetails()) { + if (null != beneficiaryModel && null != beneficiaryModel.getBeneficiaryDetails()) { beneficiary.setCommunityName(beneficiaryModel.getBeneficiaryDetails().getCommunity()); beneficiary.setReligion(beneficiaryModel.getBeneficiaryDetails().getReligion()); beneficiary.setReligionName(beneficiaryModel.getBeneficiaryDetails().getReligion()); diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java index 5ebe3b24..41a132b0 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java @@ -54,6 +54,8 @@ List getBeneficiaryListByBenRegID(Long benRegId, String auth, List searchBeneficiaryList(String identitySearchDTO, String auth, Boolean is1097) throws IEMRException; + public Map searchBeneficiaryListES(String identitySearchDTO, String auth, Boolean is1097) throws IEMRException ; + Integer editIdentityEditDTOCommunityorEducation(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException; diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 0136c0f8..350f2527 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -34,7 +34,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.iemr.common.dto.identity.BeneficiariesDTO; @@ -70,12 +69,10 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; @Value("${genben-api}") - private String BEN_GEN ; - + private String BEN_GEN; @Value("${generateBeneficiaryIDs-api-url}") - private String BEN_GEN_API_URL ; - + private String BEN_GEN_API_URL; @Override // public List getBeneficiaryListByIDs() {// search by regID @@ -99,13 +96,10 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String } if (null != result) { JsonObject responseObj = (JsonObject) parser.parse(result); - // JsonArray data = (JsonArray) parser.parse( JsonObject data1 = (JsonObject) responseObj.get("response"); String s = data1.get("data").getAsString(); JsonArray responseArray = parser.parse(s).getAsJsonArray(); - // String data="s"; - // JsonArray responseArray = (JsonArray) parser.parse(data); for (JsonElement jsonElement : responseArray) { @@ -118,20 +112,21 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String return listBenDetailForOutboundDTO; } - /** - Call Identity API's Elasticsearch universal search - */ + /** + * Call Identity API's Elasticsearch universal search + */ @Override - public Map searchBeneficiariesUsingES(String query, Integer userId, String auth, Boolean is1097 ) throws IEMRException { + public Map searchBeneficiariesUsingES(String query, Integer userId, String auth, Boolean is1097) + throws IEMRException { - Map response = new HashMap<>(); + Map response = new HashMap<>(); try { HashMap headers = new HashMap<>(); if (auth != null && !auth.isEmpty()) { headers.put("Authorization", auth); } - + String baseUrl = ConfigProperties .getPropertyByName("identity-api-url-searchByES") .replace( @@ -139,58 +134,57 @@ public Map searchBeneficiariesUsingES(String query, Integer user (Boolean.TRUE.equals(is1097)) ? identity1097BaseURL : identityBaseURL ); - StringBuilder url = new StringBuilder(baseUrl) - .append("?query=").append(URLEncoder.encode(query, StandardCharsets.UTF_8)); + StringBuilder url = new StringBuilder(baseUrl) + .append("?query=").append(URLEncoder.encode(query, StandardCharsets.UTF_8)); - if (userId != null) { - url.append("&userId=").append(userId); - } + if (userId != null) { + url.append("&userId=").append(userId); + } - logger.info("Calling Identity ES search URL: {}", url); + logger.info("Calling Identity ES search URL: {}", url); - String result = httpUtils.get(url.toString(), headers); + String result = httpUtils.get(url.toString()); - if (result == null || result.isEmpty()) { - response.put("data", Collections.emptyList()); - response.put("statusCode", 200); - response.put("status", "Success"); - response.put("errorMessage", "Success"); - return response; - } + if (result == null || result.isEmpty()) { + response.put("data", Collections.emptyList()); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + return response; + } - ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false); - JsonNode rootNode = mapper.readTree(result); + JsonNode rootNode = mapper.readTree(result); - if (rootNode.has("statusCode") && rootNode.get("statusCode").asInt() != 200) { - String errMsg = rootNode.has("errorMessage") - ? rootNode.get("errorMessage").asText() - : "Identity ES search failed"; - throw new IEMRException(errMsg); - } + if (rootNode.has("statusCode") && rootNode.get("statusCode").asInt() != 200) { + String errMsg = rootNode.has("errorMessage") + ? rootNode.get("errorMessage").asText() + : "Identity ES search failed"; + throw new IEMRException(errMsg); + } - response.put("data", rootNode.path("data")); - response.put("statusCode", 200); - response.put("status", "Success"); - response.put("errorMessage", "Success"); + response.put("data", rootNode.path("data")); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); - return response; + return response; - } catch (IEMRException e) { - throw e; - } catch (Exception e) { - logger.error("Error calling Identity ES search API", e); - throw new IEMRException("Error calling Identity ES search API"); - } -} + } catch (IEMRException e) { + throw e; + } catch (Exception e) { + logger.error("Error calling Identity ES search API", e); + throw new IEMRException("Error calling Identity ES search API"); + } + } @Override public List getPartialBeneficiaryListByIDs(HashSet benIdList, String auth, Boolean is1097) throws IEMRException { - // TODO Auto-generated method stub List listBenDetailForOutboundDTO = new ArrayList<>(); JsonParser parser = new JsonParser(); @@ -210,13 +204,10 @@ public List getPartialBeneficiaryListByIDs(HashSet benI throw new IEMRException(identityResponse.getErrorMessage()); } JsonObject responseObj = (JsonObject) parser.parse(result); - // JsonArray data = (JsonArray) parser.parse( JsonObject data1 = (JsonObject) responseObj.get("response"); String s = data1.get("data").getAsString(); JsonArray responseArray = parser.parse(s).getAsJsonArray(); - // String data="s"; - // JsonArray responseArray = (JsonArray) parser.parse(data); for (JsonElement jsonElement : responseArray) { @@ -231,9 +222,9 @@ public List getPartialBeneficiaryListByIDs(HashSet benI // search beneficiaries by phone number public List getBeneficiaryListByPhone(String phoneNo, String auth, Boolean is1097) throws IEMRException { - logger.info("Phone no from getBeneficiaryListByPhone: " + phoneNo); - String cleanedPhoneNo = cleanPhoneNumber(phoneNo); - logger.info("Cleaned phone no: " + cleanedPhoneNo); + logger.info("Phone no from getBeneficiaryListByPhone: " + phoneNo); + String cleanedPhoneNo = cleanPhoneNumber(phoneNo); + logger.info("Cleaned phone no: " + cleanedPhoneNo); List listBenDetailForOutboundDTO = new ArrayList<>(); @@ -245,12 +236,13 @@ public List getBeneficiaryListByPhone(String phoneNo, String a if (auth != null) { header.put("Authorization", auth); } - - logger.info("Result="+(ConfigProperties.getPropertyByName("identity-api-url-getByPhoneNum") + + logger.info("Result=" + (ConfigProperties.getPropertyByName("identity-api-url-getByPhoneNum") .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + cleanedPhoneNo); result = httpUtils.post((ConfigProperties.getPropertyByName("identity-api-url-getByPhoneNum") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + cleanedPhoneNo, "", header); + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + cleanedPhoneNo, "", + header); OutputResponse identityResponse = InputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { @@ -271,22 +263,22 @@ public List getBeneficiaryListByPhone(String phoneNo, String a } private String cleanPhoneNumber(String phoneNumber) { - if (phoneNumber == null || phoneNumber.trim().isEmpty()) { - return phoneNumber; - } - - String cleaned = phoneNumber.trim(); - - // Remove +91 prefix - if (cleaned.startsWith("+91")) { - cleaned = cleaned.substring(3); - } - // Remove 91 prefix if it's a 12-digit number (91 + 10 digit mobile) - else if (cleaned.startsWith("91") && cleaned.length() == 12) { - cleaned = cleaned.substring(2); - } - - return cleaned.trim(); + if (phoneNumber == null || phoneNumber.trim().isEmpty()) { + return phoneNumber; + } + + String cleaned = phoneNumber.trim(); + + // Remove +91 prefix + if (cleaned.startsWith("+91")) { + cleaned = cleaned.substring(3); + } + // Remove 91 prefix if it's a 12-digit number (91 + 10 digit mobile) + else if (cleaned.startsWith("91") && cleaned.length() == 12) { + cleaned = cleaned.substring(2); + } + + return cleaned.trim(); } @Override @@ -533,7 +525,6 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t return result; } - public Integer editIdentityEditDTO(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException { JsonParser parser = new JsonParser(); @@ -578,13 +569,10 @@ public List searchBeneficiaryList(String identitySearchDTO, St IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), identitySearchDTO, header); JsonObject responseObj = (JsonObject) parser.parse(result); - // JsonArray data = (JsonArray) parser.parse( JsonObject data1 = (JsonObject) responseObj.get("response"); String s = data1.get("data").getAsString(); JsonArray responseArray = parser.parse(s).getAsJsonArray(); - // String data="s"; - // JsonArray responseArray = (JsonArray) parser.parse(data); for (JsonElement jsonElement : responseArray) { @@ -596,6 +584,68 @@ public List searchBeneficiaryList(String identitySearchDTO, St return listBenDetailForOutboundDTO; } + @Override + public Map searchBeneficiaryListES(String identitySearchDTO, String auth, Boolean is1097) + throws IEMRException { + + Map response = new HashMap<>(); + + try { + HashMap headers = new HashMap<>(); + if (auth != null && !auth.isEmpty()) { + headers.put("Authorization", auth); + } + + String url = ConfigProperties + .getPropertyByName("identity-api-url-advancesearch-es") + .replace( + IDENTITY_BASE_URL, + Boolean.TRUE.equals(is1097) + ? identity1097BaseURL + : identityBaseURL); + + logger.info("Calling Identity ES Advance Search API"); + + String result = httpUtils.post(url, identitySearchDTO, headers); + + if (result == null || result.isEmpty()) { + response.put("data", Collections.emptyList()); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + return response; + } + + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + JsonNode rootNode = mapper.readTree(result); + + if (rootNode.has("statusCode") + && rootNode.get("statusCode").asInt() != 200) { + + String errMsg = rootNode.has("errorMessage") + ? rootNode.get("errorMessage").asText() + : "Identity ES advance search failed"; + + throw new IEMRException(errMsg); + } + + response.put("data", rootNode.path("data")); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + + return response; + + } catch (IEMRException e) { + throw e; + } catch (Exception e) { + logger.error("Error calling Identity ES advance search API", e); + throw new IEMRException("Error calling Identity ES advance search API", e); + } + } + @Override public Integer editIdentityEditDTOCommunityorEducation(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException { @@ -635,11 +685,11 @@ public List generateBeneficiaryIDs(String request, String a if (auth != null) { header.put("Authorization", auth); } - + logger.info("Request to generate ben IDs: " + request); logger.info("Generating ben IDs API URL: " + BEN_GEN + BEN_GEN_API_URL); result = httpUtils.post(BEN_GEN + BEN_GEN_API_URL, request, header); -logger.info("Response from generate ben IDs: " + result); + logger.info("Response from generate ben IDs: " + result); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index d8414968..5d37a990 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -2,6 +2,7 @@ import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -161,4 +162,58 @@ public String getUserIdFromToken(String token) { public long getRefreshTokenExpiration() { return REFRESH_EXPIRATION_TIME; } + + /** + * Extract user ID from JWT token in the request (checks header and cookie) + * @param request the HTTP request + * @return the user ID, or null if not found + */ +public Integer getUserIdFromRequest(HttpServletRequest request) { + try { + String jwtToken = request.getHeader("Jwttoken"); + String cookieToken = CookieUtil.getJwtTokenFromCookie(request); + + // Prefer header token, fallback to cookie + String token = (jwtToken != null && !jwtToken.isEmpty()) ? jwtToken : cookieToken; + + if (token == null || token.isEmpty()) { + return null; + } + + Claims claims = validateToken(token); + if (claims == null) { + return null; + } + + String userId = claims.get("userId", String.class); + return userId != null ? Integer.parseInt(userId) : null; + + } catch (Exception e) { + return null; + } +} + +/** + * Extract username from JWT token in the request (checks header and cookie) + * @param request the HTTP request + * @return the username, or null if not found + */ +public String getUsernameFromRequest(HttpServletRequest request) { + try { + String jwtToken = request.getHeader("Jwttoken"); + String cookieToken = CookieUtil.getJwtTokenFromCookie(request); + + String token = (jwtToken != null && !jwtToken.isEmpty()) ? jwtToken : cookieToken; + + if (token == null || token.isEmpty()) { + return null; + } + + Claims claims = validateToken(token); + return claims != null ? claims.getSubject() : null; + + } catch (Exception e) { + return null; + } +} } diff --git a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java index c8299fe7..4e4fa483 100644 --- a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java +++ b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java @@ -39,6 +39,8 @@ public static HttpEntity createRequestEntity(Object body, String authori headers.add(HttpHeaders.AUTHORIZATION, authorization); if (null != requestHeader.getHeader(Constants.JWT_TOKEN)) { headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); + headers.add(HttpHeaders.COOKIE, "Jwttoken=" + requestHeader.getHeader(Constants.JWT_TOKEN)); + } if (null != jwtTokenFromCookie) { headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie); @@ -77,9 +79,10 @@ public static void getJwttokenFromHeaders(HttpHeaders headers) { if (null != jwtTokenFromCookie) { headers.add(HttpHeaders.COOKIE, Constants.JWT_TOKEN + "=" + jwtTokenFromCookie); } else if (null != requestHeader.getHeader(Constants.JWT_TOKEN)) { - headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); - } + headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); + headers.add(HttpHeaders.COOKIE, Constants.JWT_TOKEN + "=" + requestHeader.getHeader(Constants.JWT_TOKEN)); + } } } diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 0c609839..b4aaad60 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -36,10 +36,14 @@ import com.iemr.common.utils.sessionobject.SessionObject; import com.iemr.common.utils.validator.Validator; +import com.iemr.common.utils.JwtUtil; +import io.jsonwebtoken.Claims; +import com.iemr.common.utils.CookieUtil; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + @Configuration @Component public class HTTPRequestInterceptor implements HandlerInterceptor { @@ -50,6 +54,9 @@ public class HTTPRequestInterceptor implements HandlerInterceptor { @Value("${cors.allowed-origins}") private String allowedOrigins; + @Autowired + private JwtUtil jwtUtil; + @Autowired public void setValidator(Validator validator) { this.validator = validator; @@ -67,100 +74,101 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons boolean status = true; logger.info("In info preHandle we are Intercepting the Request"); logger.debug("In preHandle we are Intercepting the Request"); - // String authorization = request.getHeader("Authorization"); + // String authorization = request.getHeader("Authorization"); String authorization = null; String preAuth = request.getHeader("Authorization"); - if(null != preAuth && preAuth.contains("Bearer ")) - authorization=preAuth.replace("Bearer ", ""); + if (null != preAuth && preAuth.contains("Bearer ")) + authorization = preAuth.replace("Bearer ", ""); else authorization = preAuth; - + if (authorization == null || authorization.isEmpty()) { - logger.info("Authorization header is null or empty. Skipping HTTPRequestInterceptor."); - return true; // Allow the request to proceed without validation - } - logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization + logger.info("Authorization header is null or empty. Skipping HTTPRequestInterceptor."); + return true; // Allow the request to proceed without validation + } + + logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization + " || method :: " + request.getMethod()); if (!request.getMethod().equalsIgnoreCase("OPTIONS")) { try { String[] requestURIParts = request.getRequestURI().split("/"); String requestAPI = requestURIParts[requestURIParts.length - 1]; switch (requestAPI) { - case "userAuthenticate": - case "superUserAuthenticate": - case "userAuthenticateNew": - case "userAuthenticateV1": - case "forgetPassword": - case "setForgetPassword": - case "changePassword": - case "saveUserSecurityQuesAns": - case "doAgentLogout": - case "userLogout": - case "swagger-ui.html": - case "index.html": - case "index.css": - case "swagger-initializer.js": - case "swagger-config": - case "swagger-ui-bundle.js": - case "swagger-ui.css": - case "ui": - case "swagger-ui-standalone-preset.js": - case "favicon-32x32.png": - case "favicon-16x16.png": - case "swagger-resources": - case "api-docs": - case "updateBenCallIdsInPhoneBlock": - case "userAuthenticateByEncryption": - case "sendOTP": - case "validateOTP": - case "resendOTP": - case "validateSecurityQuestionAndAnswer": - case "logOutUserFromConcurrentSession": - case "refreshToken": - break; - case "error": - status = false; - break; - default: - String remoteAddress = request.getHeader("X-FORWARDED-FOR"); - if (remoteAddress == null || remoteAddress.trim().length() == 0) { - remoteAddress = request.getRemoteAddr(); - } - validator.checkKeyExists(authorization, remoteAddress); - break; + case "userAuthenticate": + case "superUserAuthenticate": + case "userAuthenticateNew": + case "userAuthenticateV1": + case "forgetPassword": + case "setForgetPassword": + case "changePassword": + case "saveUserSecurityQuesAns": + case "doAgentLogout": + case "userLogout": + case "swagger-ui.html": + case "index.html": + case "index.css": + case "swagger-initializer.js": + case "swagger-config": + case "swagger-ui-bundle.js": + case "swagger-ui.css": + case "ui": + case "swagger-ui-standalone-preset.js": + case "favicon-32x32.png": + case "favicon-16x16.png": + case "swagger-resources": + case "api-docs": + case "updateBenCallIdsInPhoneBlock": + case "userAuthenticateByEncryption": + case "sendOTP": + case "validateOTP": + case "resendOTP": + case "validateSecurityQuestionAndAnswer": + case "logOutUserFromConcurrentSession": + case "refreshToken": + break; + case "error": + status = false; + break; + default: + String remoteAddress = request.getHeader("X-FORWARDED-FOR"); + if (remoteAddress == null || remoteAddress.trim().length() == 0) { + remoteAddress = request.getRemoteAddr(); + } + validator.checkKeyExists(authorization, remoteAddress); + break; } } catch (Exception e) { logger.error("Authorization failed: {}", e.getMessage(), e); - String errorMessage = e.getMessage(); - if (errorMessage == null || errorMessage.trim().isEmpty()) { - errorMessage = "Unauthorized access or session expired."; - } - - String jsonErrorResponse = "{" - + "\"status\": \"Unauthorized\"," - + "\"statusCode\": 401," - + "\"errorMessage\": \"" + errorMessage.replace("\"", "\\\"") + "\"" - + "}"; - - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 - response.setContentType(MediaType.APPLICATION_JSON); - - String origin = request.getHeader("Origin"); - if (origin != null && isOriginAllowed(origin)) { - response.setHeader("Access-Control-Allow-Origin", origin); - response.setHeader("Access-Control-Allow-Credentials", "true"); - } else if (origin != null) { - logger.warn("CORS headers NOT added for error response | Unauthorized origin: {}", origin); - } - - // Better to use getBytes().length for accurate byte size - byte[] responseBytes = jsonErrorResponse.getBytes(StandardCharsets.UTF_8); - response.setContentLength(responseBytes.length); - - ServletOutputStream out = response.getOutputStream(); - out.write(responseBytes); - out.flush(); + String errorMessage = e.getMessage(); + if (errorMessage == null || errorMessage.trim().isEmpty()) { + errorMessage = "Unauthorized access or session expired."; + } + + String jsonErrorResponse = "{" + + "\"status\": \"Unauthorized\"," + + "\"statusCode\": 401," + + "\"errorMessage\": \"" + errorMessage.replace("\"", "\\\"") + "\"" + + "}"; + + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 + response.setContentType(MediaType.APPLICATION_JSON); + + String origin = request.getHeader("Origin"); + if (origin != null && isOriginAllowed(origin)) { + response.setHeader("Access-Control-Allow-Origin", origin); + response.setHeader("Access-Control-Allow-Credentials", "true"); + } else if (origin != null) { + logger.warn("CORS headers NOT added for error response | Unauthorized origin: {}", origin); + } + + // Better to use getBytes().length for accurate byte size + byte[] responseBytes = jsonErrorResponse.getBytes(StandardCharsets.UTF_8); + response.setContentLength(responseBytes.length); + + ServletOutputStream out = response.getOutputStream(); + out.write(responseBytes); + out.flush(); status = false; } } @@ -172,15 +180,14 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response, throws Exception { try { logger.debug("In postHandle we are Intercepting the Request"); - // String authorization = request.getHeader("Authorization"); String authorization = null; String postAuth = request.getHeader("Authorization"); - if(null != postAuth && postAuth.contains("Bearer ")) - authorization=postAuth.replace("Bearer ", ""); + if (null != postAuth && postAuth.contains("Bearer ")) + authorization = postAuth.replace("Bearer ", ""); else authorization = postAuth; logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); - + if (authorization != null && !authorization.equals("")) { sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); } @@ -212,8 +219,10 @@ private boolean isOriginAllowed(String origin) { .anyMatch(pattern -> { String regex = pattern .replace(".", "\\.") - .replace("*", ".*"); + .replace("*", ".*"); return origin.matches(regex); }); } + + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8ab4669b..5263ca41 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -110,6 +110,7 @@ iemr.extend.expiry.time.changePassword=true iemr.session.expiry.time.changePassword=600 identity-api-url-advancesearch =IDENTITY_BASE_URL/id/advanceSearch +identity-api-url-advancesearch-es =IDENTITY_BASE_URL/beneficiary/advancedSearchES identity-api-url-getByBenRegIdList =IDENTITY_BASE_URL/id/getByBenRegIdList identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenRegIdList identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= From 38a4147f1a07c607888cbf9953b1703cbd0c90a4 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Thu, 8 Jan 2026 11:02:34 +0530 Subject: [PATCH 09/47] Remove empty line in application.properties --- src/main/resources/application.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a1135a2a..57652e66 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -372,5 +372,3 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent - -cors.allowed-origin = From 17620d329ba6d2085e2c49aeeecb6e42bb02d428 Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Fri, 9 Jan 2026 10:08:42 +0530 Subject: [PATCH 10/47] fix:signature check for mmu --- .../common/service/users/EmployeeSignatureServiceImpl.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java b/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java index 115970ed..eff5c8e4 100644 --- a/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java +++ b/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java @@ -33,8 +33,6 @@ public class EmployeeSignatureServiceImpl implements EmployeeSignatureService { @Autowired EmployeeSignatureRepo employeeSignatureRepo; - - @Override public EmployeeSignature fetchSignature(Long userSignID) { // TODO Auto-generated method stub @@ -44,12 +42,12 @@ public EmployeeSignature fetchSignature(Long userSignID) { @Override public EmployeeSignature fetchActiveSignature(Long userSignID) { // New method - fetches only non-deleted records - return employeeSignatureRepo.findOneByUserIDAndDeleted(userSignID, false); + return employeeSignatureRepo.findOneByUserID(userSignID); } public Boolean existSignature(Long userID) { // TODO Auto-generated method stub - return employeeSignatureRepo.countByUserIDAndSignatureNotNull(userID)>0; + return employeeSignatureRepo.countByUserIDAndSignatureNotNull(userID) > 0; } } From 9c1493a3b45de27c946ff29b1a31ac9480f3ca0d Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:24:25 +0530 Subject: [PATCH 11/47] Update application.properties --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 57652e66..f34f770c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -372,3 +372,4 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent +cors.allowed-origin = From 984d533671f5e84e58b85c7d5efe0248bebc12e4 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:43:02 +0530 Subject: [PATCH 12/47] Update application.properties --- src/main/resources/application.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f34f770c..4409afd4 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -372,4 +372,5 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent -cors.allowed-origin = +cors.allowed-origin=https://amritdemo.piramalswasthya.org + From c3bc3cbda47b0465df3008ad3407bc73b6dd7590 Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 13 Jan 2026 17:16:25 +0530 Subject: [PATCH 13/47] fix: retrive any user without deleted --- .../controller/users/IEMRAdminController.java | 20 ++++++++++++++++++- .../users/IEMRUserRepositoryCustom.java | 3 +++ .../service/users/IEMRAdminUserService.java | 2 ++ .../users/IEMRAdminUserServiceImpl.java | 6 ++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 8bc0e74d..554500f3 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -1224,7 +1224,25 @@ public ResponseEntity getUserDetails(@PathVariable("userName") String userNam return new ResponseEntity<>(Map.of("error", "UserName Not Found"), HttpStatus.NOT_FOUND); } User user = users.get(0); - return new ResponseEntity<>(Map.of("userName", user.getUserName(), "userId", user.getUserID()), HttpStatus.OK); + return new ResponseEntity<>(Map.of("userName", user.getUserName(), "userId", user.getUserID()), + HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(Map.of("error", "Internal server error"), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + @Operation(summary = "Get UserId based on userName") + @GetMapping(value = "/checkUserName/{userName}", produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public ResponseEntity checkUserDetails(@PathVariable("userName") String userName) { + try { + List users = iemrAdminUserServiceImpl.findUserIdByUserName(userName); + if (users.isEmpty()) { + return new ResponseEntity<>(Map.of("error", "UserName Not Found"), HttpStatus.NOT_FOUND); + } + User user = users.get(0); + return new ResponseEntity<>(Map.of("userName", user.getUserName(), "userId", user.getUserID()), + HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(Map.of("error", "Internal server error"), HttpStatus.INTERNAL_SERVER_ERROR); } diff --git a/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java b/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java index 3ee48ab3..cc1abccc 100644 --- a/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java +++ b/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java @@ -78,4 +78,7 @@ UserSecurityQMapping verifySecurityQuestionAnswers(@Param("UserID") Long UserID, User findByUserID(Long userID); + @Query("SELECT u FROM User u WHERE LOWER(u.userName) = LOWER(:userName)") + List findUserName(@Param("userName") String username); + } diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java index d7dc6e2e..26b7bb15 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java @@ -123,6 +123,8 @@ public List getUserServiceRoleMappingForProvider(Integ List getUserIdbyUserName(String userName) throws IEMRException; + List findUserIdByUserName(String userName) throws IEMRException; + } diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java index 44bd2247..71d72c97 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java @@ -1224,4 +1224,10 @@ public List getUserIdbyUserName(String userName) { return iEMRUserRepositoryCustom.findByUserName(userName); } + + @Override + public List findUserIdByUserName(String userName) { + + return iEMRUserRepositoryCustom.findUserName(userName); + } } From 519073753e456648ccf9be428b98fb0037e8c37c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 14 Jan 2026 16:35:19 +0530 Subject: [PATCH 14/47] implement state wise hide un hide form fields --- .../dynamicForm/DynamicFormController.java | 4 +- .../common/data/dynamic_from/FormField.java | 6 + .../common/data/users/UserServiceRole.java | 368 ++++++++++++++++++ .../dto/dynamicForm/FieldResponseDTO.java | 2 + .../repository/users/UserServiceRoleRepo.java | 16 + .../dynamicForm/FormMasterService.java | 2 +- .../dynamicForm/FormMasterServiceImpl.java | 188 +++++---- 7 files changed, 503 insertions(+), 83 deletions(-) create mode 100644 src/main/java/com/iemr/common/data/users/UserServiceRole.java create mode 100644 src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 30a1bc3f..cd83246f 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -84,9 +84,9 @@ public ResponseEntity> deleteField(@PathVariable Long fieldId) { } @GetMapping(value = "form/{formId}/fields") - public ResponseEntity> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang) { + public ResponseEntity> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang,@RequestHeader(value = "JwtToken") String token) { try { - Object result = formMasterService.getStructuredFormByFormId(formId,lang); + Object result = formMasterService.getStructuredFormByFormId(formId,lang,token); return ResponseEntity.status(HttpStatus.OK) .body(ApiResponse.success("Form structure fetched successfully", HttpStatus.OK.value(), result)); } catch (Exception e) { diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java index 39785ae9..e902acf1 100644 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java @@ -53,6 +53,12 @@ public class FormField { @Column(name = "sequence") private Integer sequence; + @Column(name = "is_editable") + private Boolean isEditable; + + @Column(name = "state_code") + private Integer stateCode; + @Column(name = "created_at") private LocalDateTime createdAt = LocalDateTime.now(); diff --git a/src/main/java/com/iemr/common/data/users/UserServiceRole.java b/src/main/java/com/iemr/common/data/users/UserServiceRole.java new file mode 100644 index 00000000..63af40dd --- /dev/null +++ b/src/main/java/com/iemr/common/data/users/UserServiceRole.java @@ -0,0 +1,368 @@ +package com.iemr.common.data.users; + +import jakarta.persistence.*; +import java.util.Objects; + +@Entity +@Table(name = "v_userservicerolemapping", schema = "db_iemr") +public class UserServiceRole { + private Integer userId; + private int usrMappingId; + private String name; + private String userName; + private Short serviceId; + private String serviceName; + private Boolean isNational; + private Integer stateId; + private String stateName; + private Integer workingDistrictId; + private String workingDistrictName; + private Integer workingLocationId; + private Short serviceProviderId; + private String locationName; + private String workingLocationAddress; + private Integer roleId; + private String roleName; + private Integer providerServiceMapId; + private String agentId; + private Short psmStatusId; + private String psmStatus; + private Boolean userServciceRoleDeleted; + private Boolean userDeleted; + private Boolean serviceProviderDeleted; + private Boolean roleDeleted; + private Boolean providerServiceMappingDeleted; + private Boolean isInbound; + private Boolean isOutbound; + private Integer blockid; + private String blockname; + private String villageid; + private String villagename; + + @Basic + @Column(name = "UserID") + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + @Basic + @Column(name = "USRMappingID") + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + public int getUsrMappingId() { + return usrMappingId; + } + + public void setUsrMappingId(int usrMappingId) { + this.usrMappingId = usrMappingId; + } + + @Basic + @Column(name = "Name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Basic + @Column(name = "UserName") + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + @Basic + @Column(name = "ServiceID") + public Short getServiceId() { + return serviceId; + } + + public void setServiceId(Short serviceId) { + this.serviceId = serviceId; + } + + @Basic + @Column(name = "ServiceName") + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + @Basic + @Column(name = "IsNational") + public Boolean getNational() { + return isNational; + } + + public void setNational(Boolean national) { + isNational = national; + } + + @Basic + @Column(name = "StateID") + public Integer getStateId() { + return stateId; + } + + public void setStateId(Integer stateId) { + this.stateId = stateId; + } + + @Basic + @Column(name = "StateName") + public String getStateName() { + return stateName; + } + + public void setStateName(String stateName) { + this.stateName = stateName; + } + + @Basic + @Column(name = "WorkingDistrictID") + public Integer getWorkingDistrictId() { + return workingDistrictId; + } + + public void setWorkingDistrictId(Integer workingDistrictId) { + this.workingDistrictId = workingDistrictId; + } + + @Basic + @Column(name = "WorkingDistrictName") + public String getWorkingDistrictName() { + return workingDistrictName; + } + + public void setWorkingDistrictName(String workingDistrictName) { + this.workingDistrictName = workingDistrictName; + } + + @Basic + @Column(name = "WorkingLocationID") + public Integer getWorkingLocationId() { + return workingLocationId; + } + + public void setWorkingLocationId(Integer workingLocationId) { + this.workingLocationId = workingLocationId; + } + + @Basic + @Column(name = "ServiceProviderID") + public Short getServiceProviderId() { + return serviceProviderId; + } + + public void setServiceProviderId(Short serviceProviderId) { + this.serviceProviderId = serviceProviderId; + } + + @Basic + @Column(name = "LocationName") + public String getLocationName() { + return locationName; + } + + public void setLocationName(String locationName) { + this.locationName = locationName; + } + + @Basic + @Column(name = "WorkingLocationAddress") + public String getWorkingLocationAddress() { + return workingLocationAddress; + } + + public void setWorkingLocationAddress(String workingLocationAddress) { + this.workingLocationAddress = workingLocationAddress; + } + + @Basic + @Column(name = "RoleID") + public Integer getRoleId() { + return roleId; + } + + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + + @Basic + @Column(name = "RoleName") + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + @Basic + @Column(name = "ProviderServiceMapID") + public Integer getProviderServiceMapId() { + return providerServiceMapId; + } + + public void setProviderServiceMapId(Integer providerServiceMapId) { + this.providerServiceMapId = providerServiceMapId; + } + + @Basic + @Column(name = "AgentID") + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + @Basic + @Column(name = "PSMStatusID") + public Short getPsmStatusId() { + return psmStatusId; + } + + public void setPsmStatusId(Short psmStatusId) { + this.psmStatusId = psmStatusId; + } + + @Basic + @Column(name = "PSMStatus") + public String getPsmStatus() { + return psmStatus; + } + + public void setPsmStatus(String psmStatus) { + this.psmStatus = psmStatus; + } + + @Basic + @Column(name = "UserServciceRoleDeleted") + public Boolean getUserServciceRoleDeleted() { + return userServciceRoleDeleted; + } + + public void setUserServciceRoleDeleted(Boolean userServciceRoleDeleted) { + this.userServciceRoleDeleted = userServciceRoleDeleted; + } + + @Basic + @Column(name = "UserDeleted") + public Boolean getUserDeleted() { + return userDeleted; + } + + public void setUserDeleted(Boolean userDeleted) { + this.userDeleted = userDeleted; + } + + @Basic + @Column(name = "ServiceProviderDeleted") + public Boolean getServiceProviderDeleted() { + return serviceProviderDeleted; + } + + public void setServiceProviderDeleted(Boolean serviceProviderDeleted) { + this.serviceProviderDeleted = serviceProviderDeleted; + } + + @Basic + @Column(name = "RoleDeleted") + public Boolean getRoleDeleted() { + return roleDeleted; + } + + public void setRoleDeleted(Boolean roleDeleted) { + this.roleDeleted = roleDeleted; + } + + @Basic + @Column(name = "ProviderServiceMappingDeleted") + public Boolean getProviderServiceMappingDeleted() { + return providerServiceMappingDeleted; + } + + public void setProviderServiceMappingDeleted(Boolean providerServiceMappingDeleted) { + this.providerServiceMappingDeleted = providerServiceMappingDeleted; + } + + @Basic + @Column(name = "isInbound") + public Boolean getInbound() { + return isInbound; + } + + public void setInbound(Boolean inbound) { + isInbound = inbound; + } + + @Basic + @Column(name = "isOutbound") + public Boolean getOutbound() { + return isOutbound; + } + + public void setOutbound(Boolean outbound) { + isOutbound = outbound; + } + + @Basic + @Column(name = "blockid") + public Integer getBlockid() { + return blockid; + } + + public void setBlockid(Integer blockid) { + this.blockid = blockid; + } + + @Basic + @Column(name = "blockname") + public String getBlockname() { + return blockname; + } + + public void setBlockname(String blockname) { + this.blockname = blockname; + } + + @Basic + @Column(name = "villageid") + public String getVillageid() { + return villageid; + } + + public void setVillageid(String villageid) { + this.villageid = villageid; + } + + @Basic + @Column(name = "villagename") + public String getVillagename() { + return villagename; + } + + public void setVillagename(String villagename) { + this.villagename = villagename; + } + + @Override + public int hashCode() { + return Objects.hash(userId, usrMappingId, name, userName, serviceId, serviceName, isNational, stateId, stateName, workingDistrictId, workingDistrictName, workingLocationId, serviceProviderId, locationName, workingLocationAddress, roleId, roleName, providerServiceMapId, agentId, psmStatusId, psmStatus, userServciceRoleDeleted, userDeleted, serviceProviderDeleted, roleDeleted, providerServiceMappingDeleted, isInbound, isOutbound, blockid, blockname, villageid, villagename); + } +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java index 3415d91a..e41f8e80 100644 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java @@ -18,6 +18,8 @@ public class FieldResponseDTO { private String defaultValue; private String placeholder; private Integer sequence; + private Boolean isEditable; + private Integer stateCode; private List options; private Map validation; private Map conditional; diff --git a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java new file mode 100644 index 00000000..ee7db934 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java @@ -0,0 +1,16 @@ +package com.iemr.common.repository.users; + +import com.iemr.common.data.users.UserServiceRole; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface UserServiceRoleRepo extends JpaRepository { + UserServiceRole findByUserName(String userName); + UserServiceRole findByUserId(Integer userId); + +} diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java index 6d22e59a..2f7360b8 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java @@ -16,7 +16,7 @@ public interface FormMasterService { List createField(List dto); FormField updateField(FieldDTO dto); - FormResponseDTO getStructuredFormByFormId(String formId,String lang); + FormResponseDTO getStructuredFormByFormId(String formId,String lang,String token); void deleteField(Long fieldId); } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 98d93dbe..27dd5d08 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -7,23 +7,29 @@ import com.iemr.common.data.dynamic_from.FormField; import com.iemr.common.data.dynamic_from.FormModule; import com.iemr.common.data.translation.Translation; +import com.iemr.common.data.users.UserServiceRole; +import com.iemr.common.data.users.UserServiceRoleMapping; import com.iemr.common.dto.dynamicForm.*; import com.iemr.common.repository.dynamic_form.FieldRepository; import com.iemr.common.repository.dynamic_form.FormRepository; import com.iemr.common.repository.dynamic_form.ModuleRepository; import com.iemr.common.repository.translation.TranslationRepo; +import com.iemr.common.repository.users.UserRoleMappingRepository; +import com.iemr.common.repository.users.UserServiceRoleRepo; +import com.iemr.common.utils.JwtUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.type.TypeReference; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import javax.persistence.criteria.CriteriaBuilder; +import java.util.*; import java.util.stream.Collectors; @Service public class FormMasterServiceImpl implements FormMasterService { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired private ModuleRepository moduleRepo; @@ -33,6 +39,12 @@ public class FormMasterServiceImpl implements FormMasterService { @Autowired private TranslationRepo translationRepo; + @Autowired + private UserServiceRoleRepo userServiceRoleRepo; + + @Autowired + private JwtUtil jwtUtil; + @Override public FormModule createModule(ModuleDTO dto) { FormModule module = new FormModule(); @@ -103,99 +115,115 @@ public FormField updateField(FieldDTO dto) { } @Override - public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { - FormDefinition form = formRepo.findByFormId(formId) - .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); + public FormResponseDTO getStructuredFormByFormId(String formId,String lang,String token) { + int stateId =0 ; + + try { + UserServiceRole userServiceRole= userServiceRoleRepo.findByUserName(jwtUtil.getUsernameFromToken(token)); + if(userServiceRole!=null){ + stateId = userServiceRole.getStateId(); + } + FormDefinition form = formRepo.findByFormId(formId) + .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); - List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); - ObjectMapper objectMapper = new ObjectMapper(); + List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); + ObjectMapper objectMapper = new ObjectMapper(); - List fieldDtos = fields.stream() - .map(field -> { - String labelKey = field.getFieldId(); // field label already contains label_key + Integer finalStateId = stateId; + List fieldDtos = fields.stream().filter(formField -> Objects.equals(formField.getStateCode(), finalStateId) || formField.getStateCode()==0) + .map(field -> { + String labelKey = field.getFieldId(); // field label already contains label_key - Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) - .orElse(null); + Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) + .orElse(null); - String translatedLabel = field.getLabel(); // fallback + String translatedLabel = field.getLabel(); // fallback - if (t != null) { - if ("hi".equalsIgnoreCase(lang)) { - translatedLabel = t.getHindiTranslation(); - } else if("as".equalsIgnoreCase(lang)){ - translatedLabel = t.getAssameseTranslation(); - }else if("en".equalsIgnoreCase(lang)){ - translatedLabel = t.getEnglish(); + if (t != null) { + if ("hi".equalsIgnoreCase(lang)) { + translatedLabel = t.getHindiTranslation(); + } else if("as".equalsIgnoreCase(lang)){ + translatedLabel = t.getAssameseTranslation(); + }else if("en".equalsIgnoreCase(lang)){ + translatedLabel = t.getEnglish(); - } - } - - FieldResponseDTO dto = new FieldResponseDTO(); - dto.setId(field.getId()); - dto.setVisible(field.getIsVisible()); - dto.setFormId(field.getForm().getFormId()); - dto.setSectionTitle(field.getSectionTitle()); - dto.setFieldId(field.getFieldId()); - dto.setLabel(translatedLabel); - dto.setType(field.getType()); - dto.setIsRequired(field.getIsRequired()); - dto.setDefaultValue(field.getDefaultValue()); - dto.setPlaceholder(field.getPlaceholder()); - dto.setSequence(field.getSequence()); - - try { - // Handle options - if (field.getOptions() != null && !field.getOptions().isBlank()) { - JsonNode node = objectMapper.readTree(field.getOptions()); - List options = null; - if (node.isArray()) { - options = objectMapper.convertValue(node, new TypeReference<>() {}); - } else if (node.has("options")) { - options = objectMapper.convertValue(node.get("options"), new TypeReference<>() {}); } - dto.setOptions(options == null || options.isEmpty() ? null : options); - } else { - dto.setOptions(null); } - // Handle validation - if (field.getValidation() != null && !field.getValidation().isBlank()) { - Map validation = objectMapper.readValue(field.getValidation(), new TypeReference<>() {}); - dto.setValidation(validation.isEmpty() ? null : validation); - } else { - dto.setValidation(null); - } + FieldResponseDTO dto = new FieldResponseDTO(); + dto.setId(field.getId()); + dto.setIsEditable(field.getIsEditable()); + dto.setStateCode(field.getStateCode()); + dto.setVisible(field.getIsVisible()); + dto.setFormId(field.getForm().getFormId()); + dto.setSectionTitle(field.getSectionTitle()); + dto.setFieldId(field.getFieldId()); + dto.setLabel(translatedLabel); + dto.setType(field.getType()); + dto.setIsRequired(field.getIsRequired()); + dto.setDefaultValue(field.getDefaultValue()); + dto.setPlaceholder(field.getPlaceholder()); + dto.setSequence(field.getSequence()); + + try { + // Handle options + if (field.getOptions() != null && !field.getOptions().isBlank()) { + JsonNode node = objectMapper.readTree(field.getOptions()); + List options = null; + if (node.isArray()) { + options = objectMapper.convertValue(node, new TypeReference<>() {}); + } else if (node.has("options")) { + options = objectMapper.convertValue(node.get("options"), new TypeReference<>() {}); + } + dto.setOptions(options == null || options.isEmpty() ? null : options); + } else { + dto.setOptions(null); + } + + // Handle validation + if (field.getValidation() != null && !field.getValidation().isBlank()) { + Map validation = objectMapper.readValue(field.getValidation(), new TypeReference<>() {}); + dto.setValidation(validation.isEmpty() ? null : validation); + } else { + dto.setValidation(null); + } - // Handle conditional - if (field.getConditional() != null && !field.getConditional().isBlank()) { - Map conditional = objectMapper.readValue(field.getConditional(), new TypeReference<>() {}); - dto.setConditional(conditional.isEmpty() ? null : conditional); - } else { - dto.setConditional(null); + // Handle conditional + if (field.getConditional() != null && !field.getConditional().isBlank()) { + Map conditional = objectMapper.readValue(field.getConditional(), new TypeReference<>() {}); + dto.setConditional(conditional.isEmpty() ? null : conditional); + } else { + dto.setConditional(null); + } + } catch (Exception e) { + + System.err.println("JSON Parsing Error in field: " + field.getFieldId()); + throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); } - } catch (Exception e) { - System.err.println("JSON Parsing Error in field: " + field.getFieldId()); - throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); - } + return dto; + }) + .sorted(Comparator.comparing(FieldResponseDTO::getId)) + .collect(Collectors.toList()); + - return dto; - }) - .sorted(Comparator.comparing(FieldResponseDTO::getId)) - .collect(Collectors.toList()); + GroupedFieldResponseDTO singleSection = new GroupedFieldResponseDTO(); + singleSection.setSectionTitle(singleSection.getSectionTitle()); // your custom section title + singleSection.setFields(fieldDtos); + FormResponseDTO response = new FormResponseDTO(); + response.setVersion(form.getVersion()); + response.setFormId(form.getFormId()); + response.setFormName(form.getFormName()); + response.setSections(List.of(singleSection)); + return response; - GroupedFieldResponseDTO singleSection = new GroupedFieldResponseDTO(); - singleSection.setSectionTitle(singleSection.getSectionTitle()); // your custom section title - singleSection.setFields(fieldDtos); + }catch (Exception e){ + logger.error("Exception:"+e.getMessage()); + } - FormResponseDTO response = new FormResponseDTO(); - response.setVersion(form.getVersion()); - response.setFormId(form.getFormId()); - response.setFormName(form.getFormName()); - response.setSections(List.of(singleSection)); + return null; - return response; } From 4d20b8cf8be32079cd84ec21c4c461f24f32a752 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 14 Jan 2026 16:46:22 +0530 Subject: [PATCH 15/47] implement state wise hide un hide form fields --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + .../java/com/iemr/common/data/users/UserServiceRole.java | 1 + .../iemr/common/repository/dynamic_form/FieldRepository.java | 5 +++++ .../iemr/common/repository/users/UserServiceRoleRepo.java | 1 + .../iemr/common/service/dynamicForm/FormMasterService.java | 1 + .../common/service/dynamicForm/FormMasterServiceImpl.java | 5 ++--- 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index cd83246f..3d49e808 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -97,4 +97,5 @@ public ResponseEntity> getStructuredForm(@PathVariable String for } + } diff --git a/src/main/java/com/iemr/common/data/users/UserServiceRole.java b/src/main/java/com/iemr/common/data/users/UserServiceRole.java index 63af40dd..27c044cf 100644 --- a/src/main/java/com/iemr/common/data/users/UserServiceRole.java +++ b/src/main/java/com/iemr/common/data/users/UserServiceRole.java @@ -365,4 +365,5 @@ public void setVillagename(String villagename) { public int hashCode() { return Objects.hash(userId, usrMappingId, name, userName, serviceId, serviceName, isNational, stateId, stateName, workingDistrictId, workingDistrictName, workingLocationId, serviceProviderId, locationName, workingLocationAddress, roleId, roleName, providerServiceMapId, agentId, psmStatusId, psmStatus, userServciceRoleDeleted, userDeleted, serviceProviderDeleted, roleDeleted, providerServiceMappingDeleted, isInbound, isOutbound, blockid, blockname, villageid, villagename); } + } diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java index 4aea5698..20a86e3e 100644 --- a/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java @@ -9,4 +9,9 @@ @Repository public interface FieldRepository extends JpaRepository { List findByForm_FormIdOrderBySequenceAsc(String formId); + List findByForm_FormIdAndStateCodeOrderBySequenceAsc( + String formId, + Integer stateCode + ); + } diff --git a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java index ee7db934..798f47c1 100644 --- a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java +++ b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java @@ -13,4 +13,5 @@ public interface UserServiceRoleRepo extends JpaRepository new IllegalArgumentException("Invalid form ID")); - List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); + List fields = fieldRepo.findByForm_FormIdAndStateCodeOrderBySequenceAsc(formId,stateId); ObjectMapper objectMapper = new ObjectMapper(); - Integer finalStateId = stateId; - List fieldDtos = fields.stream().filter(formField -> Objects.equals(formField.getStateCode(), finalStateId) || formField.getStateCode()==0) + List fieldDtos = fields.stream() .map(field -> { String labelKey = field.getFieldId(); // field label already contains label_key From bed849b895b9aca8e121696717e3668bd55ac91c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 16 Jan 2026 20:18:50 +0530 Subject: [PATCH 16/47] implement state wise hide un hide form fields --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + src/main/java/com/iemr/common/data/translation/Translation.java | 1 + .../com/iemr/common/repository/dynamic_form/FieldRepository.java | 1 + .../com/iemr/common/repository/translation/TranslationRepo.java | 1 + .../com/iemr/common/repository/users/UserServiceRoleRepo.java | 1 + .../com/iemr/common/service/dynamicForm/FormMasterService.java | 1 + .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 1 - 7 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 3d49e808..6f64a135 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -98,4 +98,5 @@ public ResponseEntity> getStructuredForm(@PathVariable String for + } diff --git a/src/main/java/com/iemr/common/data/translation/Translation.java b/src/main/java/com/iemr/common/data/translation/Translation.java index 0dad116d..52cb8027 100644 --- a/src/main/java/com/iemr/common/data/translation/Translation.java +++ b/src/main/java/com/iemr/common/data/translation/Translation.java @@ -22,4 +22,5 @@ public class Translation { private String assameseTranslation; @Column(name = "is_active") private Boolean isActive; + } diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java index 20a86e3e..50e84248 100644 --- a/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java @@ -14,4 +14,5 @@ List findByForm_FormIdAndStateCodeOrderBySequenceAsc( Integer stateCode ); + } diff --git a/src/main/java/com/iemr/common/repository/translation/TranslationRepo.java b/src/main/java/com/iemr/common/repository/translation/TranslationRepo.java index f6a5dcb0..139b5ee9 100644 --- a/src/main/java/com/iemr/common/repository/translation/TranslationRepo.java +++ b/src/main/java/com/iemr/common/repository/translation/TranslationRepo.java @@ -10,4 +10,5 @@ public interface TranslationRepo extends JpaRepository { Optional findByLabelKeyAndIsActive(String labelKey, boolean isActive); + } diff --git a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java index 798f47c1..17edb5e0 100644 --- a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java +++ b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java @@ -14,4 +14,5 @@ public interface UserServiceRoleRepo extends JpaRepository Date: Sun, 18 Jan 2026 11:30:45 +0530 Subject: [PATCH 17/47] enhance welcome sms code --- .../com/iemr/common/CommonApplication.java | 2 + .../RegisterBenificiaryServiceImpl.java | 25 ++++++- .../WelcomeBenificarySmsServiceImpl.java | 72 +++++++++---------- 3 files changed, 60 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index e4a59994..dff5d809 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -29,6 +29,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.web.client.RestTemplate; @@ -40,6 +41,7 @@ @SpringBootApplication @EnableScheduling +@EnableAsync public class CommonApplication extends SpringBootServletInitializer { @Bean diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 54637a4c..388d6298 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -29,6 +29,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch; import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsService; @@ -234,9 +235,27 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet } else { return response.toString(); } - if(beneficiary!=null){ - if(beneficiary.getBenPhoneMaps().get(0).getPhoneNo()!=null){ - welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiary.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + // ========== SEND SMS BUT DON'T FAIL IF IT ERRORS ========== + if (beneficiary != null && beneficiary.getBenPhoneMaps() != null && !beneficiary.getBenPhoneMaps().isEmpty()) { + String phoneNo = beneficiary.getBenPhoneMaps().get(0).getPhoneNo(); + + if (phoneNo != null && !phoneNo.trim().isEmpty()) { + String beneficiaryName = (beneficiary.getFirstName() != null ? beneficiary.getFirstName() : "") + " " + + (beneficiary.getLastName() != null ? beneficiary.getLastName() : ""); + + try { + logger.info("[SMS] Attempting to send welcome SMS to: " + phoneNo); + String smsResult = welcomeBenificarySmsService.sendWelcomeSMStoBenificiary( + phoneNo, + beneficiaryName.trim(), + beneficiary.getBeneficiaryID() + ); + logger.info("[SMS] Result: " + smsResult); + } catch (Exception smsError) { + // SMS failed but beneficiary is already created - don't fail the request + logger.warn("[SMS] Failed to send SMS: " + smsError.getMessage() + + " - But beneficiary already created successfully"); + } } } diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index 67b642ab..a80a98e8 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -12,6 +12,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @@ -46,58 +47,57 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsServ private String smsTemplateName = "welcome_sms"; - private String smsTemplate; + private String smsTemplate =null; @Override + @Async public String sendWelcomeSMStoBenificiary(String contactNo, String beneficiaryName, String beneficiaryId) { - final RestTemplate restTemplate = new RestTemplate(); - - Optional smsTemplateData = smsTemplateRepository.findBySmsTemplateName(smsTemplateName); - if (smsTemplateData.isPresent()) { - smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplateData.get().getSmsTemplateID()).getSmsTemplate(); - - } - - logger.info("sms template" + smsTemplate); - - - String sendSMSAPI = SMS_GATEWAY_URL; try { + String sendSMSAPI = SMS_GATEWAY_URL; + + final RestTemplate restTemplate = new RestTemplate(); - String message = smsTemplate.replace("$$BENE_NAME$$", beneficiaryName).replace("$$BEN_ID$$", beneficiaryId); - // Build payload - Map payload = new HashMap<>(); - payload.put("customerId", smsUserName); - payload.put("destinationAddress", contactNo); - payload.put("message", message); - payload.put("sourceAddress", smsSourceAddress); - payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", smsTemplateData.get().getDltTemplateId()); - payload.put("entityId", smsEntityId); - // Set headers - HttpHeaders headers = new HttpHeaders(); - String auth = smsUserName + ":" + smsPassword; - headers.add("Authorization", - "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); + Optional smsTemplateData = smsTemplateRepository.findBySmsTemplateName(smsTemplateName); + if (smsTemplateData.isPresent()) { + smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplateData.get().getSmsTemplateID()).getSmsTemplate(); + } + if(smsTemplate!=null){ + String message = smsTemplate.replace("$$BENE_NAME$$", beneficiaryName).replace("$$BEN_ID$$", beneficiaryId); + // Build payload + Map payload = new HashMap<>(); + payload.put("customerId", smsUserName); + payload.put("destinationAddress", contactNo); + payload.put("message", message); + payload.put("sourceAddress", smsSourceAddress); + payload.put("messageType", "SERVICE_IMPLICIT"); + payload.put("dltTemplateId", smsTemplateData.get().getDltTemplateId()); + payload.put("entityId", smsEntityId); + // Set headers + HttpHeaders headers = new HttpHeaders(); + String auth = smsUserName + ":" + smsPassword; + headers.add("Authorization", + "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); headers.setContentType(MediaType.APPLICATION_JSON); logger.info("payload: " + payload); HttpEntity> request = new HttpEntity<>(payload, headers); - // Call API - ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); - logger.info("sms-response:" + response.getBody()); - if (response.getStatusCode().value() == 200) { - return "OTP sent successfully on register mobile number"; - } else { - return "Fail"; + // Call API + ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + logger.info("sms-response:" + response.getBody()); + if (response.getStatusCode().value() == 200) { + return "OTP sent successfully on register mobile number"; + } else { + return "Fail"; + } } + } catch (Exception e) { return "Error sending SMS: " + e.getMessage().toString(); } - + return null; } } From 4104ad034e2983d7e11f5696057a607181e579ec Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Sun, 18 Jan 2026 23:15:23 +0530 Subject: [PATCH 18/47] fix hide unhide form issue --- .../common/service/dynamicForm/FormMasterServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 2edd805c..4e952a68 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -125,10 +125,11 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang,Strin FormDefinition form = formRepo.findByFormId(formId) .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); - List fields = fieldRepo.findByForm_FormIdAndStateCodeOrderBySequenceAsc(formId,stateId); + List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); ObjectMapper objectMapper = new ObjectMapper(); - List fieldDtos = fields.stream() + int finalStateId = stateId; + List fieldDtos = fields.stream().filter(formField -> formField.getStateCode()== 0 || formField.getStateCode()== finalStateId) .map(field -> { String labelKey = field.getFieldId(); // field label already contains label_key From fdbc9b762da293fe4763e3ef45206c332400de79 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 17:46:01 +0530 Subject: [PATCH 19/47] fix hide unhide form issue --- .../common/service/dynamicForm/FormMasterServiceImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 27dd5d08..a4db6b46 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -126,11 +126,11 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang,Strin FormDefinition form = formRepo.findByFormId(formId) .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); - List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); + int finalStateId = stateId; + List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId).stream().filter(formField -> (formField.getStateCode() == 0 || formField.getStateCode() == finalStateId)).toList(); ObjectMapper objectMapper = new ObjectMapper(); - Integer finalStateId = stateId; - List fieldDtos = fields.stream().filter(formField -> Objects.equals(formField.getStateCode(), finalStateId) || formField.getStateCode()==0) + List fieldDtos = fields.stream() .map(field -> { String labelKey = field.getFieldId(); // field label already contains label_key From 0c64cef2ec7456507645d96726038f51f41f5c27 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 17:58:48 +0530 Subject: [PATCH 20/47] fix hide unhide form issue --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index a4db6b46..645bc272 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -126,8 +126,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang,Strin FormDefinition form = formRepo.findByFormId(formId) .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); - int finalStateId = stateId; - List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId).stream().filter(formField -> (formField.getStateCode() == 0 || formField.getStateCode() == finalStateId)).toList(); + List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); ObjectMapper objectMapper = new ObjectMapper(); List fieldDtos = fields.stream() From b3a1922544e11e181c4ac043cac897d0c1c54e4c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:11:51 +0530 Subject: [PATCH 21/47] fix hide unhide form issue --- .../service/dynamicForm/FormMasterServiceImpl.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 645bc272..9d3b14e3 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -122,7 +122,16 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang,Strin UserServiceRole userServiceRole= userServiceRoleRepo.findByUserName(jwtUtil.getUsernameFromToken(token)); if(userServiceRole!=null){ stateId = userServiceRole.getStateId(); + logger.info("State:Id"+stateId); } + if(!token.isEmpty()){ + logger.info("Token: "+token); + + } + + logger.info("State outSide: "+stateId); + + FormDefinition form = formRepo.findByFormId(formId) .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); From c4c1d48f79184173906838814177e81530c76d24 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:17:59 +0530 Subject: [PATCH 22/47] fix hide unhide form issue --- .../common/controller/dynamicForm/DynamicFormController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index cd83246f..62bf7e7c 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -84,7 +84,7 @@ public ResponseEntity> deleteField(@PathVariable Long fieldId) { } @GetMapping(value = "form/{formId}/fields") - public ResponseEntity> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang,@RequestHeader(value = "JwtToken") String token) { + public ResponseEntity> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang,@RequestHeader(value = "jwttoken") String token) { try { Object result = formMasterService.getStructuredFormByFormId(formId,lang,token); return ResponseEntity.status(HttpStatus.OK) From f10f37cb86948e657f84c4663627403b70d05930 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:23:40 +0530 Subject: [PATCH 23/47] fix hide unhide form issue --- .../service/dynamicForm/FormMasterServiceImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 9d3b14e3..7ce3e01d 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -119,11 +119,14 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang,Strin int stateId =0 ; try { - UserServiceRole userServiceRole= userServiceRoleRepo.findByUserName(jwtUtil.getUsernameFromToken(token)); - if(userServiceRole!=null){ - stateId = userServiceRole.getStateId(); - logger.info("State:Id"+stateId); + if(!token.isEmpty()){ + UserServiceRole userServiceRole= userServiceRoleRepo.findByUserName(jwtUtil.getUsernameFromToken(token)); + if(userServiceRole!=null){ + stateId = userServiceRole.getStateId(); + logger.info("State:Id"+stateId); + } } + if(!token.isEmpty()){ logger.info("Token: "+token); From b3da893ff0fb540203939c57f0527565e56ebcc7 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:32:07 +0530 Subject: [PATCH 24/47] fix hide unhide form issue --- .../dynamicForm/FormMasterServiceImpl.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 7ce3e01d..e61f7b17 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -116,23 +116,7 @@ public FormField updateField(FieldDTO dto) { @Override public FormResponseDTO getStructuredFormByFormId(String formId,String lang,String token) { - int stateId =0 ; - try { - if(!token.isEmpty()){ - UserServiceRole userServiceRole= userServiceRoleRepo.findByUserName(jwtUtil.getUsernameFromToken(token)); - if(userServiceRole!=null){ - stateId = userServiceRole.getStateId(); - logger.info("State:Id"+stateId); - } - } - - if(!token.isEmpty()){ - logger.info("Token: "+token); - - } - - logger.info("State outSide: "+stateId); FormDefinition form = formRepo.findByFormId(formId) From f94d0b07cc4ebfc6c4cdb54b13a0df6dd7e14d75 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:40:18 +0530 Subject: [PATCH 25/47] fix hide unhide form issue --- .../common/repository/users/UserServiceRoleRepo.java | 2 +- .../service/dynamicForm/FormMasterServiceImpl.java | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java index ee7db934..65691053 100644 --- a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java +++ b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java @@ -10,7 +10,7 @@ @Repository public interface UserServiceRoleRepo extends JpaRepository { - UserServiceRole findByUserName(String userName); + List findByUserName(String userName); UserServiceRole findByUserId(Integer userId); } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index e61f7b17..93a8d209 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -116,7 +116,16 @@ public FormField updateField(FieldDTO dto) { @Override public FormResponseDTO getStructuredFormByFormId(String formId,String lang,String token) { + int stateId =0 ; + try { + if(!token.isEmpty()){ + List userServiceRole= userServiceRoleRepo.findByUserName(jwtUtil.getUsernameFromToken(token)); + if(userServiceRole!=null){ + stateId = userServiceRole.get(0).getStateId(); + logger.info("State:Id"+stateId); + } + } FormDefinition form = formRepo.findByFormId(formId) @@ -125,7 +134,8 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang,Strin List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); ObjectMapper objectMapper = new ObjectMapper(); - List fieldDtos = fields.stream() + int finalStateId = stateId; + List fieldDtos = fields.stream().filter(formField -> (formField.getStateCode()==0 || formField.getStateCode().equals(finalStateId))) .map(field -> { String labelKey = field.getFieldId(); // field label already contains label_key From be7889e1407544df7fe91c48ffa35b83d28003b1 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:48:20 +0530 Subject: [PATCH 26/47] fix hide unhide form issue --- .../java/com/iemr/common/config/encryption/SecurePassword.java | 3 +++ .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 1 + 2 files changed, 4 insertions(+) diff --git a/src/main/java/com/iemr/common/config/encryption/SecurePassword.java b/src/main/java/com/iemr/common/config/encryption/SecurePassword.java index 15463b7a..7aa9c6fd 100644 --- a/src/main/java/com/iemr/common/config/encryption/SecurePassword.java +++ b/src/main/java/com/iemr/common/config/encryption/SecurePassword.java @@ -30,6 +30,8 @@ import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service; @Service @@ -149,4 +151,5 @@ private byte[] fromHex(String hex) { } return bytes; } + } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 93a8d209..512ad015 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -128,6 +128,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang,Strin } + FormDefinition form = formRepo.findByFormId(formId) .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); From 00223293fed97811c81cec301268b20cc56813e8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:48:40 +0530 Subject: [PATCH 27/47] fix hide unhide form issue --- .../com/iemr/common/repository/users/UserServiceRoleRepo.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java index 65691053..111fcf43 100644 --- a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java +++ b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java @@ -11,6 +11,5 @@ @Repository public interface UserServiceRoleRepo extends JpaRepository { List findByUserName(String userName); - UserServiceRole findByUserId(Integer userId); } From ba824bee7ce2cc2717b8c0298dc08513057748cf Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:50:02 +0530 Subject: [PATCH 28/47] fix hide unhide form issue --- .../com/iemr/common/config/encryption/SecurePassword.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/iemr/common/config/encryption/SecurePassword.java b/src/main/java/com/iemr/common/config/encryption/SecurePassword.java index 7aa9c6fd..9b717375 100644 --- a/src/main/java/com/iemr/common/config/encryption/SecurePassword.java +++ b/src/main/java/com/iemr/common/config/encryption/SecurePassword.java @@ -29,9 +29,6 @@ import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service; @Service @@ -151,5 +148,4 @@ private byte[] fromHex(String hex) { } return bytes; } - } From c0c53333b8ba76f52e1e3bcbe1eb658ef30bcb4a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:51:26 +0530 Subject: [PATCH 29/47] fix hide unhide form issue --- src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4409afd4..9fb04c9d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -372,5 +372,4 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent -cors.allowed-origin=https://amritdemo.piramalswasthya.org From 2e18fddcdd254a4ce7ff7ab0ec02df4a9445b9a1 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:52:29 +0530 Subject: [PATCH 30/47] fix hide unhide form issue --- .../java/com/iemr/common/config/encryption/SecurePassword.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/config/encryption/SecurePassword.java b/src/main/java/com/iemr/common/config/encryption/SecurePassword.java index 9b717375..95cdd7f3 100644 --- a/src/main/java/com/iemr/common/config/encryption/SecurePassword.java +++ b/src/main/java/com/iemr/common/config/encryption/SecurePassword.java @@ -26,7 +26,6 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; - import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import org.springframework.stereotype.Service; From acd9d8e9d7348ddfb43e34330af4537ea262e399 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:53:58 +0530 Subject: [PATCH 31/47] fix hide unhide form issue --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 11ad9f37..171ab162 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.0 + 3.6.1 war Common-API From 475a4acae64e598d980de47a89a700d5ae4ac929 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:55:10 +0530 Subject: [PATCH 32/47] fix hide unhide form issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9fb04c9d..6b52b9b5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -372,4 +372,4 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent - +cors.allowed-origin = From f95270843c29a9037ee5fe105c91c3c2556070dc Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:55:47 +0530 Subject: [PATCH 33/47] fix hide unhide form issue --- src/main/resources/application.properties | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6b52b9b5..eee27bbc 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -76,14 +76,14 @@ get-details-call-report-URL=http://CTI_SERVER/apps/customize_apps/piramil_report #============================================================================ # Configure Main Scheduler Properties #============================================================================ - + org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.makeSchedulerThreadDaemon = true - + #============================================================================ # Configure ThreadPool #============================================================================ - + org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.makeThreadsDaemons = true org.quartz.threadPool.threadCount: 20 @@ -110,6 +110,7 @@ iemr.extend.expiry.time.changePassword=true iemr.session.expiry.time.changePassword=600 identity-api-url-advancesearch =IDENTITY_BASE_URL/id/advanceSearch +identity-api-url-advancesearch-es =IDENTITY_BASE_URL/beneficiary/advancedSearchES identity-api-url-getByBenRegIdList =IDENTITY_BASE_URL/id/getByBenRegIdList identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenRegIdList identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= @@ -118,6 +119,7 @@ identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity +identity-api-url-searchByES=IDENTITY_BASE_URL/beneficiary/search identity-api-url-getByFamilyId=IDENTITY_BASE_URL/id/searchByFamilyId?familyId= identity-api-url-getByGovIdentity=IDENTITY_BASE_URL/id/searchByGovIdentity?identity= @@ -372,4 +374,5 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent -cors.allowed-origin = + +cors.allowed-origin = \ No newline at end of file From 64b2a7e8eb7a4378e1e4ebfddb048b3975ffb44c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 21 Jan 2026 18:56:43 +0530 Subject: [PATCH 34/47] fix hide unhide form issue --- src/main/resources/application.properties | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eee27bbc..beefff31 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -110,7 +110,6 @@ iemr.extend.expiry.time.changePassword=true iemr.session.expiry.time.changePassword=600 identity-api-url-advancesearch =IDENTITY_BASE_URL/id/advanceSearch -identity-api-url-advancesearch-es =IDENTITY_BASE_URL/beneficiary/advancedSearchES identity-api-url-getByBenRegIdList =IDENTITY_BASE_URL/id/getByBenRegIdList identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenRegIdList identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= @@ -119,7 +118,6 @@ identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity -identity-api-url-searchByES=IDENTITY_BASE_URL/beneficiary/search identity-api-url-getByFamilyId=IDENTITY_BASE_URL/id/searchByFamilyId?familyId= identity-api-url-getByGovIdentity=IDENTITY_BASE_URL/id/searchByGovIdentity?identity= @@ -375,4 +373,4 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent -cors.allowed-origin = \ No newline at end of file +cors.allowed-origin = From f487978241fb553638caf098b275c23f3a66a0ae Mon Sep 17 00:00:00 2001 From: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:22:34 +0530 Subject: [PATCH 35/47] Move code to 3.6.1 to 3.8.0 (#372) * fix: cors spell fixes and import of packages updates * fix: deployment issue fix * feat: amm-1959 dhis token for cho report re-direction * fix: beneficiary history on revisit (#320) * fix: call type mapper (#322) * Elasticsearch implementation for Beneficiary Search (#324) * fix: implement functionality to search beneficiaries with Elasticsearch * fix: remove unwanted import * fix: update pom.xml * fix: change the response code * variable added * Elastic Search Implementation for Advanced Search (#327) * fix: cherry-pick commits for advanced search * fix: cherry-pick commit for token issue - mobile application * fix: add the missing properties * fix: add function to retrieve userid * fix: move the fetch Userid to jwtUtil * fix:signature check for mmu * fix: retrive any user without deleted * fix: update KM filepath * FLW-713 Remove All File Upload Options (#350) * FLW-713 Remove All File Upload Options * Fix UserServiceRoleRepo dependency issue and codeRabit comment * fixed coderabit comment * fix userMappingId issue * Add SMS functionality in release-3.6.1 (#358) * Enable SMS Functionality in MMU App to Send Prescriptions (#325) * fix: sms template save and map mmu (#306) * Vb/sms (#307) * fix: sms template save and map mmu * fix: enable mms for mmu prescription * Enable SMS Functionality in MMU App to Send Prescriptions (#325) * fix: sms template save and map mmu (#306) * Vb/sms (#307) * fix: sms template save and map mmu * fix: enable mms for mmu prescription --------- Co-authored-by: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> --------- Co-authored-by: 5Amogh Co-authored-by: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Co-authored-by: Sachin Kadam <152252767+sac2kadam@users.noreply.github.com> Co-authored-by: vanitha1822 Co-authored-by: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> --- .vscode/settings.json | 3 + pom.xml | 2 +- src/main/environment/common_ci.properties | 1 + src/main/environment/common_docker.properties | 2 +- .../environment/common_example.properties | 2 + .../com/iemr/common/config/CorsConfig.java | 2 +- .../BeneficiaryRegistrationController.java | 88 +++++ .../dynamicForm/DynamicFormController.java | 4 +- .../PlatformFeedbackController.java | 8 +- .../controller/users/IEMRAdminController.java | 21 +- .../common/data/dynamic_from/FormField.java | 8 + .../PrescribedMMUDrugDetail.java | 119 ++++++ .../data/mmuDrugHistory/PrescriptionMMU.java | 43 +++ .../data/platform_feedback/Feedback.java | 2 +- .../platform_feedback/FeedbackCategory.java | 2 +- .../common/data/translation/Translation.java | 2 + .../java/com/iemr/common/data/users/User.java | 11 +- .../common/data/users/UserServiceRole.java | 364 ++++++++++++++++++ .../dto/dynamicForm/FieldResponseDTO.java | 2 + .../platform_feedback/CategoryResponse.java | 2 +- .../platform_feedback/FeedbackRequest.java | 3 +- .../platform_feedback/FeedbackResponse.java | 2 +- .../iemr/common/dto/sms/SMSTemplateDTO.java | 114 ++++++ .../com/iemr/common/mapper/sms/SMSMapper.java | 24 ++ .../PrescribedMMUDrugRepository.java | 11 + .../PlatformFeedbackCategoryRepository.java | 2 +- .../PlatformFeedbackRepository.java | 2 +- .../users/IEMRUserRepositoryCustom.java | 3 + .../repository/users/UserServiceRoleRepo.java | 12 + .../beneficiary/IEMRSearchUserService.java | 4 + .../IEMRSearchUserServiceImpl.java | 99 ++++- .../IdentityBeneficiaryService.java | 7 + .../IdentityBeneficiaryServiceImpl.java | 196 +++++++++- .../callhandling/CalltypeServiceImpl.java | 12 +- .../dynamicForm/FormMasterService.java | 4 +- .../dynamicForm/FormMasterServiceImpl.java | 206 ++++++---- .../KMFileManagerServiceImpl.java | 4 +- .../PlatformFeedbackService.java | 10 +- .../common/service/sms/SMSServiceImpl.java | 243 +++++++++--- .../users/EmployeeSignatureServiceImpl.java | 6 +- .../service/users/IEMRAdminUserService.java | 2 + .../users/IEMRAdminUserServiceImpl.java | 6 + .../java/com/iemr/common/utils/JwtUtil.java | 55 +++ .../iemr/common/utils/RestTemplateUtil.java | 7 +- .../utils/http/HTTPRequestInterceptor.java | 177 +++++---- .../common/utils/mapper/CallTypeMapper.java | 43 +++ src/main/resources/application.properties | 4 +- 47 files changed, 1652 insertions(+), 294 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java create mode 100644 src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java create mode 100644 src/main/java/com/iemr/common/data/users/UserServiceRole.java create mode 100644 src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java create mode 100644 src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java create mode 100644 src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java create mode 100644 src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..7b016a89 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "automatic" +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 11ad9f37..171ab162 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.0 + 3.6.1 war Common-API diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 0184b32f..9f54a35d 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -19,6 +19,7 @@ km-base-path=@env.KM_API_BASE_PATH@ km-root-path=/okm:personal/users/ km-guest-user=@env.KM_GUEST_USER@ km-guest-password=@env.KM_GUEST_PASSWORD@ +tempFilePath=@env.TEMP_FILE_PATH@ # CTI Config cti-server-ip=@env.CTI_SERVER_IP@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index a81ea62e..59cb580d 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -126,7 +126,7 @@ everwellRegisterBenficiary = ${COMMON_API_BASE_URL}/beneficiary/create ## LungAssessment credentials lungAssessmentEmail = ${SWAASA_EMAIL} lungAssessmentPassword =${SWAASA_PASSWORD} - +tempFilePath=${TEMP_FILE_PATH} ## SWASSA APIs lungAssessmentAdminLogin = ${SWAASA_BASE_URL}/api/adminLogin diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index aca73ddb..03f0d915 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -25,6 +25,8 @@ km-root-path=/okm:personal/users/ km-guest-user=guest km-guest-password=guest +tempFilePath=/opt/openkm + # CTI Config cti-server-ip=10.208.122.99 cti-logger_base_url=http://10.208.122.99/logger diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index bdee1beb..fdd9b494 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -9,7 +9,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allowed-origin}") + @Value("${cors.allowed-origins}") private String allowedOrigins; @Override public void addCorsMappings(CorsRegistry registry) { diff --git a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java index 8f573d6d..3784f3a9 100644 --- a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java +++ b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java @@ -36,6 +36,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @@ -70,6 +71,8 @@ import com.iemr.common.service.userbeneficiarydata.MaritalStatusService; import com.iemr.common.service.userbeneficiarydata.StatusService; import com.iemr.common.service.userbeneficiarydata.TitleService; +import com.iemr.common.utils.CookieUtil; +import com.iemr.common.utils.JwtUtil; import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.mapper.OutputMapper; import com.iemr.common.utils.response.OutputResponse; @@ -103,6 +106,8 @@ public class BeneficiaryRegistrationController { private BeneficiaryOccupationService beneficiaryOccupationService; private GovtIdentityTypeService govtIdentityTypeService; + @Autowired + private JwtUtil jwtUtil; @Autowired public void setBenRelationshipTypeService(BenRelationshipTypeService benRelationshipTypeService) { @@ -342,6 +347,54 @@ public String searchUserByPhone( return response.toString(); } + @Operation(summary = "Provide the list of beneficiaries using Elasticsearch") + @RequestMapping(value = "/searchUser", method = RequestMethod.POST, headers = "Authorization") + public String searchUser(@RequestBody String request, HttpServletRequest httpRequest) { + OutputResponse response = new OutputResponse(); + try { + logger.info("Universal search request received"); + + JsonParser parser = new JsonParser(); + JsonObject requestObj = parser.parse(request).getAsJsonObject(); + + String searchQuery = null; + if (requestObj.has("search") && !requestObj.get("search").isJsonNull()) { + searchQuery = requestObj.get("search").getAsString(); + } + + if (searchQuery == null || searchQuery.trim().isEmpty()) { + response.setError(400, "Search query is required"); + return response.toString(); + } + + String auth = httpRequest.getHeader("Authorization"); + + Integer userID = jwtUtil.getUserIdFromRequest(httpRequest); + + logger.info("ES search for userId: {}", userID); + + Boolean is1097 = false; + if (requestObj.has("is1097") && !requestObj.get("is1097").isJsonNull()) { + is1097 = requestObj.get("is1097").getAsBoolean(); + } + + logger.info("Searching with query: {}, userId: {}, is1097: {}", searchQuery, userID, is1097); + String result = iemrSearchUserService.searchUser(searchQuery, userID, auth, is1097); + + if (result == null || result.trim().isEmpty()) { + response.setError(200, "No beneficiaries found"); + return response.toString(); + } + + return result; + + } catch (Exception e) { + logger.error("Error in universal search: {}", e.getMessage(), e); + response.setError(400, "Error searching beneficiaries: " + e.getMessage()); + return response.toString(); + } + } + @Operation(summary = "Provide the list of beneficiaries based on search criteria") @RequestMapping(value = "/searchBeneficiary", method = RequestMethod.POST, headers = "Authorization") public String searchBeneficiary( @@ -364,6 +417,41 @@ public String searchBeneficiary( return output.toString(); } + /** + * Elasticsearch-based advanced search endpoint + */ + @Operation(summary = "Advanced search beneficiaries using Elasticsearch") + @RequestMapping(value = "/searchBeneficiaryES", method = RequestMethod.POST, headers = "Authorization") + public String searchBeneficiaryES( + @RequestBody BeneficiaryModel request, + HttpServletRequest httpRequest) { + + logger.info("searchBeneficiaryES request: {}", request); + OutputResponse output = new OutputResponse(); + + try { + + String auth = httpRequest.getHeader("Authorization"); + + Integer userID = jwtUtil.getUserIdFromRequest(httpRequest); + + logger.info("ES Advanced search for userId: {}", userID); + + String result = iemrSearchUserService.findBeneficiaryES(request, userID, auth); + + return result; + + } catch (NumberFormatException ne) { + logger.error("searchBeneficiaryES failed with number format error: {}", ne.getMessage(), ne); + output.setError(400, "Invalid number format in search criteria"); + return output.toString(); + } catch (Exception e) { + logger.error("searchBeneficiaryES failed with error: {}", e.getMessage(), e); + output.setError(500, "Error searching beneficiaries: " + e.getMessage()); + return output.toString(); + } + } + @Operation(summary = "Provide all common data list needed for beneficiary registration") @RequestMapping(value = "/getRegistrationData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String getRegistrationData() { diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 30a1bc3f..62bf7e7c 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -84,9 +84,9 @@ public ResponseEntity> deleteField(@PathVariable Long fieldId) { } @GetMapping(value = "form/{formId}/fields") - public ResponseEntity> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang) { + public ResponseEntity> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang,@RequestHeader(value = "jwttoken") String token) { try { - Object result = formMasterService.getStructuredFormByFormId(formId,lang); + Object result = formMasterService.getStructuredFormByFormId(formId,lang,token); return ResponseEntity.status(HttpStatus.OK) .body(ApiResponse.success("Form structure fetched successfully", HttpStatus.OK.value(), result)); } catch (Exception e) { diff --git a/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java b/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java index fd9aad90..556561cf 100644 --- a/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java +++ b/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java @@ -19,10 +19,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.controller; +package com.iemr.common.controller.platform_feedback; -import com.iemr.common.dto.*; -import com.iemr.common.service.PlatformFeedbackService; +import com.iemr.common.dto.platform_feedback.CategoryResponse; +import com.iemr.common.dto.platform_feedback.FeedbackRequest; +import com.iemr.common.dto.platform_feedback.FeedbackResponse; +import com.iemr.common.service.platform_feedback.PlatformFeedbackService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 55e2f93f..554500f3 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -392,6 +392,7 @@ private void createUserMapping(User mUser, JSONObject resMap, JSONObject service resMap.put("agentPassword", mUser.getAgentPassword()); resMap.put("m_UserLangMappings", new JSONArray(mUser.getM_UserLangMappings().toString())); resMap.put("designationID", mUser.getDesignationID()); + resMap.put("dhistoken",mUser.getDhistoken()); if (mUser.getDesignation() != null) { resMap.put("designation", new JSONObject(mUser.getDesignation().toString())); } @@ -1223,7 +1224,25 @@ public ResponseEntity getUserDetails(@PathVariable("userName") String userNam return new ResponseEntity<>(Map.of("error", "UserName Not Found"), HttpStatus.NOT_FOUND); } User user = users.get(0); - return new ResponseEntity<>(Map.of("userName", user.getUserName(), "userId", user.getUserID()), HttpStatus.OK); + return new ResponseEntity<>(Map.of("userName", user.getUserName(), "userId", user.getUserID()), + HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(Map.of("error", "Internal server error"), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } + + @Operation(summary = "Get UserId based on userName") + @GetMapping(value = "/checkUserName/{userName}", produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public ResponseEntity checkUserDetails(@PathVariable("userName") String userName) { + try { + List users = iemrAdminUserServiceImpl.findUserIdByUserName(userName); + if (users.isEmpty()) { + return new ResponseEntity<>(Map.of("error", "UserName Not Found"), HttpStatus.NOT_FOUND); + } + User user = users.get(0); + return new ResponseEntity<>(Map.of("userName", user.getUserName(), "userId", user.getUserID()), + HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(Map.of("error", "Internal server error"), HttpStatus.INTERNAL_SERVER_ERROR); } diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java index 39785ae9..1b195db9 100644 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java @@ -53,7 +53,15 @@ public class FormField { @Column(name = "sequence") private Integer sequence; + @Column(name = "is_editable") + private Boolean isEditable; + + @Column(name = "state_code") + private Integer stateCode; + @Column(name = "created_at") private LocalDateTime createdAt = LocalDateTime.now(); + + } diff --git a/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java new file mode 100644 index 00000000..e478420d --- /dev/null +++ b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java @@ -0,0 +1,119 @@ +package com.iemr.common.data.mmuDrugHistory; + +import java.sql.Date; +import java.sql.Timestamp; + +import com.google.gson.annotations.Expose; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; +import lombok.Data; + +@Entity +@Data +@Table(name = "t_prescribeddrug") +public class PrescribedMMUDrugDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Expose + @Column(name = "PrescribedDrugID") + private Long prescribedDrugID; + + @Expose + @Column(name = "BeneficiaryRegID") + private Long beneficiaryRegID; + + @Expose + @Column(name = "BenVisitID") + private Long benVisitID; + + @Expose + @Column(name = "ProviderServiceMapID") + private Integer providerServiceMapID; + + @Expose + @Column(name = "VisitCode") + private Long visitCode; + + @Expose + @Column(name = "PrescriptionID") + private Long prescriptionID; + + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "PrescriptionID", referencedColumnName = "PrescriptionID", insertable = false, updatable = false) + private PrescriptionMMU prescription; + + @Expose + @Column(name = "DrugForm") + private String formName; + + @Expose + @Column(name = "DrugTradeOrBrandName") + private String drugTradeOrBrandName; + + @Expose + @Column(name = "DrugID") + private Integer drugID; + + @Expose + @Column(name = "GenericDrugName") + private String drugName; + + @Expose + @Column(name = "DrugStrength") + private String drugStrength; + + @Expose + @Column(name = "Dose") + private String dose; + + @Expose + @Column(name = "Route") + private String route; + + @Expose + @Column(name = "Frequency") + private String frequency; + + @Expose + @Column(name = "Duration") + private String duration; + + @Expose + @Column(name = "DuartionUnit") + private String unit; + + @Expose + @Column(name = "RelationToFood") + private String relationToFood; + + @Expose + @Column(name = "SpecialInstruction") + private String instructions; + + @Expose + @Column(name = "QtyPrescribed") + private Integer qtyPrescribed; + + @Expose + @Column(name = "Deleted", insertable = false, updatable = true) + private Boolean deleted; + + @Expose + @Column(name = "Processed", insertable = false, updatable = true) + private String processed; + + @Expose + @Column(name = "CreatedBy") + private String createdBy; + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java new file mode 100644 index 00000000..cd3f655e --- /dev/null +++ b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java @@ -0,0 +1,43 @@ +package com.iemr.common.data.mmuDrugHistory; + +import com.google.gson.annotations.Expose; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Data +@Table(name = "t_prescription") +public class PrescriptionMMU { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Expose + @Column(name = "PrescriptionID", insertable = false, updatable = false) + private Long prescriptionID; + + @Expose + @Column(name = "BenVisitID") + private Long benVisitID; + + @Expose + @Column(name = "ProviderServiceMapID") + private Integer providerServiceMapID; + + @Expose + @Column(name = "DiagnosisProvided") + private String diagnosisProvided; + + @Expose + @Column(name = "Remarks") + private String remarks; + + @Expose + @Column(name = "Deleted", insertable = false, updatable = true) + private Boolean deleted; + +} diff --git a/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java index b499ef3a..776d3c08 100644 --- a/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java +++ b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java @@ -19,7 +19,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.model; +package com.iemr.common.data.platform_feedback; import jakarta.persistence.*; import jakarta.validation.constraints.Max; diff --git a/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java index ee9ffffe..a3e4c692 100644 --- a/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java +++ b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java @@ -19,7 +19,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.model; +package com.iemr.common.data.platform_feedback; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/com/iemr/common/data/translation/Translation.java b/src/main/java/com/iemr/common/data/translation/Translation.java index 81a906fa..0dad116d 100644 --- a/src/main/java/com/iemr/common/data/translation/Translation.java +++ b/src/main/java/com/iemr/common/data/translation/Translation.java @@ -18,6 +18,8 @@ public class Translation { private String english; @Column(name = "hindi_translation") private String hindiTranslation; + @Column(name = "assamese_translation") + private String assameseTranslation; @Column(name = "is_active") private Boolean isActive; } diff --git a/src/main/java/com/iemr/common/data/users/User.java b/src/main/java/com/iemr/common/data/users/User.java index e6184e60..275b0ec6 100644 --- a/src/main/java/com/iemr/common/data/users/User.java +++ b/src/main/java/com/iemr/common/data/users/User.java @@ -55,6 +55,7 @@ @Entity @Table(name = "m_user") @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -208,6 +209,10 @@ public class User implements Serializable { @Column(name = "failed_attempt") private Integer failedAttempt; + @Expose + @Column(name = "dhistoken") + private String dhistoken; + /* * protected User() { } */ @@ -217,7 +222,7 @@ public static User initializeUsers(Long userID, Integer titleID, String firstNam Timestamp dOJ, Integer qualificationID, String userName, String password, String emailID, Status m_Status, List m_UserServiceRoleMapping, String emergencyContactPerson, String emergencyContactNo, Boolean isSupervisor, Boolean deleted, String createdBy, Timestamp createdDate, - String modifiedBy, Timestamp lastModDate, String newPassword) { + String modifiedBy, Timestamp lastModDate, String newPassword, String dhistoken) { User user = new User(); user.userID = userID; user.titleID = titleID; @@ -244,6 +249,7 @@ public static User initializeUsers(Long userID, Integer titleID, String firstNam user.modifiedBy = modifiedBy; user.lastModDate = lastModDate; user.newPassword = newPassword; + user.dhistoken = dhistoken; return user; } @@ -530,6 +536,9 @@ public Integer getDesignationID() { public Designation getDesignation() { return designation; } + public String getDhistoken() { + return dhistoken; + } /* * public User(String userName, String password) { this.userName = userName; diff --git a/src/main/java/com/iemr/common/data/users/UserServiceRole.java b/src/main/java/com/iemr/common/data/users/UserServiceRole.java new file mode 100644 index 00000000..935940d5 --- /dev/null +++ b/src/main/java/com/iemr/common/data/users/UserServiceRole.java @@ -0,0 +1,364 @@ +package com.iemr.common.data.users; + +import jakarta.persistence.*; +import java.util.Objects; + +@Entity +@Table(name = "v_userservicerolemapping", schema = "db_iemr") +public class UserServiceRole { + private Integer userId; + private int usrMappingId; + private String name; + private String userName; + private Short serviceId; + private String serviceName; + private Boolean isNational; + private Integer stateId; + private String stateName; + private Integer workingDistrictId; + private String workingDistrictName; + private Integer workingLocationId; + private Short serviceProviderId; + private String locationName; + private String workingLocationAddress; + private Integer roleId; + private String roleName; + private Integer providerServiceMapId; + private String agentId; + private Short psmStatusId; + private String psmStatus; + private Boolean userServciceRoleDeleted; + private Boolean userDeleted; + private Boolean serviceProviderDeleted; + private Boolean roleDeleted; + private Boolean providerServiceMappingDeleted; + private Boolean isInbound; + private Boolean isOutbound; + private Integer blockid; + private String blockname; + private String villageid; + private String villagename; + + @Basic + @Column(name = "UserID") + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + @Basic + @Column(name = "USRMappingID") + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + public int getUsrMappingId() { + return usrMappingId; + } + + public void setUsrMappingId(int usrMappingId) { + this.usrMappingId = usrMappingId; + } + + @Basic + @Column(name = "Name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Basic + @Column(name = "UserName") + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + @Basic + @Column(name = "ServiceID") + public Short getServiceId() { + return serviceId; + } + + public void setServiceId(Short serviceId) { + this.serviceId = serviceId; + } + + @Basic + @Column(name = "ServiceName") + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + @Basic + @Column(name = "IsNational") + public Boolean getNational() { + return isNational; + } + + public void setNational(Boolean national) { + isNational = national; + } + + @Basic + @Column(name = "StateID") + public Integer getStateId() { + return stateId; + } + + public void setStateId(Integer stateId) { + this.stateId = stateId; + } + + @Basic + @Column(name = "StateName") + public String getStateName() { + return stateName; + } + + public void setStateName(String stateName) { + this.stateName = stateName; + } + + @Basic + @Column(name = "WorkingDistrictID") + public Integer getWorkingDistrictId() { + return workingDistrictId; + } + + public void setWorkingDistrictId(Integer workingDistrictId) { + this.workingDistrictId = workingDistrictId; + } + + @Basic + @Column(name = "WorkingDistrictName") + public String getWorkingDistrictName() { + return workingDistrictName; + } + + public void setWorkingDistrictName(String workingDistrictName) { + this.workingDistrictName = workingDistrictName; + } + + @Basic + @Column(name = "WorkingLocationID") + public Integer getWorkingLocationId() { + return workingLocationId; + } + + public void setWorkingLocationId(Integer workingLocationId) { + this.workingLocationId = workingLocationId; + } + + @Basic + @Column(name = "ServiceProviderID") + public Short getServiceProviderId() { + return serviceProviderId; + } + + public void setServiceProviderId(Short serviceProviderId) { + this.serviceProviderId = serviceProviderId; + } + + @Basic + @Column(name = "LocationName") + public String getLocationName() { + return locationName; + } + + public void setLocationName(String locationName) { + this.locationName = locationName; + } + + @Basic + @Column(name = "WorkingLocationAddress") + public String getWorkingLocationAddress() { + return workingLocationAddress; + } + + public void setWorkingLocationAddress(String workingLocationAddress) { + this.workingLocationAddress = workingLocationAddress; + } + + @Basic + @Column(name = "RoleID") + public Integer getRoleId() { + return roleId; + } + + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + + @Basic + @Column(name = "RoleName") + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + @Basic + @Column(name = "ProviderServiceMapID") + public Integer getProviderServiceMapId() { + return providerServiceMapId; + } + + public void setProviderServiceMapId(Integer providerServiceMapId) { + this.providerServiceMapId = providerServiceMapId; + } + + @Basic + @Column(name = "AgentID") + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + @Basic + @Column(name = "PSMStatusID") + public Short getPsmStatusId() { + return psmStatusId; + } + + public void setPsmStatusId(Short psmStatusId) { + this.psmStatusId = psmStatusId; + } + + @Basic + @Column(name = "PSMStatus") + public String getPsmStatus() { + return psmStatus; + } + + public void setPsmStatus(String psmStatus) { + this.psmStatus = psmStatus; + } + + @Basic + @Column(name = "UserServciceRoleDeleted") + public Boolean getUserServciceRoleDeleted() { + return userServciceRoleDeleted; + } + + public void setUserServciceRoleDeleted(Boolean userServciceRoleDeleted) { + this.userServciceRoleDeleted = userServciceRoleDeleted; + } + + @Basic + @Column(name = "UserDeleted") + public Boolean getUserDeleted() { + return userDeleted; + } + + public void setUserDeleted(Boolean userDeleted) { + this.userDeleted = userDeleted; + } + + @Basic + @Column(name = "ServiceProviderDeleted") + public Boolean getServiceProviderDeleted() { + return serviceProviderDeleted; + } + + public void setServiceProviderDeleted(Boolean serviceProviderDeleted) { + this.serviceProviderDeleted = serviceProviderDeleted; + } + + @Basic + @Column(name = "RoleDeleted") + public Boolean getRoleDeleted() { + return roleDeleted; + } + + public void setRoleDeleted(Boolean roleDeleted) { + this.roleDeleted = roleDeleted; + } + + @Basic + @Column(name = "ProviderServiceMappingDeleted") + public Boolean getProviderServiceMappingDeleted() { + return providerServiceMappingDeleted; + } + + public void setProviderServiceMappingDeleted(Boolean providerServiceMappingDeleted) { + this.providerServiceMappingDeleted = providerServiceMappingDeleted; + } + + @Basic + @Column(name = "isInbound") + public Boolean getInbound() { + return isInbound; + } + + public void setInbound(Boolean inbound) { + isInbound = inbound; + } + + @Basic + @Column(name = "isOutbound") + public Boolean getOutbound() { + return isOutbound; + } + + public void setOutbound(Boolean outbound) { + isOutbound = outbound; + } + + @Basic + @Column(name = "blockid") + public Integer getBlockid() { + return blockid; + } + + public void setBlockid(Integer blockid) { + this.blockid = blockid; + } + + @Basic + @Column(name = "blockname") + public String getBlockname() { + return blockname; + } + + public void setBlockname(String blockname) { + this.blockname = blockname; + } + + @Basic + @Column(name = "villageid") + public String getVillageid() { + return villageid; + } + + public void setVillageid(String villageid) { + this.villageid = villageid; + } + + @Basic + @Column(name = "villagename") + public String getVillagename() { + return villagename; + } + + public void setVillagename(String villagename) { + this.villagename = villagename; + } + +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java index 3415d91a..e41f8e80 100644 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java @@ -18,6 +18,8 @@ public class FieldResponseDTO { private String defaultValue; private String placeholder; private Integer sequence; + private Boolean isEditable; + private Integer stateCode; private List options; private Map validation; private Map conditional; diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java b/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java index df1c7184..c01ff197 100644 --- a/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java +++ b/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java @@ -19,6 +19,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.dto; +package com.iemr.common.dto.platform_feedback; public record CategoryResponse(String categoryId, String slug, String label, String scope, boolean active) {} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java index 7002ece9..02c52c3a 100644 --- a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java +++ b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java @@ -19,13 +19,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.dto; +package com.iemr.common.dto.platform_feedback; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; -import java.time.LocalDateTime; public record FeedbackRequest( @Min(1) @Max(5) int rating, diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java index 6b348f6e..51003353 100644 --- a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java +++ b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java @@ -19,7 +19,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.dto; +package com.iemr.common.dto.platform_feedback; import java.time.LocalDateTime; diff --git a/src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java b/src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java new file mode 100644 index 00000000..ab71d8cc --- /dev/null +++ b/src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java @@ -0,0 +1,114 @@ +package com.iemr.common.dto.sms; + +public class SMSTemplateDTO { + private Integer smsTemplateID; + private String smsTemplateName; + private String smsTemplate; + private String dltTemplateId; + private String smsSenderID; + private Integer smsTypeID; + private Integer providerServiceMapID; + private Boolean deleted; + private String createdBy; + private String modifiedBy; + private String createdDate; + private String lastModDate; + + // Getters and Setters for all fields + + public Integer getSmsTemplateID() { + return smsTemplateID; + } + + public void setSmsTemplateID(Integer smsTemplateID) { + this.smsTemplateID = smsTemplateID; + } + + public String getSmsTemplateName() { + return smsTemplateName; + } + + public void setSmsTemplateName(String smsTemplateName) { + this.smsTemplateName = smsTemplateName; + } + + public String getSmsTemplate() { + return smsTemplate; + } + + public void setSmsTemplate(String smsTemplate) { + this.smsTemplate = smsTemplate; + } + + public String getDltTemplateId() { + return dltTemplateId; + } + + public void setDltTemplateId(String dltTemplateId) { + this.dltTemplateId = dltTemplateId; + } + + public String getSmsSenderID() { + return smsSenderID; + } + + public void setSmsSenderID(String smsSenderID) { + this.smsSenderID = smsSenderID; + } + + public Integer getSmsTypeID() { + return smsTypeID; + } + + public void setSmsTypeID(Integer smsTypeID) { + this.smsTypeID = smsTypeID; + } + + public Integer getProviderServiceMapID() { + return providerServiceMapID; + } + + public void setProviderServiceMapID(Integer providerServiceMapID) { + this.providerServiceMapID = providerServiceMapID; + } + + public Boolean getDeleted() { + return deleted; + } + + public void setDeleted(Boolean deleted) { + this.deleted = deleted; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(String modifiedBy) { + this.modifiedBy = modifiedBy; + } + + public String getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(String createdDate) { + this.createdDate = createdDate; + } + + public String getLastModDate() { + return lastModDate; + } + + public void setLastModDate(String lastModDate) { + this.lastModDate = lastModDate; + } +} diff --git a/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java b/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java index 7fe629f1..1982a74f 100644 --- a/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java +++ b/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java @@ -21,7 +21,9 @@ */ package com.iemr.common.mapper.sms; +import java.text.SimpleDateFormat; import java.util.List; +import java.sql.Timestamp; import org.mapstruct.IterableMapping; import org.mapstruct.Mapper; @@ -33,6 +35,7 @@ import com.iemr.common.data.sms.SMSParametersMap; import com.iemr.common.data.sms.SMSTemplate; import com.iemr.common.data.sms.SMSType; +import com.iemr.common.dto.sms.SMSTemplateDTO; import com.iemr.common.model.sms.CreateSMSRequest; import com.iemr.common.model.sms.FullSMSTemplateResponse; import com.iemr.common.model.sms.SMSParameterMapModel; @@ -110,4 +113,25 @@ public interface SMSMapper @IterableMapping(elementTargetType = FullSMSTemplateResponse.class) List smsTemplateToFullResponse(List smsTemplate); + @Mapping(source = "smsTemplateID", target = "smsTemplateID") + @Mapping(source = "smsTemplateName", target = "smsTemplateName") + @Mapping(source = "smsTemplate", target = "smsTemplate") + @Mapping(source = "dltTemplateId", target = "dltTemplateId") + @Mapping(source = "smsSenderID", target = "smsSenderID") + @Mapping(source = "smsTypeID", target = "smsTypeID") + @Mapping(source = "providerServiceMapID", target = "providerServiceMapID") + @Mapping(source = "deleted", target = "deleted") + @Mapping(source = "createdBy", target = "createdBy") + @Mapping(source = "modifiedBy", target = "modifiedBy") + @Mapping(target = "createdDate", expression = "java(formatDate(template.getCreatedDate()))") + @Mapping(target = "lastModDate", expression = "java(formatDate(template.getLastModDate()))") + SMSTemplateDTO smsTemplateToDTO(SMSTemplate template); + + default String formatDate(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + return sdf.format(timestamp); + } } diff --git a/src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java b/src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java new file mode 100644 index 00000000..17eb2c13 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java @@ -0,0 +1,11 @@ +package com.iemr.common.repository.mmuDrugHistory; + +import com.iemr.common.data.mmuDrugHistory.PrescribedMMUDrugDetail; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PrescribedMMUDrugRepository extends CrudRepository { + PrescribedMMUDrugDetail findByPrescribedDrugID(Long prescribedDrugID); + +} diff --git a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java index 083ca5f7..43096490 100644 --- a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java +++ b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java @@ -21,11 +21,11 @@ */ package com.iemr.common.repository.platform_feedback; -import com.iemr.common.model.FeedbackCategory; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.iemr.common.data.platform_feedback.FeedbackCategory; @Repository public interface PlatformFeedbackCategoryRepository extends JpaRepository { diff --git a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java index fd00bdbc..020a7997 100644 --- a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java +++ b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java @@ -21,7 +21,7 @@ */ package com.iemr.common.repository.platform_feedback; -import com.iemr.common.model.Feedback; +import com.iemr.common.data.platform_feedback.Feedback; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java b/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java index 3ee48ab3..cc1abccc 100644 --- a/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java +++ b/src/main/java/com/iemr/common/repository/users/IEMRUserRepositoryCustom.java @@ -78,4 +78,7 @@ UserSecurityQMapping verifySecurityQuestionAnswers(@Param("UserID") Long UserID, User findByUserID(Long userID); + @Query("SELECT u FROM User u WHERE LOWER(u.userName) = LOWER(:userName)") + List findUserName(@Param("userName") String username); + } diff --git a/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java new file mode 100644 index 00000000..cfb85d0a --- /dev/null +++ b/src/main/java/com/iemr/common/repository/users/UserServiceRoleRepo.java @@ -0,0 +1,12 @@ +package com.iemr.common.repository.users; + +import com.iemr.common.data.users.UserServiceRole; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface UserServiceRoleRepo extends JpaRepository { + List findByUserName(String userName); +} diff --git a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java index 6e7848cd..e39cfcab 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserService.java @@ -38,6 +38,10 @@ String findByBeneficiaryPhoneNo(BenPhoneMap benPhoneMap, Integer pageNo, Integer String findBeneficiary(BeneficiaryModel request, String auth) throws Exception; + String searchUser(String searchQuery, Integer userId, String auth, Boolean is1097) throws Exception; + + String findBeneficiaryES(BeneficiaryModel i_beneficiary, Integer userId, String auth) throws Exception; + List userExitsCheckWithId(String beneficiaryID, String auth, Boolean is1097) throws Exception; public List userExitsCheckWithHealthId_ABHAId(String healthID, String auth, Boolean is1097) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java index f67d7815..28d664c8 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IEMRSearchUserServiceImpl.java @@ -25,6 +25,7 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import org.slf4j.Logger; @@ -76,7 +77,7 @@ import com.iemr.common.repository.userbeneficiarydata.MaritalStatusRepository; import com.iemr.common.repository.userbeneficiarydata.SexualOrientationRepository; import com.iemr.common.repository.userbeneficiarydata.TitleRepository; -import com.iemr.common.utils.mapper.OutputMapper; +import com.iemr.common.utils.exception.IEMRException; /** * @@ -198,7 +199,7 @@ private void addCreatedDateToOtherFields(BeneficiaryModel beneficiaryModel) { JsonNode otherFieldsNode = objectMapper.readTree(beneficiaryModel.getOtherFields()); // Convert createdDate to a string - String createdDateString = beneficiaryModel.getCreatedDate().toString(); + String createdDateString = beneficiaryModel.getCreatedDate().toString(); // Add createdDate to the JSON node ((ObjectNode) otherFieldsNode).put("createdDate", createdDateString); @@ -219,10 +220,10 @@ public List userExitsCheckWithHealthId_ABHAId(String healthID, List beneficiaryList = new ArrayList(); // search patient by ben id, call Identity API List listBen = null; - if(healthID.contains("@")) { + if (healthID.contains("@")) { listBen = identityBeneficiaryService.getBeneficiaryListByHealthID_ABHAAddress(healthID, auth, is1097); - }else { + } else { String healthIdNumber = getHealthId(healthID); listBen = identityBeneficiaryService.getBeneficiaryListByHealthIDNo_ABHAIDNo(healthIdNumber, auth, is1097); } @@ -232,6 +233,7 @@ public List userExitsCheckWithHealthId_ABHAId(String healthID, } return beneficiaryList; } + private String getHealthId(String healthID) { String healthIdNumber = null; if (null != healthID) { @@ -249,6 +251,7 @@ private String getHealthId(String healthID) { } return healthIdNumber; } + // search patient by healthidNo / ABHA Id No @Override public List userExitsCheckWithHealthIdNo_ABHAIdNo(String healthIDNo, String auth, Boolean is1097) @@ -322,6 +325,90 @@ private void setBeneficiaryGender(List iBeneficiary) { } + /** + * Universal search using Elasticsearch + */ + @Override + public String searchUser(String searchQuery, Integer userId, String auth, Boolean is1097) throws Exception { + + try { + if (searchQuery == null || searchQuery.trim().isEmpty()) { + throw new IEMRException("Search query is required"); + } + + logger.info("Universal search with query: {}, userId: {}", searchQuery, userId); + + Map response = identityBeneficiaryService.searchBeneficiariesUsingES( + searchQuery, userId, auth, is1097); + + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(response); + + } catch (Exception e) { + logger.error("Error in universal search", e); + throw new Exception("Error searching beneficiaries: " + e.getMessage(), e); + } + } + + /** + * Advanced search using Elasticsearch with multiple criteria + */ + + @Override + public String findBeneficiaryES( + BeneficiaryModel i_beneficiary, + Integer userId, + String auth) throws Exception { + + try { + IdentitySearchDTO identitySearchDTO = identityBenEditMapper.getidentitysearchModel(i_beneficiary); + + if (i_beneficiary.getDOB() != null) { + identitySearchDTO.setDob(i_beneficiary.getDOB()); + } + + if (i_beneficiary.getHouseHoldID() != null) { + identitySearchDTO.setHouseHoldID(i_beneficiary.getHouseHoldID()); + } + + if (i_beneficiary.getIsD2D() != null) { + identitySearchDTO.setIsD2D(i_beneficiary.getIsD2D()); + } + + if (i_beneficiary.getBenPhoneMaps() != null + && !i_beneficiary.getBenPhoneMaps().isEmpty()) { + identitySearchDTO.setContactNumber( + i_beneficiary.getBenPhoneMaps().get(0).getPhoneNo()); + } + + if (i_beneficiary.getBeneficiaryID() != null + && !i_beneficiary.getBeneficiaryID().isEmpty()) { + identitySearchDTO.setBeneficiaryId( + new BigInteger(i_beneficiary.getBeneficiaryID())); + } + + i_beneficiary.setIs1097(Boolean.TRUE.equals(i_beneficiary.getIs1097())); + + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd") + .create(); + + String requestJson = gson.toJson(identitySearchDTO); + + Map response = identityBeneficiaryService.searchBeneficiaryListES( + requestJson, + auth, + i_beneficiary.getIs1097()); + + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(response); + + } catch (Exception e) { + logger.error("Error in ES advance search", e); + throw new Exception("Error searching beneficiaries using ES", e); + } + } + // Advance search @Override public String findBeneficiary(BeneficiaryModel i_beneficiary, String auth) throws Exception { @@ -364,7 +451,7 @@ public String findBeneficiary(BeneficiaryModel i_beneficiary, String auth) throw + (beneficiaryList != null ? beneficiaryList.size() : "No Beneficiary Found")); ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(beneficiaryList); - + } // get response mapper @@ -374,7 +461,7 @@ public List getBeneficiaryListFromMapper(List { BeneficiaryModel beneficiary = benCompleteMapper.benDetailForOutboundDTOToIBeneficiary(beneficiaryModel); - if(null != beneficiaryModel && null != beneficiaryModel.getBeneficiaryDetails()) { + if (null != beneficiaryModel && null != beneficiaryModel.getBeneficiaryDetails()) { beneficiary.setCommunityName(beneficiaryModel.getBeneficiaryDetails().getCommunity()); beneficiary.setReligion(beneficiaryModel.getBeneficiaryDetails().getReligion()); beneficiary.setReligionName(beneficiaryModel.getBeneficiaryDetails().getReligion()); diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java index 8b84bc8a..41a132b0 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryService.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.List; +import java.util.Map; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; @@ -53,6 +54,8 @@ List getBeneficiaryListByBenRegID(Long benRegId, String auth, List searchBeneficiaryList(String identitySearchDTO, String auth, Boolean is1097) throws IEMRException; + public Map searchBeneficiaryListES(String identitySearchDTO, String auth, Boolean is1097) throws IEMRException ; + Integer editIdentityEditDTOCommunityorEducation(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException; @@ -69,4 +72,8 @@ public List getBeneficiaryListByFamilyId(String familyId, Stri public List getBeneficiaryListByGovId(String identity, String auth, Boolean is1097) throws IEMRException; + + public Map searchBeneficiariesUsingES(String query, Integer userId, String auth, Boolean is1097) throws IEMRException; + + } diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a79d3683..350f2527 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -21,15 +21,19 @@ */ package com.iemr.common.service.beneficiary; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import com.google.gson.*; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.iemr.common.dto.identity.BeneficiariesDTO; @@ -42,8 +46,13 @@ import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.mapper.OutputMapper; import com.iemr.common.utils.response.OutputResponse; + import org.springframework.beans.factory.annotation.Value; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + @Service public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryService { @@ -52,7 +61,6 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - @Value("${identity-api-url}") private String identityBaseURL; @Value("${identity-1097-api-url}") @@ -61,12 +69,10 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; @Value("${genben-api}") - private String BEN_GEN ; - + private String BEN_GEN; @Value("${generateBeneficiaryIDs-api-url}") - private String BEN_GEN_API_URL ; - + private String BEN_GEN_API_URL; @Override // public List getBeneficiaryListByIDs() {// search by regID @@ -90,13 +96,10 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String } if (null != result) { JsonObject responseObj = (JsonObject) parser.parse(result); - // JsonArray data = (JsonArray) parser.parse( JsonObject data1 = (JsonObject) responseObj.get("response"); String s = data1.get("data").getAsString(); JsonArray responseArray = parser.parse(s).getAsJsonArray(); - // String data="s"; - // JsonArray responseArray = (JsonArray) parser.parse(data); for (JsonElement jsonElement : responseArray) { @@ -109,10 +112,79 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String return listBenDetailForOutboundDTO; } + /** + * Call Identity API's Elasticsearch universal search + */ + @Override + public Map searchBeneficiariesUsingES(String query, Integer userId, String auth, Boolean is1097) + throws IEMRException { + + Map response = new HashMap<>(); + + try { + HashMap headers = new HashMap<>(); + if (auth != null && !auth.isEmpty()) { + headers.put("Authorization", auth); + } + + String baseUrl = ConfigProperties + .getPropertyByName("identity-api-url-searchByES") + .replace( + IDENTITY_BASE_URL, + (Boolean.TRUE.equals(is1097)) ? identity1097BaseURL : identityBaseURL + ); + + StringBuilder url = new StringBuilder(baseUrl) + .append("?query=").append(URLEncoder.encode(query, StandardCharsets.UTF_8)); + + if (userId != null) { + url.append("&userId=").append(userId); + } + + logger.info("Calling Identity ES search URL: {}", url); + + String result = httpUtils.get(url.toString()); + + if (result == null || result.isEmpty()) { + response.put("data", Collections.emptyList()); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + return response; + } + + ObjectMapper mapper = new ObjectMapper(); + + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false); + + JsonNode rootNode = mapper.readTree(result); + + if (rootNode.has("statusCode") && rootNode.get("statusCode").asInt() != 200) { + String errMsg = rootNode.has("errorMessage") + ? rootNode.get("errorMessage").asText() + : "Identity ES search failed"; + throw new IEMRException(errMsg); + } + + response.put("data", rootNode.path("data")); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + + return response; + + } catch (IEMRException e) { + throw e; + } catch (Exception e) { + logger.error("Error calling Identity ES search API", e); + throw new IEMRException("Error calling Identity ES search API"); + } + } + @Override public List getPartialBeneficiaryListByIDs(HashSet benIdList, String auth, Boolean is1097) throws IEMRException { - // TODO Auto-generated method stub List listBenDetailForOutboundDTO = new ArrayList<>(); JsonParser parser = new JsonParser(); @@ -132,13 +204,10 @@ public List getPartialBeneficiaryListByIDs(HashSet benI throw new IEMRException(identityResponse.getErrorMessage()); } JsonObject responseObj = (JsonObject) parser.parse(result); - // JsonArray data = (JsonArray) parser.parse( JsonObject data1 = (JsonObject) responseObj.get("response"); String s = data1.get("data").getAsString(); JsonArray responseArray = parser.parse(s).getAsJsonArray(); - // String data="s"; - // JsonArray responseArray = (JsonArray) parser.parse(data); for (JsonElement jsonElement : responseArray) { @@ -153,6 +222,9 @@ public List getPartialBeneficiaryListByIDs(HashSet benI // search beneficiaries by phone number public List getBeneficiaryListByPhone(String phoneNo, String auth, Boolean is1097) throws IEMRException { + logger.info("Phone no from getBeneficiaryListByPhone: " + phoneNo); + String cleanedPhoneNo = cleanPhoneNumber(phoneNo); + logger.info("Cleaned phone no: " + cleanedPhoneNo); List listBenDetailForOutboundDTO = new ArrayList<>(); @@ -164,8 +236,13 @@ public List getBeneficiaryListByPhone(String phoneNo, String a if (auth != null) { header.put("Authorization", auth); } + + logger.info("Result=" + (ConfigProperties.getPropertyByName("identity-api-url-getByPhoneNum") + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + cleanedPhoneNo); + result = httpUtils.post((ConfigProperties.getPropertyByName("identity-api-url-getByPhoneNum") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + phoneNo, "", header); + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + cleanedPhoneNo, "", + header); OutputResponse identityResponse = InputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { @@ -185,6 +262,25 @@ public List getBeneficiaryListByPhone(String phoneNo, String a return listBenDetailForOutboundDTO; } + private String cleanPhoneNumber(String phoneNumber) { + if (phoneNumber == null || phoneNumber.trim().isEmpty()) { + return phoneNumber; + } + + String cleaned = phoneNumber.trim(); + + // Remove +91 prefix + if (cleaned.startsWith("+91")) { + cleaned = cleaned.substring(3); + } + // Remove 91 prefix if it's a 12-digit number (91 + 10 digit mobile) + else if (cleaned.startsWith("91") && cleaned.length() == 12) { + cleaned = cleaned.substring(2); + } + + return cleaned.trim(); + } + @Override // search beneficiary by beneficiary id public List getBeneficiaryListByBenID(String benId, String auth, Boolean is1097) @@ -429,7 +525,6 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t return result; } - public Integer editIdentityEditDTO(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException { JsonParser parser = new JsonParser(); @@ -474,13 +569,10 @@ public List searchBeneficiaryList(String identitySearchDTO, St IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), identitySearchDTO, header); JsonObject responseObj = (JsonObject) parser.parse(result); - // JsonArray data = (JsonArray) parser.parse( JsonObject data1 = (JsonObject) responseObj.get("response"); String s = data1.get("data").getAsString(); JsonArray responseArray = parser.parse(s).getAsJsonArray(); - // String data="s"; - // JsonArray responseArray = (JsonArray) parser.parse(data); for (JsonElement jsonElement : responseArray) { @@ -492,6 +584,68 @@ public List searchBeneficiaryList(String identitySearchDTO, St return listBenDetailForOutboundDTO; } + @Override + public Map searchBeneficiaryListES(String identitySearchDTO, String auth, Boolean is1097) + throws IEMRException { + + Map response = new HashMap<>(); + + try { + HashMap headers = new HashMap<>(); + if (auth != null && !auth.isEmpty()) { + headers.put("Authorization", auth); + } + + String url = ConfigProperties + .getPropertyByName("identity-api-url-advancesearch-es") + .replace( + IDENTITY_BASE_URL, + Boolean.TRUE.equals(is1097) + ? identity1097BaseURL + : identityBaseURL); + + logger.info("Calling Identity ES Advance Search API"); + + String result = httpUtils.post(url, identitySearchDTO, headers); + + if (result == null || result.isEmpty()) { + response.put("data", Collections.emptyList()); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + return response; + } + + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + JsonNode rootNode = mapper.readTree(result); + + if (rootNode.has("statusCode") + && rootNode.get("statusCode").asInt() != 200) { + + String errMsg = rootNode.has("errorMessage") + ? rootNode.get("errorMessage").asText() + : "Identity ES advance search failed"; + + throw new IEMRException(errMsg); + } + + response.put("data", rootNode.path("data")); + response.put("statusCode", 200); + response.put("status", "Success"); + response.put("errorMessage", "Success"); + + return response; + + } catch (IEMRException e) { + throw e; + } catch (Exception e) { + logger.error("Error calling Identity ES advance search API", e); + throw new IEMRException("Error calling Identity ES advance search API", e); + } + } + @Override public Integer editIdentityEditDTOCommunityorEducation(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException { @@ -531,11 +685,11 @@ public List generateBeneficiaryIDs(String request, String a if (auth != null) { header.put("Authorization", auth); } - + logger.info("Request to generate ben IDs: " + request); logger.info("Generating ben IDs API URL: " + BEN_GEN + BEN_GEN_API_URL); result = httpUtils.post(BEN_GEN + BEN_GEN_API_URL, request, header); -logger.info("Response from generate ben IDs: " + result); + logger.info("Response from generate ben IDs: " + result); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { @@ -557,4 +711,4 @@ public List generateBeneficiaryIDs(String request, String a return listBen; } -} +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java b/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java index 1cf9ce32..7d2d7e62 100644 --- a/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java +++ b/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java @@ -42,11 +42,14 @@ import com.iemr.common.data.notification.Notification; import com.iemr.common.repository.callhandling.IEMRCalltypeRepositoryImplCustom; import com.iemr.common.utils.exception.IEMRException; +import com.iemr.common.utils.mapper.CallTypeMapper; import com.iemr.common.utils.mapper.InputMapper; @Service -public class CalltypeServiceImpl implements CalltypeService -{ +public class CalltypeServiceImpl implements CalltypeService { + + @Autowired + private CallTypeMapper callTypeMapper; private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); InputMapper inputMapper = new InputMapper(); @@ -55,9 +58,8 @@ public class CalltypeServiceImpl implements CalltypeService private IEMRCalltypeRepositoryImplCustom iEMRCalltypeRepositoryImplCustom; @Override - public List getAllCalltypes(String request) throws IEMRException - { - CallType provider = inputMapper.gson().fromJson(request, CallType.class); + public List getAllCalltypes(String request) throws IEMRException { + CallType provider = callTypeMapper.fromJson(request, CallType.class); List callTypes = new ArrayList(); Set callTypesArray = new HashSet(); if (provider.getIsInbound() != null && provider.getIsOutbound() != null) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java index 6d22e59a..e00663b7 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java @@ -15,8 +15,6 @@ public interface FormMasterService { FormDefinition createForm(FormDTO dto); List createField(List dto); FormField updateField(FieldDTO dto); - - FormResponseDTO getStructuredFormByFormId(String formId,String lang); - + FormResponseDTO getStructuredFormByFormId(String formId,String lang,String token); void deleteField(Long fieldId); } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index df019de7..acbcb4e7 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -1,38 +1,48 @@ package com.iemr.common.service.dynamicForm; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.iemr.common.data.dynamic_from.FormDefinition; import com.iemr.common.data.dynamic_from.FormField; import com.iemr.common.data.dynamic_from.FormModule; import com.iemr.common.data.translation.Translation; +import com.iemr.common.data.users.UserServiceRole; import com.iemr.common.dto.dynamicForm.*; import com.iemr.common.repository.dynamic_form.FieldRepository; import com.iemr.common.repository.dynamic_form.FormRepository; import com.iemr.common.repository.dynamic_form.ModuleRepository; import com.iemr.common.repository.translation.TranslationRepo; +import com.iemr.common.repository.users.UserServiceRoleRepo; +import com.iemr.common.utils.JwtUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.type.TypeReference; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @Service public class FormMasterServiceImpl implements FormMasterService { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired private ModuleRepository moduleRepo; - @Autowired private FormRepository formRepo; - @Autowired private FieldRepository fieldRepo; + @Autowired + private FormRepository formRepo; + @Autowired + private FieldRepository fieldRepo; @Autowired private TranslationRepo translationRepo; + @Autowired + private UserServiceRoleRepo userServiceRoleRepo; + + @Autowired + private JwtUtil jwtUtil; + @Override public FormModule createModule(ModuleDTO dto) { FormModule module = new FormModule(); @@ -85,7 +95,7 @@ public List createField(List dtoList) { public FormField updateField(FieldDTO dto) { FormField field = fieldRepo.findById(dto.getId()) .orElseThrow(() -> new IllegalArgumentException("Field not found: " + dto.getId())); - field.setId(dto.getId()); + field.setId(dto.getId()); field.setSectionTitle(dto.getSectionTitle()); field.setLabel(dto.getLabel()); field.setType(dto.getType()); @@ -103,96 +113,124 @@ public FormField updateField(FieldDTO dto) { } @Override - public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { - FormDefinition form = formRepo.findByFormId(formId) - .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); + public FormResponseDTO getStructuredFormByFormId(String formId, String lang, String token) { + Integer stateId = 0; + try { + String username = jwtUtil.getUsernameFromToken(token); - List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); - ObjectMapper objectMapper = new ObjectMapper(); + stateId = userServiceRoleRepo.findByUserName(username) + .stream() + .findFirst() + .map(UserServiceRole::getStateId) + .filter(Objects::nonNull) + .orElse(null); - List fieldDtos = fields.stream() - .map(field -> { - String labelKey = field.getFieldId(); // field label already contains label_key - Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) - .orElse(null); + FormDefinition form = formRepo.findByFormId(formId) + .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); - String translatedLabel = field.getLabel(); // fallback + List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); + ObjectMapper objectMapper = new ObjectMapper(); - if (t != null) { - if ("hi".equalsIgnoreCase(lang)) { - translatedLabel = t.getHindiTranslation(); - } else { - translatedLabel = t.getEnglish(); - } - } - - FieldResponseDTO dto = new FieldResponseDTO(); - dto.setId(field.getId()); - dto.setVisible(field.getIsVisible()); - dto.setFormId(field.getForm().getFormId()); - dto.setSectionTitle(field.getSectionTitle()); - dto.setFieldId(field.getFieldId()); - dto.setLabel(translatedLabel); - dto.setType(field.getType()); - dto.setIsRequired(field.getIsRequired()); - dto.setDefaultValue(field.getDefaultValue()); - dto.setPlaceholder(field.getPlaceholder()); - dto.setSequence(field.getSequence()); - - try { - // Handle options - if (field.getOptions() != null && !field.getOptions().isBlank()) { - JsonNode node = objectMapper.readTree(field.getOptions()); - List options = null; - if (node.isArray()) { - options = objectMapper.convertValue(node, new TypeReference<>() {}); - } else if (node.has("options")) { - options = objectMapper.convertValue(node.get("options"), new TypeReference<>() {}); - } - dto.setOptions(options == null || options.isEmpty() ? null : options); - } else { - dto.setOptions(null); - } + Integer finalStateId = stateId; + List fieldDtos = fields.stream().filter(formField -> (formField.getStateCode().equals(0) || formField.getStateCode().equals(finalStateId))) + .map(field -> { + String labelKey = field.getFieldId(); // field label already contains label_key - // Handle validation - if (field.getValidation() != null && !field.getValidation().isBlank()) { - Map validation = objectMapper.readValue(field.getValidation(), new TypeReference<>() {}); - dto.setValidation(validation.isEmpty() ? null : validation); - } else { - dto.setValidation(null); - } + Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) + .orElse(null); + + String translatedLabel = field.getLabel(); // fallback + + if (t != null) { + if ("hi".equalsIgnoreCase(lang)) { + translatedLabel = t.getHindiTranslation(); + } else if ("as".equalsIgnoreCase(lang)) { + translatedLabel = t.getAssameseTranslation(); + } else if ("en".equalsIgnoreCase(lang)) { + translatedLabel = t.getEnglish(); - // Handle conditional - if (field.getConditional() != null && !field.getConditional().isBlank()) { - Map conditional = objectMapper.readValue(field.getConditional(), new TypeReference<>() {}); - dto.setConditional(conditional.isEmpty() ? null : conditional); - } else { - dto.setConditional(null); + } } - } catch (Exception e) { - System.err.println("JSON Parsing Error in field: " + field.getFieldId()); - throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); - } + FieldResponseDTO dto = new FieldResponseDTO(); + dto.setId(field.getId()); + dto.setIsEditable(field.getIsEditable()); + dto.setStateCode(field.getStateCode()); + dto.setVisible(field.getIsVisible()); + dto.setFormId(field.getForm().getFormId()); + dto.setSectionTitle(field.getSectionTitle()); + dto.setFieldId(field.getFieldId()); + dto.setLabel(translatedLabel); + dto.setType(field.getType()); + dto.setIsRequired(field.getIsRequired()); + dto.setDefaultValue(field.getDefaultValue()); + dto.setPlaceholder(field.getPlaceholder()); + dto.setSequence(field.getSequence()); + + try { + // Handle options + if (field.getOptions() != null && !field.getOptions().isBlank()) { + JsonNode node = objectMapper.readTree(field.getOptions()); + List options = null; + if (node.isArray()) { + options = objectMapper.convertValue(node, new TypeReference<>() { + }); + } else if (node.has("options")) { + options = objectMapper.convertValue(node.get("options"), new TypeReference<>() { + }); + } + dto.setOptions(options == null || options.isEmpty() ? null : options); + } else { + dto.setOptions(null); + } - return dto; - }) - .sorted(Comparator.comparing(FieldResponseDTO::getId)) - .collect(Collectors.toList()); + // Handle validation + if (field.getValidation() != null && !field.getValidation().isBlank()) { + Map validation = objectMapper.readValue(field.getValidation(), new TypeReference<>() { + }); + dto.setValidation(validation.isEmpty() ? null : validation); + } else { + dto.setValidation(null); + } + // Handle conditional + if (field.getConditional() != null && !field.getConditional().isBlank()) { + Map conditional = objectMapper.readValue(field.getConditional(), new TypeReference<>() { + }); + dto.setConditional(conditional.isEmpty() ? null : conditional); + } else { + dto.setConditional(null); + } + } catch (Exception e) { - GroupedFieldResponseDTO singleSection = new GroupedFieldResponseDTO(); - singleSection.setSectionTitle(singleSection.getSectionTitle()); // your custom section title - singleSection.setFields(fieldDtos); + System.err.println("JSON Parsing Error in field: " + field.getFieldId()); + throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); + } - FormResponseDTO response = new FormResponseDTO(); - response.setVersion(form.getVersion()); - response.setFormId(form.getFormId()); - response.setFormName(form.getFormName()); - response.setSections(List.of(singleSection)); + return dto; + }) + .sorted(Comparator.comparing(FieldResponseDTO::getId)) + .collect(Collectors.toList()); + + + GroupedFieldResponseDTO singleSection = new GroupedFieldResponseDTO(); + singleSection.setFields(fieldDtos); + singleSection.setSectionTitle( + Objects.requireNonNullElse(singleSection.getSectionTitle(), "Section Title") + ); + FormResponseDTO response = new FormResponseDTO(); + response.setVersion(form.getVersion()); + response.setFormId(form.getFormId()); + response.setFormName(form.getFormName()); + response.setSections(List.of(singleSection)); + return response; + + } catch (Exception e) { + logger.error("Exception while building form response", e); + throw new RuntimeException("Failed to build form structure"); + } - return response; } diff --git a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java index 4297022a..43c5c1f2 100644 --- a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java +++ b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java @@ -89,6 +89,9 @@ public void setSubCategoryRepository(SubCategoryRepository subCategoryRepository @Value("${allowed.file.extensions}") private String allowedFileExtensions; + @Value("${tempFilePath}") + private String tempFilePath; + @Override public String getKMFileLists(String request) throws Exception { ObjectMapper objectMapper = new ObjectMapper(); @@ -183,7 +186,6 @@ private ArrayList addKMFile(Iterable kmFileManager .replace("}", "").replace("[", "").replace("]", "").replace("|", "").replace("\\", "") .replace(":", "").replace(";", "").replace("-", "").replace("_", "").replace("+", "") .replace("=", "").replace("\"", "").replace("'", "")); - String tempFilePath = ConfigProperties.getPropertyByName("tempFilePath"); newFile = new FileOutputStream(tempFilePath + "/" + kmFileManager.getFileName()); newFile.write(Base64.getDecoder().decode(kmFileManager.getFileContent())); newFile.flush(); diff --git a/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java b/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java index 5149e3ed..c4cccb42 100644 --- a/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java +++ b/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java @@ -19,11 +19,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.service; +package com.iemr.common.service.platform_feedback; -import com.iemr.common.dto.*; -import com.iemr.common.model.Feedback; -import com.iemr.common.model.FeedbackCategory; +import com.iemr.common.data.platform_feedback.Feedback; +import com.iemr.common.data.platform_feedback.FeedbackCategory; +import com.iemr.common.dto.platform_feedback.CategoryResponse; +import com.iemr.common.dto.platform_feedback.FeedbackRequest; +import com.iemr.common.dto.platform_feedback.FeedbackResponse; import com.iemr.common.repository.platform_feedback.PlatformFeedbackCategoryRepository; import com.iemr.common.repository.platform_feedback.PlatformFeedbackRepository; import com.iemr.common.exception.BadRequestException; diff --git a/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java b/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java index af9cbf1c..efe0d16a 100644 --- a/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java +++ b/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java @@ -68,6 +68,7 @@ import com.iemr.common.data.location.States; import com.iemr.common.data.mctshistory.MctsDataReaderDetail; import com.iemr.common.data.mctshistory.MctsOutboundCall; +import com.iemr.common.data.mmuDrugHistory.PrescribedMMUDrugDetail; import com.iemr.common.data.sms.SMSNotification; import com.iemr.common.data.sms.SMSParameters; import com.iemr.common.data.sms.SMSParametersMap; @@ -76,6 +77,7 @@ import com.iemr.common.data.telemedicine.PrescribedDrugDetail; import com.iemr.common.data.users.User; import com.iemr.common.data.videocall.VideoCallParameters; +import com.iemr.common.dto.sms.SMSTemplateDTO; import com.iemr.common.mapper.sms.SMSMapper; import com.iemr.common.model.beneficiary.BeneficiaryModel; import com.iemr.common.model.sms.CreateSMSRequest; @@ -95,6 +97,7 @@ import com.iemr.common.repository.location.LocationDistrictRepository; import com.iemr.common.repository.location.LocationStateRepository; import com.iemr.common.repository.mctshistory.OutboundHistoryRepository; +import com.iemr.common.repository.mmuDrugHistory.PrescribedMMUDrugRepository; import com.iemr.common.repository.sms.SMSNotificationRepository; import com.iemr.common.repository.sms.SMSParameterMapRepository; import com.iemr.common.repository.sms.SMSParameterRepository; @@ -164,6 +167,9 @@ public class SMSServiceImpl implements SMSService { @Autowired PrescribedDrugRepository prescribedDrugRepository; + @Autowired + PrescribedMMUDrugRepository prescribedMMUDrugRepository; + @Autowired OutboundHistoryRepository outboundHistoryRepository; @@ -218,10 +224,16 @@ public String saveSMSTemplate(CreateSMSRequest smsRequest) throws Exception { } SMSTemplate smsTemplate; SMSTemplate request = smsMapper.createRequestToSMSTemplate(smsRequest); - smsTemplate = smsTemplateRepository.save(request); - saveSMSParameterMaps(smsRequest, smsTemplate.getSmsTemplateID()); - smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplate.getSmsTemplateID()); - return OutputMapper.gsonWithoutExposeRestriction().toJson(smsMapper.smsTemplateToResponse(smsTemplate)); + SMSTemplate savedTemplate = smsTemplateRepository.save(request); + + saveSMSParameterMaps(smsRequest, savedTemplate.getSmsTemplateID()); + + + SMSTemplate fetchedTemplate = smsTemplateRepository.findBySmsTemplateID(savedTemplate.getSmsTemplateID()); + + SMSTemplateDTO responseDTO = smsMapper.smsTemplateToDTO(fetchedTemplate); + + return OutputMapper.gsonWithoutExposeRestriction().toJson(responseDTO); } /** @@ -267,7 +279,13 @@ private void saveSMSParameterMaps(CreateSMSRequest smsRequest, Integer smsTempla List smsParameterMapModels = smsRequest.getSmsParameterMaps(); for (SMSParameterMapModel smsParameterMapModel : smsParameterMapModels) { smsParameterMapModel.setSmsTemplateID(smsTemplateID); - smsParameterMapRepository.save(smsMapper.smsParameterMapModelToSMSParametersMap(smsParameterMapModel)); + SMSParametersMap entity = smsMapper.smsParameterMapModelToSMSParametersMap(smsParameterMapModel); + + if (entity.getCreatedBy() == null) { + entity.setCreatedBy(smsRequest.getCreatedBy()); + } + + SMSParametersMap savedEntity = smsParameterMapRepository.save(entity); } } @@ -684,61 +702,64 @@ private SMSNotification prepareSMS( String methodName = smsParametersMap.getSmsParameter().getDataName(); // DataVariableName String variableValue = ""; switch (paramType) { - case "Beneficiary": - variableValue = getBeneficiaryData(className, methodName, request, beneficiary); - benID = variableValue; - break; - case "Institute": - if (request.getIs1097() == true) { - variableValue = getInstituteData(className, methodName, request, authToken); - } else { - variableValue = getDirectoryserviceData(className, methodName, request); - } - break; - case "User": - variableValue = getUserData(className, methodName, request, authToken); - break; - case "Feedback": - variableValue = getFeedbackData(className, methodName, request, authToken); - break; - case "Prescription": - variableValue = getPrescriptionData(className, methodName, request, beneficiary); - break; - case "Blood on Call": - variableValue = getBloodOnCallData(className, methodName, request, beneficiary); - break; - case "Food Safety Complaint": - variableValue = getFoodSafetyComplaintData(className, methodName, request); - break; - case "Epidemic Outbreak Complaint": - variableValue = getEpidemicComplaintData(className, methodName, request); - break; - case "Grievance Tracking": - variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); - break; - case "MCTS Call Alert": - variableValue = getMCTSCallAlertData(className, methodName, request); - break; - case "Organ Donation": - variableValue = getOrganDonationData(className, methodName, request); - break; - case "TM Schedule": - variableValue = getSpecializationAndTcDateInfo(className, methodName, request); - break; - case "COVID-19": - variableValue = getCOVIDData(className, methodName, request); - break; - case "IMRMMR": - variableValue = getIMRMMRData(className, methodName, request); - break; - case "104 appointment": - variableValue = getUptsuData(className, methodName, request); - break; - case "Grievance": - variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); - break; - default: - break; + case "Beneficiary": + variableValue = getBeneficiaryData(className, methodName, request, beneficiary); + benID = variableValue; + break; + case "Institute": + if (request.getIs1097() == true) { + variableValue = getInstituteData(className, methodName, request, authToken); + } else { + variableValue = getDirectoryserviceData(className, methodName, request); + } + break; + case "User": + variableValue = getUserData(className, methodName, request, authToken); + break; + case "Feedback": + variableValue = getFeedbackData(className, methodName, request, authToken); + break; + case "Prescription": + variableValue = getPrescriptionData(className, methodName, request, beneficiary); + break; + case "Blood on Call": + variableValue = getBloodOnCallData(className, methodName, request, beneficiary); + break; + case "Food Safety Complaint": + variableValue = getFoodSafetyComplaintData(className, methodName, request); + break; + case "Epidemic Outbreak Complaint": + variableValue = getEpidemicComplaintData(className, methodName, request); + break; + case "Grievance Tracking": + variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); + break; + case "MCTS Call Alert": + variableValue = getMCTSCallAlertData(className, methodName, request); + break; + case "Organ Donation": + variableValue = getOrganDonationData(className, methodName, request); + break; + case "TM Schedule": + variableValue = getSpecializationAndTcDateInfo(className, methodName, request); + break; + case "COVID-19": + variableValue = getCOVIDData(className, methodName, request); + break; + case "IMRMMR": + variableValue = getIMRMMRData(className, methodName, request); + break; + case "104 appointment": + variableValue = getUptsuData(className, methodName, request); + break; + case "Grievance": + variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); + break; + case "MMUPrescription": + variableValue = getMMUPrescriptionData(className, methodName, request, beneficiary); + break; + default: + break; } if (variable.equalsIgnoreCase("SMS_PHONE_NO")) { if (request.getIsBloodBankSMS() == true) { @@ -1304,6 +1325,108 @@ private String getEpidemicComplaintData(String className, String methodName, SMS return variableValue; } + private String getMMUPrescriptionData(String className, String methodName, SMSRequest request, + BeneficiaryModel beneficiary) throws NoSuchMethodException, SecurityException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, ClassNotFoundException { + PrescribedMMUDrugDetail prescribedMMUDrug = prescribedMMUDrugRepository + .findByPrescribedDrugID(request.getPrescribedDrugID()); + String variableValue = ""; + switch (methodName.toLowerCase()) { + case "diagnosis": + // Format: "Diagnosis, DrugName(DrugStrength)" + StringBuilder diagnosisBuilder = new StringBuilder(); + + // Add diagnosis + String diagnosis = prescribedMMUDrug.getPrescription() != null + && prescribedMMUDrug.getPrescription().getDiagnosisProvided() != null + ? prescribedMMUDrug.getPrescription().getDiagnosisProvided().trim() + : ""; + + if (!diagnosis.isEmpty()) { + diagnosisBuilder.append(diagnosis); + } + + // Add drug name with strength + String drugName = prescribedMMUDrug.getDrugName(); + String drugStrength = prescribedMMUDrug.getDrugStrength(); + + if (drugName != null && !drugName.trim().isEmpty()) { + if (diagnosisBuilder.length() > 0) { + diagnosisBuilder.append(", "); + } + diagnosisBuilder.append(drugName.trim()); + + if (drugStrength != null && !drugStrength.trim().isEmpty()) { + diagnosisBuilder.append(" (").append(drugStrength.trim()).append(")"); + } + } + + variableValue = diagnosisBuilder.toString(); + break; + case "dosage": + // Format: "duration unit, dose, frequency" + StringBuilder dosageBuilder = new StringBuilder(); + + // Add duration with unit + String duration = prescribedMMUDrug.getDuration(); + String unit = prescribedMMUDrug.getUnit(); + + if (duration != null && !duration.trim().isEmpty()) { + dosageBuilder.append(duration.trim()); + if (unit != null && !unit.trim().isEmpty()) { + dosageBuilder.append(" ").append(unit.trim()); + } + } + + // Add dose + String dose = prescribedMMUDrug.getDose(); + if (dose != null && !dose.trim().isEmpty()) { + if (dosageBuilder.length() > 0) { + dosageBuilder.append(", "); + } + dosageBuilder.append(dose.trim()); + } + + // Add frequency + String frequency = prescribedMMUDrug.getFrequency(); + if (frequency != null && !frequency.trim().isEmpty()) { + if (dosageBuilder.length() > 0) { + dosageBuilder.append(", "); + } + dosageBuilder.append(frequency.trim()); + } + + variableValue = dosageBuilder.toString(); + break; + + case "by": + // Format: "route, By: CreatedBy" + StringBuilder doctorBuilder = new StringBuilder(); + + // Add route + String route = prescribedMMUDrug.getRoute(); + if (route != null && !route.trim().isEmpty()) { + doctorBuilder.append(route.trim()); + } + + // Add created by + String createdBy = prescribedMMUDrug.getCreatedBy(); + if (createdBy != null && !createdBy.trim().isEmpty()) { + if (doctorBuilder.length() > 0) { + doctorBuilder.append(", "); + } + doctorBuilder.append("By: ").append(createdBy.trim()); + } + + variableValue = doctorBuilder.toString(); + break; + default: + break; + } + return variableValue; + } + + private String getGrievanceData(String className, String methodName, SMSRequest request, String authToken, BeneficiaryModel beneficiary) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { diff --git a/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java b/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java index 115970ed..eff5c8e4 100644 --- a/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java +++ b/src/main/java/com/iemr/common/service/users/EmployeeSignatureServiceImpl.java @@ -33,8 +33,6 @@ public class EmployeeSignatureServiceImpl implements EmployeeSignatureService { @Autowired EmployeeSignatureRepo employeeSignatureRepo; - - @Override public EmployeeSignature fetchSignature(Long userSignID) { // TODO Auto-generated method stub @@ -44,12 +42,12 @@ public EmployeeSignature fetchSignature(Long userSignID) { @Override public EmployeeSignature fetchActiveSignature(Long userSignID) { // New method - fetches only non-deleted records - return employeeSignatureRepo.findOneByUserIDAndDeleted(userSignID, false); + return employeeSignatureRepo.findOneByUserID(userSignID); } public Boolean existSignature(Long userID) { // TODO Auto-generated method stub - return employeeSignatureRepo.countByUserIDAndSignatureNotNull(userID)>0; + return employeeSignatureRepo.countByUserIDAndSignatureNotNull(userID) > 0; } } diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java index d7dc6e2e..26b7bb15 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java @@ -123,6 +123,8 @@ public List getUserServiceRoleMappingForProvider(Integ List getUserIdbyUserName(String userName) throws IEMRException; + List findUserIdByUserName(String userName) throws IEMRException; + } diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java index 44bd2247..71d72c97 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java @@ -1224,4 +1224,10 @@ public List getUserIdbyUserName(String userName) { return iEMRUserRepositoryCustom.findByUserName(userName); } + + @Override + public List findUserIdByUserName(String userName) { + + return iEMRUserRepositoryCustom.findUserName(userName); + } } diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index d8414968..5d37a990 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -2,6 +2,7 @@ import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -161,4 +162,58 @@ public String getUserIdFromToken(String token) { public long getRefreshTokenExpiration() { return REFRESH_EXPIRATION_TIME; } + + /** + * Extract user ID from JWT token in the request (checks header and cookie) + * @param request the HTTP request + * @return the user ID, or null if not found + */ +public Integer getUserIdFromRequest(HttpServletRequest request) { + try { + String jwtToken = request.getHeader("Jwttoken"); + String cookieToken = CookieUtil.getJwtTokenFromCookie(request); + + // Prefer header token, fallback to cookie + String token = (jwtToken != null && !jwtToken.isEmpty()) ? jwtToken : cookieToken; + + if (token == null || token.isEmpty()) { + return null; + } + + Claims claims = validateToken(token); + if (claims == null) { + return null; + } + + String userId = claims.get("userId", String.class); + return userId != null ? Integer.parseInt(userId) : null; + + } catch (Exception e) { + return null; + } +} + +/** + * Extract username from JWT token in the request (checks header and cookie) + * @param request the HTTP request + * @return the username, or null if not found + */ +public String getUsernameFromRequest(HttpServletRequest request) { + try { + String jwtToken = request.getHeader("Jwttoken"); + String cookieToken = CookieUtil.getJwtTokenFromCookie(request); + + String token = (jwtToken != null && !jwtToken.isEmpty()) ? jwtToken : cookieToken; + + if (token == null || token.isEmpty()) { + return null; + } + + Claims claims = validateToken(token); + return claims != null ? claims.getSubject() : null; + + } catch (Exception e) { + return null; + } +} } diff --git a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java index c8299fe7..4e4fa483 100644 --- a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java +++ b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java @@ -39,6 +39,8 @@ public static HttpEntity createRequestEntity(Object body, String authori headers.add(HttpHeaders.AUTHORIZATION, authorization); if (null != requestHeader.getHeader(Constants.JWT_TOKEN)) { headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); + headers.add(HttpHeaders.COOKIE, "Jwttoken=" + requestHeader.getHeader(Constants.JWT_TOKEN)); + } if (null != jwtTokenFromCookie) { headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie); @@ -77,9 +79,10 @@ public static void getJwttokenFromHeaders(HttpHeaders headers) { if (null != jwtTokenFromCookie) { headers.add(HttpHeaders.COOKIE, Constants.JWT_TOKEN + "=" + jwtTokenFromCookie); } else if (null != requestHeader.getHeader(Constants.JWT_TOKEN)) { - headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); - } + headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); + headers.add(HttpHeaders.COOKIE, Constants.JWT_TOKEN + "=" + requestHeader.getHeader(Constants.JWT_TOKEN)); + } } } diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 0c609839..b4aaad60 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -36,10 +36,14 @@ import com.iemr.common.utils.sessionobject.SessionObject; import com.iemr.common.utils.validator.Validator; +import com.iemr.common.utils.JwtUtil; +import io.jsonwebtoken.Claims; +import com.iemr.common.utils.CookieUtil; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + @Configuration @Component public class HTTPRequestInterceptor implements HandlerInterceptor { @@ -50,6 +54,9 @@ public class HTTPRequestInterceptor implements HandlerInterceptor { @Value("${cors.allowed-origins}") private String allowedOrigins; + @Autowired + private JwtUtil jwtUtil; + @Autowired public void setValidator(Validator validator) { this.validator = validator; @@ -67,100 +74,101 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons boolean status = true; logger.info("In info preHandle we are Intercepting the Request"); logger.debug("In preHandle we are Intercepting the Request"); - // String authorization = request.getHeader("Authorization"); + // String authorization = request.getHeader("Authorization"); String authorization = null; String preAuth = request.getHeader("Authorization"); - if(null != preAuth && preAuth.contains("Bearer ")) - authorization=preAuth.replace("Bearer ", ""); + if (null != preAuth && preAuth.contains("Bearer ")) + authorization = preAuth.replace("Bearer ", ""); else authorization = preAuth; - + if (authorization == null || authorization.isEmpty()) { - logger.info("Authorization header is null or empty. Skipping HTTPRequestInterceptor."); - return true; // Allow the request to proceed without validation - } - logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization + logger.info("Authorization header is null or empty. Skipping HTTPRequestInterceptor."); + return true; // Allow the request to proceed without validation + } + + logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization + " || method :: " + request.getMethod()); if (!request.getMethod().equalsIgnoreCase("OPTIONS")) { try { String[] requestURIParts = request.getRequestURI().split("/"); String requestAPI = requestURIParts[requestURIParts.length - 1]; switch (requestAPI) { - case "userAuthenticate": - case "superUserAuthenticate": - case "userAuthenticateNew": - case "userAuthenticateV1": - case "forgetPassword": - case "setForgetPassword": - case "changePassword": - case "saveUserSecurityQuesAns": - case "doAgentLogout": - case "userLogout": - case "swagger-ui.html": - case "index.html": - case "index.css": - case "swagger-initializer.js": - case "swagger-config": - case "swagger-ui-bundle.js": - case "swagger-ui.css": - case "ui": - case "swagger-ui-standalone-preset.js": - case "favicon-32x32.png": - case "favicon-16x16.png": - case "swagger-resources": - case "api-docs": - case "updateBenCallIdsInPhoneBlock": - case "userAuthenticateByEncryption": - case "sendOTP": - case "validateOTP": - case "resendOTP": - case "validateSecurityQuestionAndAnswer": - case "logOutUserFromConcurrentSession": - case "refreshToken": - break; - case "error": - status = false; - break; - default: - String remoteAddress = request.getHeader("X-FORWARDED-FOR"); - if (remoteAddress == null || remoteAddress.trim().length() == 0) { - remoteAddress = request.getRemoteAddr(); - } - validator.checkKeyExists(authorization, remoteAddress); - break; + case "userAuthenticate": + case "superUserAuthenticate": + case "userAuthenticateNew": + case "userAuthenticateV1": + case "forgetPassword": + case "setForgetPassword": + case "changePassword": + case "saveUserSecurityQuesAns": + case "doAgentLogout": + case "userLogout": + case "swagger-ui.html": + case "index.html": + case "index.css": + case "swagger-initializer.js": + case "swagger-config": + case "swagger-ui-bundle.js": + case "swagger-ui.css": + case "ui": + case "swagger-ui-standalone-preset.js": + case "favicon-32x32.png": + case "favicon-16x16.png": + case "swagger-resources": + case "api-docs": + case "updateBenCallIdsInPhoneBlock": + case "userAuthenticateByEncryption": + case "sendOTP": + case "validateOTP": + case "resendOTP": + case "validateSecurityQuestionAndAnswer": + case "logOutUserFromConcurrentSession": + case "refreshToken": + break; + case "error": + status = false; + break; + default: + String remoteAddress = request.getHeader("X-FORWARDED-FOR"); + if (remoteAddress == null || remoteAddress.trim().length() == 0) { + remoteAddress = request.getRemoteAddr(); + } + validator.checkKeyExists(authorization, remoteAddress); + break; } } catch (Exception e) { logger.error("Authorization failed: {}", e.getMessage(), e); - String errorMessage = e.getMessage(); - if (errorMessage == null || errorMessage.trim().isEmpty()) { - errorMessage = "Unauthorized access or session expired."; - } - - String jsonErrorResponse = "{" - + "\"status\": \"Unauthorized\"," - + "\"statusCode\": 401," - + "\"errorMessage\": \"" + errorMessage.replace("\"", "\\\"") + "\"" - + "}"; - - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 - response.setContentType(MediaType.APPLICATION_JSON); - - String origin = request.getHeader("Origin"); - if (origin != null && isOriginAllowed(origin)) { - response.setHeader("Access-Control-Allow-Origin", origin); - response.setHeader("Access-Control-Allow-Credentials", "true"); - } else if (origin != null) { - logger.warn("CORS headers NOT added for error response | Unauthorized origin: {}", origin); - } - - // Better to use getBytes().length for accurate byte size - byte[] responseBytes = jsonErrorResponse.getBytes(StandardCharsets.UTF_8); - response.setContentLength(responseBytes.length); - - ServletOutputStream out = response.getOutputStream(); - out.write(responseBytes); - out.flush(); + String errorMessage = e.getMessage(); + if (errorMessage == null || errorMessage.trim().isEmpty()) { + errorMessage = "Unauthorized access or session expired."; + } + + String jsonErrorResponse = "{" + + "\"status\": \"Unauthorized\"," + + "\"statusCode\": 401," + + "\"errorMessage\": \"" + errorMessage.replace("\"", "\\\"") + "\"" + + "}"; + + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 + response.setContentType(MediaType.APPLICATION_JSON); + + String origin = request.getHeader("Origin"); + if (origin != null && isOriginAllowed(origin)) { + response.setHeader("Access-Control-Allow-Origin", origin); + response.setHeader("Access-Control-Allow-Credentials", "true"); + } else if (origin != null) { + logger.warn("CORS headers NOT added for error response | Unauthorized origin: {}", origin); + } + + // Better to use getBytes().length for accurate byte size + byte[] responseBytes = jsonErrorResponse.getBytes(StandardCharsets.UTF_8); + response.setContentLength(responseBytes.length); + + ServletOutputStream out = response.getOutputStream(); + out.write(responseBytes); + out.flush(); status = false; } } @@ -172,15 +180,14 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response, throws Exception { try { logger.debug("In postHandle we are Intercepting the Request"); - // String authorization = request.getHeader("Authorization"); String authorization = null; String postAuth = request.getHeader("Authorization"); - if(null != postAuth && postAuth.contains("Bearer ")) - authorization=postAuth.replace("Bearer ", ""); + if (null != postAuth && postAuth.contains("Bearer ")) + authorization = postAuth.replace("Bearer ", ""); else authorization = postAuth; logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); - + if (authorization != null && !authorization.equals("")) { sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); } @@ -212,8 +219,10 @@ private boolean isOriginAllowed(String origin) { .anyMatch(pattern -> { String regex = pattern .replace(".", "\\.") - .replace("*", ".*"); + .replace("*", ".*"); return origin.matches(regex); }); } + + } diff --git a/src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java b/src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java new file mode 100644 index 00000000..ace82367 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java @@ -0,0 +1,43 @@ +package com.iemr.common.utils.mapper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +@Service +public class CallTypeMapper { + private static GsonBuilder builder; + private static Gson gsonInstance; + private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); + + public CallTypeMapper() { + if (builder == null) { + builder = new GsonBuilder(); + // Only serialize/deserialize fields with @Expose annotation + builder.excludeFieldsWithoutExposeAnnotation(); + + logger.info("CallTypeMapper initialized - Only @Expose fields will be processed"); + } + } + + public static Gson gson() { + if (gsonInstance == null) { + gsonInstance = builder.create(); + } + return gsonInstance; + } + + public T fromJson(String json, Class classOfT) { + try { + T result = gson().fromJson(json, classOfT); + logger.info("Successfully deserialized to class: {}", classOfT.getSimpleName()); + return result; + } catch (Exception e) { + logger.error("Error deserializing JSON to {}: {}", classOfT.getSimpleName(), e.getMessage(), e); + throw e; + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 18723465..868ab464 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -27,8 +27,6 @@ BeneficiarySmsTemplate=Beneficiary UPTSU SMS ######Project specific settings future-days=7 -## Path where the files would be stored before uploading to KM server -tempFilePath=c:/temp/ ## swaasa file path lungAssessmentPath=c:/swaasa_audio/ @@ -110,6 +108,7 @@ iemr.extend.expiry.time.changePassword=true iemr.session.expiry.time.changePassword=600 identity-api-url-advancesearch =IDENTITY_BASE_URL/id/advanceSearch +identity-api-url-advancesearch-es =IDENTITY_BASE_URL/beneficiary/advancedSearchES identity-api-url-getByBenRegIdList =IDENTITY_BASE_URL/id/getByBenRegIdList identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenRegIdList identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= @@ -118,6 +117,7 @@ identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity +identity-api-url-searchByES=IDENTITY_BASE_URL/beneficiary/search identity-api-url-getByFamilyId=IDENTITY_BASE_URL/id/searchByFamilyId?familyId= identity-api-url-getByGovIdentity=IDENTITY_BASE_URL/id/searchByGovIdentity?identity= From 1cc3888615fcd35ed7ebe533e701cb65b857a425 Mon Sep 17 00:00:00 2001 From: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:54:42 +0530 Subject: [PATCH 36/47] fix: add OTP rate limiting to prevent OTP flooding on sendConsent endpoint (#373) - Add OtpRateLimiterService with Redis-backed per-mobile rate limits (3/min, 10/hr, 20/day) - Add OtpRateLimitException for 429 responses - Integrate rate limiter in BeneficiaryOTPHandlerImpl and BeneficiaryConsentController - Add otp.ratelimit.* properties to common_ci and common_docker profiles - Update common_example.properties with new OTP rate limit config Co-authored-by: Claude Sonnet 4.6 --- pom.xml | 2 +- src/main/environment/common_ci.properties | 4 + src/main/environment/common_docker.properties | 4 + .../environment/common_example.properties | 5 + .../BeneficiaryConsentController.java | 8 +- .../exception/OtpRateLimitException.java | 30 +++++ .../BeneficiaryOTPHandlerImpl.java | 5 + .../service/otp/OtpRateLimiterService.java | 104 ++++++++++++++++++ 8 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/iemr/common/exception/OtpRateLimitException.java create mode 100644 src/main/java/com/iemr/common/service/otp/OtpRateLimiterService.java diff --git a/pom.xml b/pom.xml index 171ab162..6a821d7d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.1 + 3.8.0 war Common-API diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 9f54a35d..f2b774a3 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -203,5 +203,9 @@ platform.feedback.ratelimit.day-limit=@env.PLATFORM_FEEDBACK_RATELIMIT_DAY_LIMIT platform.feedback.ratelimit.user-day-limit=@env.PLATFORM_FEEDBACK_RATELIMIT_USER_DAY_LIMIT@ platform.feedback.ratelimit.fail-window-minutes=@env.PLATFORM_FEEDBACK_RATELIMIT_FAIL_WINDOW_MINUTES@ platform.feedback.ratelimit.backoff-minutes=@env.PLATFORM_FEEDBACK_RATELIMIT_BACKOFF_MINUTES@ +otp.ratelimit.enabled=@env.OTP_RATELIMIT_ENABLED@ +otp.ratelimit.minute-limit=@env.OTP_RATELIMIT_MINUTE_LIMIT@ +otp.ratelimit.hour-limit=@env.OTP_RATELIMIT_HOUR_LIMIT@ +otp.ratelimit.day-limit=@env.OTP_RATELIMIT_DAY_LIMIT@ generateBeneficiaryIDs-api-url=@env.GEN_BENEFICIARY_IDS_API_URL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 59cb580d..a5c633e4 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -206,4 +206,8 @@ platform.feedback.ratelimit.day-limit=${PLATFORM_FEEDBACK_RATELIMIT_DAY_LIMIT} platform.feedback.ratelimit.user-day-limit=${PLATFORM_FEEDBACK_RATELIMIT_USER_DAY_LIMIT} platform.feedback.ratelimit.fail-window-minutes=${PLATFORM_FEEDBACK_RATELIMIT_FAIL_WINDOW_MINUTES} platform.feedback.ratelimit.backoff-minutes=${PLATFORM_FEEDBACK_RATELIMIT_BACKOFF_MINUTES} +otp.ratelimit.enabled=${OTP_RATELIMIT_ENABLED} +otp.ratelimit.minute-limit=${OTP_RATELIMIT_MINUTE_LIMIT} +otp.ratelimit.hour-limit=${OTP_RATELIMIT_HOUR_LIMIT} +otp.ratelimit.day-limit=${OTP_RATELIMIT_DAY_LIMIT} generateBeneficiaryIDs-api-url={GEN_BENEFICIARY_IDS_API_URL} diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index 03f0d915..e3b5c031 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -226,5 +226,10 @@ platform.feedback.ratelimit.user-day-limit=50 platform.feedback.ratelimit.fail-window-minutes=5 platform.feedback.ratelimit.backoff-minutes=15 +# --- OTP Rate Limiting (per mobile number) --- +otp.ratelimit.minute-limit=3 +otp.ratelimit.hour-limit=10 +otp.ratelimit.day-limit=20 + ### generate Beneficiary IDs URL generateBeneficiaryIDs-api-url=/generateBeneficiaryController/generateBeneficiaryIDs diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index 77492d89..8750c0a1 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -22,6 +22,7 @@ package com.iemr.common.controller.beneficiaryConsent; import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.exception.OtpRateLimitException; import com.iemr.common.service.beneficiaryOTPHandler.BeneficiaryOTPHandler; import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.response.OutputResponse; @@ -58,7 +59,9 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody logger.info(success.toString()); response.setResponse(success); - + } catch (OtpRateLimitException e) { + logger.warn("OTP rate limit hit for sendConsent: " + e.getMessage()); + response.setError(429, e.getMessage()); } catch (Exception e) { response.setError(500, "error : " + e); } @@ -105,6 +108,9 @@ public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBod else response.setError(500, "failure"); + } catch (OtpRateLimitException e) { + logger.warn("OTP rate limit hit for resendConsent: " + e.getMessage()); + response.setError(429, e.getMessage()); } catch (Exception e) { logger.error("error in re-sending Consent : " + e); response.setError(500, "error : " + e); diff --git a/src/main/java/com/iemr/common/exception/OtpRateLimitException.java b/src/main/java/com/iemr/common/exception/OtpRateLimitException.java new file mode 100644 index 00000000..a0f3b53f --- /dev/null +++ b/src/main/java/com/iemr/common/exception/OtpRateLimitException.java @@ -0,0 +1,30 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.TOO_MANY_REQUESTS) +public class OtpRateLimitException extends RuntimeException { + public OtpRateLimitException(String message) { super(message); } +} diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 42e0acfe..3cc0a709 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -32,6 +32,7 @@ import com.iemr.common.repository.sms.SMSTemplateRepository; import com.iemr.common.repository.sms.SMSTypeRepository; import com.iemr.common.service.otp.OTPHandler; +import com.iemr.common.service.otp.OtpRateLimiterService; import com.iemr.common.service.users.IEMRAdminUserServiceImpl; import com.iemr.common.utils.config.ConfigProperties; import com.iemr.common.utils.http.HttpUtils; @@ -59,6 +60,8 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { HttpUtils httpUtils; @Autowired private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; + @Autowired + private OtpRateLimiterService otpRateLimiterService; final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired @@ -107,6 +110,7 @@ public String load(String key) { */ @Override public String sendOTP(BeneficiaryConsentRequest obj) throws Exception { + otpRateLimiterService.checkRateLimit(obj.getMobNo()); int otp = generateOTP(obj.getMobNo()); return sendSMS(otp, obj); } @@ -141,6 +145,7 @@ public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception { */ @Override public String resendOTP(BeneficiaryConsentRequest obj) throws Exception { + otpRateLimiterService.checkRateLimit(obj.getMobNo()); int otp = generateOTP(obj.getMobNo()); return sendSMS(otp, obj); } diff --git a/src/main/java/com/iemr/common/service/otp/OtpRateLimiterService.java b/src/main/java/com/iemr/common/service/otp/OtpRateLimiterService.java new file mode 100644 index 00000000..da06a64b --- /dev/null +++ b/src/main/java/com/iemr/common/service/otp/OtpRateLimiterService.java @@ -0,0 +1,104 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.service.otp; + +import com.iemr.common.exception.OtpRateLimitException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.concurrent.TimeUnit; + +/** + * Rate-limits OTP send/resend requests per mobile number using Redis counters. + * + * Limits (configurable via properties): + * otp.ratelimit.minute-limit – max OTPs per minute (default 3) + * otp.ratelimit.hour-limit – max OTPs per hour (default 10) + * otp.ratelimit.day-limit – max OTPs per day (default 20) + * + * Redis key pattern: + * rl:otp:min:{mobNo}:{minuteSlot} TTL 60 s + * rl:otp:hr:{mobNo}:{hourSlot} TTL 3600 s + * rl:otp:day:{mobNo}:{yyyyMMdd} TTL 86400 s + */ +@Component +public class OtpRateLimiterService { + + private final StringRedisTemplate redis; + + @Value("${otp.ratelimit.enabled:true}") + private boolean enabled; + + @Value("${otp.ratelimit.minute-limit:3}") + private int minuteLimit; + + @Value("${otp.ratelimit.hour-limit:10}") + private int hourLimit; + + @Value("${otp.ratelimit.day-limit:20}") + private int dayLimit; + + public OtpRateLimiterService(StringRedisTemplate redis) { + this.redis = redis; + } + + /** + * Checks all three rate-limit windows for the given mobile number. + * Throws {@link OtpRateLimitException} if any limit is exceeded. + * No-op when otp.ratelimit.enabled=false. + */ + public void checkRateLimit(String mobNo) { + if (!enabled) return; + String today = LocalDate.now(ZoneId.of("Asia/Kolkata")) + .toString().replaceAll("-", ""); // yyyyMMdd + long minuteSlot = System.currentTimeMillis() / 60_000L; + long hourSlot = System.currentTimeMillis() / 3_600_000L; + + String minKey = "rl:otp:min:" + mobNo + ":" + minuteSlot; + String hourKey = "rl:otp:hr:" + mobNo + ":" + hourSlot; + String dayKey = "rl:otp:day:" + mobNo + ":" + today; + + if (incrementWithExpire(minKey, 60L) > minuteLimit) { + throw new OtpRateLimitException( + "OTP request limit exceeded. Maximum " + minuteLimit + " OTPs allowed per minute. Please try again later."); + } + if (incrementWithExpire(hourKey, 3600L) > hourLimit) { + throw new OtpRateLimitException( + "OTP request limit exceeded. Maximum " + hourLimit + " OTPs allowed per hour. Please try again later."); + } + if (incrementWithExpire(dayKey, 86400L) > dayLimit) { + throw new OtpRateLimitException( + "OTP request limit exceeded. Maximum " + dayLimit + " OTPs allowed per day. Please try again tomorrow."); + } + } + + private long incrementWithExpire(String key, long ttlSeconds) { + Long value = redis.opsForValue().increment(key, 1L); + if (value != null && value == 1L) { + redis.expire(key, ttlSeconds, TimeUnit.SECONDS); + } + return value == null ? 0L : value; + } +} From eec7cfefbadbbb7c6c46b23964300695b3088199 Mon Sep 17 00:00:00 2001 From: SnehaRH Date: Mon, 30 Mar 2026 19:05:18 +0530 Subject: [PATCH 37/47] docs: add CLAUDE.md for Claude Code guidance Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..913e1435 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,98 @@ +# CLAUDE.md - Common-API + +## Project Overview + +Common-API is the gateway microservice for the AMRIT healthcare platform. It provides shared APIs consumed by all frontend UIs including authentication, beneficiary registration, call handling, location masters, notifications, feedback, reporting, and integrations with external systems (c-Zentrix CTI, Everwell, eAusadha, eSanjeevani, ABDM, Firebase, Honeywell POCT devices). + +## Tech Stack + +- Java 17 +- Spring Boot 3.2.2 +- Spring Data JPA / Hibernate +- MySQL 8.0 +- Redis (session management, caching) +- MongoDB (optional, for specific integrations) +- Maven (build tool) +- Swagger/OpenAPI (API documentation) +- Lombok, MapStruct +- CryptoJS-compatible AES encryption +- Firebase Admin SDK +- WAR packaging (deploys to Wildfly) + +## Build and Run + +```bash +# Build +mvn clean install -DENV_VAR=local + +# Run locally (start Redis first) +mvn spring-boot:run -DENV_VAR=local + +# Package WAR +mvn -B package --file pom.xml -P # profiles: dev, local, test, ci, uat + +# Run tests +mvn test +``` + +### Configuration + +- Copy `src/main/environment/common_example.properties` to `common_local.properties` and edit. +- Environment selected via `-DENV_VAR=`. +- Swagger UI: `http://localhost:8083/swagger-ui.html` + +## Package Structure + +Base package: `com.iemr.common` + +| Layer | Package | Description | +|-------|---------|-------------| +| Controllers | `controller.*` | REST endpoints (40+ sub-packages) | +| Services | `service.*` | Business logic | +| Repositories | `repository.*`, `repo.*` | JPA repositories | +| Entities | `data.*` | JPA entity classes | +| DTOs | `model.*` | Transfer objects | +| Mappers | `mapper.*` | Object mapping | +| Config | `config.*` | Swagger, encryption, Firebase, Quartz, prototypes | +| Constants | `constant` | Application constants | +| Utils | `utils.*` | Redis, HTTP, session, validation, exception | + +## Key Functional Domains + +- **Authentication/Authorization**: `controller.users` - login, session, user management +- **Beneficiary Registration**: `controller.beneficiary` - create, search, update beneficiaries +- **Call Handling**: `controller.callhandling` - CTI integration, call lifecycle +- **Feedback/Grievance**: `controller.feedback`, `controller.grievance` - feedback and complaint management +- **Location**: `controller.location` - state, district, block, village masters +- **Notifications**: `controller.notification` - alerts, SMS, email, Firebase push +- **Reporting**: `controller.report`, `controller.secondaryReport` - CRM reports +- **Helpline 104**: `controller.helpline104history` - medical advice history +- **COVID**: `controller.covid` - vaccination status +- **CTI Integration**: `controller.cti` - c-Zentrix computer telephony +- **External Integrations**: `controller.eausadha`, `controller.esanjeevani`, `controller.everwell`, `controller.honeywell`, `controller.brd`, `controller.carestream` +- **ABDM**: `controller.abdmfacility` - Ayushman Bharat Digital Mission +- **KM File Management**: `controller.kmfilemanager` - OpenKM document management +- **OTP/SMS**: `controller.otp`, `controller.sms` (via SMS gateway) +- **Scheduling**: `controller.questionconfig`, `controller.scheme` +- **Door-to-Door App**: `controller.door_to_door_app` - field worker support +- **NHM Dashboard**: `controller.nhmdashboard` - National Health Mission integration + +## Architecture Notes + +- Entry point: `CommonMain.java` (main class in `utils` package) +- Acts as the API gateway; all frontend UIs authenticate through Common-API +- Session management via Redis with 27-minute timeout +- HTTP interceptors attach `Authorization` and `ServerAuthorization` headers +- Status code `5002` signals session expiration to frontends +- AES + PBKDF2 encryption for password handling (`config.encryption`) +- Firebase integration for push notifications (`config.firebase`) +- Quartz scheduler for background jobs (`config.quartz`) +- Extensive test coverage with unit tests under `src/test/` + +## CI/CD + +- GitHub Actions: `package.yml`, `build-on-pull-request.yml`, `sast.yml`, `commit-lint.yml`, `codeql.yml` +- Conventional Commits enforced via Husky + commitlint +- Checkstyle configuration in `checkstyle.xml` +- JaCoCo for code coverage, SonarQube integration configured +- Dockerfile for containerized deployment From 6902ae8a8adc9b12a429addb5542d2c584b6b64d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 2 Apr 2026 22:54:04 +0530 Subject: [PATCH 38/47] Fix issue for translation in hint --- .../dynamicForm/FormMasterServiceImpl.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index acbcb4e7..80eece11 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -137,18 +137,33 @@ public FormResponseDTO getStructuredFormByFormId(String formId, String lang, Str .map(field -> { String labelKey = field.getFieldId(); // field label already contains label_key - Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) + Translation label = translationRepo.findByLabelKeyAndIsActive(labelKey, true) + .orElse(null); + + Translation placeHolder = translationRepo.findByLabelKeyAndIsActive("placeholder_"+labelKey, true) .orElse(null); String translatedLabel = field.getLabel(); // fallback + String translatedPlaceHolder = field.getPlaceholder(); // fallback + + if (label != null) { + if ("hi".equalsIgnoreCase(lang)) { + translatedLabel = label.getHindiTranslation(); + } else if ("as".equalsIgnoreCase(lang)) { + translatedLabel = label.getAssameseTranslation(); + } else if ("en".equalsIgnoreCase(lang)) { + translatedLabel = label.getEnglish(); + + } + } - if (t != null) { + if (placeHolder != null) { if ("hi".equalsIgnoreCase(lang)) { - translatedLabel = t.getHindiTranslation(); + translatedPlaceHolder= placeHolder.getHindiTranslation(); } else if ("as".equalsIgnoreCase(lang)) { - translatedLabel = t.getAssameseTranslation(); + translatedPlaceHolder = placeHolder.getAssameseTranslation(); } else if ("en".equalsIgnoreCase(lang)) { - translatedLabel = t.getEnglish(); + translatedPlaceHolder = placeHolder.getEnglish(); } } @@ -165,7 +180,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId, String lang, Str dto.setType(field.getType()); dto.setIsRequired(field.getIsRequired()); dto.setDefaultValue(field.getDefaultValue()); - dto.setPlaceholder(field.getPlaceholder()); + dto.setPlaceholder(translatedPlaceHolder); dto.setSequence(field.getSequence()); try { From a5918e3658043f1c39f70d4ac23711507ffaee5a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 6 Apr 2026 16:09:43 +0530 Subject: [PATCH 39/47] fix dropdown translation --- .../common/data/dynamic_from/FormField.java | 3 ++ .../data/dynamic_from/FormFieldOption.java | 34 +++++++++++++++++ .../dto/dynamicForm/FieldResponseDTO.java | 2 +- .../FormFieldOptionRepository.java | 16 ++++++++ .../dynamicForm/FormMasterServiceImpl.java | 38 ++++++++++++------- 5 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormFieldOption.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormFieldOptionRepository.java diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java index 1b195db9..08534239 100644 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java @@ -62,6 +62,9 @@ public class FormField { @Column(name = "created_at") private LocalDateTime createdAt = LocalDateTime.now(); + @Column(name = "option_key") + private String optionKey; + } diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormFieldOption.java b/src/main/java/com/iemr/common/data/dynamic_from/FormFieldOption.java new file mode 100644 index 00000000..8cfeb0de --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormFieldOption.java @@ -0,0 +1,34 @@ +package com.iemr.common.data.dynamic_from; + +import jakarta.persistence.*; +import lombok.Data; + +@Entity +@Table(name = "form_field_options") +@Data +public class FormFieldOption { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "option_key") + private String optionKey; + + @Column(name = "value") + private String value; + + @Column(name = "label_en") + private String labelEn; + + @Column(name = "label_hi") + private String labelHi; + + @Column(name = "label_as") + private String labelAs; + + @Column(name = "sort_order") + private Integer sortOrder; + + // getters/setters +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java index e41f8e80..a70389e1 100644 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java @@ -20,7 +20,7 @@ public class FieldResponseDTO { private Integer sequence; private Boolean isEditable; private Integer stateCode; - private List options; + public List> options; private Map validation; private Map conditional; } \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormFieldOptionRepository.java b/src/main/java/com/iemr/common/service/dynamicForm/FormFieldOptionRepository.java new file mode 100644 index 00000000..5bf04f7d --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormFieldOptionRepository.java @@ -0,0 +1,16 @@ +package com.iemr.common.service.dynamicForm; + +import com.iemr.common.data.dynamic_from.FormFieldOption; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface FormFieldOptionRepository + extends JpaRepository { + + List findByOptionKeyOrderBySortOrderAsc(String optionKey); + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 80eece11..dbb1df1b 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -1,9 +1,11 @@ package com.iemr.common.service.dynamicForm; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.iemr.common.data.dynamic_from.FormDefinition; import com.iemr.common.data.dynamic_from.FormField; +import com.iemr.common.data.dynamic_from.FormFieldOption; import com.iemr.common.data.dynamic_from.FormModule; import com.iemr.common.data.translation.Translation; import com.iemr.common.data.users.UserServiceRole; @@ -43,6 +45,9 @@ public class FormMasterServiceImpl implements FormMasterService { @Autowired private JwtUtil jwtUtil; + @Autowired + private FormFieldOptionRepository formFieldOptionRepo ; + @Override public FormModule createModule(ModuleDTO dto) { FormModule module = new FormModule(); @@ -168,6 +173,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId, String lang, Str } } + FieldResponseDTO dto = new FieldResponseDTO(); dto.setId(field.getId()); dto.setIsEditable(field.getIsEditable()); @@ -183,23 +189,29 @@ public FormResponseDTO getStructuredFormByFormId(String formId, String lang, Str dto.setPlaceholder(translatedPlaceHolder); dto.setSequence(field.getSequence()); + try { - // Handle options - if (field.getOptions() != null && !field.getOptions().isBlank()) { - JsonNode node = objectMapper.readTree(field.getOptions()); - List options = null; - if (node.isArray()) { - options = objectMapper.convertValue(node, new TypeReference<>() { - }); - } else if (node.has("options")) { - options = objectMapper.convertValue(node.get("options"), new TypeReference<>() { - }); - } - dto.setOptions(options == null || options.isEmpty() ? null : options); + if (field.getOptionKey() != null && !field.getOptionKey().isBlank()) { + // NEW: option_key column se directly fetch karo + List dbOptions = formFieldOptionRepo + .findByOptionKeyOrderBySortOrderAsc(field.getOptionKey()); + + List> translatedOptions = dbOptions.stream() + .map(opt -> { + Map map = new LinkedHashMap<>(); + map.put("value", opt.getValue()); + if ("hi".equalsIgnoreCase(lang)) map.put("label", opt.getLabelHi()); + else if ("as".equalsIgnoreCase(lang)) map.put("label", opt.getLabelAs()); + else map.put("label", opt.getLabelEn()); + return map; + }) + .collect(Collectors.toList()); + + dto.setOptions(translatedOptions.isEmpty() ? null : translatedOptions); + } else { dto.setOptions(null); } - // Handle validation if (field.getValidation() != null && !field.getValidation().isBlank()) { Map validation = objectMapper.readValue(field.getValidation(), new TypeReference<>() { From b166ceb9d0c8c8ba957489bf068aca7602fd4205 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 6 Apr 2026 16:10:04 +0530 Subject: [PATCH 40/47] fix dropdown translation --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index dbb1df1b..12618682 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -192,7 +192,6 @@ public FormResponseDTO getStructuredFormByFormId(String formId, String lang, Str try { if (field.getOptionKey() != null && !field.getOptionKey().isBlank()) { - // NEW: option_key column se directly fetch karo List dbOptions = formFieldOptionRepo .findByOptionKeyOrderBySortOrderAsc(field.getOptionKey()); From 9a472d33acb1964da83f0568234044a7b449d578 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 7 Apr 2026 13:33:08 +0530 Subject: [PATCH 41/47] fix dropdown translation --- .../iemr/common/dto/dynamicForm/FieldResponseDTO.java | 2 +- .../dynamic_form}/FormFieldOptionRepository.java | 4 +--- .../service/dynamicForm/FormMasterServiceImpl.java | 10 ++++++---- 3 files changed, 8 insertions(+), 8 deletions(-) rename src/main/java/com/iemr/common/{service/dynamicForm => repository/dynamic_form}/FormFieldOptionRepository.java (84%) diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java index a70389e1..dbf241ae 100644 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java @@ -20,7 +20,7 @@ public class FieldResponseDTO { private Integer sequence; private Boolean isEditable; private Integer stateCode; - public List> options; + public List> options; private Map validation; private Map conditional; } \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormFieldOptionRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FormFieldOptionRepository.java similarity index 84% rename from src/main/java/com/iemr/common/service/dynamicForm/FormFieldOptionRepository.java rename to src/main/java/com/iemr/common/repository/dynamic_form/FormFieldOptionRepository.java index 5bf04f7d..3f258ae4 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormFieldOptionRepository.java +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FormFieldOptionRepository.java @@ -1,11 +1,9 @@ -package com.iemr.common.service.dynamicForm; - +package com.iemr.common.repository.dynamic_form; import com.iemr.common.data.dynamic_from.FormFieldOption; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Optional; @Repository public interface FormFieldOptionRepository diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 12618682..9f9121e5 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -11,6 +11,7 @@ import com.iemr.common.data.users.UserServiceRole; import com.iemr.common.dto.dynamicForm.*; import com.iemr.common.repository.dynamic_form.FieldRepository; +import com.iemr.common.repository.dynamic_form.FormFieldOptionRepository; import com.iemr.common.repository.dynamic_form.FormRepository; import com.iemr.common.repository.dynamic_form.ModuleRepository; import com.iemr.common.repository.translation.TranslationRepo; @@ -121,7 +122,7 @@ public FormField updateField(FieldDTO dto) { public FormResponseDTO getStructuredFormByFormId(String formId, String lang, String token) { Integer stateId = 0; try { - String username = jwtUtil.getUsernameFromToken(token); + String username = "moon"; stateId = userServiceRoleRepo.findByUserName(username) .stream() @@ -140,7 +141,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId, String lang, Str Integer finalStateId = stateId; List fieldDtos = fields.stream().filter(formField -> (formField.getStateCode().equals(0) || formField.getStateCode().equals(finalStateId))) .map(field -> { - String labelKey = field.getFieldId(); // field label already contains label_key + String labelKey = field.getFieldId(); Translation label = translationRepo.findByLabelKeyAndIsActive(labelKey, true) .orElse(null); @@ -195,9 +196,10 @@ public FormResponseDTO getStructuredFormByFormId(String formId, String lang, Str List dbOptions = formFieldOptionRepo .findByOptionKeyOrderBySortOrderAsc(field.getOptionKey()); - List> translatedOptions = dbOptions.stream() + List> translatedOptions = dbOptions.stream() .map(opt -> { - Map map = new LinkedHashMap<>(); + Map map = new LinkedHashMap<>(); + map.put("id", opt.getId()); map.put("value", opt.getValue()); if ("hi".equalsIgnoreCase(lang)) map.put("label", opt.getLabelHi()); else if ("as".equalsIgnoreCase(lang)) map.put("label", opt.getLabelAs()); From 72f0c28a2b6c10f134e7470c5a14fd4ed047229e Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Tue, 7 Apr 2026 15:27:06 +0530 Subject: [PATCH 42/47] Fix the OpenKM Issue (#389) * fix: remove km in application.properties * fix: update all the properties to fetch from env * fix: update path * fix: KM issue * fix: get file from km * fix: build issue * fix: build issue * fix: remove unwanted imports * fix: build issue * fix: remove commented line * Enable KM configuration in common_example.properties Uncomment KM configuration properties for OpenKM. --- .../environment/common_example.properties | 2 + .../com/iemr/common/CommonApplication.java | 2 +- .../common/service/cti/CTIServiceImpl.java | 2 + .../service/feedback/FeedbackServiceImpl.java | 19 +++++-- .../notification/NotificationServiceImpl.java | 19 +++++-- .../service/scheme/SchemeServiceImpl.java | 24 +++++--- .../service/services/CommonServiceImpl.java | 25 +++++--- .../com/iemr/common/utils/IEMRApplBeans.java | 12 ++-- .../common/utils/JwtAuthenticationUtil.java | 4 -- .../utils/km/openkm/OpenKMServiceImpl.java | 57 ++++++++++--------- src/main/resources/application.properties | 16 +++--- 11 files changed, 113 insertions(+), 69 deletions(-) diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index aca73ddb..e2b2555c 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -25,6 +25,8 @@ km-root-path=/okm:personal/users/ km-guest-user=guest km-guest-password=guest +tempFilePath=/tmp + # CTI Config cti-server-ip=10.208.122.99 cti-logger_base_url=http://10.208.122.99/logger diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index dff5d809..45d61800 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -41,7 +41,7 @@ @SpringBootApplication @EnableScheduling -@EnableAsync +@EnableAsync(proxyTargetClass = true) public class CommonApplication extends SpringBootServletInitializer { @Bean diff --git a/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java b/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java index 81d8953a..3348befe 100644 --- a/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java +++ b/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java @@ -26,6 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @@ -90,6 +91,7 @@ public class CTIServiceImpl implements CTIService { @Autowired private BeneficiaryCallRepository beneficiaryCallRepository; + @Lazy @Autowired private CTIService ctiService; diff --git a/src/main/java/com/iemr/common/service/feedback/FeedbackServiceImpl.java b/src/main/java/com/iemr/common/service/feedback/FeedbackServiceImpl.java index b4c7782e..f94b6e9a 100644 --- a/src/main/java/com/iemr/common/service/feedback/FeedbackServiceImpl.java +++ b/src/main/java/com/iemr/common/service/feedback/FeedbackServiceImpl.java @@ -36,6 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @@ -104,6 +105,19 @@ public class FeedbackServiceImpl implements FeedbackService { private Logger logger = LoggerFactory.getLogger(FeedbackServiceImpl.class); // private ExecutorService executor = Executors.newCachedThreadPool(); + + @Value("${km-base-path}") + private String dmsPath; + + @Value("${km-guest-user}") + private String userName; + + @Value("${km-guest-password}") + private String userPassword; + + @Value("${km-base-protocol}") + private String dmsProtocol; + @Autowired private T_EpidemicOutbreakRepo t_EpidemicOutbreakRepo; @@ -736,10 +750,7 @@ private String getFilePath(KMFileManager kmFileManager) { String fileUIDAsURI = null; if (kmFileManager != null && kmFileManager.getFileUID() != null) { String fileUID = kmFileManager.getFileUID(); - String dmsPath = ConfigProperties.getPropertyByName("km-base-path"); - String dmsProtocol = ConfigProperties.getPropertyByName("km-base-protocol"); - String userName = ConfigProperties.getPropertyByName("km-guest-user"); - String userPassword = ConfigProperties.getPassword("km-guest-user"); + fileUIDAsURI = dmsProtocol + "://" + userName + ":" + userPassword + "@" + dmsPath + "/Download?uuid=" + fileUID; } diff --git a/src/main/java/com/iemr/common/service/notification/NotificationServiceImpl.java b/src/main/java/com/iemr/common/service/notification/NotificationServiceImpl.java index 2d8aaeb3..a4fda6f5 100644 --- a/src/main/java/com/iemr/common/service/notification/NotificationServiceImpl.java +++ b/src/main/java/com/iemr/common/service/notification/NotificationServiceImpl.java @@ -38,6 +38,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.JsonProcessingException; @@ -70,6 +71,19 @@ public class NotificationServiceImpl implements NotificationService private EmailService emailService; + + @Value("${km-base-path}") + private String dmsPath; + + @Value("${km-guest-user}") + private String userName; + + @Value("${km-guest-password}") + private String userPassword; + + @Value("${km-base-protocol}") + private String dmsProtocol; + @Autowired public void setEmailService(EmailService emailService) { @@ -415,10 +429,7 @@ private String getFilePath(KMFileManager kmFileManager) if (kmFileManager != null && kmFileManager.getFileUID() != null) { String fileUID = kmFileManager.getFileUID(); - String dmsPath = ConfigProperties.getPropertyByName("km-base-path"); - String dmsProtocol = ConfigProperties.getPropertyByName("km-base-protocol"); - String userName = ConfigProperties.getPropertyByName("km-guest-user"); - String userPassword = ConfigProperties.getPassword("km-guest-user"); + fileUIDAsURI = dmsProtocol + "://" + userName + ":" + userPassword + "@" + dmsPath + "/Download?uuid=" + fileUID; } diff --git a/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java b/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java index 44e1efaa..947c2c17 100644 --- a/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java +++ b/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java @@ -30,6 +30,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -59,6 +60,18 @@ public class SchemeServiceImpl implements SchemeService { private KMFileManagerService kmFileManagerService; + @Value("${km-api-base-protocol}") + private String dmsProtocol; + + @Value("${km-api-base-url}") + private String dmsPath; + + @Value("${km-guest-user}") + private String userName; + + @Value("${km-guest-password}") + private String userPassword; + @Autowired public void setKmFileManagerService(KMFileManagerService kmFileManagerService) { this.kmFileManagerService = kmFileManagerService; @@ -104,16 +117,13 @@ public String getFilePath(KMFileManager kmFileManager) { String fileUIDAsURI = null; if (kmFileManager != null && kmFileManager.getFileUID() != null) { String fileUID = kmFileManager.getFileUID(); - String dmsPath = ConfigProperties.getPropertyByName("km-base-path"); - String dmsProtocol = ConfigProperties.getPropertyByName("km-base-protocol"); - String userName = ConfigProperties.getPropertyByName("km-guest-user"); - String userPassword = ConfigProperties.getPassword("km-guest-user"); + fileUIDAsURI = dmsProtocol + "://" + userName + ":" + userPassword + "@" + dmsPath + "/Download?uuid=" + fileUID; } - // return fileUIDAsURI; - String message = kmFileManager.getFileUID() ; - return message; + return fileUIDAsURI; + // String message = kmFileManager.getFileUID() ; + // return message; } @Override diff --git a/src/main/java/com/iemr/common/service/services/CommonServiceImpl.java b/src/main/java/com/iemr/common/service/services/CommonServiceImpl.java index ff6f83e9..d8587a86 100644 --- a/src/main/java/com/iemr/common/service/services/CommonServiceImpl.java +++ b/src/main/java/com/iemr/common/service/services/CommonServiceImpl.java @@ -64,7 +64,19 @@ public class CommonServiceImpl implements CommonService { private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); + + @Value("${km-base-path}") + private String dmsPath; + + @Value("${km-guest-user}") + private String userName; + @Value("${km-guest-password}") + private String userPassword; + + @Value("${km-base-protocol}") + private String dmsProtocol; + private static final String FILE_PATH = "filePath"; /** @@ -177,10 +189,6 @@ private String getFilePath(String fileUID) { String fileUIDAsURI = null; - String dmsPath = ConfigProperties.getPropertyByName("km-base-path"); - String dmsProtocol = ConfigProperties.getPropertyByName("km-base-protocol"); - String userName = ConfigProperties.getPropertyByName("km-guest-user"); - String userPassword = ConfigProperties.getPassword("km-guest-user"); fileUIDAsURI = dmsProtocol + "://" + userName + ":" + userPassword + "@" + dmsPath + "/Download?uuid=" + fileUID; @@ -233,12 +241,13 @@ public List getSubCategoryFilesWithURL(String request) throw SubCategoryDetails subCategory = subCategoriesList.get(index); if (subCategory.getSubCatFilePath() != null && subCategory.getSubCatFilePath().length() > 0) { String subCatFilePath = subCategory.getSubCatFilePath(); - String dmsPath = ConfigProperties.getPropertyByName("km-base-path"); - String dmsProtocol = ConfigProperties.getPropertyByName("km-base-protocol"); - String userName = ConfigProperties.getPropertyByName("km-guest-user"); - String userPassword = ConfigProperties.getPassword("km-guest-user"); String fileUIDAsURI = dmsProtocol + "://" + userName + ":" + userPassword + "@" + dmsPath + "/Download?uuid=" + subCategory.getSubCatFilePath(); + logger.info("file url="+fileUIDAsURI); + logger.info("file path="+subCategory.getSubCatFilePath()); + logger.info("dms Path="+dmsPath); + logger.info("subcatfilePath="+subCatFilePath); + subCategory.setSubCatFilePath(fileUIDAsURI); subCategoriesList.get(index).setFileManger(kmFileManagerRepository .getKMFileLists(subCategoryDetails.getProviderServiceMapID(), subCatFilePath)); diff --git a/src/main/java/com/iemr/common/utils/IEMRApplBeans.java b/src/main/java/com/iemr/common/utils/IEMRApplBeans.java index 92d3c339..7747f6ee 100644 --- a/src/main/java/com/iemr/common/utils/IEMRApplBeans.java +++ b/src/main/java/com/iemr/common/utils/IEMRApplBeans.java @@ -40,12 +40,12 @@ @Configuration public class IEMRApplBeans { - @Bean - public KMService getOpenKMService() - { - KMService kmService = new OpenKMServiceImpl(); - return kmService; - } + // @Bean + // public KMService getOpenKMService() + // { + // KMService kmService = new OpenKMServiceImpl(); + // return kmService; + // } @Bean public Validator getVaidator() diff --git a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java index 1e9f589d..d9eb1ce2 100644 --- a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java @@ -13,7 +13,6 @@ import com.iemr.common.data.users.User; import com.iemr.common.repository.users.IEMRUserRepositoryCustom; -import com.iemr.common.service.users.IEMRAdminUserServiceImpl; import com.iemr.common.utils.exception.IEMRException; import io.jsonwebtoken.Claims; @@ -32,9 +31,6 @@ public class JwtAuthenticationUtil { private IEMRUserRepositoryCustom iEMRUserRepositoryCustom; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - @Autowired - private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; - public JwtAuthenticationUtil(CookieUtil cookieUtil, JwtUtil jwtUtil) { this.cookieUtil = cookieUtil; this.jwtUtil = jwtUtil; diff --git a/src/main/java/com/iemr/common/utils/km/openkm/OpenKMServiceImpl.java b/src/main/java/com/iemr/common/utils/km/openkm/OpenKMServiceImpl.java index 2be04cfc..4a6e68ec 100644 --- a/src/main/java/com/iemr/common/utils/km/openkm/OpenKMServiceImpl.java +++ b/src/main/java/com/iemr/common/utils/km/openkm/OpenKMServiceImpl.java @@ -46,44 +46,47 @@ import com.openkm.sdk4j.exception.VirusDetectedException; import com.openkm.sdk4j.exception.WebserviceException; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.client.ClientProperties; -import org.glassfish.jersey.client.JerseyClientBuilder; +import jakarta.annotation.PostConstruct; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +@Service public class OpenKMServiceImpl implements KMService { - // private ConfigProperties configProperties; - // - // @Autowired - // public void setConfigProperties(ConfigProperties configProperties) - // { - // this.configProperties = configProperties; - // } + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - private static String url; - private static String username; - private static String password; - private static String kmRootPath; - private static String guestUser; - private static String guestPassword; + @Value("${km-base-url}") + private String url; + + @Value("${km-username}") + private String username; + + @Value("${km-password}") + private String password; + + @Value("${km-root-path}") + private String kmRootPath; + + @Value("${km-guest-user}") + private String guestUser; + + @Value("${km-guest-password}") + private String guestPassword; public OpenKMServiceImpl() { } - private static OKMWebservices connector = null; + private OKMWebservices connector; + @PostConstruct public void init() { - if (connector == null) { - url = ConfigProperties.getPropertyByName("km-base-url"); - username = ConfigProperties.getPropertyByName("km-username"); - password = ConfigProperties.getPropertyByName("km-password"); - kmRootPath = ConfigProperties.getPropertyByName("km-root-path"); - guestUser = ConfigProperties.getPropertyByName("km-guest-user"); - guestPassword = ConfigProperties.getPropertyByName("km-guest-password"); - connector = OpenKMConnector.initialize(url, username, password); + logger.info("KM URL=",url); + connector = OpenKMConnector.initialize(url, username, password); - } - } + } @Override public String getDocumentRoot() { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a3de6772..c44efdf0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -181,14 +181,14 @@ jwt.refresh.expiration=604800000 ## KM Configuration -km-base-protocol=http -km-username=okmAdmin -km-password=admin -km-base-url=http://localhost:8084/OpenKM -km-base-path=localhost:8084/OpenKM -km-root-path=/okm:personal/users/ -km-guest-user=guest -km-guest-password=guest +# km-base-protocol=http +# km-username=okmAdmin +# km-password=admin +# km-base-url=http://localhost:8084/OpenKM +# km-base-path=localhost:8084/OpenKM +# km-root-path=/okm:personal/users/ +# km-guest-user=guest +# km-guest-password=guest # CTI Config cti-server-ip=10.208.122.99 From 39f069d74bda3a6f7a9261cbd8327dab2dd7ac68 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 7 Apr 2026 18:55:41 +0530 Subject: [PATCH 43/47] fix dropdown translation --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 171ab162..a41fb9f5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.1 + 3.6.2 war Common-API From fc21d6469c9e57e7c545728968f828dae2539607 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 7 Apr 2026 19:06:00 +0530 Subject: [PATCH 44/47] fix dropdown translation --- .../java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java index e41f8e80..dbf241ae 100644 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java @@ -20,7 +20,7 @@ public class FieldResponseDTO { private Integer sequence; private Boolean isEditable; private Integer stateCode; - private List options; + public List> options; private Map validation; private Map conditional; } \ No newline at end of file From eb4d9b123b71f011e5e6326883ca7f3fcbde415f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 7 Apr 2026 20:47:45 +0530 Subject: [PATCH 45/47] fix dropdown translation --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 9f9121e5..0b6908d0 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -122,7 +122,7 @@ public FormField updateField(FieldDTO dto) { public FormResponseDTO getStructuredFormByFormId(String formId, String lang, String token) { Integer stateId = 0; try { - String username = "moon"; + String username = jwtUtil.getUsernameFromToken(token); stateId = userServiceRoleRepo.findByUserName(username) .stream() From 79b050da315571512b9cfa3b7e8b59e3e37315b3 Mon Sep 17 00:00:00 2001 From: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:14:18 +0530 Subject: [PATCH 46/47] Fix ConfigProperties to resolve env variable placeholders via Spring Environment (#390) Co-authored-by: Claude Opus 4.6 (1M context) --- .../common/utils/config/ConfigProperties.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/config/ConfigProperties.java b/src/main/java/com/iemr/common/utils/config/ConfigProperties.java index 59b69b82..43a49364 100644 --- a/src/main/java/com/iemr/common/utils/config/ConfigProperties.java +++ b/src/main/java/com/iemr/common/utils/config/ConfigProperties.java @@ -144,11 +144,21 @@ public static String getPropertyByName(String propertyName) String result = null; try { - if (properties == null) + if (environment != null) { - initalizeProperties(); + result = environment.getProperty(propertyName); + } + if (result == null) + { + if (properties == null) + { + initalizeProperties(); + } + result = properties.getProperty(propertyName).trim(); + } else + { + result = result.trim(); } - result = properties.getProperty(propertyName).trim(); } catch (Exception e) { logger.error(propertyName + " retrival failed.", e); From bded02ec87f1da7cb14ea5b9f0e156fa149a9823 Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:43:15 +0530 Subject: [PATCH 47/47] fix: async notation (#392) --- .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 1dd0b533..ac084e15 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -120,7 +120,7 @@ private void updateBeneficiaryID(String beneficiaryID, Long beneficiaryRegID) { } } - @Async + // @Async @Override public Integer updateBenificiary(BeneficiaryModel benificiaryDetails, String auth) throws IEMRException { Integer updatedRows = 0;