10-11-2025

This commit is contained in:
Mohd-Arham
2025-11-10 10:11:26 +05:30
parent cfac612306
commit c67f222957
34 changed files with 1544 additions and 425 deletions
+3
View File
@@ -172,7 +172,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>BBPS</finalName>
</build>
</project>
@@ -0,0 +1,18 @@
package com.billpaymentservice.bbps.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CORSConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") // Or specific origin like "http://localhost:4200"
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(false); // Set to true if you're sending cookies
}
}
@@ -0,0 +1,28 @@
package com.billpaymentservice.bbps.config;
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@Configuration
public class SecurityConfig {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("*")); // Or use specific origin like "http://localhost:4200"
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowCredentials(false); // true only if you're sending cookies
// Use UrlBasedCorsConfigurationSource as it implements CorsConfigurationSource
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); // Apply CORS to all paths
return source; // Return as CorsConfigurationSource
}
}
@@ -13,45 +13,37 @@ import com.billpaymentservice.bbps.service.AgentService;
@RestController
@RequestMapping("/agent")
@CrossOrigin(origins = "*")
public class AgentController {
private final AgentService agentService;
private final AgentService agentService;
public AgentController(AgentService agentService) {
this.agentService = agentService;
}
public AgentController(AgentService agentService) {
this.agentService = agentService;
}
/**
* Fetches bill details from external BBPS service
*/
@PostMapping(
value = "/requestBillFetch",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity<ResponseModel> requestBillFetch(
@Validated @RequestBody FetchBillRequest fetchBillRequest) {
/**
* Fetches bill details from external BBPS service
*/
@PostMapping(value = "/requestBillFetch", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> requestBillFetch(@Validated @RequestBody FetchBillRequest fetchBillRequest) {
ResponseModel response = agentService.initiateBillFetch(fetchBillRequest);
return ResponseEntity.ok(response);
}
/**
* Fetches bill details from external BBPS service
*/
@PostMapping(
value = "/fetchBillById",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity<ResponseModel> fetchBillById(
@Validated @RequestBody BillFetchByBillIdRequest billFetchByBillIdRequest) {
ResponseModel response = agentService.initiateBillFetch(fetchBillRequest);
return ResponseEntity.ok(response);
}
ResponseModel response = agentService.fetchBillById(billFetchByBillIdRequest);
return ResponseEntity.ok(response);
}
/**
/**
* Fetches bill details from external BBPS service
*/
@PostMapping(value = "/fetchBillById", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> fetchBillById(
@Validated @RequestBody BillFetchByBillIdRequest billFetchByBillIdRequest) {
ResponseModel response = agentService.fetchBillById(billFetchByBillIdRequest);
return ResponseEntity.ok(response);
}
/**
* Fetches bill details validate from external BBPS service
*/
@PostMapping(value = "/requestBillValidate", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@@ -66,7 +58,8 @@ public class AgentController {
* Fetches bill details by bill Id from external BBPS service
*/
@PostMapping(value = "/requestBillValidateByBillId", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> requestBillByBillId(@Validated @RequestBody BillFetchByBillIdRequest billRequest) {
public ResponseEntity<ResponseModel> requestBillByBillId(
@Validated @RequestBody BillFetchByBillIdRequest billRequest) {
ResponseModel response = agentService.initiateBillValidateByBillId(billRequest);
return ResponseEntity.ok(response);
@@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -25,6 +26,7 @@ import jakarta.validation.Valid;
@RequestMapping("/masterData")
@RestController
@Validated
@CrossOrigin(origins="*")
public class MasterDataController {
private static final Logger log = LoggerFactory.getLogger(MasterDataController.class);
@@ -74,7 +76,7 @@ public class MasterDataController {
}
/**
* Get All Master Data .The parameter is different from the data we are getting
* Get All Master Data .The parameter is different from the data we are getting Made By Arham
* in the MasterRequest
**/
@PostMapping("/getAllMastersData")
@@ -82,14 +84,14 @@ public class MasterDataController {
return masterDataService.getMasterData(masterRequest);
}
/** POST Master Category Wise API Fetch Category Wise from BBPS URL **/
/** POST Master CategoryResponseList Wise API Fetch CategoryResponseList Wise from BBPS URL Made By Arham **/
@PostMapping(value = "/getMasterCategoryWise", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> getMasterDataCategoryWise(
@Validated @RequestBody MasterCategoryRequest masterRequest) {
@Valid @RequestBody MasterCategoryRequest masterRequest) {
return ResponseEntity.ok(masterDataService.fetchMasterDataCategoryWise(masterRequest));
}
/** POST Customer Param Groups API Fetch Category Wise from BBPS URL **/
/** POST Customer Param Groups API Fetch CategoryResponseList Wise from BBPS URL Made By Arham**/
@PostMapping(value = "/customerParamGroupsByBillerId", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> getCustomerParamGroup(
@Validated @RequestBody BillerDetailRequest requestModel) {
@@ -97,8 +99,8 @@ public class MasterDataController {
}
/**
* POST Fetch All AMount Options By Biller Id API Fetch Category Wise from BBPS
* URL
* POST Fetch All AMount Options By Biller Id API Fetch CategoryResponseList Wise from BBPS
* URL Made By Arham
**/
@PostMapping(value = "/fetchAmountOptionsByBillerId", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> fetchAllMasterAmountOptionsByBillerId(
@@ -107,8 +109,8 @@ public class MasterDataController {
}
/**
* POST Fetch All AMount Options By Biller Id API Fetch Category Wise from BBPS
* URL
* POST Fetch All AMount Options By Biller Id API Fetch CategoryResponseList Wise from BBPS
* URL Made By Arham
**/
@PostMapping(value = "/fetchAllPlanCategoriesByBillerId", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> fetchPlanCategories(@Validated @RequestBody BillerDetailRequest requestModel) {
@@ -116,7 +118,7 @@ public class MasterDataController {
}
/**
* POST Fetch Initiating Channel API Fetch Category Wise from BBPS URL
* POST Fetch Initiating Channel API Fetch CategoryResponseList Wise from BBPS URL Made By Arham
**/
@PostMapping(value = "/initiatingChannel", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> initiatingChannel(@Validated @RequestBody BillerDetailRequest requestModel) {
@@ -124,7 +126,7 @@ public class MasterDataController {
}
/**
* POST Fetch All AMount Options By Biller Id API Fetch Category Wise from BBPS
* POST Fetch All AMount Options By Biller Id API Fetch CategoryResponseList Wise from BBPS Made By Arham
* URL
**/
@PostMapping(value = "/fetchPlanByCategoryName", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@@ -10,45 +10,43 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@AllArgsConstructor
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public abstract class BaseClass {
@NotBlank(message = "MID cannot be null or blank")
private String mid;
private String mid;
@NotBlank(message = "Secret key cannot be null or blank")
private String secretKey;
@NotBlank(message = "Request ID cannot be null or blank")
private String reqId;
//private String txnId;
private DeviceDetail deviceDetial;
// ✅ 10 User Defined Fields (UDF1–UDF10)
private String udf1;
private DeviceDetail deviceDetial;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String udf2;
// ✅ 10 User Defined Fields (UDF1–UDF10)
private String udf1;
private String udf3;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String udf2;
private String udf4;
private String udf3;
private String udf5;
private String udf4;
private String udf6;
private String udf7;
private String udf5;
private String udf8;
private String udf6;
private String udf9;
private String udf7;
private String udf10;
private String udf8;
private String udf9;
private String udf10;
}
@@ -19,7 +19,7 @@ public class FetchBillValidatestRequest extends BaseClass {
@NotNull
private String billerName; // String, Name of the biller
@NotNull
private String billerCategory; // String, Category of the biller
private String billerCategory; // String, CategoryResponseList of the biller
@NotNull
private String customerMobNo; // String, Mobile of the Customer
@@ -1,5 +1,6 @@
package com.billpaymentservice.bbps.dto.request;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -19,6 +20,8 @@ public class MasterCategoryRequest extends BaseClass {
private Integer pageStart = 0;
private Integer pageEnd = 10;
@NotNull(message = "pageEnd is required")
@Min(value = 1, message = "pageEnd must be greater than 0")
private Integer pageEnd;
}
@@ -0,0 +1,33 @@
package com.billpaymentservice.bbps.entites;
import java.util.List;
import java.util.UUID;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "additional_info")
@Getter
@Setter
public class AdditionalInfoPlans {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "plan_ddditional_info_id")
private Long planAdditionalInfoId;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<PlanTag> tags;
}
@@ -0,0 +1,36 @@
package com.billpaymentservice.bbps.entites;
import java.util.List;
import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.CascadeType;
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.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "amount_option_biller_id")
public class AmountOptionByBillerId extends Auditable<String> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id; // Use Long for auto-increment identity
@Column(name = "amount_options")
private Boolean amountOptions; // This is true or false
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "amount_option_id_long") // Foreign key field that links to the 'Long' column
private List<AmountOptionDetails> amountOptionDetails; // List of AmountOptionDetails
}
@@ -0,0 +1,38 @@
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.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "amount_option_details")
public class AmountOptionDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id; // Primary Key
@Column(name = "amount_breakup_set")
private String amountBreakupSet; // Each string in the list (BASE_BILL_AMOUNT, Apple_Sab, etc.)
@Column(name = "amount_option_id")
private String amountOptionId; // Now a String (change this from Long to String, to match the foreign key)
@Column(name = "amount_option_id_long")
private Long amountOptionIdLong; // Long type for foreign key (added for the FK relationship)
@Column(name = "request_id")
private String requestId;
@Column(name = "txn_id")
private String txnId;
}
@@ -0,0 +1,45 @@
package com.billpaymentservice.bbps.entites;
import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "biller_category_icon")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BillerCategoryIcon extends Auditable<String>{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "icon_id")
private Long id;
@Column(name = "icon_data")
private String iconData;
@Column(name = "icon_type")
private String iconType;
// Owning side of One-to-One
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "biller_id", nullable = false, referencedColumnName = "biller_id",
foreignKey = @ForeignKey(name = "fk_icon_biller"))
private BillerCategoryWise biller;
}
@@ -0,0 +1,66 @@
package com.billpaymentservice.bbps.entites;
import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "biller_category_wise")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BillerCategoryWise extends Auditable<String> {
@Id
@Column(name = "biller_id")
private String billerId;
@Column(name = "biller_name", columnDefinition = "TEXT")
private String billerName;
@Column(name = "biller_type", columnDefinition = "TEXT")
private String billerType;
@Column(name = "biller_category", columnDefinition = "TEXT")
private String billerCategory;
@Column(name = "biller_coverage", columnDefinition = "TEXT")
private String billerCoverage;
@Column(name = "biller_response_type", columnDefinition = "TEXT")
private String billerResponseType;
@Column(name = "biller_description", columnDefinition = "TEXT")
private String billerDescription;
@Column(name = "plan_mdm_requirement", columnDefinition = "TEXT")
private String planMDMRequirement;
@Column(name = "adhoc_biller", columnDefinition = "TEXT")
private String adhocBiller;
@Column(name = "payment_amount_exactness", columnDefinition = "TEXT")
private String paymentAmountExactness;
@Column(name = "request_id")
private String requestId;
@Column(name = "txn_id")
private String txnId;
// One-to-One mapping with icon
@OneToOne(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private BillerCategoryIcon icon;
}
@@ -0,0 +1,33 @@
package com.billpaymentservice.bbps.entites;
import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "category_response_list")
@Getter
@Setter
public class CategoryResponseList extends Auditable<String> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "category_resp_list", columnDefinition = "TEXT")
private String categoryRespList;
@Column(name = "reqquest_id")
private String requestId;
@Column(name = "txn_id")
private String txnId;
}
@@ -0,0 +1,59 @@
package com.billpaymentservice.bbps.entites;
import java.util.List;
import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.CascadeType;
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.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "customer_param_group_by_biller_id")
public class CustomerParamGroupById extends Auditable<String> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "group_id")
private String groupId; // Unique ID for each group, it’s a UUID
@Column(name = "name")
private String name; // Name of the group
@Column(name = "input")
private String input; // Input data for the group (can be a simple string)
// One-to-many relationship with parameters of this group
@OneToMany(mappedBy = "group", cascade = CascadeType.ALL, orphanRemoval = true)
private List<GroupParam> params; // List of parameters related to this group
// One-to-many relationship with child groups (recursively)
@OneToMany(mappedBy = "parentGroup", cascade = CascadeType.ALL, orphanRemoval = true)
private List<CustomerParamGroupById> childGroups; // Child groups of this group
// Many-to-one relationship with parent group (optional, for root groups, this
// will be null)
@ManyToOne
@JoinColumn(name = "parent_group_id")
private CustomerParamGroupById parentGroup; // Link to the parent group
@Column(name = "request_id")
private String requestId;
@Column(name = "txn_id")
private String txnId;
}
@@ -0,0 +1,77 @@
package com.billpaymentservice.bbps.entites;
import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "fetch_bill_validate_response")
public class FetchBillValidate extends Auditable<String> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "bill_id")
private String billId;
@Column(name = "ref_id")
private String refId;
@Column(name = "biller_id")
private String billerId;
@Column(name = "status")
private String status;
@Column(name = "action_type")
private String actionType;
@Column(name = "user_id")
private String userId;
@Column(name = "biller_response")
private String billerResponse;
@Column(name = "additional_info")
private String additionalInfo;
@Column(name = "customer_params")
private String customerParams;
@Column(name = "plan_info_daos")
private String planInfoDaos;
@Column(name = "creation_date")
private String creationDate;
@Column(name = "modified_date")
private String modifiedDate;
@Column(name = "created_epoch_date")
private long createdEpochDate;
@Column(name = "modified_epoch_date")
private long modifiedEpochDate;
@Column(name = "request_id")
private String requestId;
@Column(name = "txn_id")
private String txnId;
}
@@ -0,0 +1,31 @@
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 lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "group_params")
public class GroupParam {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "param_name")
private String paramName; // The parameter name (e.g., "Admission No")
@ManyToOne
@JoinColumn(name = "group_id")
private CustomerParamGroupById group; // Link to the group this parameter belongs to
}
@@ -0,0 +1,65 @@
package com.billpaymentservice.bbps.entites;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "plan")
@Getter
@Setter
public class Plan {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "plan_id")
private String planId;
@Column(name = "description")
private String description;
@Column(name = "biller_id")
private String billerId;
@Column(name = "category_type")
private String categoryType;
@Column(name = "amount_rupees")
private String amountInRupees;
@Column(name = "effectv_form")
private String effctvFrom;
@Column(name = "effectv_to")
private String effctvTo;
@Column(name = "status")
private String status;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "plan")
private List<PlanCategorySubType> categorySubTypes; // List of categorySubTypes
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "plans_list_id")
private PlansList plansList;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "additional_info_id")
private AdditionalInfoPlans additionalInfo;
}
@@ -0,0 +1,30 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "plan_category_sub_type")
@Getter
@Setter
public class PlanCategorySubType {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String categorySubType;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "plan_id")
private Plan plan;
}
@@ -0,0 +1,50 @@
package com.billpaymentservice.bbps.entites;
import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "plan_response")
@Getter
@Setter
public class PlanResponses extends Auditable<String> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "plans_list_id")
private PlansList plansList;
@Column(name = "page_no")
private int pageNo;
@Column(name = "page_size")
private int pageSize;
@Column(name = "total_elements")
private long totalElements;
@Column(name = "total_pages")
private int totalPages;
@Column(name = "request_id")
private String requestId;
@Column(name = "txn_id")
private String txnId;
}
@@ -0,0 +1,37 @@
package com.billpaymentservice.bbps.entites;
import java.util.UUID;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "plan_tag")
@Getter
@Setter
public class PlanTag {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID tagId;
@Column(name="name")
private String name;
@Column(name="value")
private String value;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "plan_id")
private Plan plan;
}
@@ -0,0 +1,29 @@
package com.billpaymentservice.bbps.entites;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "plans_list")
@Getter
@Setter
public class PlansList {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "plansList")
private List<Plan> plans;
}
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.AmountOptionByBillerId;
@Repository
public interface AmountOptionByBillerIdRepository extends JpaRepository<AmountOptionByBillerId, Long> {
}
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.BillerCategoryIcon;
@Repository
public interface BillerCategoryIconRepository extends JpaRepository<BillerCategoryIcon, Long> {
}
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.BillerCategoryWise;
@Repository
public interface BillerCategoryWiseRepository extends JpaRepository<BillerCategoryWise, String>{
}
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.CategoryResponseList;
@Repository
public interface CategoryResponseListRepository extends JpaRepository<CategoryResponseList, Long> {
}
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.CustomerParamGroupById;
@Repository
public interface CustomerParamGroupByBillerIdRepository extends JpaRepository<CustomerParamGroupById, Long> {
}
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.FetchBillValidate;
@Repository
public interface FetchBillValidateRepository extends JpaRepository<FetchBillValidate, Long> {
}
@@ -0,0 +1,12 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.PlanResponses;
@Repository
public interface PlanResponseRepository extends JpaRepository<PlanResponses, Long> {
}
@@ -26,6 +26,7 @@ import com.billpaymentservice.bbps.repository.InboundTraceLogRepository;
import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository;
import com.billpaymentservice.bbps.service.AgentService;
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.fasterxml.jackson.core.JsonProcessingException;
@@ -45,179 +46,176 @@ public class AgentServiceImpl implements AgentService {
private final HttpService httpService;
private final Helper helper;
private final BharatConnectMasterRepository beneficiaryDetailsRepository;
private final BillerMapperHelper mapperHelper;
public AgentServiceImpl(RestClient restClient, HttpService httpService, Helper helper,
BharatConnectMasterRepository beneficiaryDetailsRepository,InboundTraceLogRepository inboundTraceLogRepository,
OutboundTraceLogRepository outboundTraceLogRepository) {
BharatConnectMasterRepository beneficiaryDetailsRepository,
InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository,
BillerMapperHelper mapperHelper) {
this.restClient = restClient;
this.httpService = httpService;
this.helper = helper;
this.beneficiaryDetailsRepository = beneficiaryDetailsRepository;
this.mapperHelper = mapperHelper;
}
@Override
public ResponseModel initiateBillFetch(FetchBillRequest fetchBillRequest) {
String apiName = "InitiateBillFetch";
String txnId = helper.generateTxnId(15);
String requestId = fetchBillRequest.getReqId();
String url = agentDtaUrl + BBPSConstant.BILL_FETCH_INTI;
String apiName = "InitiateBillFetch";
String txnId = helper.generateTxnId(15);
String requestId = fetchBillRequest.getReqId();
String url = agentDtaUrl + BBPSConstant.BILL_FETCH_INTI;
helper.validateMerchant(fetchBillRequest.getMid());
helper.validateMerchant(fetchBillRequest.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);
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(fetchBillRequest);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String requestJson = helper.convertObjectToJson(fetchBillRequest);
// ✅ Create inbound & outbound logs
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, fetchBillRequest.getMid(), "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "POST", requestJson);
// ✅ Create inbound & outbound logs
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, fetchBillRequest.getMid(),
"POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "POST", requestJson);
try {
Map<String, String> responseMap = httpService.postRequest(url, requestJson, headers);
String responseData = responseMap.get("data");
try {
Map<String, String> responseMap = httpService.postRequest(url, requestJson, headers);
String responseData = responseMap.get("data");
log.info("📦 Bill Fetch API Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
log.info("📦 Bill Fetch API Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
if (responseData == null || responseData.isEmpty()) {
helper.updateInboundLogFailure(inboundLog, "Empty response from BBPS", "FAILED");
throw new CustomException("Empty response from BBPS server");
}
if (responseData == null || responseData.isEmpty()) {
helper.updateInboundLogFailure(inboundLog, "Empty response from BBPS", "FAILED");
throw new CustomException("Empty response from BBPS server");
}
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
if (!dataMap.containsKey("genericResponse")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_STRUCTURE");
throw new CustomException("Invalid response structure from BBPS");
}
Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() {
});
if (!dataMap.containsKey("genericResponse")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_STRUCTURE");
throw new CustomException("Invalid response structure from BBPS");
}
FetchBillResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillResponse.class);
GeneralResp generalResponse = fetchBillResponse.getGenericResponse();
FetchBillResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillResponse.class);
GeneralResp generalResponse = fetchBillResponse.getGenericResponse();
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
// ✅ Directly call fetchBillById (no polling)
BillFetchByBillIdRequest billFetchByBillIdRequest = new BillFetchByBillIdRequest();
billFetchByBillIdRequest.setBillId(fetchBillResponse.getBillId());
billFetchByBillIdRequest.setMid(fetchBillRequest.getMid());
billFetchByBillIdRequest.setReqId(requestId);
// ✅ Directly call fetchBillById (no polling)
BillFetchByBillIdRequest billFetchByBillIdRequest = new BillFetchByBillIdRequest();
billFetchByBillIdRequest.setBillId(fetchBillResponse.getBillId());
billFetchByBillIdRequest.setMid(fetchBillRequest.getMid());
billFetchByBillIdRequest.setReqId(requestId);
return fetchBillById(billFetchByBillIdRequest, inboundLog);
return fetchBillById(billFetchByBillIdRequest, inboundLog);
} catch (JsonProcessingException e) {
log.error("❌ JSON Parsing Error: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException ce) {
throw ce;
} catch (Exception e) {
log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "EXCEPTION");
throw new CustomException("Bill Fetch initiation failed: " + e.getMessage());
}
} catch (JsonProcessingException e) {
log.error("❌ JSON Parsing Error: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException ce) {
throw ce;
} catch (Exception e) {
log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "EXCEPTION");
throw new CustomException("Bill Fetch initiation failed: " + e.getMessage());
}
}
public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest, InboundTraceLog inboundLog) {
String apiName = "FetchBillById";
String txnId = helper.generateTxnId(15);
String requestId = billFetchByBillIdRequest.getReqId();
String billId = billFetchByBillIdRequest.getBillId();
String url = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + "1ced7566-1add-4e01-9ed6-04cd67ac9684";
String apiName = "FetchBillById";
String txnId = helper.generateTxnId(15);
String requestId = billFetchByBillIdRequest.getReqId();
String billId = billFetchByBillIdRequest.getBillId();
String url = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + "1ced7566-1add-4e01-9ed6-04cd67ac9684";
helper.validateMerchant(billFetchByBillIdRequest.getMid());
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);
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, requestId, apiName, url, "GET", null);
ObjectMapper objectMapper = new ObjectMapper();
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "GET", null);
// ✅ Loop setup
long startTime = System.currentTimeMillis();
long maxWaitTimeMs = 40000; // 40 seconds
long intervalMs = 5000; // 5 seconds
// ✅ Loop setup
long startTime = System.currentTimeMillis();
long maxWaitTimeMs = 40000; // 40 seconds
long intervalMs = 5000; // 5 seconds
while (true) {
try {
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
log.info("📦 Bill FetchById Response: {}", responseData);
while (true) {
try {
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
log.info("📦 Bill FetchById Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() {
});
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"))
);
}
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();
BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class);
GeneralResp generalResp = responseWrapper.getGenericResponse();
String status = generalResp.getStatus();
log.info("📡 Current Bill Status: {}", status);
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 waiting for bill fetch completion", "FAILED", 408, "Bill fetch still in progress");
}
// ✅ 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 waiting for bill fetch completion", "FAILED", 408,
"Bill fetch still in progress");
}
Thread.sleep(intervalMs);
continue; // retry again
}
Thread.sleep(intervalMs);
continue; // retry again
}
// ✅ Final successful response
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
// ✅ Final successful response
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
);
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");
} catch (CustomException ce) {
throw ce;
} catch (Exception e) {
log.error("❌ Exception in fetchBillById(): {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "EXCEPTION");
throw new CustomException("Bill Fetch by ID failed: " + e.getMessage());
}
}
} 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");
} catch (CustomException ce) {
throw ce;
} catch (Exception e) {
log.error("❌ Exception in fetchBillById(): {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "EXCEPTION");
throw new CustomException("Bill Fetch by ID failed: " + e.getMessage());
}
}
}
@Override
public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest) {
@@ -272,140 +270,144 @@ public class AgentServiceImpl implements AgentService {
}
@Override
public ResponseModel initiateBillValidate(FetchBillValidatestRequest fetchBillValidateRequest) {
// TODO Auto-generated method stub
return null;
ResponseModel responseModel = new ResponseModel();
try {
String apiName = "InitiateBillValidate";
String txnId = helper.generateTxnId(15);
String requestId = fetchBillValidateRequest.getReqId();
String url = agentDtaUrl + BBPSConstant.BILLER_VALIDATE_URL;
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);
String requestJson = helper.convertObjectToJson(fetchBillValidateRequest);
ObjectMapper objectMapper = new ObjectMapper();
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName,
fetchBillValidateRequest.getMid(), "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "POST",
requestJson);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
String json = objectMapper.writeValueAsString(fetchBillValidateRequest);
Map<String, String> responseMap = httpService.postRequest(url, json, headers);
String responseData = responseMap.get("data");
log.info("📦 Bill Fetch API Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
if (responseData == null || responseData.isEmpty()) {
helper.updateInboundLogFailure(inboundLog, "Empty response from BBPS", "FAILED");
throw new CustomException("Empty response from BBPS server");
}
Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() {
});
if (!dataMap.containsKey("genericResponse")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_STRUCTURE");
throw new CustomException("Invalid response structure from BBPS");
}
FetchBillValidatestResponse fetchBillResponse = objectMapper.convertValue(dataMap,
FetchBillValidatestResponse.class);
mapperHelper.saveFetchBillValidateResponse(fetchBillResponse, requestId, txnId);
GeneralResp generalResponse = fetchBillResponse.getGenericResponse();
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
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();
} 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) {
// TODO Auto-generated method stub
return null;
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);
Map<String, String> 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");
}
Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() {
});
if (!dataMap.containsKey("genericResponse")) {
throw new CustomException("Invalid response structure from BBPS");
}
BillDataResponse fetchBillResponse = objectMapper.convertValue(dataMap, BillDataResponse.class);
GeneralResp generalResponse = fetchBillResponse.getGenericResponse();
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();
} 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
* 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<String, String>
* 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<String, Object> dataMap =
* objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>()
* { });
*
* // ✅ 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<String, String> 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<String, Object> dataMap =
* objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>()
* { });
*
* // ✅ 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;
*
* }
*/
}
@@ -1,16 +1,18 @@
// java
package com.billpaymentservice.bbps.serviceImpl;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.billpaymentservice.bbps.dto.CustomerParamGroupsDTO;
import com.billpaymentservice.bbps.dto.GeneralResp;
import com.billpaymentservice.bbps.dto.MasterApiResponse;
import com.billpaymentservice.bbps.dto.ResponseModel;
@@ -31,6 +33,7 @@ import com.billpaymentservice.bbps.dto.response.DispositionResponse;
import com.billpaymentservice.bbps.dto.response.PlanResponse;
import com.billpaymentservice.bbps.dto.response.PlaneCategoriesResponse;
import com.billpaymentservice.bbps.entites.BharatConnectMaster;
import com.billpaymentservice.bbps.entites.BillerCategoryWise;
import com.billpaymentservice.bbps.entites.BillerDetails;
import com.billpaymentservice.bbps.entites.DispositionDetails;
import com.billpaymentservice.bbps.entites.InboundTraceLog;
@@ -44,6 +47,7 @@ import com.billpaymentservice.bbps.repository.MerchantRepository;
import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository;
import com.billpaymentservice.bbps.service.MasterDataService;
import com.billpaymentservice.bbps.util.BBPSConstant;
import com.billpaymentservice.bbps.util.BillerMapperHelper;
import com.billpaymentservice.bbps.util.EntityRelationshipUtil;
import com.billpaymentservice.bbps.util.Helper;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -58,7 +62,7 @@ public class MasterDataServiceImpl implements MasterDataService {
@Value("${master.data.url}")
private String masterRegisterUrl;
private final BharatConnectMasterRepository beneficiaryDetailsRepository;
private final BillerMapperHelper mapperHelper;
private MerchantRepository merchantRegisterRepo;
private HttpClientApi httpClientApi;
private final DispositionRepository dispositionRepository;
@@ -73,8 +77,8 @@ public class MasterDataServiceImpl implements MasterDataService {
public MasterDataServiceImpl(MerchantRepository merchantRegisterRepo, HttpService httpService,
HttpClientApi httpClientApi, Helper helper, BillerDataRepository billerDataRespository,
DispositionRepository dispositionRepository, BharatConnectMasterRepository beneficiaryDetailsRepository,
InboundTraceLogRepository inboundTraceLogRepository,
OutboundTraceLogRepository outboundTraceLogRepository) {
InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository,
BillerMapperHelper mapperHelper) {
this.merchantRegisterRepo = merchantRegisterRepo;
this.httpService = httpService;
this.httpClientApi = httpClientApi;
@@ -84,6 +88,7 @@ public class MasterDataServiceImpl implements MasterDataService {
this.beneficiaryDetailsRepository = beneficiaryDetailsRepository;
this.inboundTraceLogRepository = inboundTraceLogRepository;
this.outboundTraceLogRepository = outboundTraceLogRepository;
this.mapperHelper = mapperHelper;
}
@@ -95,10 +100,10 @@ public class MasterDataServiceImpl implements MasterDataService {
String apiName = "GetMasterData";
String requestId = masterRequest.getReqId();
String requestJson = helper.convertObjectToJson(masterRequest);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, masterRequest.getMid(), "POST",
requestJson);
try {
// Merchant Validation
helper.validateMerchant(masterRequest.getMid());
@@ -155,15 +160,12 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException ex) {
LOGGER.warn("Merchant validation failed: {}", ex.getMessage());
return ex.getResponseModel(); // Directly return ResponseModel from exception
}
}
@Override
public ResponseModel getBillerByBillerId(BillerDetailRequest billerDetailRequest) {
helper.validateMerchant(billerDetailRequest.getMid());
String txnID = helper.generateTxnId(15);
String apiName = "GetBillerByBillerId";
@@ -172,8 +174,8 @@ public class MasterDataServiceImpl implements MasterDataService {
String fullUrl = masterRegisterUrl + BBPSConstant.BILLER_DATA_FETCH_URL + billerId;
String requestJson = helper.convertObjectToJson(billerDetailRequest);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, billerDetailRequest.getMid(), "POST",
requestJson);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, billerDetailRequest.getMid(),
"POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
@@ -224,8 +226,8 @@ public class MasterDataServiceImpl implements MasterDataService {
String apiName = "GetCustomerParamByBillerId";
String requestId = customerParamRequest.getReqId();
String requestJson = helper.convertObjectToJson(customerParamRequest);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, customerParamRequest.getMid(), "POST",
requestJson);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, customerParamRequest.getMid(),
"POST", requestJson);
try {
helper.validateMerchant(customerParamRequest.getMid());
@@ -270,9 +272,6 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException ex) {
LOGGER.warn("Merchant validation failed: {}", ex.getMessage());
return ex.getResponseModel(); // Directly return ResponseModel from exception
}
}
@@ -285,7 +284,7 @@ public class MasterDataServiceImpl implements MasterDataService {
@Override
public ResponseModel fetchMasterDataCategoryWise(MasterCategoryRequest masterRequest) {
LOGGER.info("Fetching Master Data Category-wise " + masterRequest);
LOGGER.info("Fetching Master Data CategoryResponseList-wise " + masterRequest);
String txnID = helper.generateTxnId(15);
String apiName = "FetchMasterDataCategoryWise";
@@ -323,6 +322,9 @@ public class MasterDataServiceImpl implements MasterDataService {
}
BillerResponse responseWrapper = objectMapper.convertValue(dataMap, BillerResponse.class);
List<BillerCategoryWise> savedEntities = mapperHelper.mapAndSaveAll(responseWrapper.getBillerResp(),
requestId, txnID);
GeneralResp generalResp = responseWrapper.getGeneralResp();
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
@@ -335,9 +337,6 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException ex) {
LOGGER.warn("Merchant validation failed: {}", ex.getMessage());
return ex.getResponseModel(); // Directly return ResponseModel from exception
}
}
@@ -347,8 +346,8 @@ public class MasterDataServiceImpl implements MasterDataService {
String apiName = "GetDispositionDetails";
String requestId = dispositionDetailRequest.getReqId();
;
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, dispositionDetailRequest.getMid(),
"GET", "N/A");
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName,
dispositionDetailRequest.getMid(), "GET", "N/A");
String fullUrl = masterRegisterUrl + BBPSConstant.DISPOSTION_URL;
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
@@ -397,15 +396,12 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException ex) {
LOGGER.warn("Merchant validation failed: {}", ex.getMessage());
return ex.getResponseModel(); // Directly return ResponseModel from exception
}
}
@Override
public ResponseModel fetchCustomerParamGroup(BillerDetailRequest requestModel) {
LOGGER.info("Fetching Master Data Category-wise for MID={}", requestModel.getMid());
LOGGER.info("Fetching Master Data CategoryResponseList-wise for MID={}", requestModel.getMid());
String txnID = helper.generateTxnId(15);
String apiName = "FetchCustomerParamGroup";
@@ -439,6 +435,9 @@ public class MasterDataServiceImpl implements MasterDataService {
CustomerParamGroupsResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
CustomerParamGroupsDTO responseDTO = mapperHelper
.saveCustomerParamGroups(responseWrapper.getCustomerParamGroupResp(), requestId, txnID);
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
@@ -450,9 +449,6 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException ex) {
LOGGER.warn("Merchant validation failed: {}", ex.getMessage());
return ex.getResponseModel(); // Directly return ResponseModel from exception
}
}
@@ -492,6 +488,10 @@ public class MasterDataServiceImpl implements MasterDataService {
}
AmountOptionsResponse responseWrapper = objectMapper.convertValue(dataMap, AmountOptionsResponse.class);
String saveAmountOptionsResponse = mapperHelper.saveAmountOptionsResponse(responseWrapper, requestId,
txnID);
GeneralResp generalResp = responseWrapper.getGeneralResp();
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
@@ -505,9 +505,6 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException e) {
LOGGER.error("Custom Exception: {}", e.getMessage());
throw e; // Rethrow custom exceptions to be handled by the controller
}
}
@@ -547,6 +544,8 @@ public class MasterDataServiceImpl implements MasterDataService {
}
PlaneCategoriesResponse responseWrapper = objectMapper.convertValue(dataMap, PlaneCategoriesResponse.class);
mapperHelper.saveCategoryItems(responseWrapper.getCategoryRespList(), requestId, txnID);
GeneralResp generalResp = responseWrapper.getGeneralResp();
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
@@ -560,9 +559,6 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException e) {
LOGGER.error("Custom Exception: {}", e.getMessage());
throw e; // Rethrow custom exceptions to be handled by the controller
}
}
@@ -616,84 +612,70 @@ public class MasterDataServiceImpl implements MasterDataService {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException e) {
LOGGER.error("Custom Exception: {}", e.getMessage());
throw e; // Rethrow custom exceptions to be handled by the controller
}
}
public ResponseModel fetchPlanByCategories(PlanRequest requestModel) {
LOGGER.info("Fetching Initiating Fetch Plan Category By Biller Id for MID={}", requestModel.getMid());
LOGGER.info("Fetching Initiating Fetch Plan CategoryResponseList By Biller Id for MID={}",
requestModel.getMid());
String txnID = helper.generateTxnId(15);
String apiName = "FetchPlanByCategories";
String requestId = requestModel.getReqId();
String txnID = helper.generateTxnId(15);
String apiName = "FetchPlanByCategories";
String requestId = requestModel.getReqId();
helper.validateMerchant(requestModel.getMid());
helper.validateMerchant(requestModel.getMid());
String url = String.format("%s%s?billerId=%s%s%s%s&page=%d&pagesize=%d",
masterRegisterUrl,
BBPSConstant.PLANS_URL,
requestModel.getBillerId(),
requestModel.getCategory() != null ? "&category=" + requestModel.getCategory() : "",
requestModel.getAmountInRupees() != null ? "&amountInRupees=" + requestModel.getAmountInRupees() : "",
requestModel.getCircle() != null ? "&circle=" + requestModel.getCircle() : "",
requestModel.getPage(),
requestModel.getPagesize()
);
String url = String.format("%s%s?billerId=%s%s%s%s&page=%d&pagesize=%d", masterRegisterUrl,
BBPSConstant.PLANS_URL, requestModel.getBillerId(),
requestModel.getCategory() != null ? "&category=" + requestModel.getCategory() : "",
requestModel.getAmountInRupees() != null ? "&amountInRupees=" + requestModel.getAmountInRupees() : "",
requestModel.getCircle() != null ? "&circle=" + requestModel.getCircle() : "", requestModel.getPage(),
requestModel.getPagesize());
LOGGER.info("Calling Master API: {}", url);
LOGGER.info("Calling Master API: {}", url);
// Convert request to JSON and create inbound & outbound logs
String requestJson = helper.convertObjectToJson(requestModel);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, requestModel.getMid(), "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null);
// Convert request to JSON and create inbound & outbound logs
String requestJson = helper.convertObjectToJson(requestModel);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, requestModel.getMid(), "POST",
requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null);
try {
Map<String, String> apiResponse = httpService.getRequest(url);
String responseData = apiResponse.get("data");
log.info("Response Data: {}", responseData);
try {
Map<String, String> apiResponse = httpService.getRequest(url);
String responseData = apiResponse.get("data");
log.info("Response Data: {}", responseData);
// Update outbound log with response
helper.updateOutboundLogResponse(outboundLog, responseData);
// Update outbound log with response
helper.updateOutboundLogResponse(outboundLog, responseData);
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() {
});
if (!dataMap.containsKey("generalResp")) {
// Failure response
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"))
);
}
if (!dataMap.containsKey("generalResp")) {
// Failure response
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")));
}
// Success response
PlanResponse responseWrapper = objectMapper.convertValue(dataMap, PlanResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
// Success response
PlanResponse responseWrapper = objectMapper.convertValue(dataMap, PlanResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
);
mapperHelper.savePlanResponse(responseWrapper, requestId, txnID);
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (CustomException e) {
LOGGER.error("Custom Exception: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "Custom_exception");
throw e; // Rethrow for controller-level handling
}
} catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
}
}
}
@@ -0,0 +1,32 @@
package com.billpaymentservice.bbps.swagger;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.servers.Server;
@Configuration
public class SwaggerConfig {
@Value("${swagger.server.url}")
private String serverUrl;
@Value("${swagger.server.description}")
private String serverDescription;
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info().title("BBPS API").description("Spring Boot REST API for BBPS System API Documentation")
.version("1.0.0").contact(new Contact().name("BBPS ")))
.servers(List.of(new Server().url(serverUrl).description(serverDescription)));
}
}
@@ -0,0 +1,344 @@
package com.billpaymentservice.bbps.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import com.billpaymentservice.bbps.dto.AmountOptionDTO;
import com.billpaymentservice.bbps.dto.BillerIconDTO;
import com.billpaymentservice.bbps.dto.CustomerParamGroupsDTO;
import com.billpaymentservice.bbps.dto.GroupDTO;
import com.billpaymentservice.bbps.dto.MasterCategoryBillerResponse;
import com.billpaymentservice.bbps.dto.response.AmountOptionsResponse;
import com.billpaymentservice.bbps.dto.response.FetchBillValidatestResponse;
import com.billpaymentservice.bbps.dto.response.PlanResponse;
import com.billpaymentservice.bbps.entites.AmountOptionByBillerId;
import com.billpaymentservice.bbps.entites.AmountOptionDetails;
import com.billpaymentservice.bbps.entites.BillerCategoryIcon;
import com.billpaymentservice.bbps.entites.BillerCategoryWise;
import com.billpaymentservice.bbps.entites.CategoryResponseList;
import com.billpaymentservice.bbps.entites.CustomerParamGroupById;
import com.billpaymentservice.bbps.entites.FetchBillValidate;
import com.billpaymentservice.bbps.entites.GroupParam;
import com.billpaymentservice.bbps.entites.PlanResponses;
import com.billpaymentservice.bbps.repository.AmountOptionByBillerIdRepository;
import com.billpaymentservice.bbps.repository.BillerCategoryWiseRepository;
import com.billpaymentservice.bbps.repository.CategoryResponseListRepository;
import com.billpaymentservice.bbps.repository.CustomerParamGroupByBillerIdRepository;
import com.billpaymentservice.bbps.repository.FetchBillValidateRepository;
import com.billpaymentservice.bbps.repository.PlanResponseRepository;
@Component
public class BillerMapperHelper {
private final BillerCategoryWiseRepository billerRepo;
private final CustomerParamGroupByBillerIdRepository customerParamGroupByBillerIdRepo;
private final AmountOptionByBillerIdRepository amountOptionByBillerIdRepository;
private final PlanResponseRepository planResponseRepository;
private final CategoryResponseListRepository categoryResponseListRepository;
private final FetchBillValidateRepository fetchBillValidateRepository;
public BillerMapperHelper(BillerCategoryWiseRepository billerRepo,
CustomerParamGroupByBillerIdRepository customerParamGroupByBillerIdRepo,
AmountOptionByBillerIdRepository amountOptionByBillerIdRepository,
PlanResponseRepository planResponseRepository,
CategoryResponseListRepository categoryResponseListRepository,
FetchBillValidateRepository fetchBillValidateRepository) {
this.billerRepo = billerRepo;
this.customerParamGroupByBillerIdRepo = customerParamGroupByBillerIdRepo;
this.amountOptionByBillerIdRepository = amountOptionByBillerIdRepository;
this.planResponseRepository = planResponseRepository;
this.categoryResponseListRepository = categoryResponseListRepository;
this.fetchBillValidateRepository = fetchBillValidateRepository;
}
/**
* Maps a list of MasterCategoryBillerResponse DTOs to entities, saves them, and
* returns the saved list
*/
public List<BillerCategoryWise> mapAndSaveAll(List<MasterCategoryBillerResponse> dtos, String requestId,
String txnId) {
if (dtos == null || dtos.isEmpty()) {
return Collections.emptyList();
}
List<BillerCategoryWise> 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.setCreateDateTime(new Date());
biller.setRequestId(requestId);
biller.setTxnId(txnId);
// 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) {
if (dtos == null || dtos.getGroups() == null || dtos.getGroups().isEmpty()) {
return new CustomerParamGroupsDTO(); // Return empty DTO if no groups exist
}
List<CustomerParamGroupById> 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); // 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<CustomerParamGroupById> 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) {
// 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.setCreateDateTime(new Date());
// Save group parameters (if any)
if (groupDTO.getParams() != null && !groupDTO.getParams().isEmpty()) {
List<GroupParam> 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<CustomerParamGroupById> childEntities = new ArrayList<>();
for (GroupDTO childGroupDTO : groupDTO.getGroups()) {
CustomerParamGroupById childEntity = saveGroupWithChildren(childGroupDTO, groupEntity, requestId,
txnId); // 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<CustomerParamGroupById> 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<GroupDTO> 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<GroupDTO> 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) {
// 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<AmountOptionDetails> amountOptionDetailsList = mapAmountOptionDTOToEntity(
responseWrapper.getAmountOptionDAOS(), requestId, txnId);
// Set the mapped AmountOptionDetails list to AmountOptionByBillerId entity
entity.setAmountOptionDetails(amountOptionDetailsList);
entity.setCreateDateTime(new Date());
// Save AmountOptionByBillerId entity (this will also save related
// AmountOptionDetails entities)
amountOptionByBillerIdRepository.save(entity); // Saves the entity and cascades to AmountOptionDetails
// Return success message
return "Data saved successfully!";
}
private List<AmountOptionDetails> mapAmountOptionDTOToEntity(List<AmountOptionDTO> amountOptionDTOs,
String requestId, String txnId) {
// 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);
// Return the mapped AmountOptionDetails entity
return amountOptionDetails;
})).collect(Collectors.toList()); // Collect them into a list and return
}
public PlanResponses savePlanResponse(PlanResponse planResponseDTO, String requestId, String txnId) {
// If the list is null or empty, return an empty list of entities
if (planResponseDTO == null) {
return new PlanResponses(); // Return an empty list of AmountOptionDetails
}
// Convert DTO to Entity using ModelMapper
ModelMapper modelMapper = new ModelMapper();
PlanResponses planResponseEntity = modelMapper.map(planResponseDTO, PlanResponses.class);
// Save the entity to the database
// Set the requestId and txnId in the entity
planResponseEntity.setRequestId(requestId);
planResponseEntity.setTxnId(txnId);
planResponseEntity.setCreateDateTime(new Date());
return planResponseRepository.save(planResponseEntity);
}
public String saveCategoryItems(List<String> categoryRespList, String requestId, String txnId) {
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.setCreateDateTime(new Date());
categoryResponseListRepository.save(category);
savedCount++;
}
return savedCount + " items were successfully saved.";
}
public FetchBillValidate saveFetchBillValidateResponse(FetchBillValidatestResponse dto, String requestId,
String txnId) {
if (dto == null) {
return new FetchBillValidate();
}
// Convert DTO to Entity
FetchBillValidate entity = new FetchBillValidate();
entity.setBillId(dto.getBillId());
entity.setRefId(dto.getRefId());
entity.setBillerId(dto.getBillerId());
entity.setStatus(dto.getStatus());
entity.setActionType(dto.getActionType());
entity.setUserId(dto.getUserId());
entity.setBillerResponse(dto.getBillerResponse());
entity.setAdditionalInfo(dto.getAdditionalInfo());
entity.setCustomerParams(dto.getCustomerParams());
entity.setPlanInfoDaos(dto.getPlanInfoDaos());
entity.setCreationDate(dto.getCreationDate());
entity.setModifiedDate(dto.getModifiedDate());
entity.setCreatedEpochDate(dto.getCreatedEpochDate());
entity.setModifiedEpochDate(dto.getModifiedEpochDate());
entity.setRequestId(requestId);
entity.setTxnId(txnId);
entity.setCreateDateTime(new Date());
// Save the entity in the database
return fetchBillValidateRepository.save(entity);
}
}
+8 -1
View File
@@ -9,11 +9,18 @@ spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.default_schema=public
#swagger.server.url=https://procurelinc.in/BBPS
#swagger.server.description=Production Server
swagger.server.url=http://192.168.1.24:9090
swagger.server.description=Local Development Server
# DataSource
spring.datasource.url=jdbc:postgresql://localhost:5432/BBPS
spring.datasource.username=postgres
spring.datasource.password=thakur@123
spring.datasource.password=UAT@DB_2025
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource