feat: Implement major features and fix theming bug
This commit introduces several new features and a critical bug fix. - Implemented a full "Quick Pay" flow for both within and outside the bank, including IFSC validation, beneficiary verification, and a TPIN-based payment process. - Added a date range filter to the Account Statement screen and streamlined the UI by removing the amount filters. - Fixed a major bug that prevented dynamic theme changes from being applied. The app now correctly switches between color themes. - Refactored and improved beneficiary management, transaction models, and the fund transfer flow to support NEFT/RTGS.
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
class Beneficiary {
|
||||
@@ -9,6 +7,7 @@ class Beneficiary {
|
||||
final String ifscCode;
|
||||
final String? bankName;
|
||||
final String? branchName;
|
||||
final String? tpin;
|
||||
|
||||
Beneficiary({
|
||||
required this.accountNo,
|
||||
@@ -17,30 +16,43 @@ class Beneficiary {
|
||||
required this.ifscCode,
|
||||
this.bankName,
|
||||
this.branchName,
|
||||
this.tpin,
|
||||
});
|
||||
|
||||
factory Beneficiary.fromJson(Map<String, dynamic> json) {
|
||||
return Beneficiary(
|
||||
accountNo: json['accountNo'] ?? '',
|
||||
accountType: json['accountType'] ?? '',
|
||||
accountNo: json['account_no'] ?? json['accountNo'] ?? '',
|
||||
accountType: json['account_type'] ?? json['accountType'] ?? '',
|
||||
name: json['name'] ?? '',
|
||||
ifscCode: json['ifscCode'] ?? '',
|
||||
bankName: json['bankName'] ?? '',
|
||||
branchName: json['branchName'] ?? '',
|
||||
ifscCode: json['ifsc_code'] ?? json['ifscCode'] ?? '',
|
||||
bankName: json['bank_name'] ?? json['bankName'] ?? '',
|
||||
branchName: json['branch_name'] ?? json['branchName'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
final Map<String, dynamic> json = {
|
||||
'accountNo': accountNo,
|
||||
'accountType': accountType,
|
||||
'name': name,
|
||||
'ifscCode' : ifscCode,
|
||||
'ifscCode': ifscCode,
|
||||
};
|
||||
if (bankName != null && bankName!.isNotEmpty) {
|
||||
json['bankName'] = bankName;
|
||||
}
|
||||
if (branchName != null && branchName!.isNotEmpty) {
|
||||
json['branchName'] = branchName;
|
||||
}
|
||||
if (tpin != null && tpin!.isNotEmpty) {
|
||||
json['tpin'] = tpin;
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
static List<Beneficiary> listFromJson(List<dynamic> jsonList) {
|
||||
final beneficiaryList = jsonList.map((beneficiary) => Beneficiary.fromJson(beneficiary)).toList();
|
||||
final beneficiaryList = jsonList
|
||||
.map((beneficiary) => Beneficiary.fromJson(beneficiary))
|
||||
.toList();
|
||||
print(beneficiaryList);
|
||||
return beneficiaryList;
|
||||
}
|
||||
@@ -49,4 +61,5 @@ class Beneficiary {
|
||||
String toString() {
|
||||
return 'Beneficiary(accountNo: $accountNo, accountType: $accountType, ifscCode: $ifscCode, name: $name)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,16 +1,16 @@
|
||||
class ifsc {
|
||||
class Ifsc {
|
||||
final String ifscCode;
|
||||
final String bankName;
|
||||
final String branchName;
|
||||
|
||||
ifsc({
|
||||
Ifsc({
|
||||
required this.ifscCode,
|
||||
required this.bankName,
|
||||
required this.branchName,
|
||||
});
|
||||
|
||||
factory ifsc.fromJson(Map<String, dynamic> json) {
|
||||
return ifsc(
|
||||
factory Ifsc.fromJson(Map<String, dynamic> json) {
|
||||
return Ifsc(
|
||||
ifscCode: json['ifsc_code'] ?? '',
|
||||
bankName: json['bank_name'] ?? '',
|
||||
branchName: json['branch_name'] ?? '',
|
||||
@@ -29,4 +29,5 @@ class ifsc {
|
||||
String toString() {
|
||||
return 'IFSC(ifscCode: $ifscCode, bankName: $bankName, branchName: $branchName)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
16
lib/data/models/neft_response.dart
Normal file
16
lib/data/models/neft_response.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
class NeftResponse {
|
||||
final String message;
|
||||
final String utr;
|
||||
|
||||
NeftResponse({
|
||||
required this.message,
|
||||
required this.utr,
|
||||
});
|
||||
|
||||
factory NeftResponse.fromJson(Map<String, dynamic> json) {
|
||||
return NeftResponse(
|
||||
message: json['message'] ?? '',
|
||||
utr: json['utr'] ?? '',
|
||||
);
|
||||
}
|
||||
}
|
31
lib/data/models/neft_transaction.dart
Normal file
31
lib/data/models/neft_transaction.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
class NeftTransaction {
|
||||
final String fromAccount;
|
||||
final String toAccount;
|
||||
final String amount;
|
||||
final String ifscCode;
|
||||
final String remitterName;
|
||||
final String beneficiaryName;
|
||||
final String tpin;
|
||||
|
||||
NeftTransaction({
|
||||
required this.fromAccount,
|
||||
required this.toAccount,
|
||||
required this.amount,
|
||||
required this.ifscCode,
|
||||
required this.remitterName,
|
||||
required this.beneficiaryName,
|
||||
required this.tpin,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'fromAccount': fromAccount,
|
||||
'toAccount': toAccount,
|
||||
'amount': amount,
|
||||
'ifscCode': ifscCode,
|
||||
'remitterName': remitterName,
|
||||
'beneficiaryName': beneficiaryName,
|
||||
'tpin': tpin,
|
||||
};
|
||||
}
|
||||
}
|
@@ -6,6 +6,7 @@ class PaymentResponse {
|
||||
final String? currency;
|
||||
final String? errorMessage;
|
||||
final String? errorCode;
|
||||
final String? utr;
|
||||
|
||||
PaymentResponse({
|
||||
required this.isSuccess,
|
||||
@@ -15,5 +16,6 @@ class PaymentResponse {
|
||||
this.currency,
|
||||
this.errorMessage,
|
||||
this.errorCode,
|
||||
this.utr,
|
||||
});
|
||||
}
|
||||
|
16
lib/data/models/rtgs_response.dart
Normal file
16
lib/data/models/rtgs_response.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
class RtgsResponse {
|
||||
final String message;
|
||||
final String utr;
|
||||
|
||||
RtgsResponse({
|
||||
required this.message,
|
||||
required this.utr,
|
||||
});
|
||||
|
||||
factory RtgsResponse.fromJson(Map<String, dynamic> json) {
|
||||
return RtgsResponse(
|
||||
message: json['message'] ?? '',
|
||||
utr: json['utr'] ?? '',
|
||||
);
|
||||
}
|
||||
}
|
31
lib/data/models/rtgs_transaction.dart
Normal file
31
lib/data/models/rtgs_transaction.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
class RtgsTransaction {
|
||||
final String fromAccount;
|
||||
final String toAccount;
|
||||
final String amount;
|
||||
final String ifscCode;
|
||||
final String remitterName;
|
||||
final String beneficiaryName;
|
||||
final String tpin;
|
||||
|
||||
RtgsTransaction({
|
||||
required this.fromAccount,
|
||||
required this.toAccount,
|
||||
required this.amount,
|
||||
required this.ifscCode,
|
||||
required this.remitterName,
|
||||
required this.beneficiaryName,
|
||||
required this.tpin,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'fromAccount': fromAccount,
|
||||
'toAccount': toAccount,
|
||||
'amount': amount,
|
||||
'ifscCode': ifscCode,
|
||||
'remitterName': remitterName,
|
||||
'beneficiaryName': beneficiaryName,
|
||||
'tpin': tpin,
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,8 +1,12 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:kmobile/data/models/transaction.dart';
|
||||
|
||||
abstract class TransactionRepository {
|
||||
Future<List<Transaction>> fetchTransactions(String accountNo);
|
||||
Future<List<Transaction>> fetchTransactions(String accountNo,
|
||||
{DateTime? fromDate, DateTime? toDate});
|
||||
}
|
||||
|
||||
class TransactionRepositoryImpl implements TransactionRepository {
|
||||
@@ -10,9 +14,23 @@ class TransactionRepositoryImpl implements TransactionRepository {
|
||||
TransactionRepositoryImpl(this._dio);
|
||||
|
||||
@override
|
||||
Future<List<Transaction>> fetchTransactions(String accountNo) async {
|
||||
Future<List<Transaction>> fetchTransactions(String accountNo,
|
||||
{DateTime? fromDate, DateTime? toDate}) async {
|
||||
final queryParameters = <String, String>{};
|
||||
|
||||
final resp = await _dio.get('/api/transactions/account/$accountNo');
|
||||
if (fromDate != null) {
|
||||
queryParameters['fromDate'] = DateFormat('ddMMyyyy').format(fromDate);
|
||||
}
|
||||
if (toDate != null) {
|
||||
queryParameters['toDate'] = DateFormat('ddMMyyyy').format(toDate);
|
||||
}
|
||||
|
||||
log('query params below');
|
||||
log(queryParameters.toString());
|
||||
final resp = await _dio.get(
|
||||
'/api/transactions/account/$accountNo',
|
||||
queryParameters: queryParameters.isNotEmpty ? queryParameters : null,
|
||||
);
|
||||
|
||||
if (resp.statusCode != 200) {
|
||||
throw Exception(
|
||||
@@ -25,4 +43,4 @@ class TransactionRepositoryImpl implements TransactionRepository {
|
||||
.map((e) => Transaction.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user