From f1a2d62a392cad9e92f6d702c6ade713ee9d2e8f Mon Sep 17 00:00:00 2001 From: Lincpay Tech Date: Fri, 21 Nov 2025 21:22:52 +0530 Subject: [PATCH 1/3] added billValidateByBillId direct method --- .../entites/AdditionalInfoBillValidate.java | 29 ++ .../bbps/serviceImpl/AgentServiceImpl.java | 372 ++++++------------ 2 files changed, 155 insertions(+), 246 deletions(-) create mode 100644 src/main/java/com/billpaymentservice/bbps/entites/AdditionalInfoBillValidate.java diff --git a/src/main/java/com/billpaymentservice/bbps/entites/AdditionalInfoBillValidate.java b/src/main/java/com/billpaymentservice/bbps/entites/AdditionalInfoBillValidate.java new file mode 100644 index 0000000..57392d8 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/AdditionalInfoBillValidate.java @@ -0,0 +1,29 @@ +package com.billpaymentservice.bbps.entites; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Table(name = "additional_info_bill_validate") +@Getter +@Setter +public class AdditionalInfoBillValidate { + @Id + @GeneratedValue + private Long id; + + private String name; + private String value; + // ✅ Many Params → One Bill + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "bill_id_fk") + private BillValidation bill; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java index 8686427..efc03f8 100644 --- a/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java @@ -75,8 +75,8 @@ public class AgentServiceImpl implements AgentService { @Override public ResponseModel initiateBillFetch(FetchBillRequest fetchBillRequest) { - LOGGER.info("Initiating bill fetch for request ID: {} and MID", fetchBillRequest.getReqId(), - fetchBillRequest.getMid()); + LOGGER.info("Initiating bill fetch for request ID: {} and MID :{} and billerId:{} ", fetchBillRequest.getReqId(), + fetchBillRequest.getMid(),fetchBillRequest.getBillerId()); String apiName = "InitiateBillFetch"; String txnId = helper.generateTxnId(15); String requestId = fetchBillRequest.getReqId(); @@ -224,69 +224,81 @@ public class AgentServiceImpl implements AgentService { @Override public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest) { - String apiName = "FetchBillById"; - String txnId = helper.generateTxnId(15); - String reqId = billFetchByBillIdRequest.getReqId(); - String billId = billFetchByBillIdRequest.getBillId(); - String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + billFetchByBillIdRequest.getBillId(); + String apiName = "FetchBillById"; + String txnId = helper.generateTxnId(15); + String reqId = billFetchByBillIdRequest.getReqId(); + String billId = billFetchByBillIdRequest.getBillId(); + String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + billFetchByBillIdRequest.getBillId(); - LOGGER.info("Initiating {} API for billId={} and reqId={}", apiName, billId, reqId); + LOGGER.info("Initiating {} API for billId={} and reqId={}", apiName, billId, reqId); - try { - helper.validateMerchant(billFetchByBillIdRequest.getMid()); - LOGGER.debug("Merchant validated successfully for MID={}", billFetchByBillIdRequest.getMid()); + // create inbound log (GET -> no request body) + InboundTraceLog inboundLog = helper.createInboundLog(reqId, txnId, apiName, + billFetchByBillIdRequest.getMid(), "GET", null); - 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); + try { + helper.validateMerchant(billFetchByBillIdRequest.getMid()); + LOGGER.debug("Merchant validated successfully for MID={}", billFetchByBillIdRequest.getMid()); - LOGGER.info("Calling external BBPS API for FetchBillById, URL={}", fullUrl); - Map responseMap = httpService.getRequest(fullUrl, headers); - String responseData = responseMap.get("data"); - LOGGER.info("Response received from BBPS for billId={} : {}", billId, responseData); + 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(); - Map dataMap = objectMapper.readValue(responseData, - new TypeReference>() { - }); + // create outbound log + OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl, "GET", null); + LOGGER.info("Calling external BBPS API for FetchBillById, URL={}", fullUrl); + Map responseMap = httpService.getRequest(fullUrl, headers); + String responseData = responseMap.get("data"); + LOGGER.info("Response received from BBPS for billId={} : {}", billId, responseData); - if (!dataMap.containsKey("genericResponse")) { - LOGGER.warn("Invalid response structure received for billId={} | Response={}", billId, responseData); - throw new CustomException(String.valueOf(dataMap.get("message")), // message - String.valueOf(dataMap.get("status")), // status - Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), // statusCode - String.valueOf(dataMap.get("remarks"))); - } + // update outbound log with response + helper.updateOutboundLogResponse(outboundLog, responseData); - BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class); - GeneralResp generalResp = responseWrapper.getGenericResponse(); - ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), - Integer.parseInt(generalResp.getStatusCode()), responseWrapper); + ObjectMapper objectMapper = new ObjectMapper(); + Map dataMap = objectMapper.readValue(responseData, + new TypeReference>() { + }); - helper.saveOrUpdateBillData(responseWrapper, billFetchByBillIdRequest,txnId); - LOGGER.info("Bill data saved successfully for billId={} | Status={}", billId, generalResp.getStatus()); + if (!dataMap.containsKey("genericResponse")) { + helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); + LOGGER.warn("Invalid response structure received for billId={} | Response={}", billId, responseData); + throw new CustomException(String.valueOf(dataMap.get("message")), // message + String.valueOf(dataMap.get("status")), // status + Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), // statusCode + String.valueOf(dataMap.get("remarks"))); + } - return responseModel; + BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class); + GeneralResp generalResp = responseWrapper.getGenericResponse(); + ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), + Integer.parseInt(generalResp.getStatusCode()), responseWrapper); - } catch (JsonProcessingException e) { - LOGGER.error("Error parsing responseData JSON for billId={} : {}", billId, e.getMessage(), e); - throw new CustomException("Invalid JSON received from API"); - } + // update inbound log success and persist bill data + helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); + helper.saveOrUpdateBillData(responseWrapper, billFetchByBillIdRequest, txnId); + LOGGER.info("Bill data saved successfully for billId={} | Status={}", billId, generalResp.getStatus()); + + return responseModel; + + } catch (JsonProcessingException e) { + LOGGER.error("Error parsing responseData JSON for billId={} : {}", billId, e.getMessage(), e); + helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); + throw new CustomException("Invalid JSON received from API"); + } } + @Override - public ResponseModel initiateBillValidate(FetchBillValidatestRequest fetchBillValidateRequest) { - - - LOGGER.info("Initiating bill Validate for request ID: {} and MID", fetchBillValidateRequest.getReqId(), - fetchBillValidateRequest.getMid()); + public ResponseModel initiateBillValidate(FetchBillValidatestRequest fetchBillValidateRequest) { + LOGGER.info("Initiating bill Validate for request ID: {} and MID:{} and billerId:{}", fetchBillValidateRequest.getReqId(), + fetchBillValidateRequest.getMid(),fetchBillValidateRequest.getBillerId()); String apiName = "InitiateBillValidate"; String txnId = helper.generateTxnId(15); String reqId = fetchBillValidateRequest.getReqId(); @@ -445,6 +457,71 @@ public class AgentServiceImpl implements AgentService { } }} + + + @Override + public ResponseModel initiateBillValidateByBillId(BillFetchByBillIdRequest billRequest) { + String apiName = "FetchBillById"; + String txnId = helper.generateTxnId(15); + String reqId = billRequest.getReqId(); + String billId = billRequest.getBillId(); + String fullUrl = agentDtaUrl + BBPSConstant.BILL_VALIDATE_ID_URL + billRequest.getBillId(); + + LOGGER.info("Initiating {} API for billId={} and reqId={}", apiName, billId, reqId); + + // create inbound log (GET -> no request body) + InboundTraceLog inboundLog = helper.createInboundLog(reqId, txnId, apiName, billRequest.getMid(), "GET", null); + + try { + helper.validateMerchant(billRequest.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); + + // create outbound log + OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl, "GET", null); + LOGGER.info("Calling external BBPS API for ValidateByBillId, URL={}", fullUrl); + + Map responseMap = httpService.getRequest(fullUrl, headers); + String responseData = responseMap.get("data"); + LOGGER.info("Response received from BBPS for billId={} : {}", billId, responseData); + + // update outbound log with response + helper.updateOutboundLogResponse(outboundLog, responseData); + + ObjectMapper objectMapper = new ObjectMapper(); + Map dataMap = objectMapper.readValue(responseData, new com.fasterxml.jackson.core.type.TypeReference>(){}); + + if (!dataMap.containsKey("genericResponse")) { + helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); + LOGGER.warn("Invalid response structure received for billId={} | Response={}", billId, responseData); + 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"))); + } + + FetchBillValidateResponse responseWrapper = objectMapper.convertValue(dataMap, FetchBillValidateResponse.class); + GeneralResp generalResp = responseWrapper.getGenericResponse(); + + // update inbound log and save validation data + helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); + helper.saveBillValidation(responseWrapper, billRequest); + LOGGER.info("Bill validation saved successfully for billId: {}", billId); + + return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); + + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { + LOGGER.error("Error parsing ValidateByBillId JSON: {}", e.getMessage(), e); + helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); + throw new CustomException("Invalid JSON received from API"); + } + } + //================================== Bill fetch and Bill Validate by Client Req Id==================================// @@ -582,201 +659,4 @@ public class AgentServiceImpl implements AgentService { } } - - - - /* - * @Override public ResponseModel - * initiateBillValidate(FetchBillValidatestRequest fetchBillValidateRequest) { - * - * ResponseModel responseModel = new ResponseModel(); try { - * - * helper.validateMerchant(fetchBillValidateRequest.getMid()); - * - * BharatConnectMaster headersData = - * beneficiaryDetailsRepository.findByOrgId("ORG001"); - * - * if (headersData == null) { responseModel = new - * ResponseModel("Tenant Id Is Null", "Not Found", BBPSConstant.BADREQUEST, - * headersData); return responseModel; } - * - * 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 - * json = objectMapper.writeValueAsString(fetchBillValidateRequest); String url - * = agentDtaUrl + BBPSConstant.BILLER_VALIDATE_URL; - * - * Map responseMap = httpService.postRequest(url, json, - * headers); String responseData = responseMap.get("data"); - * - * log.info("📦 Bill Fetch API Response: {}", responseData); - * - * if (responseData == null || responseData.isEmpty()) { throw new - * CustomException("Empty response from BBPS server"); } - * - * // ✅ Convert JSON string → Map Map dataMap = - * objectMapper.readValue(responseData, new TypeReference>() - * {}); - * - * // ✅ Validate generalResp if (!dataMap.containsKey("genericResponse")) { - * throw new CustomException("Invalid response structure from BBPS"); } - * - * // ✅ Convert to your custom DTO FetchBillValidatestResponse fetchBillResponse - * = objectMapper.convertValue(dataMap, FetchBillValidatestResponse.class); - * GeneralResp generalResponse = fetchBillResponse.getGenericResponse(); - * - * // ✅ Build final ResponseModel responseModel = new ResponseModel( - * generalResponse.getMessage(), generalResponse.getStatus(), - * Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse ); - * - * } catch (CustomException ex) { log.warn("Merchant validation failed: {}", - * ex.getMessage()); return ex.getResponseModel(); // Directly return - * ResponseModel from exception } catch (Exception e) { - * log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); - * responseModel.setStatus("500"); - * responseModel.setMessage("Exception occurred"); - * responseModel.setData(e.getMessage()); } - * - * return responseModel; } - * - * @Override public ResponseModel - * initiateBillValidateByBillId(BillFetchByBillIdRequest billRequest) { - * - * ResponseModel responseModel = new ResponseModel(); try { - * helper.validateMerchant(billRequest.getMid()); - * - * BharatConnectMaster headersData = - * beneficiaryDetailsRepository.findByOrgId("ORG001"); - * - * if (headersData == null) { responseModel = new - * ResponseModel("Tenant Id Is Null", "Not Found", BBPSConstant.BADREQUEST, - * headersData); return responseModel; } - * - * 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 - * json = objectMapper.writeValueAsString(billRequest); String url = agentDtaUrl - * + BBPSConstant.BILL_ID_URL + billRequest.getBillId(); - * - * log.info("Full URL: {}", url); - * objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - * - * // ✅ Call the API using httpService Map responseMap = - * httpService.getRequest(url, headers); String responseData = - * responseMap.get("data"); - * - * log.info("📦 Bill Fetch API Response: {}", responseData); - * - * if (responseData == null || responseData.isEmpty()) { throw new - * CustomException("Empty response from BBPS server"); } - * - * // ✅ Convert JSON string → Map Map dataMap = - * objectMapper.readValue(responseData, new TypeReference>() - * {}); - * - * // ✅ Validate generalResp if (!dataMap.containsKey("genericResponse")) { - * throw new CustomException("Invalid response structure from BBPS"); } - * - * // ✅ Convert to your custom DTO BillDataResponse fetchBillResponse = - * objectMapper.convertValue(dataMap, BillDataResponse.class); GeneralResp - * generalResponse = fetchBillResponse.getGenericResponse(); - * - * // ✅ Build final ResponseModel responseModel = new ResponseModel( - * generalResponse.getRemarks(), generalResponse.getStatus(), - * Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse ); - * - * } catch (CustomException ex) { log.warn("Merchant validation failed: {}", - * ex.getMessage()); return ex.getResponseModel(); // Directly return - * ResponseModel from exception } catch (Exception e) { - * log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); - * responseModel.setStatus("500"); - * responseModel.setMessage("Exception occurred"); - * responseModel.setData(e.getMessage()); } - * - * return responseModel; } - */ - - /* - * POLLING METHOD public ResponseModel fetchBillById(BillFetchByBillIdRequest - * billFetchByBillIdRequest, InboundTraceLog inboundLog) { String apiName = - * "FetchBillById"; String txnId = helper.generateTxnId(15); String reqId = - * billFetchByBillIdRequest.getReqId(); String billId = - * billFetchByBillIdRequest.getBillId(); String url = agentDtaUrl + - * BBPSConstant.BILL_FETCH_BY_ID + "1ced7566-1add-4e01-9ed6-04cd67ac9684"; - * - * helper.validateMerchant(billFetchByBillIdRequest.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(); OutboundTraceLog outboundLog - * = helper.createOutboundLog(txnId, reqId, apiName, url, "GET", null); - * - * // ✅ Loop setup long startTime = System.currentTimeMillis(); long - * maxWaitTimeMs = 40000; // 40 seconds long intervalMs = 5000; // 5 seconds - * - * while (true) { try { Map responseMap = - * httpService.getRequest(url, headers); String responseData = - * responseMap.get("data"); log.info("📦 Bill FetchById Response: {}", - * responseData); - * - * helper.updateOutboundLogResponse(outboundLog, responseData); - * - * Map dataMap = objectMapper.readValue(responseData, new - * TypeReference>() {}); - * - * if (!dataMap.containsKey("genericResponse")) { - * helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); - * 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")) ); } - * - * BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, - * BillDataResponse.class); GeneralResp generalResp = - * responseWrapper.getGenericResponse(); - * - * String status = generalResp.getStatus(); - * log.info("📡 Current Bill Status: {}", status); // ✅ Check for "INPROGRESS" - * or pending state if ("INPROGRESS".equalsIgnoreCase(status)) { if - * (System.currentTimeMillis() - startTime > maxWaitTimeMs) { - * helper.updateInboundLogFailure(inboundLog, "Timeout after 40 seconds", - * "FAILED"); throw new CustomException("Timeout", "FAILED", 408, - * "Bill fetch still in progress"); } Thread.sleep(intervalMs); continue; // - * retry again } // ✅ Final successful response - * helper.updateInboundLogSuccess(inboundLog, responseData, - * generalResp.getStatus()); return new ResponseModel( generalResp.getMessage(), - * generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), - * responseWrapper ); } catch (JsonProcessingException e) { - * log.error("Error parsing BillById JSON: {}", e.getMessage()); - * helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); - * throw new CustomException("Invalid JSON received from API"); } catch - * (InterruptedException e) { Thread.currentThread().interrupt(); - * helper.updateInboundLogFailure(inboundLog, e.getMessage(), "INTERRUPTED"); - * throw new CustomException("Thread interrupted during bill status check"); } } - * } - */ - - - - - @Override - public ResponseModel initiateBillValidateByBillId(BillFetchByBillIdRequest billRequest) { - // TODO Auto-generated method stub - return null; - }} +} From 135947cfd6cbde2525d481f0219b77862d5d4168 Mon Sep 17 00:00:00 2001 From: Lincpay Tech Date: Fri, 21 Nov 2025 23:29:29 +0530 Subject: [PATCH 2/3] added dto and entityn for biller --- .../bbps/dto/BillerAdditonalInfoDTO.java | 15 ++++++ .../entites/BillerAdditionalInfoPayment.java | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/main/java/com/billpaymentservice/bbps/dto/BillerAdditonalInfoDTO.java create mode 100644 src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java diff --git a/src/main/java/com/billpaymentservice/bbps/dto/BillerAdditonalInfoDTO.java b/src/main/java/com/billpaymentservice/bbps/dto/BillerAdditonalInfoDTO.java new file mode 100644 index 0000000..0cc657c --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/BillerAdditonalInfoDTO.java @@ -0,0 +1,15 @@ +package com.billpaymentservice.bbps.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class BillerAdditonalInfoDTO { + private String paramConfigId; + private String paramName; + private String dataTypeDAO; + private String dataTypeModel; + private boolean optional; + private boolean visibility; +} diff --git a/src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java b/src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java new file mode 100644 index 0000000..5411901 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java @@ -0,0 +1,47 @@ +package com.billpaymentservice.bbps.entites; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; +@Getter +@Setter +@Table(name = "biller_additional_additional_info_payment") +@Entity +public class BillerAdditionalInfoPayment { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; // primary key for the table + + @Column(name = "param_config_id", nullable = false) + @NotBlank(message = "Param Config ID cannot be blank") + private String paramConfigId; + + @Column(name = "param_name", nullable = false) + @NotBlank(message = "Param name cannot be blank") + private String paramName; + + @Column(name = "data_type_dao") + private String dataTypeDAO; + + @Column(name = "data_type_model") + private String dataTypeModel; + + @Column(name = "optional", nullable = false) + private boolean optional; + + @Column(name = "visibility", nullable = false) + private boolean visibility; + + // 🔗 Many AdditionalInfos belong to one Biller + @ManyToOne + @JoinColumn(name = "biller_id", nullable = false) + private BillerDetails biller; +} From d46d084654b24254413e7df4885f2da2ff69fbc6 Mon Sep 17 00:00:00 2001 From: Lincpay Tech Date: Sun, 23 Nov 2025 23:33:47 +0530 Subject: [PATCH 3/3] improved code quality and tested with test data --- .../bbps/dto/BillerDTO.java | 3 +- .../response/FetchBillValidateResponse.java | 1 - .../bbps/entites/BillValidation.java | 4 +- .../entites/BillerAdditionalInfoPayment.java | 2 +- .../bbps/entites/BillerDetails.java | 11 +++-- .../serviceImpl/MasterDataServiceImpl.java | 2 +- .../bbps/util/EntityRelationshipUtil.java | 4 ++ .../billpaymentservice/bbps/util/Helper.java | 41 +++++++------------ 8 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/billpaymentservice/bbps/dto/BillerDTO.java b/src/main/java/com/billpaymentservice/bbps/dto/BillerDTO.java index 005b1d2..99af937 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/BillerDTO.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/BillerDTO.java @@ -2,6 +2,7 @@ package com.billpaymentservice.bbps.dto; import java.util.List; +import com.billpaymentservice.bbps.entites.AdditionalInfoBillValidate; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import jakarta.validation.constraints.NotBlank; @@ -102,7 +103,7 @@ public class BillerDTO { private BillerResponseParamsDTO billerResponseParams; private List billerAdditionalInfos; - private List billerAdditionalInfoPayments; + private List billerAdditionalInfoPayments; private List interchangeFeeConves; private List interchangeFees; diff --git a/src/main/java/com/billpaymentservice/bbps/dto/response/FetchBillValidateResponse.java b/src/main/java/com/billpaymentservice/bbps/dto/response/FetchBillValidateResponse.java index 471b13b..4593f61 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/response/FetchBillValidateResponse.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/response/FetchBillValidateResponse.java @@ -19,7 +19,6 @@ import lombok.ToString; @NoArgsConstructor @ToString public class FetchBillValidateResponse { - @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private GeneralResp genericResponse; private String billId; diff --git a/src/main/java/com/billpaymentservice/bbps/entites/BillValidation.java b/src/main/java/com/billpaymentservice/bbps/entites/BillValidation.java index b620411..d4a01dd 100644 --- a/src/main/java/com/billpaymentservice/bbps/entites/BillValidation.java +++ b/src/main/java/com/billpaymentservice/bbps/entites/BillValidation.java @@ -37,8 +37,8 @@ public class BillValidation { @Column(name = "biller_response", columnDefinition = "TEXT") private String billerResponse; - @Column(name = "additional_info", columnDefinition = "TEXT") - private String additionalInfo; + @OneToMany(mappedBy = "bill", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List additionalInfo; // 👇 Proper nested customer params (OneToMany) @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "bill") diff --git a/src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java b/src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java index 5411901..5599c1b 100644 --- a/src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java +++ b/src/main/java/com/billpaymentservice/bbps/entites/BillerAdditionalInfoPayment.java @@ -13,7 +13,7 @@ import lombok.Getter; import lombok.Setter; @Getter @Setter -@Table(name = "biller_additional_additional_info_payment") +@Table(name = "biller_additional_info_payment") @Entity public class BillerAdditionalInfoPayment { @Id diff --git a/src/main/java/com/billpaymentservice/bbps/entites/BillerDetails.java b/src/main/java/com/billpaymentservice/bbps/entites/BillerDetails.java index 63b08fd..24f4511 100644 --- a/src/main/java/com/billpaymentservice/bbps/entites/BillerDetails.java +++ b/src/main/java/com/billpaymentservice/bbps/entites/BillerDetails.java @@ -29,7 +29,8 @@ import lombok.ToString; "billerAdditionalInfos", "interchangeFeeConves", "interchangeFees", - "billerPlanResponseParams" + "billerPlanResponseParams", + "billerAdditionalInfoPayments" }) @Table(name = "biller_details") @@ -151,11 +152,9 @@ public class BillerDetails { @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) private List billerAdditionalInfos; - - /* - * OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval - * =true) private List billerAdditionalInfoPayments; - */ + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval=true) + private List billerAdditionalInfoPayments; + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) private List interchangeFeeConves; diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java index 87da985..b322de8 100644 --- a/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java @@ -194,7 +194,7 @@ public class MasterDataServiceImpl implements MasterDataService { mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); BillerDetails entity = mapper.map(responseWrapper.getBillerDAO(), BillerDetails.class); EntityRelationshipUtil.linkBillerRelationships(entity);// linking nesting entity foreign key - //helper.saveOrUpdateBillerData(entity); + helper.saveOrUpdateBillerData(entity); ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); diff --git a/src/main/java/com/billpaymentservice/bbps/util/EntityRelationshipUtil.java b/src/main/java/com/billpaymentservice/bbps/util/EntityRelationshipUtil.java index b7b24c3..caec51d 100644 --- a/src/main/java/com/billpaymentservice/bbps/util/EntityRelationshipUtil.java +++ b/src/main/java/com/billpaymentservice/bbps/util/EntityRelationshipUtil.java @@ -37,6 +37,10 @@ public class EntityRelationshipUtil { entity.getBillerAdditionalInfos().forEach(a -> a.setBiller(entity)); } + if(entity.getBillerAdditionalInfoPayments() != null) { + entity.getBillerAdditionalInfoPayments().forEach(a -> a.setBiller(entity)); + } + if (entity.getInterchangeFees() != null) { for (InterchangeFee fee : entity.getInterchangeFees()) { diff --git a/src/main/java/com/billpaymentservice/bbps/util/Helper.java b/src/main/java/com/billpaymentservice/bbps/util/Helper.java index 379ba40..a73ca30 100644 --- a/src/main/java/com/billpaymentservice/bbps/util/Helper.java +++ b/src/main/java/com/billpaymentservice/bbps/util/Helper.java @@ -26,6 +26,7 @@ import com.billpaymentservice.bbps.dto.sentRequest.BillPaymentForwardRequest; import com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest; import com.billpaymentservice.bbps.dto.sentRequest.FetchBillValidatestForwardRequest; import com.billpaymentservice.bbps.entites.AdditionalInfoBill; +import com.billpaymentservice.bbps.entites.AdditionalInfoBillValidate; import com.billpaymentservice.bbps.entites.BBPSMastersData; import com.billpaymentservice.bbps.entites.BillMaster; import com.billpaymentservice.bbps.entites.BillValidation; @@ -218,32 +219,7 @@ public class Helper { Optional existingOpt = billerDataRespository.findByBillerId(newEntity.getBillerId()); if (existingOpt.isPresent()) { - BillerDetails existing = existingOpt.get(); - - // Update base biller fields - existing.setBillerName(newEntity.getBillerName()); - existing.setBillerAliasName(newEntity.getBillerAliasName()); - existing.setBillerDescription(newEntity.getBillerDescription()); - existing.setStatus(newEntity.getStatus()); - existing.setBillerCoverage(newEntity.getBillerCoverage()); - // ... (update other simple fields as needed) - - // ✅ Clear and replace nested lists to avoid duplicate inserts - existing.getBillerPaymentModes().clear(); - if (newEntity.getBillerPaymentModes() != null) { - for (PaymentMode mode : newEntity.getBillerPaymentModes()) { - mode.setBiller(existing); - existing.getBillerPaymentModes().add(mode); - } - } - existing.getBillerPaymentChannels().clear(); - if (newEntity.getBillerPaymentChannels() != null) { - for (PaymentChannel channel : newEntity.getBillerPaymentChannels()) { - channel.setBiller(existing); - existing.getBillerPaymentChannels().add(channel); - } - } - billerDataRespository.save(existing); + //logic to be written } else { // brand new biller @@ -348,7 +324,18 @@ billMasterRepository.save(billMaster); .collect(Collectors.toList()); billEntity.setCustomerParams(customerParams); } - + if (responseWrapper.getAdditionalInfo() != null) { + List additionalInfos = responseWrapper.getAdditionalInfo() + .stream() + .map(info -> { + AdditionalInfoBillValidate ai = modelMapper.map(info, AdditionalInfoBillValidate.class); + ai.setBill(billEntity); // maintain relation + return ai; + }) + .collect(Collectors.toList()); + billEntity.setAdditionalInfo(additionalInfos); + + } // ✅ Save everything (cascade handles child) billValidationRepository.save(billEntity);