package com.billpaymentservice.bbps.util; import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import org.modelmapper.ModelMapper; import org.modelmapper.convention.MatchingStrategies; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.billpaymentservice.bbps.dto.AdditionalInfoBillDTO; import com.billpaymentservice.bbps.dto.AmountOptionDTO; import com.billpaymentservice.bbps.dto.BillAdditionalInfoDTO; import com.billpaymentservice.bbps.dto.BillCustomerParamsDTO; import com.billpaymentservice.bbps.dto.BillerIconDTO; import com.billpaymentservice.bbps.dto.CheckClientBillerResponseDTO; import com.billpaymentservice.bbps.dto.ComplaintHistoryDTO; import com.billpaymentservice.bbps.dto.ContactMaster; import com.billpaymentservice.bbps.dto.CustomerParamDAO; import com.billpaymentservice.bbps.dto.CustomerParamGroupsDTO; import com.billpaymentservice.bbps.dto.Detail; import com.billpaymentservice.bbps.dto.GroupDTO; import com.billpaymentservice.bbps.dto.MasterCategoryBillerResponse; import com.billpaymentservice.bbps.dto.PlanDTO; import com.billpaymentservice.bbps.dto.TicketDetailsDTO; import com.billpaymentservice.bbps.dto.TicketDispositionsDTO; import com.billpaymentservice.bbps.dto.TransactionHistoryMasterDTO; import com.billpaymentservice.bbps.dto.TransactionHistoryParticularDetailsDTO; import com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest; import com.billpaymentservice.bbps.dto.request.BillPaymentRequest; import com.billpaymentservice.bbps.dto.request.ComplaintRequestDTO; import com.billpaymentservice.bbps.dto.request.FetchBillRequest; import com.billpaymentservice.bbps.dto.request.FetchBillValidatestRequest; import com.billpaymentservice.bbps.dto.request.GetTicketLatestStausRequest; import com.billpaymentservice.bbps.dto.request.PaymentStartUserRequest; import com.billpaymentservice.bbps.dto.response.AmountOptionsResponse; import com.billpaymentservice.bbps.dto.response.BillDataResponse; import com.billpaymentservice.bbps.dto.response.ClientReqIdResponse; import com.billpaymentservice.bbps.dto.response.ComplaintHistoryStatusResponse; import com.billpaymentservice.bbps.dto.response.ComplaintResponse; import com.billpaymentservice.bbps.dto.response.FetchBillValidateResponse; import com.billpaymentservice.bbps.dto.response.PaymentStartApiResponse; import com.billpaymentservice.bbps.dto.response.PlanResponse; import com.billpaymentservice.bbps.dto.response.TicketCheckStatusResponse; import com.billpaymentservice.bbps.dto.response.ViewAllComplaintsResponse; import com.billpaymentservice.bbps.dto.response.ViewAllComplaintsTicketsResponse; import com.billpaymentservice.bbps.dto.response.ViewComplainByIdResponse; 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.dto.sentRequest.FetchComplaintForwardRequest; import com.billpaymentservice.bbps.dto.sentRequest.FetchTicketLatestStatusRequest; import com.billpaymentservice.bbps.entites.AdditionalInfoBill; import com.billpaymentservice.bbps.entites.AdditionalInfoBillValidate; import com.billpaymentservice.bbps.entites.AdditionalInfoPlans; import com.billpaymentservice.bbps.entites.AmountOptionByBillerId; import com.billpaymentservice.bbps.entites.AmountOptionDetails; import com.billpaymentservice.bbps.entites.BillAdditionalInfo; import com.billpaymentservice.bbps.entites.BillCustomerParams; import com.billpaymentservice.bbps.entites.BillMaster; import com.billpaymentservice.bbps.entites.BillTag; import com.billpaymentservice.bbps.entites.BillValidation; import com.billpaymentservice.bbps.entites.BillerCategoryIcon; import com.billpaymentservice.bbps.entites.BillerCategoryWise; import com.billpaymentservice.bbps.entites.BillerDetails; import com.billpaymentservice.bbps.entites.BillerResponse; import com.billpaymentservice.bbps.entites.CategoryResponseList; import com.billpaymentservice.bbps.entites.CheckClientBillerData; import com.billpaymentservice.bbps.entites.CheckClientStatusReqId; import com.billpaymentservice.bbps.entites.ComplainStatus; import com.billpaymentservice.bbps.entites.ComplaintHistory; import com.billpaymentservice.bbps.entites.ComplaintResponseEntity; import com.billpaymentservice.bbps.entites.ComplaintStatusDetails; import com.billpaymentservice.bbps.entites.ContactMasterData; import com.billpaymentservice.bbps.entites.CustomerParamBill; import com.billpaymentservice.bbps.entites.CustomerParamBillValidation; import com.billpaymentservice.bbps.entites.CustomerParamGroupById; import com.billpaymentservice.bbps.entites.GroupParam; import com.billpaymentservice.bbps.entites.PaymentStartRecord; import com.billpaymentservice.bbps.entites.Plan; import com.billpaymentservice.bbps.entites.PlanCategorySubType; import com.billpaymentservice.bbps.entites.PlanResponses; import com.billpaymentservice.bbps.entites.PlansList; import com.billpaymentservice.bbps.entites.TicketDispositionDetails; import com.billpaymentservice.bbps.entites.TransactionMaster; import com.billpaymentservice.bbps.entites.ViewAllComplaintTicketStatusDetails; import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.repository.AmountOptionByBillerIdRepository; import com.billpaymentservice.bbps.repository.BBPSMasterDataRepo; import com.billpaymentservice.bbps.repository.BillMasterRepository; import com.billpaymentservice.bbps.repository.BillValidationRepository; import com.billpaymentservice.bbps.repository.BillerCategoryWiseRepository; import com.billpaymentservice.bbps.repository.BillerDataRepository; import com.billpaymentservice.bbps.repository.CategoryResponseListRepository; import com.billpaymentservice.bbps.repository.CheckClientBillerDataRepository; import com.billpaymentservice.bbps.repository.ClientReqIdRepository; import com.billpaymentservice.bbps.repository.ComplainDetailRepository; import com.billpaymentservice.bbps.repository.ComplaintHistoryRepository; import com.billpaymentservice.bbps.repository.ComplaintResponseRepository; import com.billpaymentservice.bbps.repository.ComplaintStatusRepository; import com.billpaymentservice.bbps.repository.ContactMasterDataRepository; import com.billpaymentservice.bbps.repository.CustomerParamGroupByBillerIdRepository; import com.billpaymentservice.bbps.repository.FetchBillValidateRepository; import com.billpaymentservice.bbps.repository.PaymentStartRecordRepository; import com.billpaymentservice.bbps.repository.PlanResponseRepository; import com.billpaymentservice.bbps.repository.ReOpenComplaintRepository; import com.billpaymentservice.bbps.repository.TicketDispositionRepository; import com.billpaymentservice.bbps.repository.ViewAllComplainTicketDetailRepository; import jakarta.persistence.Column; @Component public class BillerMapperHelper { private static final Logger LOGGER = LoggerFactory.getLogger(BillerMapperHelper.class); private final BillerCategoryWiseRepository billerRepo; private final CustomerParamGroupByBillerIdRepository customerParamGroupByBillerIdRepo; private final AmountOptionByBillerIdRepository amountOptionByBillerIdRepository; private final PlanResponseRepository planResponseRepository; private final TicketDispositionRepository ticketDispositionRepository; private final CategoryResponseListRepository categoryResponseListRepository; private final FetchBillValidateRepository fetchBillValidateRepository; private final ComplaintStatusRepository complaintStatusRepository; private final ReOpenComplaintRepository reOpenComplaintRepository; private final ComplaintHistoryRepository complaintHistoryRepository; private final ClientReqIdRepository clientReqIdRepository; private final ComplainDetailRepository complainDetailRepository; private final CheckClientBillerDataRepository checkClientBillerDataRepository; private final ViewAllComplainTicketDetailRepository viewAllComplainTicketDetailRepository; private final ContactMasterDataRepository contactMasterDataRepository; private final BBPSMasterDataRepo bbpsMasterDataRepo; private final BillerDataRepository billerDataRespository; private final BillMasterRepository billMasterRepository; private final BillValidationRepository billValidationRepository; private final ComplaintResponseRepository complaintResponseRepository; private final PaymentStartRecordRepository paymentStartRecordRepository; public BillerMapperHelper(BillerCategoryWiseRepository billerRepo, CustomerParamGroupByBillerIdRepository customerParamGroupByBillerIdRepo, AmountOptionByBillerIdRepository amountOptionByBillerIdRepository, PlanResponseRepository planResponseRepository, CategoryResponseListRepository categoryResponseListRepository, FetchBillValidateRepository fetchBillValidateRepository, ComplaintStatusRepository complaintStatusRepository, ReOpenComplaintRepository reOpenComplaintRepository, ComplaintHistoryRepository complaintHistoryRepository, ComplainDetailRepository complainDetailRepository, ClientReqIdRepository clientReqIdRepository, CheckClientBillerDataRepository checkClientBillerDataRepository, TicketDispositionRepository ticketDispositionRepository, ViewAllComplainTicketDetailRepository viewAllComplainTicketDetailRepository, ContactMasterDataRepository contactMasterDataRepository, BBPSMasterDataRepo bbpsMasterDataRepo, BillerDataRepository billerDataRespository, BillMasterRepository billMasterRepository, BillValidationRepository billValidationRepository, ComplaintResponseRepository complaintResponseRepository, PaymentStartRecordRepository paymentStartRecordRepository) { this.paymentStartRecordRepository = paymentStartRecordRepository; this.billerRepo = billerRepo; this.customerParamGroupByBillerIdRepo = customerParamGroupByBillerIdRepo; this.amountOptionByBillerIdRepository = amountOptionByBillerIdRepository; this.planResponseRepository = planResponseRepository; this.categoryResponseListRepository = categoryResponseListRepository; this.fetchBillValidateRepository = fetchBillValidateRepository; this.complaintStatusRepository = complaintStatusRepository; this.reOpenComplaintRepository = reOpenComplaintRepository; this.complaintHistoryRepository = complaintHistoryRepository; this.complainDetailRepository = complainDetailRepository; this.clientReqIdRepository = clientReqIdRepository; this.checkClientBillerDataRepository = checkClientBillerDataRepository; this.ticketDispositionRepository = ticketDispositionRepository; this.viewAllComplainTicketDetailRepository = viewAllComplainTicketDetailRepository; this.contactMasterDataRepository = contactMasterDataRepository; this.bbpsMasterDataRepo = bbpsMasterDataRepo; this.billerDataRespository = billerDataRespository; this.billMasterRepository = billMasterRepository; this.billValidationRepository = billValidationRepository; this.complaintResponseRepository = complaintResponseRepository; } /** * Maps a list of MasterCategoryBillerResponse DTOs to entities, saves them, and * returns the saved list */ public List mapAndSaveAll(List dtos, String requestId, String txnId, String userId) { if (dtos == null || dtos.isEmpty()) { return Collections.emptyList(); } List entities = new ArrayList<>(); for (MasterCategoryBillerResponse dto : dtos) { // Check if biller already exists BillerCategoryWise biller = billerRepo.findById(dto.getBillerId()).orElse(new BillerCategoryWise()); // create // Set/update fields biller.setBillerId(dto.getBillerId()); biller.setBillerName(dto.getBillerName()); biller.setBillerType(dto.getBillerType()); biller.setBillerCategory(dto.getBillerCategory()); biller.setBillerCoverage(dto.getBillerCoverage()); biller.setBillerResponseType(dto.getBillerResponseType()); biller.setBillerDescription(dto.getBillerDescription()); biller.setPlanMDMRequirement(dto.getPlanMDMRequirement()); biller.setAdhocBiller(dto.getAdhocBiller()); biller.setPaymentAmountExactness(dto.getPaymentAmountExactness()); biller.setRequestId(requestId); biller.setTxnId(txnId); biller.setUserId(userId); // Handle icon BillerIconDTO iconDTO = dto.getBiller_icon(); if (iconDTO != null) { BillerCategoryIcon icon; if (biller.getIcon() != null) { icon = biller.getIcon(); // update existing icon } else { icon = new BillerCategoryIcon(); icon.setBiller(biller); } icon.setIconData(iconDTO.getIcon_data()); icon.setIconType(iconDTO.getIcon_type()); biller.setIcon(icon); // set to biller } entities.add(biller); } // Save all at once return billerRepo.saveAll(entities); } public CustomerParamGroupsDTO saveCustomerParamGroups(CustomerParamGroupsDTO dtos, String requestId, String txnId, String userId) { if (dtos == null || dtos.getGroups() == null || dtos.getGroups().isEmpty()) { return new CustomerParamGroupsDTO(); // Return empty DTO if no groups exist } List entities = new ArrayList<>(); // Loop through the top-level groups and save them (including nested groups) for (GroupDTO groupDTO : dtos.getGroups()) { CustomerParamGroupById entity = saveGroupWithChildren(groupDTO, null, requestId, txnId, userId); // null is // for // root // (no // parent group) entities.add(entity); // Add the saved entity to the list } // Save all entities at once using the repository List savedEntities = customerParamGroupByBillerIdRepo.saveAll(entities); // Convert saved entities back into DTOs to return return convertEntitiesToDTO(savedEntities); } private CustomerParamGroupById saveGroupWithChildren(GroupDTO groupDTO, CustomerParamGroupById parentGroup, String requestId, String txnId, String userId) { // Create a new entity for the group CustomerParamGroupById groupEntity = new CustomerParamGroupById(); groupEntity.setGroupId(groupDTO.getGroupId()); groupEntity.setName(groupDTO.getName()); groupEntity.setInput(groupDTO.getInput()); groupEntity.setParentGroup(parentGroup); // Link to the parent group (if exists) groupEntity.setRequestId(requestId); groupEntity.setTxnId(txnId); groupEntity.setUserId(userId); // Save group parameters (if any) if (groupDTO.getParams() != null && !groupDTO.getParams().isEmpty()) { List groupParams = new ArrayList<>(); for (String paramName : groupDTO.getParams()) { GroupParam param = new GroupParam(); param.setParamName(paramName); // Set the parameter name (e.g., "Admission No") param.setGroup(groupEntity); // Link the parameter to the current group groupParams.add(param); } groupEntity.setParams(groupParams); // Link parameters to the group } // Recursively save child groups if they exist if (groupDTO.getGroups() != null && !groupDTO.getGroups().isEmpty()) { List childEntities = new ArrayList<>(); for (GroupDTO childGroupDTO : groupDTO.getGroups()) { CustomerParamGroupById childEntity = saveGroupWithChildren(childGroupDTO, groupEntity, requestId, txnId, userId); // Pass // current // group // as // parent childEntities.add(childEntity); } groupEntity.setChildGroups(childEntities); // Set the child groups } // Save the current group entity and return it return groupEntity; } private CustomerParamGroupsDTO convertEntitiesToDTO(List savedEntities) { if (savedEntities == null || savedEntities.isEmpty()) { // Return an empty or default DTO if no entities are found return new CustomerParamGroupsDTO(); // return an empty DTO object } CustomerParamGroupsDTO responseDTO = new CustomerParamGroupsDTO(); List savedGroups = new ArrayList<>(); // Convert each saved entity to DTO for (CustomerParamGroupById savedEntity : savedEntities) { GroupDTO groupDTO = new GroupDTO(); groupDTO.setGroupId(savedEntity.getGroupId()); groupDTO.setName(savedEntity.getName()); groupDTO.setInput(savedEntity.getInput()); // Recursively map child groups if they exist if (savedEntity.getChildGroups() != null) { List childGroupDTOs = new ArrayList<>(); for (CustomerParamGroupById childEntity : savedEntity.getChildGroups()) { GroupDTO childGroupDTO = new GroupDTO(); childGroupDTO.setGroupId(childEntity.getGroupId()); childGroupDTO.setName(childEntity.getName()); childGroupDTO.setInput(childEntity.getInput()); // childGroupDTO.setParams(childEntity.getParams()); // Set parameters of child // group childGroupDTOs.add(childGroupDTO); } groupDTO.setGroups(childGroupDTOs); } // Add the DTO to the response savedGroups.add(groupDTO); } responseDTO.setGroups(savedGroups); return responseDTO; } // Method to save AmountOptionsResponse and AmountOption entities public String saveAmountOptionsResponse(AmountOptionsResponse responseWrapper, String requestId, String txnId, String userId) { // Convert AmountOptionsResponseDTO to AmountOptionsResponse entity if (responseWrapper == null) { // Return an empty or default DTO if no entities are found return "Data Is Empty"; // return an empty DTO object } AmountOptionByBillerId entity = new AmountOptionByBillerId(); entity.setAmountOptions(responseWrapper.getAmountOptions()); // Map AmountOptionDTO list to AmountOptionDetails entities List amountOptionDetailsList = mapAmountOptionDTOToEntity( responseWrapper.getAmountOptionDAOS(), requestId, txnId, userId); entity.setAmountOptionDetails(amountOptionDetailsList); amountOptionByBillerIdRepository.save(entity); // Saves the entity and cascades to AmountOptionDetails // Return success message return "Data saved successfully!"; } private List mapAmountOptionDTOToEntity(List amountOptionDTOs, String requestId, String txnId, String userId) { // If the list is null or empty, return an empty list of entities if (amountOptionDTOs == null || amountOptionDTOs.isEmpty()) { return new ArrayList<>(); // Return an empty list of AmountOptionDetails } // AmountOptionDetails entities return amountOptionDTOs.stream().flatMap(dto -> // For each DTO, convert its breakup sets to AmountOptionDetails entities dto.getAmountBreakupSets().stream().map(breakup -> { // Create a new AmountOptionDetails entity for each breakup set AmountOptionDetails amountOptionDetails = new AmountOptionDetails(); // Set the breakup set as a separate entity (each breakup set becomes a new // record) amountOptionDetails.setAmountBreakupSet(breakup); // Store each breakup set as an individual record // You can optionally set the amountOptionId here, if you want to link this // detail to the parent. // Assuming you want to set it directly here or pass it via the entity later: amountOptionDetails.setAmountOptionId(dto.getAmountOptionId()); amountOptionDetails.setRequestId(requestId); amountOptionDetails.setTxnId(txnId); amountOptionDetails.setUserId(userId); // Return the mapped AmountOptionDetails entity return amountOptionDetails; })).collect(Collectors.toList()); // Collect them into a list and return } public PlanResponses savePlanResponse(PlanResponse planResponse, String reqId, String txnId, String userId) { PlanResponses response = new PlanResponses(); response.setRequestId(reqId); response.setPageNo(planResponse.getPageNo()); response.setPageSize(planResponse.getPageSize()); response.setTotalElements(planResponse.getTotalElements()); response.setTotalPages(planResponse.getTotalPages()); response.setTxnId(txnId); response.setUserId(userId); PlansList plansList = new PlansList(); List planEntities = new ArrayList<>(); for (PlanDTO dto : planResponse.getPlansList().getPlans()) { Plan plan = new Plan(); plan.setPlanId(dto.getPlanId()); plan.setDescription(dto.getDescription()); plan.setBillerId(dto.getBillerId()); plan.setCategoryType(dto.getCategoryType()); plan.setAmountInRupees(dto.getAmountInRupees()); plan.setEffctvFrom(dto.getEffctvFrom()); plan.setEffctvTo(dto.getEffctvTo()); plan.setStatus(dto.getStatus()); plan.setPlansList(plansList); // categorySubType List subs = new ArrayList<>(); if (dto.getCategorySubType() != null) { for (String s : dto.getCategorySubType()) { PlanCategorySubType sub = new PlanCategorySubType(); sub.setCategorySubType(s); sub.setPlan(plan); subs.add(sub); } } plan.setCategorySubTypes(subs); // additionalInfo + tags // ✅ additionalInfo + tags if (dto.getAdditionalInfo() != null) { AdditionalInfoPlans info = new AdditionalInfoPlans(); info.setPlanAdditionalInfoId(dto.getAdditionalInfo().getPlanAdditionalInfoId().toString()); List tagEntities = new ArrayList<>(); if (dto.getAdditionalInfo().getTags() != null && !dto.getAdditionalInfo().getTags().isEmpty()) { for (com.billpaymentservice.bbps.dto.PlanTag tagDto : dto.getAdditionalInfo().getTags()) { com.billpaymentservice.bbps.entites.PlanTag tagEntity = new com.billpaymentservice.bbps.entites.PlanTag(); tagEntity.setTagId(tagDto.getTagId().toString()); tagEntity.setName(tagDto.getName()); tagEntity.setValue(tagDto.getValue()); tagEntity.setAdditionalInfo(info); // ✅ maintain relationship tagEntities.add(tagEntity); } } // ✅ Now set the entity list info.setTags(tagEntities); plan.setAdditionalInfo(info); } planEntities.add(plan); } plansList.setPlans(planEntities); response.setPlansList(plansList); return planResponseRepository.save(response); } public String saveCategoryItems(List categoryRespList, String requestId, String txnId, String userId) { int savedCount = 0; // To track how many items were saved if (categoryRespList == null || categoryRespList.isEmpty()) { return "No items to save."; } for (String item : categoryRespList) { CategoryResponseList category = new CategoryResponseList(); category.setCategoryRespList(item); category.setRequestId(txnId); category.setRequestId(requestId); category.setUserId(userId); categoryResponseListRepository.save(category); savedCount++; } return savedCount + " items were successfully saved."; } public String saveComplaintStatus(TicketCheckStatusResponse response, String reqId, String txnId, String userId) { if (response == null || response.getTicketDetails() == null) { throw new CustomException("Invalid response received!", "FAILURE", 500, "Response Null"); } // ✔ Validate HTTP style statusCode if (!"200".equals(response.getStatusCode())) { throw new CustomException(response.getMessage(), response.getStatus(), Integer.parseInt(response.getStatusCode()), response.getRemarks()); } TicketDetailsDTO dto = response.getTicketDetails(); if (dto == null) { throw new CustomException("Ticket details missing!", "FAILURE", 500, "Invalid Data"); } // ✔ Check if already exists // if (complaintStatusRepository.existsByTicketId(dto.getTicketId())) { // return "Complaint already exists in DB. TicketId: " + dto.getTicketId(); // } // ✔ Create entity ComplainStatus entity = new ComplainStatus(); entity.setRefId(response.getRefId()); entity.setReqId(reqId); entity.setTxnId(txnId); entity.setTicketId(dto.getTicketId()); entity.setTicketNpciId(dto.getTicketNpciId()); entity.setTxnNpciId(dto.getTxnNpciId()); entity.setTicketType(dto.getTicketType()); entity.setTicketDespo(dto.getTicketDespo()); entity.setTicketDescr(dto.getTicketDescr()); entity.setStatus(dto.getStatus()); entity.setNpciTicketType(dto.getNpciTicketType()); entity.setNpciTicketStatus(dto.getNpciTicketStatus()); entity.setCreatedTime(dto.getCreatedTime()); entity.setUserId(userId); try { ComplainStatus saved = complaintStatusRepository.save(entity); return "Complaint saved successfully with ID: " + saved.getId(); } catch (Exception e) { e.printStackTrace(); return "Error saving complaint: " + e.getMessage(); } } public String saveComplaintHistory(ComplaintHistoryStatusResponse responseWrapper, String reqId, String txnId, String userId) { if (responseWrapper == null || responseWrapper.getTicketHistories() == null || responseWrapper.getTicketHistories().isEmpty()) { return "No complaint history data found to save."; } try { int savedCount = 0; for (ComplaintHistoryDTO dto : responseWrapper.getTicketHistories()) { ComplaintHistory entity = new ComplaintHistory(); entity.setHistoryId(dto.getHistoryId()); entity.setTicketId(dto.getTicketId()); entity.setTime(dto.getTime()); entity.setHistoryStatus(dto.getHistoryStatus()); entity.setReqId(reqId); entity.setTxnId(txnId); entity.setUserId(userId); complaintHistoryRepository.save(entity); savedCount++; } return "✅ " + savedCount + " Complaint history record(s) saved successfully."; } catch (Exception e) { // Log the error for debugging LOGGER.error("❌ Error saving complaint history data: {}", e.getMessage(), e); return "❌ Failed to save complaint history data due to: " + e.getMessage(); } } public Map getComplaintStatusJson() { Map complaints = new HashMap<>(); complaints.put("assignedTo", "XYZ Bank"); complaints.put("complaintDescr", "Testing complaint"); complaints.put("complaintDispos", "Transaction Successful, account not updated"); complaints.put("complaintId", "2dfecc3c-9114-4094-9aa8-ff26f03a9bfd"); complaints.put("complaintNpciId", "FE4123109489834"); complaints.put("complaintRaisedFrom", "agent"); complaints.put("complaintType", "npciComplaint"); complaints.put("createdEpochDate", 1681905485); complaints.put("creationDate", "2023-04-19T17:28:05.508679Z"); complaints.put("modifiedDate", "2023-04-19T17:28:10.001432Z"); complaints.put("modifiedEpochDate", 1681905490); complaints.put("refId", "mqcXfZs2XMkRKQfpIwoSYQDnIr231091728"); complaints.put("status", "COMPLAINT_OPEN_SUCCESS"); complaints.put("tenantId", "FE41"); complaints.put("txnId", "24fe190c-42c9-4cb5-9d36-965839b0cb5f"); complaints.put("txnNpciId", "FE4131090DAI26Y0mAxl"); complaints.put("userId", "FE41FE42BNK519012345"); complaints.put("agentId", "FE41FE42BNK519012345"); Map finalJson = new HashMap<>(); finalJson.put("complaints", complaints); return finalJson; } public Map getDummyReopenComplaintJson() { Map complaints = new HashMap<>(); complaints.put("assignedTo", "Federal Bank"); complaints.put("complaintDescr", "Issue not yet solved - reopening"); complaints.put("complaintDispos", "Transaction Successful, account not updated"); complaints.put("complaintId", "809ec4c7-d81b-4d2b-9c66-3011a6fae714"); complaints.put("complaintNpciId", "FE4123109776644"); complaints.put("complaintRaisedFrom", "agent"); complaints.put("complaintType", "npciComplaint"); complaints.put("createdEpochDate", 1681893776); complaints.put("creationDate", "2023-04-19T14:12:56.329935Z"); complaints.put("modifiedDate", "2023-04-19T14:19:44.891423Z"); complaints.put("modifiedEpochDate", 1681894184); complaints.put("refId", "7sQwBamvWFyLxhK84dYgGmV24r831091419"); complaints.put("status", "COMPLAINT_REOPEN_SUCCESS"); complaints.put("tenantId", "FE41"); complaints.put("txnId", "155a4a71-141f-40fd-b772-9d0e020963e8"); complaints.put("txnNpciId", "FE413045Hl3L90ZWg59o"); complaints.put("userId", "FE41FE42BNK519012345"); complaints.put("agentId", "FE41FE42BNK519012345"); Map finalJson = new HashMap<>(); finalJson.put("complaints", complaints); return finalJson; } public Map getDummyClosureComplaintJson() { Map complaints = new HashMap<>(); complaints.put("complaintDescr", "Closing complaint Issue resolved"); complaints.put("complaintDispos", "Transaction Successful, account not updated"); complaints.put("complaintId", "809ec4c7-d81b-4d2b-9c66-3011a6fae714"); complaints.put("complaintNpciId", "FE4123109776644"); complaints.put("complaintRaisedFrom", "agent"); complaints.put("complaintType", "npciComplaint"); complaints.put("createdEpochDate", 1681893776); complaints.put("creationDate", "2023-04-19T14:12:56.329935Z"); complaints.put("modifiedDate", "2023-04-19T14:13:32.25255Z"); complaints.put("modifiedEpochDate", 1681893812); complaints.put("refId", "hHfEKYZExIpxNEV65HMQZ2Lh0DA31091413"); complaints.put("status", "COMPLAINT_CLOSURE_REQUEST_SUCCESS"); // removed spaces complaints.put("tenantId", "FE41"); complaints.put("txnId", "155a4a71-141f-40fd-b772-9d0e020963e8"); complaints.put("txnNpciId", "FE413045Hl3L90ZWg59o"); complaints.put("userId", "FE41FE42BNK519012345"); complaints.put("agentId", "FE41FE42BNK519012345"); Map finalJson = new HashMap<>(); finalJson.put("complaints", complaints); return finalJson; } public String saveComplainStatusDetail(ViewComplainByIdResponse responseWrapper, String reqId, String txnId, String userId) { ModelMapper mapper = new ModelMapper(); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); // Map list → ComplaintStatusDetails list List entityList = responseWrapper.getTickets().stream() .map(c -> mapper.map(c, ComplaintStatusDetails.class)).collect(Collectors.toList()); // Set extra fields for (ComplaintStatusDetails entity : entityList) { entity.setReqId(reqId); entity.setSystemTxnId(txnId); entity.setTotalPages(String.valueOf(responseWrapper.getTotalPages())); entity.setTotalElements(String.valueOf(responseWrapper.getTotalElements())); entity.setPage(String.valueOf(responseWrapper.getPage())); entity.setPageSize(String.valueOf(responseWrapper.getPageSize())); entity.setUserId(userId); } // Save to repository complainDetailRepository.saveAll(entityList); return "SUCCESS"; } public String saveAllComplaints(ViewAllComplaintsResponse responseWrapper, String reqId, String txnId) { ModelMapper mapper = new ModelMapper(); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); // Map list → ComplaintStatusDetails list List entityList = responseWrapper.getComplaintsList().stream() .map(c -> mapper.map(c, ComplaintStatusDetails.class)).collect(Collectors.toList()); // Set extra fields for (ComplaintStatusDetails entity : entityList) { entity.setReqId(reqId); entity.setTxnId(txnId); } // Save to repository complainDetailRepository.saveAll(entityList); return "SUCCESS"; } // Payment Data Service Impl public ClientReqIdResponse storeClientReqIdResponse(ClientReqIdResponse responseWrapper, String reqId, String txnId) { // 1. Save Parent (bill_id is PK) CheckClientStatusReqId parent = new CheckClientStatusReqId(); parent.setBillId(responseWrapper.getBillId()); parent.setRefId(responseWrapper.getRefId()); parent.setBillerId(responseWrapper.getBillerId()); parent.setStatus(responseWrapper.getStatus()); parent.setActionType(responseWrapper.getActionType()); parent.setUserId(responseWrapper.getUserId()); // Map incoming DTO date strings into Auditable LocalDateTime fields LocalDateTime parentCreatedOn = parseToLocalDateTime(responseWrapper.getCreationDate()); LocalDateTime parentUpdatedOn = parseToLocalDateTime(responseWrapper.getModifiedDate()); parent.setCreatedEpochDate(responseWrapper.getCreatedEpochDate()); parent.setModifiedEpochDate(responseWrapper.getModifiedEpochDate()); parent.setReqId(reqId); parent.setTxnId(txnId); parent = clientReqIdRepository.save(parent); // If no biller data, return if (responseWrapper.getBillerResponse() == null) { return responseWrapper; } CheckClientBillerResponseDTO dto = responseWrapper.getBillerResponse(); // 2. Save Biller Data CheckClientBillerData billerData = new CheckClientBillerData(); billerData.setBillMaster(parent); billerData.setAmount(dto.getAmount()); billerData.setBillDate(dto.getBillDate()); billerData.setBillNumber(dto.getBillNumber()); billerData.setBillPeriod(dto.getBillPeriod()); billerData.setCustConvFee(dto.getCustConvFee()); billerData.setCouCustConvFee(dto.getCouCustConvFee()); billerData.setDueDate(dto.getDueDate()); billerData.setCustomerName(dto.getCustomerName()); billerData.setAmountOption(dto.getAmountOption()); billerData = checkClientBillerDataRepository.save(billerData); // 3. Save Tag List List tagList = new ArrayList<>(); if (dto.getTagList() != null) { for (Detail tagDto : dto.getTagList()) { BillTag tag = new BillTag(); tag.setName(tagDto.getName()); tag.setValue(tagDto.getValue()); tag.setBillerResponse(billerData); tagList.add(tag); } } billerData.setTagList(tagList); // 4. Save Additional Info List addList = new ArrayList<>(); if (dto.getAdditionalInfo() != null) { for (BillAdditionalInfoDTO ai : dto.getAdditionalInfo()) { BillAdditionalInfo info = new BillAdditionalInfo(); info.setAdditionalInfoId(ai.getAdditionalInfoId()); info.setName(ai.getName()); info.setValue(ai.getValue()); info.setBillerResponse(billerData); addList.add(info); } } billerData.setAdditionalInfo(addList); // 5. Save Customer Params List cpList = new ArrayList<>(); if (dto.getCustomerParams() != null) { for (BillCustomerParamsDTO cp : dto.getCustomerParams()) { BillCustomerParams param = new BillCustomerParams(); param.setName(cp.getName()); param.setValue(cp.getValue()); param.setType(cp.getType()); param.setBillerResponse(billerData); cpList.add(param); } } billerData.setCustomerParams(cpList); // Final Save for children cascade checkClientBillerDataRepository.save(billerData); return responseWrapper; } public String saveTicketDisoptionDetails(List dispositionsList, String requestId, String txnId, String userId) { if (dispositionsList == null || dispositionsList.isEmpty()) { return "No disposition data received."; } int savedCount = 0; for (TicketDispositionsDTO dto : dispositionsList) { // Check if already exists boolean exists = ticketDispositionRepository.existsByDispositionId(dto.getDispositionId()); if (!exists) { TicketDispositionDetails entity = new TicketDispositionDetails(); // Manual mapping (to avoid ModelMapper conflict) entity.setDispositionId(dto.getDispositionId()); entity.setDispositionDescr(dto.getDispositionDescr()); entity.setTenantId(dto.getTenantId()); entity.setDispositionCode(dto.getDispositionCode()); // Set current datetime entity.setTxnId(txnId); entity.setReqId(requestId); entity.setUserId(userId); ticketDispositionRepository.save(entity); savedCount++; } } if (savedCount > 0) { return savedCount + " disposition(s) saved successfully."; } else { return "All dispositions already exist. No new records saved."; } } public String saveAllComplaints(ViewAllComplaintsTicketsResponse responseWrapper, String reqId, String txnId, String userId) { ModelMapper mapper = new ModelMapper(); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); // Map list → ComplaintStatusDetails list List entityList = responseWrapper.getTickets().stream() .map(c -> mapper.map(c, ViewAllComplaintTicketStatusDetails.class)).collect(Collectors.toList()); // Set extra fields for (ViewAllComplaintTicketStatusDetails entity : entityList) { entity.setReqId(reqId); entity.setSystemTxnId(txnId); entity.setPage(String.valueOf(responseWrapper.getPage())); entity.setPageSize(String.valueOf(responseWrapper.getPageSize())); entity.setTotalPages(String.valueOf(responseWrapper.getTotalPages())); entity.setTotalElements(String.valueOf(responseWrapper.getTotalElements())); entity.setUserId(userId); } // Save to repository viewAllComplainTicketDetailRepository.saveAll(entityList); return "SUCCESS"; } public String saveContactMasterData(List contactMasterList, String requestId, String txnID, String userId) { if (contactMasterList == null || contactMasterList.isEmpty()) { return "No contact master data found"; } // Convert DTO → Entity List entities = contactMasterList.stream().map(dto -> { ContactMasterData entity = new ContactMasterData(); entity.setMobNo(dto.getMobNo()); entity.setReqId(requestId); entity.setTxnId(txnID); entity.setUserId(userId); return entity; }).collect(Collectors.toList()); // Save list in DB contactMasterDataRepository.saveAll(entities); return "Contact Master Saved Successfully"; } public void saveOrUpdateBillerData(BillerDetails newEntity) { Optional existingOpt = billerDataRespository.findByBillerId(newEntity.getBillerId()); if (existingOpt.isPresent()) { // logic to be written } else { // brand new biller billerDataRespository.save(newEntity); } } public void saveOrUpdateBillData(BillDataResponse responseWrapper, BillFetchByBillIdRequest billFetchByBillIdRequest, String txnId, String reqId, String userId) { BillMaster billMaster = new BillMaster(); billMaster.setBillId(responseWrapper.getBillId()); billMaster.setRefId(responseWrapper.getRefId()); billMaster.setBillerId(responseWrapper.getBillerId()); billMaster.setStatus(responseWrapper.getStatus()); billMaster.setActionType(responseWrapper.getActionType()); billMaster.setUserId(responseWrapper.getUserId()); billMaster.setReqId(billFetchByBillIdRequest.getReqId()); billMaster.setTxnId(txnId); billMaster.setReqId(reqId); billMaster.setUserId(userId); billMaster.setClientUserId(billFetchByBillIdRequest.getClientUserId()); // BILLER RESPONSE BillerResponse billerResponse = new BillerResponse(); if (responseWrapper.getBillerResponse() != null) { billerResponse.setBillId(responseWrapper.getBillerResponse().getBillId()); billerResponse.setAmount(responseWrapper.getBillerResponse().getAmount()); billerResponse.setBillDate(responseWrapper.getBillerResponse().getBillDate()); billerResponse.setBillNumber(responseWrapper.getBillerResponse().getBillNumber()); billerResponse.setBillPeriod(responseWrapper.getBillerResponse().getBillPeriod()); billerResponse.setCustConvFee(responseWrapper.getBillerResponse().getCustConvFee()); billerResponse.setCouCustConvFee(responseWrapper.getBillerResponse().getCouCustConvFee()); billerResponse.setDueDate(responseWrapper.getBillerResponse().getDueDate()); billerResponse.setCustomerName(responseWrapper.getBillerResponse().getCustomerName()); billerResponse.setAmountOption(responseWrapper.getBillerResponse().isAmountOption()); billerResponse.setBillMaster(billMaster); } billMaster.setBillerResponse(billerResponse); // ADDITIONAL INFO List additionalInfos = new ArrayList<>(); if (responseWrapper.getAdditionalInfo() != null) { for (AdditionalInfoBillDTO info : responseWrapper.getAdditionalInfo()) { AdditionalInfoBill entity = new AdditionalInfoBill(); entity.setName(info.getName()); entity.setValue(info.getValue()); entity.setBillMaster(billMaster); additionalInfos.add(entity); } } billMaster.setAdditionalInfo(additionalInfos); // CUSTOMER PARAMS List customerParams = new ArrayList<>(); if (responseWrapper.getCustomerParams() != null) { for (CustomerParamDAO param : responseWrapper.getCustomerParams()) { CustomerParamBill entity = new CustomerParamBill(); entity.setName(param.getName()); entity.setValue(param.getValue() == null ? "" : param.getValue()); entity.setType(param.getType() == null ? "" : param.getType()); entity.setBillMaster(billMaster); customerParams.add(entity); } } billMaster.setCustomerParams(customerParams); // DATES // Map incoming DTO date strings into Auditable LocalDateTime fields LocalDateTime bmCreatedOn = parseToLocalDateTime(responseWrapper.getCreationDate()); LocalDateTime bmUpdatedOn = parseToLocalDateTime(responseWrapper.getModifiedDate()); if (bmUpdatedOn != null) { billMaster.setUpdatedDateTime(bmUpdatedOn); } billMaster.setCreatedEpochDate(responseWrapper.getCreatedEpochDate()); billMaster.setModifiedEpochDate(responseWrapper.getModifiedEpochDate()); billMasterRepository.save(billMaster); } // Helper to parse incoming ISO date/time strings (with optional offset) into LocalDateTime private LocalDateTime parseToLocalDateTime(String dateStr) { if (dateStr == null || dateStr.isBlank()) { return null; } try { // Try parsing with offset first (e.g., 2023-04-19T17:28:05.508679Z or with +05:30) OffsetDateTime odt = OffsetDateTime.parse(dateStr); return odt.toLocalDateTime(); } catch (Exception e) { try { // Fallback to LocalDateTime without offset return LocalDateTime.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME); } catch (Exception ex) { LOGGER.warn("Unable to parse date string to LocalDateTime: {}", dateStr); return null; } } } // Convert TransactionMaster to master DTO public TransactionHistoryMasterDTO toDTO(TransactionMaster transactionMaster) { if (transactionMaster == null) return null; TransactionHistoryMasterDTO dto = new TransactionHistoryMasterDTO(); dto.setBankTxnId(transactionMaster.getBankTxnId()); dto.setTxnId(transactionMaster.getTxnId()); dto.setMid(transactionMaster.getMid()); dto.setReqId(transactionMaster.getReqId()); dto.setBillerId(transactionMaster.getBillerId()); dto.setTxnAmount(transactionMaster.getTxnAmount()); dto.setStatus(transactionMaster.getStatus()); dto.setRemitterName(transactionMaster.getRemitterName()); dto.setOrderId(transactionMaster.getOrderId()); dto.setBillId(transactionMaster.getBillId()); dto.setUserType(transactionMaster.getUserType()); dto.setUserId(transactionMaster.getUserId()); dto.setTotalTxnAmount(transactionMaster.getTotalTxnAmount()); dto.setBillerCategory(transactionMaster.getBillerCategory()); dto.setBillerName(transactionMaster.getBillerName()); dto.setClientReqId(transactionMaster.getClientReqId()); dto.setOffUsPay(transactionMaster.getOffUsPay()); dto.setSplitPay(transactionMaster.getSplitPay()); dto.setQuickPay(transactionMaster.getQuickPay()); dto.setPaymentMode(transactionMaster.getPaymentMode()); dto.setAgentPaymentInformation(transactionMaster.getAgentPaymentInformation()); dto.setCustConvFee(transactionMaster.getCustConvFee()); dto.setCurrency(transactionMaster.getCurrency()); dto.setRequestedIp(transactionMaster.getRequestedIp()); dto.setCustomerMobNo(transactionMaster.getCustomerMobNo()); dto.setMacAddress(transactionMaster.getMacAddress()); dto.setSplitPayAmount(transactionMaster.getSplitPayAmount()); dto.setCouCustConvFee(transactionMaster.getCouCustConvFee()); dto.setSettlementVerification(transactionMaster.getSettlementVerification()); dto.setFundTxnType(transactionMaster.getFundTxnType()); dto.setReason(transactionMaster.getReason()); dto.setAmountTags(transactionMaster.getAmountTags()); dto.setPaymentInformation(transactionMaster.getPaymentInformation()); dto.setPlanId(transactionMaster.getPlanId()); dto.setPlanType(transactionMaster.getPlanType()); dto.setCreationDate(transactionMaster.getCreationDate()); dto.setModifiedDate(transactionMaster.getModifiedDate()); dto.setCreatedEpochDate(transactionMaster.getCreatedEpochDate()); dto.setModifiedEpochDate(transactionMaster.getModifiedEpochDate()); return dto; } // Convert TransactionMaster to particular details DTO (used with method references) public TransactionHistoryParticularDetailsDTO billerRemainingDetails(TransactionMaster transactionMaster) { if (transactionMaster == null) return null; TransactionHistoryParticularDetailsDTO dto = new TransactionHistoryParticularDetailsDTO(); dto.setBankTxnId(transactionMaster.getBankTxnId()); dto.setTxnId(transactionMaster.getTxnId()); dto.setCreationDate(transactionMaster.getCreationDate()); dto.setBillerCategory(transactionMaster.getBillerCategory()); dto.setBillerName(transactionMaster.getBillerName()); dto.setStatus(transactionMaster.getStatus()); dto.setTotalTxnAmount(transactionMaster.getTotalTxnAmount()); return dto; } // Map BillPaymentRequest to forward request used by external BBPS API public BillPaymentForwardRequest billPaymentForwardRequest(BillPaymentRequest req) { BillPaymentForwardRequest forward = new BillPaymentForwardRequest(); forward.setRefId(req.getRefId()); forward.setBillId(req.getBillId()); forward.setAmountOptions(req.isAmountOptions()); forward.setPaymentMode(req.getPaymentMode()); forward.setPaymentInformation(req.getPaymentInformation()); forward.setBillerId(req.getBillerId()); forward.setBillerName(req.getBillerName()); forward.setBillerCategory(req.getBillerCategory()); forward.setMacAdress(req.getMacAdress()); forward.setCustomerMobNo(req.getCustomerMobNo()); forward.setTxnAmount(req.getTxnAmount()); forward.setPaymentRefId(req.getPaymentRefId()); forward.setClientReqId(req.getClientReqId()); forward.setPaymentChannel(req.getPaymentChannel()); forward.setDeviceBlockTags(req.getDeviceBlockTags()); forward.setCustomerParamsRequest(req.getCustomerParams()); forward.setRemitterIdentity(req.getRemitterIdentity()); forward.setAmountBreakSet(req.getAmountBreakSet()); return forward; } // Map PaymentStartUserRequest + API response into PaymentStartRecord and persist public void savePaymentStartRecord(PaymentStartUserRequest request, PaymentStartApiResponse apiResponse, String txnId, String orderNo, String requestJson, String rawResponse, String responseType) { PaymentStartRecord record = new PaymentStartRecord(); record.setOrderNo(orderNo); record.setRequestId(request.getReqId()); record.setClientMid(request.getMid()); record.setClientUserId(request.getClientUserId()); record.setInternalTxnId(txnId); if (apiResponse != null && apiResponse.getResponseData() != null) { record.setAmount(Optional.ofNullable(apiResponse.getResponseData().getAmount()).orElse("0.00")); record.setMid(Optional.ofNullable(apiResponse.getResponseData().getMid()).orElse("DUMMY_MID")); record.setTxnId(Optional.ofNullable(apiResponse.getResponseData().getTxnId()).orElse("DUMMY_TXN")); record.setQrString(Optional.ofNullable(apiResponse.getResponseData().getQrString()).orElse("NO_QR")); // parse createdOn string into LocalDateTime and set on Auditable LocalDateTime createdOn = parseToLocalDateTime(apiResponse.getResponseData().getCreatedOn()); record.setTxnStatus("PENDING"); } else { record.setAmount("0.00"); record.setMid(request.getMid()); record.setTxnStatus("PENDING"); } // store the original request body and raw response record.setRequestBody(requestJson); record.setResponseBody(rawResponse); record.setResponseType(responseType); paymentStartRecordRepository.save(record); } // Map ComplaintRequestDTO to forward request for complaint API public FetchComplaintForwardRequest fetchComplaintForwardRequestMap(ComplaintRequestDTO complainRequestDTO) { FetchComplaintForwardRequest forward = new FetchComplaintForwardRequest(); forward.setTicketDescription(complainRequestDTO.getTicketDescription()); forward.setTicketDisposition(complainRequestDTO.getTicketDisposition()); forward.setTicketDispositionCode(complainRequestDTO.getTicketDispositionCode()); forward.setTxnId(complainRequestDTO.getTxnId()); return forward; } // Map GetTicketLatestStausRequest to forward request public FetchTicketLatestStatusRequest fetchTicketLatestStatusRequestMap(GetTicketLatestStausRequest request) { FetchTicketLatestStatusRequest forward = new FetchTicketLatestStatusRequest(); forward.setTicketId(request.getTicketId()); forward.setTxnNpciId(request.getTxnNpciId()); return forward; } // Check if complaint can be raised (true if within 24 hours of transactionCreatedDateString) public static boolean isComplaintAllowed(String transactionCreatedDateString) { if (transactionCreatedDateString == null || transactionCreatedDateString.isBlank()) return false; try { OffsetDateTime transactionCreatedDate = OffsetDateTime.parse(transactionCreatedDateString); OffsetDateTime currentTime = OffsetDateTime.now(); long hoursDifference = ChronoUnit.HOURS.between(transactionCreatedDate, currentTime); // complaint allowed if within 24 hours return hoursDifference <= 24; } catch (Exception e) { LOGGER.warn("isComplaintAllowed - invalid date string: {}", transactionCreatedDateString); return false; } } // Persist complaint response entity public String saveComplaintResponseEntity(ComplaintResponse responseWrapper, String requestId, String txnId, String userId) { if (responseWrapper == null || responseWrapper.getTicketDetails() == null) { return "No data"; } ComplaintResponseEntity complaintResponseEntity = new ComplaintResponseEntity(); complaintResponseEntity.setRefId(responseWrapper.getTicketDetails().getRefId()); complaintResponseEntity.setTxnNpciId(responseWrapper.getTicketDetails().getTxnNpciId()); complaintResponseEntity.setTicketId(responseWrapper.getTicketDetails().getTicketId()); complaintResponseEntity.setTicketType(responseWrapper.getTicketDetails().getTicketType()); complaintResponseEntity.setTicketNpciId(responseWrapper.getTicketDetails().getTicketNpciId()); complaintResponseEntity.setTicketDesp(responseWrapper.getTicketDetails().getTicketDesp()); complaintResponseEntity.setTicketDesr(responseWrapper.getTicketDetails().getTicketDesr()); complaintResponseEntity.setMessage(responseWrapper.getMessage()); complaintResponseEntity.setRemarks(responseWrapper.getRemarks()); complaintResponseEntity.setStatus(responseWrapper.getStatus()); complaintResponseEntity.setStatusCode(responseWrapper.getStatusCode()); complaintResponseEntity.setReqId(requestId); complaintResponseEntity.setTxnId(txnId); complaintResponseEntity.setUserId(userId); complaintResponseEntity.setComplaintTicketId(generateComplaintTicketId()); ComplaintResponseEntity saved = complaintResponseRepository.save(complaintResponseEntity); if (saved != null) { return "1 record saved with id=" + saved.getId(); } return "Failed to save"; } private String generateComplaintTicketId() { return "CMP-" + UUID.randomUUID().toString(); } // Minimal mapping helpers used by AgentServiceImpl public com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest fetchBillForwardRequestMap( com.billpaymentservice.bbps.dto.request.FetchBillRequest req) { if (req == null) return null; com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest f = new com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest(); f.setBillerId(req.getBillerId()); f.setBillerName(req.getBillerName()); f.setBillerCategory(req.getBillerCategory()); f.setClientReqId(req.getClientReqId()); f.setMacAdress(req.getMacAdress()); f.setCustomerMobNo(req.getCustomerMobNo()); f.setRemitterName(req.getRemitterName()); f.setPaymentChannel(req.getPaymentChannel()); f.setDeviceBlockTags(req.getDeviceBlockTags()); f.setCustomerParamsRequest(req.getCustomerParamsRequest()); f.setRemitterIdentity(req.getRemitterIdentity()); return f; } public com.billpaymentservice.bbps.dto.sentRequest.FetchBillValidatestForwardRequest fetchBillValidatestForwardRequest( com.billpaymentservice.bbps.dto.request.FetchBillValidatestRequest req) { if (req == null) return null; com.billpaymentservice.bbps.dto.sentRequest.FetchBillValidatestForwardRequest f = new com.billpaymentservice.bbps.dto.sentRequest.FetchBillValidatestForwardRequest(); f.setBillerId(req.getBillerId()); f.setBillerName(req.getBillerName()); f.setBillerCategory(req.getBillerCategory()); f.setCustomerMobNo(req.getCustomerMobNo()); f.setClientReqId(req.getClientReqId()); f.setMacAddress(req.getMacAddress()); f.setCustomerParamsRequest(req.getCustomerParamsRequest()); return f; } public void saveBillValidation(com.billpaymentservice.bbps.dto.response.FetchBillValidateResponse responseWrapper, com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest billRequest, String txnId) { if (responseWrapper == null || billRequest == null) return; BillValidation entity = new BillValidation(); entity.setBillId(responseWrapper.getBillId()); entity.setRefId(responseWrapper.getRefId()); entity.setBillerId(responseWrapper.getBillerId()); entity.setStatus(responseWrapper.getStatus()); entity.setActionType(responseWrapper.getActionType()); entity.setUserId(responseWrapper.getUserId()); entity.setBillerResponse(responseWrapper.getBillerResponse()); entity.setTxnId(txnId); entity.setReqId(billRequest.getReqId()); // Map additionalInfo if present (minimal mapping) if (responseWrapper.getAdditionalInfo() != null) { List addList = new ArrayList<>(); for (com.billpaymentservice.bbps.dto.AdditionalInfoBillValidateDTO ai : responseWrapper.getAdditionalInfo()) { AdditionalInfoBillValidate info = new AdditionalInfoBillValidate(); // DTO only has name & value info.setName(ai.getName()); info.setValue(ai.getValue()); info.setBill(entity); addList.add(info); } entity.setAdditionalInfo(addList); } // Map customerParams if present (minimal mapping) if (responseWrapper.getCustomerParams() != null) { List cpList = new ArrayList<>(); for (com.billpaymentservice.bbps.dto.CustomerParamDAO cp : responseWrapper.getCustomerParams()) { CustomerParamBillValidation param = new CustomerParamBillValidation(); param.setName(cp.getName()); param.setValue(cp.getValue()); param.setType(cp.getType()); param.setBill(entity); cpList.add(param); } entity.setCustomerParams(cpList); } // Persist try { billValidationRepository.save(entity); } catch (Exception e) { LOGGER.error("Error saving BillValidation: {}", e.getMessage(), e); } } }