stop cheque screen added
This commit is contained in:
@@ -9,7 +9,7 @@ class Cheque {
|
|||||||
final String? Chequescount;
|
final String? Chequescount;
|
||||||
final String? ChequeNumber;
|
final String? ChequeNumber;
|
||||||
final String? transactionCode;
|
final String? transactionCode;
|
||||||
final String? amount;
|
final int? amount;
|
||||||
final String? status;
|
final String? status;
|
||||||
final String? stopIssueDate;
|
final String? stopIssueDate;
|
||||||
final String? StopExpiryDate;
|
final String? StopExpiryDate;
|
||||||
@@ -41,7 +41,7 @@ this.StopExpiryDate,
|
|||||||
Chequescount: json['Chequescount'] ?? '',
|
Chequescount: json['Chequescount'] ?? '',
|
||||||
ChequeNumber: json['ChequeNumber'] ?? '',
|
ChequeNumber: json['ChequeNumber'] ?? '',
|
||||||
transactionCode: json['transactionCode'] ?? '',
|
transactionCode: json['transactionCode'] ?? '',
|
||||||
amount: json['amount'] ?? '',
|
amount: json['amount'],
|
||||||
status: json['status'] ?? '',
|
status: json['status'] ?? '',
|
||||||
stopIssueDate: json['stopIssueDate'] ?? '',
|
stopIssueDate: json['stopIssueDate'] ?? '',
|
||||||
StopExpiryDate: json['StopExpiryDate'] ?? '',
|
StopExpiryDate: json['StopExpiryDate'] ?? '',
|
||||||
|
|||||||
@@ -3,31 +3,32 @@ import 'package:kmobile/api/services/cheque_service.dart';
|
|||||||
import 'package:kmobile/data/models/user.dart';
|
import 'package:kmobile/data/models/user.dart';
|
||||||
import 'package:kmobile/di/injection.dart';
|
import 'package:kmobile/di/injection.dart';
|
||||||
|
|
||||||
class ChequeStatusScreen extends StatefulWidget {
|
class ChequeEnquiryScreen extends StatefulWidget {
|
||||||
final List<User> users;
|
final List<User> users;
|
||||||
final int selectedIndex;
|
final int selectedIndex;
|
||||||
const ChequeStatusScreen({
|
const ChequeEnquiryScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.users,
|
required this.users,
|
||||||
required this.selectedIndex,
|
required this.selectedIndex,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ChequeStatusScreen> createState() => _ChequeStatusScreenState();
|
State<ChequeEnquiryScreen> createState() => _ChequeEnquiryScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChequeStatusScreenState extends State<ChequeStatusScreen> {
|
class _ChequeEnquiryScreenState extends State<ChequeEnquiryScreen> {
|
||||||
User? _selectedAccount;
|
User? _selectedAccount;
|
||||||
final TextEditingController _searchController = TextEditingController();
|
final TextEditingController _searchController = TextEditingController();
|
||||||
var service = getIt<ChequeService>();
|
var service = getIt<ChequeService>();
|
||||||
bool _isLoading = true;
|
bool _isLoading = true;
|
||||||
List<Cheque> _allCheques = [];
|
List<Cheque> _allCheques = [];
|
||||||
Map<String, List<Cheque>> _groupedCheques = {};
|
Map<String, List<Cheque>> _groupedCheques = {};
|
||||||
|
List<User> _filteredUsers = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
final List<User> _filteredUsers = widget.users
|
_filteredUsers = widget.users
|
||||||
.where((user) => ['SA', 'SB', 'CA', 'CC'].contains(user.accountType))
|
.where((user) => ['SA', 'SB', 'CA', 'CC'].contains(user.accountType))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -119,7 +120,6 @@ class _ChequeStatusScreenState extends State<ChequeStatusScreen> {
|
|||||||
filteredCheques = _allCheques.where((cheque) {
|
filteredCheques = _allCheques.where((cheque) {
|
||||||
final lowerQuery = query.toLowerCase();
|
final lowerQuery = query.toLowerCase();
|
||||||
return (cheque.ChequeNumber?.toLowerCase().contains(lowerQuery) ?? false) ||
|
return (cheque.ChequeNumber?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||||
(cheque.amount?.toLowerCase().contains(lowerQuery) ?? false) ||
|
|
||||||
(cheque.status?.toLowerCase().contains(lowerQuery) ?? false) ||
|
(cheque.status?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||||
(cheque.fromCheque?.toLowerCase().contains(lowerQuery) ?? false) ||
|
(cheque.fromCheque?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||||
(cheque.toCheque?.toLowerCase().contains(lowerQuery) ?? false);
|
(cheque.toCheque?.toLowerCase().contains(lowerQuery) ?? false);
|
||||||
@@ -142,80 +142,108 @@ class _ChequeStatusScreenState extends State<ChequeStatusScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Track Cheque Status'),
|
title: const Text('Cheque Enquiry'),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Stack(
|
||||||
padding: const EdgeInsets.all(16.0),
|
children: [
|
||||||
child: Column(
|
Padding(
|
||||||
children: [
|
padding: const EdgeInsets.all(16.0),
|
||||||
Card(
|
child: Column(
|
||||||
elevation: 4,
|
children: [
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
Card(
|
||||||
child: Padding(
|
elevation: 4,
|
||||||
padding: const EdgeInsets.all(16.0),
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: Column(
|
child: Padding(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
padding: const EdgeInsets.all(16.0),
|
||||||
children: [
|
child: Row(
|
||||||
const Text(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
"Account Number",
|
children: [
|
||||||
style:
|
const Text(
|
||||||
TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
|
"Account Number",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 18),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
if (_selectedAccount != null)
|
||||||
|
Expanded(
|
||||||
|
child: DropdownButton<User>(
|
||||||
|
value: _selectedAccount,
|
||||||
|
onChanged: (User? newUser) {
|
||||||
|
if (newUser != null) {
|
||||||
|
setState(() {
|
||||||
|
_selectedAccount = newUser;
|
||||||
|
_loadCheques();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
items: _filteredUsers.map((user) {
|
||||||
|
return DropdownMenuItem<User>(
|
||||||
|
value: user,
|
||||||
|
child: Text(user.accountNo.toString()),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
const Text('No accounts found'),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
if (_selectedAccount != null)
|
),
|
||||||
DropdownButtonFormField<User>(
|
),
|
||||||
value: _selectedAccount,
|
const SizedBox(height: 20),
|
||||||
onChanged: (User? newUser) {
|
Card(
|
||||||
if (newUser != null) {
|
elevation: 4,
|
||||||
setState(() {
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
_selectedAccount = newUser;
|
child: Padding(
|
||||||
_loadCheques();
|
padding: const EdgeInsets.all(8.0),
|
||||||
});
|
child: TextField(
|
||||||
}
|
controller: _searchController,
|
||||||
},
|
decoration: const InputDecoration(
|
||||||
items: widget.users
|
labelText: 'Search...',
|
||||||
.where((user) =>
|
prefixIcon: Icon(Icons.search),
|
||||||
['SA', 'SB', 'CA', 'CC'].contains(user.accountType))
|
border: InputBorder
|
||||||
.map((user) {
|
.none, // Remove border to make it look like it's inside the card
|
||||||
return DropdownMenuItem<User>(
|
),
|
||||||
value: user,
|
),
|
||||||
child: Text(user.accountNo.toString()),
|
),
|
||||||
);
|
),
|
||||||
}).toList(),
|
const SizedBox(height: 20),
|
||||||
)
|
Expanded(
|
||||||
else
|
child: _isLoading
|
||||||
const Text('No accounts found'),
|
? const Center(child: CircularProgressIndicator())
|
||||||
],
|
: _groupedCheques.isEmpty
|
||||||
|
? const Center(child: Text('No cheque status found.'))
|
||||||
|
: ListView(
|
||||||
|
children: _groupedCheques.entries.map((entry) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
...entry.value.map((cheque) =>
|
||||||
|
ChequeStatusTile(cheque: cheque)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IgnorePointer(
|
||||||
|
child: Center(
|
||||||
|
child: Opacity(
|
||||||
|
opacity: 0.07, // Reduced opacity
|
||||||
|
child: ClipOval(
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/logo.png',
|
||||||
|
width: 200, // Adjust size as needed
|
||||||
|
height: 200, // Adjust size as needed
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
),
|
||||||
TextField(
|
],
|
||||||
controller: _searchController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Search...',
|
|
||||||
prefixIcon: Icon(Icons.search),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Expanded(
|
|
||||||
child: _isLoading
|
|
||||||
? const Center(child: CircularProgressIndicator())
|
|
||||||
: _groupedCheques.isEmpty
|
|
||||||
? const Center(child: Text('No cheque status found.'))
|
|
||||||
: ListView(
|
|
||||||
children: _groupedCheques.entries.map((entry) {
|
|
||||||
return ExpansionTile(
|
|
||||||
title: Text(entry.key, style: TextStyle(fontWeight: FontWeight.bold)),
|
|
||||||
children: entry.value
|
|
||||||
.map((cheque) => ChequeStatusTile(cheque: cheque))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -245,18 +273,22 @@ class ChequeStatusTile extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildCiTile(BuildContext context) {
|
Widget _buildCiTile(BuildContext context) {
|
||||||
return Card(
|
return Card(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16),
|
margin: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8.0,
|
||||||
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
Text('Chequebook Issued (CI)',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge),
|
||||||
|
const SizedBox(height: 8),
|
||||||
_buildInfoRow('Branch Code:', cheque.branchCode),
|
_buildInfoRow('Branch Code:', cheque.branchCode),
|
||||||
_buildInfoRow('From Cheque:', cheque.fromCheque),
|
_buildInfoRow('From Cheque:', cheque.fromCheque),
|
||||||
_buildInfoRow('To Cheque:', cheque.toCheque),
|
_buildInfoRow('To Cheque:', cheque.toCheque),
|
||||||
_buildInfoRow('Date:', cheque.Date),
|
_buildInfoRow('Date:', cheque.Date),
|
||||||
_buildInfoRow('Cheques Count:', cheque.Chequescount),
|
_buildInfoRow('Cheques Count:', cheque.Chequescount),
|
||||||
_buildInfoRow('Instrument Type:', cheque.InstrType),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -265,19 +297,21 @@ class ChequeStatusTile extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildPrTile(BuildContext context) {
|
Widget _buildPrTile(BuildContext context) {
|
||||||
return Card(
|
return Card(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16),
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
Text('Presented Cheque (PR)',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge),
|
||||||
|
const SizedBox(height: 8),
|
||||||
_buildInfoRow('Branch Code:', cheque.branchCode),
|
_buildInfoRow('Branch Code:', cheque.branchCode),
|
||||||
_buildInfoRow('Cheque Number:', cheque.ChequeNumber),
|
_buildInfoRow('Cheque Number:', cheque.ChequeNumber),
|
||||||
_buildInfoRow('Date:', cheque.Date),
|
_buildInfoRow('Date:', cheque.Date),
|
||||||
_buildInfoRow('Transaction Code:', cheque.transactionCode),
|
_buildInfoRow('Transaction Code:', cheque.transactionCode),
|
||||||
_buildInfoRow('Amount:', cheque.amount),
|
_buildInfoRow('Amount:', '₹ ${cheque.amount.toString()}'),
|
||||||
_buildInfoRow('Status:', cheque.status, statusColor: _getStatusColor(cheque.status ?? '')),
|
_buildInfoRow('Status:', cheque.status),
|
||||||
_buildInfoRow('Instrument Type:', cheque.InstrType),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -286,48 +320,37 @@ class ChequeStatusTile extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildStTile(BuildContext context) {
|
Widget _buildStTile(BuildContext context) {
|
||||||
return Card(
|
return Card(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16),
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
Text('Stop Cheque (ST)',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge),
|
||||||
|
const SizedBox(height: 8),
|
||||||
_buildInfoRow('Branch Code:', cheque.branchCode),
|
_buildInfoRow('Branch Code:', cheque.branchCode),
|
||||||
_buildInfoRow('From Cheque:', cheque.fromCheque),
|
_buildInfoRow('From Cheque:', cheque.fromCheque),
|
||||||
_buildInfoRow('To Cheque:', cheque.toCheque),
|
_buildInfoRow('To Cheque:', cheque.toCheque),
|
||||||
_buildInfoRow('Stop Issue Date:', cheque.stopIssueDate),
|
_buildInfoRow('Stop Issue Date:', cheque.stopIssueDate),
|
||||||
_buildInfoRow('Stop Expiry Date:', cheque.StopExpiryDate),
|
_buildInfoRow('Stop Expiry Date:', cheque.StopExpiryDate),
|
||||||
_buildInfoRow('Cheques Count:', cheque.Chequescount),
|
_buildInfoRow('Cheques Count:', cheque.Chequescount),
|
||||||
_buildInfoRow('Instrument Type:', cheque.InstrType),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInfoRow(String label, String? value, {Color? statusColor}) {
|
Widget _buildInfoRow(String label, String? value) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
|
Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
Text(value ?? '', style: TextStyle(color: statusColor)),
|
Text(value ?? ''),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color _getStatusColor(String status) {
|
|
||||||
switch (status.toLowerCase()) {
|
|
||||||
case 'cashed':
|
|
||||||
return Colors.green;
|
|
||||||
case 'pending':
|
|
||||||
return Colors.orange;
|
|
||||||
case 'bounced':
|
|
||||||
return Colors.red;
|
|
||||||
default:
|
|
||||||
return Colors.grey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:kmobile/data/models/user.dart';
|
import 'package:kmobile/data/models/user.dart';
|
||||||
import 'package:kmobile/features/cheque/screens/cheque_status_screen.dart';
|
import 'package:kmobile/features/cheque/screens/cheque_enquiry_screen.dart';
|
||||||
|
import 'package:kmobile/features/cheque/screens/stop_cheque_screen.dart';
|
||||||
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
import '../../../l10n/app_localizations.dart';
|
import '../../../l10n/app_localizations.dart';
|
||||||
|
|
||||||
@@ -10,7 +11,8 @@ class ChequeManagementScreen extends StatefulWidget {
|
|||||||
const ChequeManagementScreen({
|
const ChequeManagementScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.users,
|
required this.users,
|
||||||
required this.selectedIndex,});
|
required this.selectedIndex,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ChequeManagementScreen> createState() => _ChequeManagementScreen();
|
State<ChequeManagementScreen> createState() => _ChequeManagementScreen();
|
||||||
@@ -36,45 +38,41 @@ class _ChequeManagementScreen extends State<ChequeManagementScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
|
||||||
child: ChequeManagementCardTile(
|
|
||||||
icon: Symbols.add,
|
|
||||||
label: AppLocalizations.of(context).requestChequeBook,
|
|
||||||
subtitle: "Apply for a new cheque book",
|
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: ChequeManagementCardTile(
|
|
||||||
icon: Symbols.data_alert,
|
|
||||||
label: "Cheque History",
|
|
||||||
subtitle: "View the status of your issued cheques",
|
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: ChequeManagementCardTile(
|
|
||||||
icon: Symbols.front_hand,
|
|
||||||
label: AppLocalizations.of(context).stopCheque,
|
|
||||||
subtitle: "Stop payment for a cheque",
|
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ChequeManagementCardTile(
|
child: ChequeManagementCardTile(
|
||||||
icon: Symbols.payments,
|
icon: Symbols.payments,
|
||||||
label: "Track Cheque Status",
|
label: "Cheque Enquiry",
|
||||||
subtitle: "Check the current status of your cheque",
|
subtitle:
|
||||||
|
"You can view the status of your issued cheque book, presented cheques and details of stopped cheques including relevant dates, cheque numbers and other essential information",
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => ChequeStatusScreen(
|
builder: (context) => ChequeEnquiryScreen(
|
||||||
users: users,
|
users: users,
|
||||||
selectedIndex: selectedAccountIndex,
|
selectedIndex: selectedAccountIndex,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ChequeManagementCardTile(
|
||||||
|
icon: Symbols.block_sharp,
|
||||||
|
label: AppLocalizations.of(context).stopCheque,
|
||||||
|
subtitle:
|
||||||
|
"Initiate a stop payment request for a cheque that has already been presented for payment. This action helps prevent unauthorized transactions or rectifies errors on cheques that are in the process of being cleared",
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => StopChequeScreen(
|
||||||
|
users: users,
|
||||||
|
selectedIndex: selectedAccountIndex,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
315
lib/features/cheque/screens/stop_cheque_screen.dart
Normal file
315
lib/features/cheque/screens/stop_cheque_screen.dart
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:kmobile/api/services/cheque_service.dart';
|
||||||
|
import 'package:kmobile/data/models/user.dart';
|
||||||
|
import 'package:kmobile/di/injection.dart';
|
||||||
|
|
||||||
|
class StopChequeScreen extends StatefulWidget {
|
||||||
|
final List<User> users;
|
||||||
|
final int selectedIndex;
|
||||||
|
const StopChequeScreen({
|
||||||
|
super.key,
|
||||||
|
required this.users,
|
||||||
|
required this.selectedIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StopChequeScreen> createState() => _StopChequeScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StopChequeScreenState extends State<StopChequeScreen> {
|
||||||
|
User? _selectedAccount;
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
var service = getIt<ChequeService>();
|
||||||
|
bool _isLoading = true;
|
||||||
|
List<Cheque> _allCheques = [];
|
||||||
|
Map<String, List<Cheque>> _groupedCheques = {};
|
||||||
|
List<User> _filteredUsers = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_filteredUsers = widget.users
|
||||||
|
.where((user) => ['SA', 'SB', 'CA', 'CC'].contains(user.accountType))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (widget.users.isNotEmpty && widget.selectedIndex < widget.users.length) {
|
||||||
|
if (_filteredUsers.isNotEmpty) {
|
||||||
|
if (_filteredUsers.contains(widget.users[widget.selectedIndex])) {
|
||||||
|
_selectedAccount = widget.users[widget.selectedIndex];
|
||||||
|
} else {
|
||||||
|
_selectedAccount = _filteredUsers.first;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_selectedAccount = widget.users[widget.selectedIndex];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_filteredUsers.isNotEmpty) {
|
||||||
|
_selectedAccount = _filteredUsers.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadCheques();
|
||||||
|
_searchController.addListener(() {
|
||||||
|
_filterCheques(_searchController.text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadCheques() async {
|
||||||
|
if (_selectedAccount == null) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
_groupedCheques = {};
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
String instrType;
|
||||||
|
switch (_selectedAccount!.accountType) {
|
||||||
|
case 'SA':
|
||||||
|
case 'SB':
|
||||||
|
instrType = '10';
|
||||||
|
break;
|
||||||
|
case 'CA':
|
||||||
|
instrType = '11';
|
||||||
|
break;
|
||||||
|
case 'CC':
|
||||||
|
instrType = '13';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
instrType = '10';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final data = await service.ChequeEnquiry(
|
||||||
|
accountNumber: _selectedAccount!.accountNo!, instrType: instrType);
|
||||||
|
_allCheques = data.where((cheque) => cheque.type == 'PR').toList();
|
||||||
|
_groupedCheques.clear();
|
||||||
|
for (var cheque in _allCheques) {
|
||||||
|
if (cheque.type != null) {
|
||||||
|
if (!_groupedCheques.containsKey(cheque.type)) {
|
||||||
|
_groupedCheques[cheque.type!] = [];
|
||||||
|
}
|
||||||
|
_groupedCheques[cheque.type!]!.add(cheque);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
_groupedCheques = {};
|
||||||
|
});
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Failed to fetch cheque status: ${e.toString()}'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _filterCheques(String query) {
|
||||||
|
_groupedCheques.clear();
|
||||||
|
List<Cheque> filteredCheques;
|
||||||
|
if (query.isEmpty) {
|
||||||
|
filteredCheques = _allCheques;
|
||||||
|
} else {
|
||||||
|
filteredCheques = _allCheques.where((cheque) {
|
||||||
|
final lowerQuery = query.toLowerCase();
|
||||||
|
return (cheque.ChequeNumber?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||||
|
(cheque.status?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||||
|
(cheque.fromCheque?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||||
|
(cheque.toCheque?.toLowerCase().contains(lowerQuery) ?? false);
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var cheque in filteredCheques) {
|
||||||
|
if (cheque.type != null) {
|
||||||
|
if (!_groupedCheques.containsKey(cheque.type)) {
|
||||||
|
_groupedCheques[cheque.type!] = [];
|
||||||
|
}
|
||||||
|
_groupedCheques[cheque.type!]!.add(cheque);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Stop Cheque'),
|
||||||
|
centerTitle: false,
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
elevation: 4,
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
"Account Number",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 18),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
if (_selectedAccount != null)
|
||||||
|
Expanded(
|
||||||
|
child: DropdownButton<User>(
|
||||||
|
value: _selectedAccount,
|
||||||
|
onChanged: (User? newUser) {
|
||||||
|
if (newUser != null) {
|
||||||
|
setState(() {
|
||||||
|
_selectedAccount = newUser;
|
||||||
|
_loadCheques();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
items: _filteredUsers.map((user) {
|
||||||
|
return DropdownMenuItem<User>(
|
||||||
|
value: user,
|
||||||
|
child: Text(user.accountNo.toString()),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
const Text('No accounts found'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Card(
|
||||||
|
elevation: 4,
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: TextField(
|
||||||
|
controller: _searchController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Search',
|
||||||
|
prefixIcon: Icon(Icons.search),
|
||||||
|
border: InputBorder
|
||||||
|
.none, // Remove border to make it look like it's inside the card
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Expanded(
|
||||||
|
child: _isLoading
|
||||||
|
? const Center(child: CircularProgressIndicator())
|
||||||
|
: _groupedCheques.isEmpty
|
||||||
|
? const Center(child: Text('No cheque status found.'))
|
||||||
|
: ListView(
|
||||||
|
children: _groupedCheques.entries.map((entry) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
...entry.value.map((cheque) =>
|
||||||
|
ChequeStatusTile(cheque: cheque)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IgnorePointer(
|
||||||
|
child: Center(
|
||||||
|
child: Opacity(
|
||||||
|
opacity: 0.07, // Reduced opacity
|
||||||
|
child: ClipOval(
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/logo.png',
|
||||||
|
width: 200, // Adjust size as needed
|
||||||
|
height: 200, // Adjust size as needed
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChequeStatusTile extends StatelessWidget {
|
||||||
|
final Cheque cheque;
|
||||||
|
|
||||||
|
const ChequeStatusTile({
|
||||||
|
super.key,
|
||||||
|
required this.cheque,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
switch (cheque.type) {
|
||||||
|
case 'PR':
|
||||||
|
return _buildPrTile(context);
|
||||||
|
default:
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPrTile(BuildContext context) {
|
||||||
|
return Card(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text('Presented Cheque(PR)',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildInfoRow('Branch Code:', cheque.branchCode),
|
||||||
|
_buildInfoRow('Cheque Number:', cheque.ChequeNumber),
|
||||||
|
_buildInfoRow('Date:', cheque.Date),
|
||||||
|
_buildInfoRow('Transaction Code:', cheque.transactionCode),
|
||||||
|
_buildInfoRow('Amount:', '₹ ${cheque.amount.toString()}'),
|
||||||
|
_buildInfoRow('Status:', cheque.status),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Center(
|
||||||
|
child: ElevatedButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
// TODO: Implement stop cheque functionality
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.block_sharp),
|
||||||
|
label: const Text('Stop Cheque'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoRow(String label, String? value) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
Text(value ?? ''),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user