diff --git a/lib/di/injection.dart b/lib/di/injection.dart index 43826f1..3913224 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -76,9 +76,9 @@ Dio _createDioClient() { final dio = Dio( BaseOptions( baseUrl: - 'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com', //test + // 'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com', //test //'http://lb-kccb-mobile-banking-app-848675342.ap-south-1.elb.amazonaws.com', //prod - //'https://kccbmbnk.net', //prod small + 'https://kccbmbnk.net', //prod small connectTimeout: const Duration(seconds: 60), receiveTimeout: const Duration(seconds: 60), headers: { diff --git a/lib/features/cheque/screens/cheque_management_screen.dart b/lib/features/cheque/screens/cheque_management_screen.dart index 1cb5267..5636f81 100644 --- a/lib/features/cheque/screens/cheque_management_screen.dart +++ b/lib/features/cheque/screens/cheque_management_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:kmobile/data/models/user.dart'; import 'package:kmobile/features/cheque/screens/cheque_enquiry_screen.dart'; +import 'package:kmobile/features/cheque/screens/revoke_stop_screen.dart'; import 'package:kmobile/features/cheque/screens/stop_cheque_screen.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; import '../../../l10n/app_localizations.dart'; @@ -75,6 +76,24 @@ class _ChequeManagementScreen extends State { }, ), ), + // Expanded( + // child: ChequeManagementCardTile( + // icon: Symbols.block_sharp, + // label: "Revoke Stop", + // subtitle: "Revoke your stopped cheques so as to reuse it", + // onTap: () { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => RevokeStopSingleChequeScreen( + // users: users, + // selectedIndex: selectedAccountIndex, + // ), + // ), + // ); + // }, + // ), + // ), ], ), ), diff --git a/lib/features/cheque/screens/revoke_stop_screen.dart b/lib/features/cheque/screens/revoke_stop_screen.dart new file mode 100644 index 0000000..6f0000b --- /dev/null +++ b/lib/features/cheque/screens/revoke_stop_screen.dart @@ -0,0 +1,332 @@ +// import 'dart:convert'; +// import 'package:dio/dio.dart'; +// import 'package:kmobile/data/models/user.dart'; +// import 'package:kmobile/di/injection.dart'; +// import 'package:flutter/material.dart'; +// import 'package:kmobile/api/services/cheque_service.dart'; +// import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart'; +// import 'package:kmobile/l10n/app_localizations.dart'; + +// class RevokeStopSingleChequeScreen extends StatefulWidget { +// final User selectedAccount; +// final String date; +// final String instrType; +// final String fromCheque; +// final String toCheque; + +// const RevokeStopSingleChequeScreen( +// {super.key, +// required this.selectedAccount, +// required this.date, +// required this.instrType, +// required this.fromCheque, +// required this.toCheque}); + +// @override +// State createState() => _RevokeStopSingleChequeScreenState(); +// } + +// class _RevokeStopSingleChequeScreenState extends State { +// final _formKey = GlobalKey(); +// final _stopFromChequeNoController = TextEditingController(); +// final _stopIssueDateController = TextEditingController(); +// final _stopExpiryDateController = TextEditingController(); +// final _stopAmountController = TextEditingController(); +// final _chequeService = getIt(); + +// String? _selectedComment; +// final _otherCommentController = TextEditingController(); +// bool _showOtherCommentField = false; +// final List _commentOptions = [ +// 'Cheque Lost', +// 'Cheque Stolen', +// 'Cheque Missing', +// 'Cheque Damaged', +// 'Other' +// ]; + +// String _formatDate(String dateString) { +// if (dateString.length != 8) { +// return dateString; // Return as is if not in expected ddmmyyyy format +// } +// try { +// final day = dateString.substring(0, 2); +// final month = dateString.substring(2, 4); +// final year = dateString.substring(4, 8); +// return '$day/$month/$year'; +// } catch (e) { +// return dateString; // Return original string on error +// } +// } + +// Future _selectDate(TextEditingController controller) async { +// final DateTime? picked = await showDatePicker( +// context: context, +// initialDate: DateTime.now(), +// firstDate: DateTime.now(), +// lastDate: DateTime(2101), +// ); +// if (picked != null) { +// setState(() { +// controller.text = +// '${picked.day.toString().padLeft(2, '0')}/${picked.month.toString().padLeft(2, '0')}/${picked.year}'; +// }); +// } +// } + +// Future _showResponseDialog(String title, String message) async { +// return showDialog( +// context: context, +// barrierDismissible: false, // user must tap button! +// builder: (BuildContext context) { +// return AlertDialog( +// title: Text(title), +// content: SingleChildScrollView( +// child: ListBody( +// children: [ +// Text(message), +// ], +// ), +// ), +// actions: [ +// TextButton( +// child: Text(AppLocalizations.of(context).closeButton), +// onPressed: () { +// Navigator.of(context).pop(); +// }, +// ), +// ], +// ); +// }, +// ); +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: const Text("Revoke Stop")), +// ); +// body: Padding( +// padding: const EdgeInsets.all(16.0), +// child: Form( +// key: _formKey, +// child: ListView( +// children: [ +// Card( +// elevation: 0, +// margin: const EdgeInsets.symmetric(vertical: 8.0), +// child: ListTile( +// leading: Image.asset( +// 'assets/images/logo.png', +// width: 40, +// height: 40, +// ), +// title: Text(widget.selectedAccount.accountNo!), +// subtitle: +// Text(AppLocalizations.of(context).accountNumberLabel), +// ), +// ), +// const SizedBox(height: 24), +// TextFormField( +// controller: _stopFromChequeNoController, +// decoration: InputDecoration( +// labelText: AppLocalizations.of(context).chequeNumberLabel, +// border: OutlineInputBorder(), +// errorMaxLines: 2, +// ), +// keyboardType: TextInputType.number, +// validator: (value) { +// if (value == null || value.isEmpty) { +// return AppLocalizations.of(context) +// .pleaseEnterChequeNumberError; +// } +// final chequeNumber = int.tryParse(value); +// final fromCheque = int.tryParse(widget.fromCheque); +// final toCheque = int.tryParse(widget.toCheque); +// if (chequeNumber == null || +// fromCheque == null || +// toCheque == null) { +// return AppLocalizations.of(context) +// .invalidChequeNumberFormatError; +// } +// if (chequeNumber < fromCheque || chequeNumber > toCheque) { +// return AppLocalizations.of(context).chequeNumberRangeError( +// widget.fromCheque, widget.toCheque); +// } +// return null; +// }, +// ), +// const SizedBox(height: 16), +// TextFormField( +// initialValue: widget.instrType, +// readOnly: true, +// decoration: InputDecoration( +// labelText: AppLocalizations.of(context).instrumentTypeLabel, +// border: const OutlineInputBorder(), +// ), +// ), +// const SizedBox(height: 16), +// TextFormField( +// controller: _stopIssueDateController, +// readOnly: true, +// onTap: () => _selectDate(_stopIssueDateController), +// decoration: InputDecoration( +// labelText: AppLocalizations.of(context).stopIssueDateLabel, +// border: const OutlineInputBorder(), +// suffixIcon: IconButton( +// icon: const Icon(Icons.calendar_today), +// onPressed: () => _selectDate(_stopIssueDateController), +// ), +// ), +// keyboardType: TextInputType.datetime, +// ), +// const SizedBox(height: 16), +// TextFormField( +// controller: _stopExpiryDateController, +// readOnly: true, +// onTap: () => _selectDate(_stopExpiryDateController), +// decoration: InputDecoration( +// labelText: AppLocalizations.of(context).stopExpiryDateLabel, +// border: const OutlineInputBorder(), +// suffixIcon: IconButton( +// icon: const Icon(Icons.calendar_today), +// onPressed: () => _selectDate(_stopExpiryDateController), +// ), +// ), +// keyboardType: TextInputType.datetime, +// ), +// const SizedBox(height: 16), +// TextFormField( +// controller: _stopAmountController, +// decoration: InputDecoration( +// labelText: AppLocalizations.of(context).stopAmountHint, +// border: const OutlineInputBorder(), +// ), +// keyboardType: TextInputType.number, +// ), +// const SizedBox(height: 16), +// DropdownButtonFormField( +// value: _selectedComment, +// items: _commentOptions.map((String value) { +// return DropdownMenuItem( +// value: value, +// child: Text(value), +// ); +// }).toList(), +// onChanged: (newValue) { +// setState(() { +// _selectedComment = newValue; +// _showOtherCommentField = newValue == 'Other'; +// }); +// }, +// decoration: InputDecoration( +// labelText: AppLocalizations.of(context).stopCommentHint, +// border: const OutlineInputBorder(), +// ), +// ), +// if (_showOtherCommentField) +// Padding( +// padding: const EdgeInsets.only(top: 16.0), +// child: TextFormField( +// controller: _otherCommentController, +// decoration: const InputDecoration( +// labelText: "Other Reasons :", +// border: OutlineInputBorder(), +// ), +// validator: (value) { +// return null; +// }, +// ), +// ), +// const SizedBox(height: 16), +// TextFormField( +// initialValue: _formatDate(widget.date), +// readOnly: true, +// decoration: InputDecoration( +// labelText: +// AppLocalizations.of(context).chequebookIssueDateHint, +// border: const OutlineInputBorder(), +// ), +// ), +// const SizedBox(height: 32), +// ElevatedButton( +// onPressed: () { +// if (_formKey.currentState!.validate()) { +// Navigator.push( +// context, +// MaterialPageRoute( +// builder: (context) => TransactionPinScreen( +// onPinCompleted: (ctx, pin) async { +// Navigator.pop(context); +// try { +// final response = await _chequeService.stopCheque( +// accountno: widget.selectedAccount.accountNo!, +// stopFromChequeNo: +// _stopFromChequeNoController.text, +// instrType: widget.instrType, +// stopToChequeNo: +// _stopFromChequeNoController.text, +// stopIssueDate: _stopIssueDateController.text, +// stopExpiryDate: _stopExpiryDateController.text, +// stopAmount: _stopAmountController.text, +// stopComment: _selectedComment == 'Other' +// ? _otherCommentController.text +// : _selectedComment ?? '', +// chequeIssueDate: widget.date, +// tpin: pin, +// ); +// if (!mounted) return; +// final decodedResponse = jsonDecode(response); +// String responseString = response.toString(); // used as the case only for incorrect TPIN +// final status = decodedResponse['status']; +// final message = decodedResponse['message']; +// final code = decodedResponse['code']; +// if (status == 'SUCCESS') { +// _showResponseDialog('Success', message); +// } if (status == 'ERROR') { +// String errMessage = "error"; +// if(code == '0429') { +// errMessage = 'The selected Cheque is already stopped'; +// } else if(code == '0748') { +// errMessage = 'The selected Cheque is already presented'; +// } +// _showResponseDialog('Error', errMessage); +// } +// if(responseString.contains('INCORRECT_TPIN')){ +// _showResponseDialog('Invalid TPIN', +// 'The TPIN you entered is incorrect. Please try again.'); +// } +// } on DioException catch (e) { +// try { +// final errorBodyString = +// e.toString().split('Exception: ')[1]; +// final errorBody = jsonDecode(errorBodyString); +// if (errorBody.containsKey('error') && +// errorBody['error'] == 'INCORRECT_TPIN') { +// _showResponseDialog('Invalid TPIN', +// 'The TPIN you entered is incorrect. Please try again.'); +// } else { +// _showResponseDialog( +// 'Error', 'Internal Server Error'); +// } +// } catch (_) { +// _showResponseDialog( +// 'Error', 'Internal Server Error'); +// } +// } +// }, +// ), +// ), +// ); +// } +// }, +// child: Text("Revoke Stop"), +// ), +// ], +// ), +// ), +// ) +// ); +// } +// } diff --git a/lib/features/cheque/screens/stop_multiple_cheques_screen.dart b/lib/features/cheque/screens/stop_multiple_cheques_screen.dart index 65d4c3c..15f7b31 100644 --- a/lib/features/cheque/screens/stop_multiple_cheques_screen.dart +++ b/lib/features/cheque/screens/stop_multiple_cheques_screen.dart @@ -309,6 +309,7 @@ class _StopMultipleChequesScreenState extends State { ); if (!mounted) return; final decodedResponse = jsonDecode(response); + String responseString = response.toString(); // used as the case only for incorrect TPIN final status = decodedResponse['status']; final message = decodedResponse['message']; final code = decodedResponse['code']; @@ -323,6 +324,10 @@ class _StopMultipleChequesScreenState extends State { } _showResponseDialog('Error', errMessage); } + if(responseString.contains('INCORRECT_TPIN')){ + _showResponseDialog('Invalid TPIN', + 'The TPIN you entered is incorrect. Please try again.'); + } } on Exception catch (e) { try { final errorBodyString = diff --git a/lib/features/cheque/screens/stop_single_cheque_screen.dart b/lib/features/cheque/screens/stop_single_cheque_screen.dart index c2a639f..559a53c 100644 --- a/lib/features/cheque/screens/stop_single_cheque_screen.dart +++ b/lib/features/cheque/screens/stop_single_cheque_screen.dart @@ -278,7 +278,7 @@ class _StopSingleChequeScreenState extends State { ); if (!mounted) return; final decodedResponse = jsonDecode(response); - + String responseString = response.toString(); // used as the case only for incorrect TPIN final status = decodedResponse['status']; final message = decodedResponse['message']; final code = decodedResponse['code']; @@ -293,12 +293,16 @@ class _StopSingleChequeScreenState extends State { } _showResponseDialog('Error', errMessage); } + if(responseString.contains('INCORRECT_TPIN')){ + _showResponseDialog('Invalid TPIN', + 'The TPIN you entered is incorrect. Please try again.'); + } } on DioException catch (e) { try { final errorBodyString = e.toString().split('Exception: ')[1]; - final errorBody = jsonDecode(errorBodyString); - if (errorBody.containsKey('error') && + final errorBody = jsonDecode(errorBodyString); + if (errorBody.containsKey('error') && errorBody['error'] == 'INCORRECT_TPIN') { _showResponseDialog('Invalid TPIN', 'The TPIN you entered is incorrect. Please try again.');