package com.billpaymentservice.bbps.serviceImpl; import java.util.Map; import org.modelmapper.ModelMapper; import org.modelmapper.convention.MatchingStrategies; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.request.CloseComplaintRequest; import com.billpaymentservice.bbps.dto.request.ComplainStatusRequest; import com.billpaymentservice.bbps.dto.request.ReOpenComplain; import com.billpaymentservice.bbps.dto.response.CloseComplaintStatusResponse; import com.billpaymentservice.bbps.dto.response.ComplaintHistoryStatusResponse; import com.billpaymentservice.bbps.dto.response.ComplaintStatusResponse; import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.request.ComplaintRequestDTO; import com.billpaymentservice.bbps.dto.response.BillerDataResponse; import com.billpaymentservice.bbps.dto.response.ComplaintResponse; import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.entites.BillPayment; import com.billpaymentservice.bbps.entites.BillerDetails; import com.billpaymentservice.bbps.entites.ComplaintDetails; import com.billpaymentservice.bbps.entites.InboundTraceLog; import com.billpaymentservice.bbps.entites.OutboundTraceLog; import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository; import com.billpaymentservice.bbps.service.ComplainService; import com.billpaymentservice.bbps.util.BBPSConstant; import com.billpaymentservice.bbps.util.BillerMapperHelper; import com.billpaymentservice.bbps.util.Helper; import com.fasterxml.jackson.annotation.JsonInclude; import com.billpaymentservice.bbps.repository.ComplainRepository; import com.billpaymentservice.bbps.service.ComplainService; import com.billpaymentservice.bbps.util.BBPSConstant; import com.billpaymentservice.bbps.util.EntityRelationshipUtil; import com.billpaymentservice.bbps.util.Helper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @Service public class ComplainServiceImpl implements ComplainService { @Value("${agent.data.url}") private String agentDtaUrl; @Value("${complaint.data.url}") private String complainDataUrl; private final RestClient restClient; private final HttpService httpService; private final Helper helper; private final BharatConnectMasterRepository beneficiaryDetailsRepository; private final BillerMapperHelper mapperHelper; private final ComplainRepository complainRepository; private final ObjectMapper objectMapper = new ObjectMapper(); private static final Logger LOGGER = LoggerFactory.getLogger(AgentServiceImpl.class); public ComplainServiceImpl(RestClient restClient, HttpService httpService, Helper helper, BharatConnectMasterRepository beneficiaryDetailsRepository, BillerMapperHelper mapperHelper, ComplainRepository complainRepository) { this.restClient = restClient; this.httpService = httpService; this.helper = helper; this.beneficiaryDetailsRepository = beneficiaryDetailsRepository; this.mapperHelper = mapperHelper; this.complainRepository = complainRepository; } @Override public ResponseModel addComplain(ComplaintRequestDTO complainRequestDTO) { LOGGER.info("Initiating addComplain for request ID: {} and MID", complainRequestDTO.getReqId(), complainRequestDTO.getMid()); String apiName = "ADDCOMPLAIN"; String txnId = helper.generateTxnId(15); String requestId = complainRequestDTO.getReqId(); String fullUrl = complainDataUrl + BBPSConstant.ADD_COMPLAIN_ENDPOINT; String requestJson = helper.convertObjectToJson(complainRequestDTO); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); HttpHeaders headers = new HttpHeaders(); headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("agentId", headersData.getAgentId()); headers.set("tenantId", headersData.getTenantId()); headers.setContentType(MediaType.APPLICATION_JSON); InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, complainRequestDTO.getMid(), "POST", requestJson); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, fullUrl, "POST", null); LOGGER.info("Calling external API: {}", fullUrl); LOGGER.info("Request payload: {}", requestJson); Map responseMap = httpService.postRequest(fullUrl, requestJson, headers); String responseData = responseMap.get("data"); LOGGER.info("fetched data from api is :{}", responseData); helper.updateOutboundLogResponse(outboundLog, responseData); try { Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); LOGGER.info("Parsed response data: {}", dataMap); if (!dataMap.containsKey("generalResp")) { helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status"))); throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), String.valueOf(dataMap.get("remarks"))); } ComplaintResponse responseWrapper = objectMapper.convertValue(dataMap, ComplaintResponse.class); GeneralResp generalResp = responseWrapper.getGeneralResp(); ModelMapper mapper = new ModelMapper(); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); ComplaintDetails entity = mapper.map(responseWrapper.getComplaints(), ComplaintDetails.class); entity.setReqId(complainRequestDTO.getReqId()); entity.setTxnId(txnId); complainRepository.save(entity); ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); return responseModel; } catch (JsonProcessingException e) { LOGGER.error("Error parsing responseData JSON: {}", e.getMessage()); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); throw new CustomException("Invalid JSON received from API"); } } @Override public ResponseModel getComplaintStatus(ComplainStatusRequest request) { LOGGER.info("Fetching Compalint Status by Complaint Id={}", request.getComplaintId(), request.getReqId()); String apiName = "Complaint Status"; String txnId = helper.generateTxnId(15); String reqId = request.getReqId(); String complaintId = request.getComplaintId(); String fullUrl = agentDtaUrl + BBPSConstant.COMPALINT_STATUS; helper.validateMerchant(request.getMid()); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); HttpHeaders headers = new HttpHeaders(); headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("agentId", headersData.getAgentId()); headers.set("tenantId", headersData.getTenantId()); headers.setContentType(MediaType.APPLICATION_JSON); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); String requestJson = helper.convertObjectToJson(request); InboundTraceLog inboundLog = helper.createInboundLog(reqId, txnId, apiName, request.getMid(), "POST", requestJson); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl, "POST", complaintId); LOGGER.debug("Outbound log created successfully for Complaint : {}", fullUrl); try { LOGGER.info("Calling external API: {}", fullUrl); Map responseMap = httpService.postRequest(fullUrl, requestJson, headers); String responseData = responseMap.get("data"); LOGGER.info("Complaint FetchById Response: {}", responseData); helper.updateOutboundLogResponse(outboundLog, responseData); Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); if (!dataMap.containsKey("genericResponse")) { helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); LOGGER.warn("Invalid response structure for txnId: {}", txnId); throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), String.valueOf(dataMap.get("remarks"))); } ComplaintStatusResponse responseWrapper = objectMapper.convertValue(dataMap, ComplaintStatusResponse.class); GeneralResp generalResp = responseWrapper.getGeneralResp(); String status = generalResp.getStatus(); LOGGER.info("Current Complaint Status: {}", status); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); mapperHelper.saveComplaintStatus(responseWrapper, reqId, txnId); LOGGER.info("Complaint data saved successfully for billId: {}", complaintId); return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); } catch (JsonProcessingException e) { LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); throw new CustomException("Invalid JSON received from API"); } } @Override public ResponseModel reOpenComplaint(ReOpenComplain request) { LOGGER.info("Fetching ReOpen Complaint by Complaint Id={}", request.getComplaintId(), request.getReqId()); String apiName = "Complaint Status"; String txnId = helper.generateTxnId(15); String reqId = request.getReqId(); String complaintId = request.getComplaintId(); String fullUrl = agentDtaUrl + BBPSConstant.REOPEN_COMPALINT; helper.validateMerchant(request.getMid()); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); HttpHeaders headers = new HttpHeaders(); headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("agentId", headersData.getAgentId()); headers.set("tenantId", headersData.getTenantId()); headers.setContentType(MediaType.APPLICATION_JSON); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); String requestJson = helper.convertObjectToJson(request); InboundTraceLog inboundLog = helper.createInboundLog(reqId, txnId, apiName, request.getMid(), "POST", requestJson); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl, "POST", complaintId); LOGGER.debug("Outbound log created successfully for Complaint : {}", fullUrl); try { LOGGER.info("Calling external API: {}", fullUrl); Map responseMap = httpService.postRequest(fullUrl, requestJson, headers); String responseData = responseMap.get("data"); LOGGER.info("Complaint ReOpen FetchById Response: {}", responseData); helper.updateOutboundLogResponse(outboundLog, responseData); Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); if (!dataMap.containsKey("genericResponse")) { helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); LOGGER.warn("Invalid response structure for txnId: {}", txnId); throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), String.valueOf(dataMap.get("remarks"))); } ComplaintStatusResponse responseWrapper = objectMapper.convertValue(dataMap, ComplaintStatusResponse.class); GeneralResp generalResp = responseWrapper.getGeneralResp(); String status = generalResp.getStatus(); LOGGER.info("Current Complaint ReOpen Status: {}", status); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); mapperHelper.saveReOpenComplaint(responseWrapper, reqId, txnId); LOGGER.info("Complaint ReOpen data saved successfully for billId: {}", complaintId); return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); } catch (JsonProcessingException e) { LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); throw new CustomException("Invalid JSON received from API"); } } @Override public ResponseModel viewComplaintHistory(ComplainStatusRequest request) { LOGGER.info("Fetching View Complaint History Complaint by Complaint Id={}", request.getComplaintId(), request.getReqId()); String apiName = "Complaint Status"; String txnId = helper.generateTxnId(15); String reqId = request.getReqId(); String complaintId = request.getComplaintId(); String fullUrl = agentDtaUrl + BBPSConstant.COMPLAINT_HISTORY + request.getComplaintId(); helper.validateMerchant(request.getMid()); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); HttpHeaders headers = new HttpHeaders(); headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("agentId", headersData.getAgentId()); headers.set("tenantId", headersData.getTenantId()); headers.setContentType(MediaType.APPLICATION_JSON); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); String requestJson = helper.convertObjectToJson(request); InboundTraceLog inboundLog = helper.createInboundLog(reqId, txnId, apiName, request.getMid(), "GET", requestJson); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl, "GET", complaintId); LOGGER.debug("Outbound log created successfully for Complaint : {}", fullUrl); try { LOGGER.info("Calling external API: {}", fullUrl); Map responseMap = httpService.getRequest(fullUrl, headers); String responseData = responseMap.get("data"); LOGGER.info("Complaint History Complaint FetchById Response: {}", responseData); helper.updateOutboundLogResponse(outboundLog, responseData); Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); if (!dataMap.containsKey("generalResp")) { helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); LOGGER.warn("Invalid response structure for txnId: {}", txnId); throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), String.valueOf("")); } ComplaintHistoryStatusResponse responseWrapper = objectMapper.convertValue(dataMap, ComplaintHistoryStatusResponse.class); GeneralResp generalResp = responseWrapper.getGeneralResp(); String status = generalResp.getStatus(); LOGGER.info("Current Complaint ReOpen Status: {}", status); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); String saveComplaintHistory = mapperHelper.saveComplaintHistory(responseWrapper, reqId, txnId); LOGGER.info("Complaint ReOpen data saved successfully for Count History: {}", saveComplaintHistory); return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); } catch (JsonProcessingException e) { LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); throw new CustomException("Invalid JSON received from API"); } } @Override public ResponseModel closeComplaint(CloseComplaintRequest request) { LOGGER.info("Fetching Close Complaint by Complaint Id={}", request.getComplaintId(), request.getReqId()); String apiName = "Complaint Status"; String txnId = helper.generateTxnId(15); String reqId = request.getReqId(); String complaintId = request.getComplaintId(); String fullUrl = agentDtaUrl + BBPSConstant.CLOSE_COMPLAINT; helper.validateMerchant(request.getMid()); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); HttpHeaders headers = new HttpHeaders(); headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("agentId", headersData.getAgentId()); headers.set("tenantId", headersData.getTenantId()); headers.setContentType(MediaType.APPLICATION_JSON); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); String requestJson = helper.convertObjectToJson(request); InboundTraceLog inboundLog = helper.createInboundLog(reqId, txnId, apiName, request.getMid(), "POST", requestJson); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl, "POST", complaintId); LOGGER.debug("Outbound log created successfully for Complaint : {}", fullUrl); try { LOGGER.info("Calling external API: {}", fullUrl); Map responseMap = httpService.postRequest(fullUrl, requestJson, headers); String responseData = responseMap.get("data"); LOGGER.info("Complaint Close FetchById Response: {}", responseData); helper.updateOutboundLogResponse(outboundLog, responseData); Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); if (!dataMap.containsKey("genericResponse")) { helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); LOGGER.warn("Invalid response structure for txnId: {}", txnId); throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), String.valueOf(dataMap.get("remarks"))); } CloseComplaintStatusResponse responseWrapper = objectMapper.convertValue(dataMap, CloseComplaintStatusResponse.class); GeneralResp generalResp = responseWrapper.getGeneralResp(); String status = generalResp.getStatus(); LOGGER.info("Current Complaint Close Status: {}", status); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); // mapperHelper.saveReOpenComplaint(responseWrapper, reqId, txnId); LOGGER.info("Complaint Close data saved successfully for billId: {}", complaintId); return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); } catch (JsonProcessingException e) { LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); throw new CustomException("Invalid JSON received from API"); } } }