diff --git a/pom.xml b/pom.xml index 454fd02a..190b3438 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,6 @@ hibernate-jpa-2.0-api 1.0.1.Final - org.springframework.boot spring-boot-starter-cache @@ -503,7 +502,7 @@ - commonapi-v3.0.0 + commonapi-v1.0 org.apache.maven.plugins diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java new file mode 100644 index 00000000..60c7bdee --- /dev/null +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -0,0 +1,100 @@ +package com.iemr.common.controller.beneficiaryConsent; + +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import com.iemr.common.service.beneficiaryOTPHandler.BeneficiaryOTPHandler; +import com.iemr.common.service.otp.OTPHandler; +import com.iemr.common.utils.mapper.InputMapper; +import com.iemr.common.utils.response.OutputResponse; +import io.lettuce.core.dynamic.annotation.Param; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.ws.rs.core.MediaType; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +public class BeneficiaryConsentController { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + private BeneficiaryOTPHandler beneficiaryOTPHandler; + + @Operation(summary = "Send Consent") + @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); + + OutputResponse response = new OutputResponse(); + + try { + BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class); + + String success = beneficiaryOTPHandler.sendOTP(obj); // method name unchanged if internal logic still uses 'OTP' + logger.info(success.toString()); + if (success.contains("otp")) + response.setResponse(success); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in sending Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + @Operation(summary = "Validate Consent") + @RequestMapping(value = "/validateConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"Integer\"}") @RequestBody String requestOBJ) { + + OutputResponse response = new OutputResponse(); + + try { + OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + + JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj); + if (responseOBJ != null) + response.setResponse(responseOBJ.toString()); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in validating Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + @Operation(summary = "Resend Consent") + @RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); + + OutputResponse response = new OutputResponse(); + + try { + OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + + String success = beneficiaryOTPHandler.resendOTP(obj); + logger.info(success.toString()); + + if (success.contains("otp")) + response.setResponse(success); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in re-sending Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + +} + + diff --git a/src/main/java/com/iemr/common/controller/grievance/GrievanceController.java b/src/main/java/com/iemr/common/controller/grievance/GrievanceController.java index bf243f69..802dcd39 100644 --- a/src/main/java/com/iemr/common/controller/grievance/GrievanceController.java +++ b/src/main/java/com/iemr/common/controller/grievance/GrievanceController.java @@ -234,6 +234,7 @@ public String completeGrievanceCall( } + @Operation(summary = "Get Grievance Details with Remarks") @PostMapping(value = "/getCompleteGrievanceDetails", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String getGrievanceDetailsWithRemarks(@RequestBody String request) { diff --git a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java index 42371a88..f74caa63 100644 --- a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java +++ b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java @@ -55,6 +55,7 @@ public class OTPGateway { @Operation(summary = "Send OTP") @RequestMapping(value = "/sendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -62,7 +63,8 @@ public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody Stri OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.sendOTP(obj); - if (success.equalsIgnoreCase("success")) + logger.info(success.toString()); + if (success.contains("otp")) response.setResponse(success); else response.setError(5000, "failure"); @@ -102,6 +104,7 @@ public String validateOTP( @Operation(summary = "Resend OTP") @RequestMapping(value = "/resendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -109,7 +112,9 @@ public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody St OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.resendOTP(obj); - if (success.equalsIgnoreCase("success")) + logger.info(success.toString()); + + if (success.contains("otp")) response.setResponse(success); else response.setError(5000, "failure"); diff --git a/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java b/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java new file mode 100644 index 00000000..ac629a3c --- /dev/null +++ b/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java @@ -0,0 +1,12 @@ +package com.iemr.common.data.beneficiaryConsent; + +import lombok.Data; + +@Data +public class BeneficiaryConsentRequest { + private String mobNo; + private int otp; + private String userName; + private String designation; + +} diff --git a/src/main/java/com/iemr/common/data/grievance/GrievanceCallRequest.java b/src/main/java/com/iemr/common/data/grievance/GrievanceCallRequest.java index 17178003..f6595f16 100644 --- a/src/main/java/com/iemr/common/data/grievance/GrievanceCallRequest.java +++ b/src/main/java/com/iemr/common/data/grievance/GrievanceCallRequest.java @@ -11,6 +11,8 @@ public class GrievanceCallRequest { Long beneficiaryRegID; Integer callTypeID; Long benCallID; + Integer providerServiceMapId; + Integer providerServiceMapID; String createdBy; diff --git a/src/main/java/com/iemr/common/data/grievance/GrievanceDetails.java b/src/main/java/com/iemr/common/data/grievance/GrievanceDetails.java index 17019b54..8108def4 100644 --- a/src/main/java/com/iemr/common/data/grievance/GrievanceDetails.java +++ b/src/main/java/com/iemr/common/data/grievance/GrievanceDetails.java @@ -183,6 +183,7 @@ public GrievanceDetails(Long gwid, Long grievanceId, Long beneficiaryRegID, Long this.severety = severety; this.level = level; this.state = state; + this.agentid = agentID; this.userID = userid; this.isAllocated = isAllocated; this.retryNeeded = retryNeeded; diff --git a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java index 8e364eb3..c057b58d 100644 --- a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java +++ b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java @@ -61,6 +61,7 @@ public class CommonIdentityDTO { private Integer educationId; private String education; private Boolean emergencyRegistration = false; + private Boolean isConsent; private Integer healthCareWorkerId; private String healthCareWorker; private String fatherName; 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 209472ef..8b00263a 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -77,6 +77,10 @@ public class BeneficiaryModel implements Comparable { // private List outboundCallRequests; // private List beneficiaryCalls; // private List feedbacks; + @Expose + private Boolean isConsent=false; + + @Expose private String beneficiaryID; @Expose diff --git a/src/main/java/com/iemr/common/repository/callhandling/IEMRCalltypeRepositoryImplCustom.java b/src/main/java/com/iemr/common/repository/callhandling/IEMRCalltypeRepositoryImplCustom.java index 0e98bf1d..544ffd7f 100644 --- a/src/main/java/com/iemr/common/repository/callhandling/IEMRCalltypeRepositoryImplCustom.java +++ b/src/main/java/com/iemr/common/repository/callhandling/IEMRCalltypeRepositoryImplCustom.java @@ -88,6 +88,8 @@ Set getOutboundCallTypes(@Param("providerServiceMapID") Integer provid @Query("select callType from CallType callType where deleted = false and callTypeID = :callTypeID") CallType getCallTypeDetails(@Param("callTypeID") Integer callTypeID); + @Query("select callType, callGroupType from CallType " + @Query("select callGroupType, callType from CallType " + "where callTypeID = :callTypeID") Set getCallDetails(@Param("callTypeID") Integer callTypeID); diff --git a/src/main/java/com/iemr/common/repository/grievance/GrievanceDataRepo.java b/src/main/java/com/iemr/common/repository/grievance/GrievanceDataRepo.java index 37d2f0dc..cddcf4a2 100644 --- a/src/main/java/com/iemr/common/repository/grievance/GrievanceDataRepo.java +++ b/src/main/java/com/iemr/common/repository/grievance/GrievanceDataRepo.java @@ -66,15 +66,28 @@ List findGrievancesByUserAndLanguage(@Param("userID") Integer @Modifying @Transactional + + @Query("UPDATE GrievanceDetails g SET g.userID = NULL WHERE g.grievanceId = :grievanceId AND g.userID = :userID") + int unassignGrievance(@Param("grievanceId") Long grievanceId, @Param("userID") Integer userID); + @Query("UPDATE GrievanceDetails g SET g.userID = :userID WHERE g.gwid = :gwid") int unassignGrievance(@Param("userID") Integer userID, @Param("gwid") Long gwid); + @Modifying @Transactional @Query("UPDATE GrievanceDetails g SET g.isAllocated = :isAllocated WHERE g.gwid = :gwid") int updateGrievanceAllocationStatus(@Param("gwid") Long gwid, @Param("isAllocated") Boolean isAllocated); + + @Query("Select grievance.preferredLanguage, count(grievance) from GrievanceDetails grievance where grievance.isAllocated=false group by grievance.preferredLanguage") + public Set fetchUnallocatedGrievanceCount(); + + @Modifying + @Query("UPDATE GrievanceDetails g SET g.complaintResolution = :complaintResolution, g.remarks = :remarks, g.modifiedBy = :modifiedBy " + + "WHERE g.complaintID = :complaintID AND g.beneficiaryRegID = :beneficiaryRegID AND g.providerServiceMapID = :providerServiceMapID" + @Query("Select grievance.preferredLanguage, count(grievance) from GrievanceDetails grievance where grievance.isAllocated=false " + "AND grievance.createdDate BETWEEN :filterStartDate AND :filterEndDate " + "group by grievance.preferredLanguage") @@ -91,12 +104,16 @@ public Set fetchUnallocatedGrievanceCount( int updateComplaintResolution(@Param("complaintResolution") String complaintResolution, @Param("remarks") String remarks, @Param("modifiedBy") String modifiedBy, + @Param("benCallID") Long benCallID, @Param("complaintID") String complaintID, @Param("beneficiaryRegID") Long beneficiaryRegID, @Param("userID") Integer userID); @Modifying + @Query("UPDATE GrievanceDetails g SET g.complaintResolution = :complaintResolution, g.modifiedBy = :modifiedBy " + + "WHERE g.complaintID = :complaintID AND g.beneficiaryRegID = :beneficiaryRegID AND g.providerServiceMapID = :providerServiceMapID" + @Query("UPDATE GrievanceDetails g SET g.complaintResolution = :complaintResolution, g.modifiedBy = :modifiedBy, " + "g.benCallID = :benCallID " + "WHERE g.complaintID = :complaintID AND g.beneficiaryRegID = :beneficiaryRegID " @@ -104,11 +121,14 @@ int updateComplaintResolution(@Param("complaintResolution") String complaintReso @Transactional int updateComplaintResolution(@Param("complaintResolution") String complaintResolution, @Param("modifiedBy") String modifiedBy, + @Param("benCallID") Long benCallID, @Param("complaintID") String complaintID, @Param("beneficiaryRegID") Long beneficiaryRegID, @Param("userID") Integer userID); + + @Query(" Select grievance.callCounter, grievance.retryNeeded,grievance.complaintResolution FROM GrievanceDetails grievance where grievance.complaintID = :complaintID") public List getCallCounter(@Param("complaintID") String complaintID); @@ -133,6 +153,7 @@ public int updateCallCounter(@Param("callCounter") Integer callCounter, @Param("complaintID") String complaintID, @Param("beneficiaryRegID") Long beneficiaryRegID, @Param("userID") Integer userID); + @Query("SELECT g FROM GrievanceDetails g WHERE " + "(g.state = :state OR :state IS NULL) " 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 4ab722e7..9e8dcb0d 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -37,7 +37,6 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.iemr.common.data.beneficiary.Beneficiary; import com.iemr.common.data.mctshistory.MctsOutboundCallDetail; @@ -77,6 +76,8 @@ public class RegisterBenificiaryServiceImpl implements RegisterBenificiaryServic @Autowired Validator validator; + + @Autowired OutboundHistoryRepository outboundHistoryRepository; @@ -171,6 +172,7 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); + identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO .setBenFamilyDTOs(identityMapper.benPhoneMapListToBenFamilyDTOList(beneficiaryModel.getBenPhoneMaps())); String request = new Gson().toJson(identityDTO); diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java new file mode 100644 index 00000000..234640a8 --- /dev/null +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java @@ -0,0 +1,14 @@ +package com.iemr.common.service.beneficiaryOTPHandler; + +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import org.json.JSONObject; + +public interface BeneficiaryOTPHandler { + public String sendOTP(BeneficiaryConsentRequest obj) throws Exception; + + public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception; + + public String resendOTP(BeneficiaryConsentRequest obj) throws Exception; + +} diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java new file mode 100644 index 00000000..9fa73005 --- /dev/null +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -0,0 +1,207 @@ +/* + * 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.beneficiaryOTPHandler; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.primitives.Ints; +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import com.iemr.common.data.sms.SMSTemplate; +import com.iemr.common.data.sms.SMSType; +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.users.IEMRAdminUserServiceImpl; +import com.iemr.common.utils.config.ConfigProperties; +import com.iemr.common.utils.http.HttpUtils; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.*; +import java.util.concurrent.TimeUnit; + +@Service +public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { + + @Autowired + HttpUtils httpUtils; + @Autowired + private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; + + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + @Autowired + SMSTemplateRepository smsTemplateRepository; + private LoadingCache otpCache; + + @Autowired + SMSTypeRepository smsTypeRepository; + + private static final Integer EXPIRE_MIN = 5; + private static final String SMS_GATEWAY_URL = ConfigProperties.getPropertyByName("sms-gateway-url"); + + // Constructor for new object creation + public BeneficiaryOTPHandlerImpl() { + otpCache = CacheBuilder.newBuilder().expireAfterWrite(EXPIRE_MIN, TimeUnit.MINUTES) + .build(new CacheLoader() { + public String load(String key) { + return "0"; + } + }); + } + + /*** + * @param obj + * @return success if OTP sent successfully + */ + @Override + public String sendOTP(BeneficiaryConsentRequest obj) throws Exception { + int otp = generateOTP(obj.getMobNo()); + sendSMS(otp, obj); + return "success"; + } + + /*** + * @param obj + * @return OTP verification success or failure + * + */ + @Override + public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception { + String cachedOTP = otpCache.get(obj.getMobNo()); + String inputOTPEncrypted = getEncryptedOTP(obj.getOtp()); + + if (cachedOTP.equalsIgnoreCase(inputOTPEncrypted)) { + JSONObject responseObj = new JSONObject(); + responseObj.put("userName", obj.getMobNo()); + responseObj.put("userID", obj.getMobNo()); + + JSONObject responseOBJ = iEMRAdminUserServiceImpl.generateKeyPostOTPValidation(responseObj); + + return responseOBJ; + } else { + throw new Exception("Please enter valid OTP"); + } + + } + + /*** + * @param obj + * @return success if OTP re-sent successfully + */ + @Override + public String resendOTP(BeneficiaryConsentRequest obj) throws Exception { + int otp = generateOTP(obj.getMobNo()); + sendSMS(otp, obj); + return "success"; + } + + // generate 6 digit random no # + public int generateOTP(String authKey) throws Exception { + String generatedPassword = null; + Random random = SecureRandom.getInstanceStrong(); + int otp = 100000 + random.nextInt(900000); + + generatedPassword = getEncryptedOTP(otp); + + if (otpCache != null) + otpCache.put(authKey, generatedPassword); + else { + BeneficiaryOTPHandlerImpl obj = new BeneficiaryOTPHandlerImpl(); + obj.otpCache.put(authKey, generatedPassword); + } + return otp; + } + + // SHA-256 encoding logic implemented + private String getEncryptedOTP(int otp) throws Exception { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] bytes = md.digest(Ints.toByteArray(otp)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + + return sb.toString(); + } + + // send SMS to beneficiary + + + public String sendSMS(int otp, BeneficiaryConsentRequest obj) { + + final RestTemplate restTemplate = new RestTemplate(); + String sendSMSURL = ConfigProperties.getPropertyByName("send-message-url"); + + String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL + "/" + sendSMSURL; + + + try { + + +// String message = "Dear Citizen, your OTP for login is " +otp+". Use it within 15 minutes. Do not share this code. Regards PSMRIAM."; + String message = "Hello! Your OTP for providing consent for registration on AMRIT is " + otp + ". This OTP is valid for 10 minutes. Kindly share it only with " + obj.getUserName() + " " + obj.getDesignation() + " to complete the process. PSMRI"; + + // Build payload + Map payload = new HashMap<>(); + payload.put("customerId", ConfigProperties.getPropertyByName("sms-username")); + payload.put("destinationAddress", obj.getMobNo()); + payload.put("message", message); + payload.put("sourceAddress", ConfigProperties.getPropertyByName("source-address")); + payload.put("messageType", "SERVICE_IMPLICIT"); + payload.put("dltTemplateId", ConfigProperties.getPropertyByName("dltTemplateId")); + payload.put("entityId",ConfigProperties.getPropertyByName("entityId") ); + payload.put("otp", true); + // Set headers + HttpHeaders headers = new HttpHeaders(); + String auth = ConfigProperties.getPropertyByName("sms-username") + ":" + ConfigProperties.getPropertyByName("sms-password"); + headers.add("Authorization", + "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); + + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> request = new HttpEntity<>(payload, headers); + + // Call API + ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + + // Return response + return response.getBody(); + + } catch (Exception e) { + e.printStackTrace(); + return "Error sending SMS: " + e.getMessage(); + } + } + +} diff --git a/src/main/java/com/iemr/common/service/grievance/GrievanceDataSync.java b/src/main/java/com/iemr/common/service/grievance/GrievanceDataSync.java index f0798533..354f18d6 100644 --- a/src/main/java/com/iemr/common/service/grievance/GrievanceDataSync.java +++ b/src/main/java/com/iemr/common/service/grievance/GrievanceDataSync.java @@ -19,4 +19,6 @@ public String fetchUnallocatedGrievanceCount(String preferredLanguage, Timestamp public String completeGrievanceCall(String request) throws Exception; + public String completeGrievanceCall(String request) throws Exception; + } diff --git a/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java b/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java index 5a05b94f..f193c643 100644 --- a/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java +++ b/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java @@ -38,6 +38,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.iemr.common.data.callhandling.CallType; +import com.iemr.common.data.everwell.EverwellDetails; import com.iemr.common.data.grievance.GrievanceCallRequest; import com.iemr.common.data.grievance.GrievanceDetails; import com.iemr.common.data.grievance.GrievanceTransaction; @@ -194,6 +195,26 @@ public String dataSyncToGrievance() { : null); ArrayList lists = grievanceFetchBenDetailsRepo .findByComplaintId(formattedComplaintId); + + grievance.setComplaint(grievanceJsonData.has("Complaint") + ? grievanceJsonData.get("Complaint").getAsString() : null); + String severityName = grievanceJsonData.has("severity") && grievanceJsonData.get("severity").getAsJsonObject().has("severity") + ? grievanceJsonData.get("severity").getAsJsonObject().get("severity").getAsString() + : null; + grievance.setSeverety(severityName); + + // Setting Level + Integer levelId = grievanceJsonData.has("level") && grievanceJsonData.get("level").getAsJsonObject().has("levelId") + ? grievanceJsonData.get("level").getAsJsonObject().get("levelId").getAsInt() + : null; + grievance.setLevel(levelId); + + // Setting state + String stateName = grievanceJsonData.has("state") && grievanceJsonData.get("state").getAsJsonObject().has("stateName") + ? grievanceJsonData.get("state").getAsJsonObject().get("stateName").getAsString() + : null; + grievance.setState(stateName);; + grievance.setComplaint(grievanceJsonData.has("Complaint") ? grievanceJsonData.get("Complaint").getAsString() : null); @@ -220,6 +241,7 @@ public String dataSyncToGrievance() { : null; grievance.setState(stateName); + for (Object[] objects : lists) { if (objects != null && objects.length <= 4) { grievance.setComplaintID((String) objects[0]); @@ -228,6 +250,12 @@ public String dataSyncToGrievance() { grievance.setProviderServiceMapID((Integer) objects[3]); } } + + + + + // setting language related properties and other + Long benDetailsID = grievanceDataRepo .getBeneficiaryMapping(grievance.getBeneficiaryRegID()); ArrayList list1 = grievanceDataRepo @@ -538,6 +566,120 @@ public String fetchUnallocatedGrievanceCount(String preferredLanguage, Timestamp public String completeGrievanceCall(String request) throws Exception { GrievanceCallRequest grievanceCallRequest = InputMapper.gson().fromJson(request, GrievanceCallRequest.class); + String complaintID = grievanceCallRequest.getComplaintID(); + Integer userID = grievanceCallRequest.getUserID(); + Boolean isCompleted = grievanceCallRequest.getIsCompleted(); + Long beneficiaryRegID = grievanceCallRequest.getBeneficiaryRegID(); + Integer callTypeID = grievanceCallRequest.getCallTypeID(); + Integer providerServiceMapId = grievanceCallRequest.getProviderServiceMapId(); + + Integer providerServiceMapID = grievanceCallRequest.getProviderServiceMapID(); + + CallType callTypeObj = new CallType(); + String response = "failure"; + int updateCount = 0; + int updateCallCounter = 0; + int callCounter = 0; + + try { + + GrievanceDetails grievanceCallStatus = new GrievanceDetails(); + + List lists = grievanceDataRepo.getCallCounter(complaintID); + for (Object[] objects : lists) { + if (objects != null && objects.length >= 2) { + grievanceCallStatus.setCallCounter((Integer) objects[0]); + grievanceCallStatus.setRetryNeeded((Boolean)objects[1]); + } + } + + // Fetching CallDetails using BenCallID and CallTypeID + Set callTypesArray = new HashSet(); + callTypesArray = iEMRCalltypeRepositoryImplCustom.getCallDetails(callTypeID); + for (Object[] object : callTypesArray) + { + if (object != null && object.length >= 2) + { + callTypeObj.setCallGroupType((String) object[0]); + callTypeObj.setCallType((String) object[1]); + + } + + } + + String callGroupType = callTypeObj.getCallGroupType(); + String callType = callTypeObj.getCallType(); + + + // Logic for reattempt based on call group type and call type + + boolean isRetryNeeded = grievanceCallStatus.getRetryNeeded(); + if (callGroupType.equals("Valid")) { + // Conditions when no reattempt is needed + + if (callType.equals("Valid") || callType.equals("Wrong Number") || callType.equals("Test Call")) { + + if (callType.equals("Valid") || callType.equals("Test Call")) { + isRetryNeeded = false; + } else if (callType.equals("Disconnected Call") || callType.equals("Serviced Call") || + callType.equals("Silent Call") || callType.equals("Call Back")) { + // Reattempt is needed for these call subtypes + isRetryNeeded = true; + } + } + + // Check if max attempts (3) are reached + if (isRetryNeeded == true && callCounter < grievanceAllocationRetryConfiguration) { + // Increment the call counter for reattempt + grievanceCallStatus.setCallCounter(grievanceCallStatus.getCallCounter() + 1); + // Update the retryNeeded flag + grievanceCallStatus.setRetryNeeded(true); + updateCallCounter = grievanceDataRepo.updateCallCounter(callCounter, grievanceCallStatus.getRetryNeeded(), grievanceCallRequest.getComplaintID(), + grievanceCallRequest.getBeneficiaryRegID(), grievanceCallRequest.getProviderServiceMapId(), + grievanceCallRequest.getUserID()); + // response = "Successfully closing call."; // Return success when reattempt logic is applied successfully. The grievance call needs to be retried, and a reattempt is performed. + if (updateCallCounter > 0) + response = "Successfully closing call"; + else { + response = "failure"; + } + } else if (callCounter == grievanceAllocationRetryConfiguration) { + // Max attempts reached, no further reattempt + grievanceCallStatus.setRetryNeeded(false); + updateCount = grievanceDataRepo.updateCompletedStatusInCall(isCompleted, grievanceCallStatus.getRetryNeeded(), complaintID, userID, beneficiaryRegID, providerServiceMapId); + + if (callGroupType.equals("Invalid") && callType.equals("Wrong Number")) { + isRetryNeeded = false; + //isCompleted = true; + grievanceDataRepo.updateCompletedStatusInCall(isCompleted, isRetryNeeded, complaintID, userID, beneficiaryRegID, providerServiceMapID); + } + + // Check if max attempts (3) are reached + if (isRetryNeeded == true && grievanceCallStatus.getCallCounter() < grievanceAllocationRetryConfiguration) { + // Increment the call counter for reattempt + grievanceCallStatus.setCallCounter(grievanceCallStatus.getCallCounter() + 1); + // Update the retryNeeded flag + isRetryNeeded = true; + //isCompleted = false; + updateCallCounter = grievanceDataRepo.updateCallCounter(grievanceCallStatus.getCallCounter(), isRetryNeeded, grievanceCallRequest.getComplaintID(), + grievanceCallRequest.getBeneficiaryRegID(), grievanceCallRequest.getProviderServiceMapID(), + grievanceCallRequest.getUserID()); + // Return success when reattempt logic is applied successfully. The grievance call needs to be retried, and a reattempt is performed. + if (updateCallCounter > 0) + response = "Successfully closing call"; + else { + response = "failure in closing call"; + } + } else if (grievanceCallStatus.getCallCounter()== grievanceAllocationRetryConfiguration) { + // Max attempts reached, no further reattempt + isRetryNeeded = false; + //isCompleted = true; + updateCount = grievanceDataRepo.updateCompletedStatusInCall(isCompleted, isRetryNeeded, complaintID, userID, beneficiaryRegID, providerServiceMapID); + response = "max_attempts_reached"; // Indicate that max attempts are reached + + + } else { + String complaintID = grievanceCallRequest.getComplaintID(); Integer userID = grievanceCallRequest.getUserID(); Boolean isCompleted = grievanceCallRequest.getIsCompleted(); @@ -617,6 +759,7 @@ else if (callGroupType.equalsIgnoreCase("Invalid") && (callType.equalsIgnoreCase response = "Successfully closing call"; } + } catch (Exception e) { response = "error: " + e.getMessage(); } @@ -624,4 +767,5 @@ else if (callGroupType.equalsIgnoreCase("Invalid") && (callType.equalsIgnoreCase return response; // Return the response (either success or error message) } + } diff --git a/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingService.java b/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingService.java index c1a19866..34abb788 100644 --- a/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingService.java +++ b/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingService.java @@ -21,6 +21,7 @@ public interface GrievanceHandlingService { public List getFormattedGrievanceData(String request) throws Exception; public String saveComplaintResolution(String request) throws Exception; + public String getGrievanceDetailsWithRemarks(String request) throws Exception; diff --git a/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java b/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java index 68e8e76e..0ec9c147 100644 --- a/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java +++ b/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java @@ -243,6 +243,9 @@ public String moveToBin(String request) throws Exception { // Step 4: Unassign grievances from the user and "move them to bin" int totalUnassigned = 0; for (GrievanceDetails grievance : grievancesToMove) { + int rowsAffected = grievanceDataRepo.unassignGrievance(grievance.getGrievanceId(), + moveToBinRequest.getUserID()); + grievance.setUserID(null); int rowsAffected = grievanceDataRepo.unassignGrievance(grievance.getUserID(), grievance.getGwid()); if (rowsAffected > 0) { @@ -251,6 +254,15 @@ public String moveToBin(String request) throws Exception { grievance.getIsAllocated()); if (updateFlagResult > 0) { totalUnassigned++; + logger.debug("Unassigned grievance ID {} from user ID {}", grievance.getGrievanceId(), + moveToBinRequest.getUserID()); + } else { + logger.error("Failed to unassign grievance ID {} from user ID {}", grievance.getGrievanceId(), + moveToBinRequest.getUserID()); + } + } else { + logger.error("Failed to unassign grievance ID {} from user ID {}", grievance.getGrievanceId(), + logger.debug("Unassigned grievance gwid {} from user ID {}", grievance.getGwid(), moveToBinRequest.getUserID()); } else { @@ -392,6 +404,7 @@ public String saveComplaintResolution(String request) throws Exception { if (grievanceRequest.getCreatedBy() == null) { throw new IllegalArgumentException("CreatedBy is required"); } + if(grievanceRequest.getBenCallID() == null) { throw new IllegalArgumentException("BencallId is required"); } @@ -403,16 +416,22 @@ public String saveComplaintResolution(String request) throws Exception { Integer providerServiceMapID = grievanceRequest.getProviderServiceMapID(); Integer userID = grievanceRequest.getUserID(); String createdBy = grievanceRequest.getCreatedBy(); + + Long benCallID = grievanceRequest.getBenCallID(); String modifiedBy = createdBy; int updateCount = 0; if (remarks == null) { + updateCount = grievanceDataRepo.updateComplaintResolution(complaintResolution, modifiedBy, complaintID, + updateCount = grievanceDataRepo.updateComplaintResolution(complaintResolution, modifiedBy, benCallID, complaintID, beneficiaryRegID, userID); logger.debug("updated complaint resolution without remarks for complaint id: {}", complaintID); } else { + updateCount = grievanceDataRepo.updateComplaintResolution(complaintResolution, remarks, modifiedBy, complaintID, + updateCount = grievanceDataRepo.updateComplaintResolution(complaintResolution, remarks, modifiedBy, benCallID, complaintID, beneficiaryRegID, userID); logger.debug("updated complaint resolution with remarks for complaint id: {}", complaintID); @@ -424,8 +443,7 @@ public String saveComplaintResolution(String request) throws Exception { throw new Exception("Failed to update complaint resolution"); } } - - + private Date parseDate(String dateStr) { diff --git a/src/main/java/com/iemr/common/service/notification/NotificationService.java b/src/main/java/com/iemr/common/service/notification/NotificationService.java index a3c85387..6fa8ee8d 100644 --- a/src/main/java/com/iemr/common/service/notification/NotificationService.java +++ b/src/main/java/com/iemr/common/service/notification/NotificationService.java @@ -55,4 +55,5 @@ String createEmergencyContacts(String request) String updateEmergencyContacts(String request) throws JSONException, NoSuchAlgorithmException, IOException, IEMRException, Exception; + } diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index b83f4873..e27ee24b 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -35,6 +35,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo String contextPath = request.getContextPath(); logger.info("JwtUserIdValidationFilter invoked for path: " + path); + // Log cookies for debugging Cookie[] cookies = request.getCookies(); if (cookies != null) { 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 b8359fe6..eee5ea85 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -1,24 +1,24 @@ /* -* 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/. -*/ + * 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.utils.http; @@ -38,24 +38,102 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + @Configuration @Component public class HTTPRequestInterceptor implements HandlerInterceptor { - private Validator validator; + private Validator validator; - Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); + Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); - @Autowired - public void setValidator(Validator validator) { - this.validator = validator; - } + @Autowired + public void setValidator(Validator validator) { + this.validator = validator; + } - private SessionObject sessionObject; + private SessionObject sessionObject; - @Autowired - public void setSessionObject(SessionObject sessionObject) { - this.sessionObject = sessionObject; - } + @Autowired + public void setSessionObject(SessionObject sessionObject) { + this.sessionObject = sessionObject; + } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { + 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 = null; + String preAuth = request.getHeader("Authorization"); + if (null != preAuth && preAuth.contains("Bearer ")) + authorization = preAuth.replace("Bearer ", ""); + else + authorization = preAuth; + 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 "create": + 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": + + 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) { + OutputResponse output = new OutputResponse(); + output.setError(e); + response.getOutputStream().print(output.toString()); + response.setContentType(MediaType.APPLICATION_JSON); + response.setContentLength(output.toString().length()); + response.setHeader("Access-Control-Allow-Origin", "*"); + status = false; + } + } + return status; + } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { @@ -132,30 +210,30 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons return status; } - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) - 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 ", ""); - else - authorization = postAuth; - logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); - if (authorization != null) { - sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); - } - } catch (Exception e) { - logger.debug("postHandle failed with error " + e.getMessage()); - } - } + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) + 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 ", ""); +// else +// authorization = postAuth; +// logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); +// if (authorization != null) { +// sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); +// } +// } catch (Exception e) { +// logger.debug("postHandle failed with error " + e.getMessage()); +// } + } - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3) - throws Exception { - logger.debug("In afterCompletion Request Completed"); - } + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3) + throws Exception { + logger.debug("In afterCompletion Request Completed"); + } } \ No newline at end of file