|  |  |  | @ -1,3 +1,8 @@ | 
		
	
		
			
				|  |  |  |  | import 'dart:convert'; | 
		
	
		
			
				|  |  |  |  | import 'dart:io'; | 
		
	
		
			
				|  |  |  |  | import 'dart:io' as Io; | 
		
	
		
			
				|  |  |  |  | import 'dart:typed_data'; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | import 'package:easy_localization/easy_localization.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:flutter/material.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/api/mowadhafhi/mowadhafhi_api_client.dart'; | 
		
	
	
		
			
				
					|  |  |  | @ -6,9 +11,16 @@ import 'package:mohem_flutter_app/classes/utils.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/extensions/int_extensions.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/extensions/string_extensions.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/main.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_details.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_transactions.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/models/mowadhafhi/get_transaction_attachment_model.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/ui/screens/mowadhafhi/view_transaction_attachment.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:open_file/open_file.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:path_provider/path_provider.dart'; | 
		
	
		
			
				|  |  |  |  | import 'package:permission_handler/permission_handler.dart'; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | class MowadhafhiRequestDetails extends StatefulWidget { | 
		
	
		
			
				|  |  |  |  |   const MowadhafhiRequestDetails({Key? key}) : super(key: key); | 
		
	
	
		
			
				
					|  |  |  | @ -21,6 +33,9 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> { | 
		
	
		
			
				|  |  |  |  |   String? itgTicketID; | 
		
	
		
			
				|  |  |  |  |   List<GetTicketDetailsByEmployee> getTicketsByEmployeeList = []; | 
		
	
		
			
				|  |  |  |  |   List<GetTicketTransactions> getTicketTransactionsList = []; | 
		
	
		
			
				|  |  |  |  |   GetTransactionAttachmentModel? getTransactionAttachmentModel; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   late File imageFile; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   @override | 
		
	
		
			
				|  |  |  |  |   void initState() { | 
		
	
	
		
			
				
					|  |  |  | @ -43,7 +58,7 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> { | 
		
	
		
			
				|  |  |  |  |       backgroundColor: Colors.white, | 
		
	
		
			
				|  |  |  |  |       appBar: AppBarWidget( | 
		
	
		
			
				|  |  |  |  |         context, | 
		
	
		
			
				|  |  |  |  |         title:  LocaleKeys.mowadhafhiRequest.tr(), | 
		
	
		
			
				|  |  |  |  |         title: LocaleKeys.mowadhafhiRequest.tr(), | 
		
	
		
			
				|  |  |  |  |       ), | 
		
	
		
			
				|  |  |  |  |       body: SingleChildScrollView( | 
		
	
		
			
				|  |  |  |  |         child: getTicketsByEmployeeList.length != 0 | 
		
	
	
		
			
				
					|  |  |  | @ -76,16 +91,16 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> { | 
		
	
		
			
				|  |  |  |  |                           ], | 
		
	
		
			
				|  |  |  |  |                         ), | 
		
	
		
			
				|  |  |  |  |                         8.height, | 
		
	
		
			
				|  |  |  |  |                       LocaleKeys.ticketReference.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         LocaleKeys.ticketReference.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         getTicketsByEmployeeList![0].ticketReferenceNo!.toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                         8.height, | 
		
	
		
			
				|  |  |  |  |                       LocaleKeys.section.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         LocaleKeys.section.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         getTicketsByEmployeeList![0].sectionName!.toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                         8.height, | 
		
	
		
			
				|  |  |  |  |                       LocaleKeys.topic.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         LocaleKeys.topic.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         getTicketsByEmployeeList![0].topicName!.toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                         8.height, | 
		
	
		
			
				|  |  |  |  |                       LocaleKeys.description.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         LocaleKeys.description.tr().toText12(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                         getTicketsByEmployeeList![0].description!.toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                       ], | 
		
	
		
			
				|  |  |  |  |                     ), | 
		
	
	
		
			
				
					|  |  |  | @ -128,15 +143,31 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> { | 
		
	
		
			
				|  |  |  |  |                                           Row( | 
		
	
		
			
				|  |  |  |  |                                             children: [ | 
		
	
		
			
				|  |  |  |  |                                               LocaleKeys.actionBy.tr().toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                                               ": ".toText14(), | 
		
	
		
			
				|  |  |  |  |                                               getTicketTransactionsList![index].actionBy!.toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                                             ], | 
		
	
		
			
				|  |  |  |  |                                           ), | 
		
	
		
			
				|  |  |  |  |                                           Row( | 
		
	
		
			
				|  |  |  |  |                                             children: [ | 
		
	
		
			
				|  |  |  |  |                                               LocaleKeys.actions.tr().toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                                               ": ".toText14(), | 
		
	
		
			
				|  |  |  |  |                                               getTicketTransactionsList![index].statusDisplayText!.toText14(color: MyColors.grey57Color), | 
		
	
		
			
				|  |  |  |  |                                             ], | 
		
	
		
			
				|  |  |  |  |                                           ), | 
		
	
		
			
				|  |  |  |  |                                           getTicketTransactionsList![index].comments!.toText14(color: MyColors.grey98Color), | 
		
	
		
			
				|  |  |  |  |                                           12.height, | 
		
	
		
			
				|  |  |  |  |                                           if (getTicketTransactionsList[index].attachments != null) | 
		
	
		
			
				|  |  |  |  |                                             InkWell( | 
		
	
		
			
				|  |  |  |  |                                               onTap: () { | 
		
	
		
			
				|  |  |  |  |                                                 print(getTicketTransactionsList[index].attachments![0].attachmentId); | 
		
	
		
			
				|  |  |  |  |                                                 getTransactionAttachment(getTicketTransactionsList[index].attachments![0].attachmentId!); | 
		
	
		
			
				|  |  |  |  |                                               }, | 
		
	
		
			
				|  |  |  |  |                                               child: LocaleKeys.attachments.tr().toText14(color: MyColors.gradiantEndColor, isUnderLine: true), | 
		
	
		
			
				|  |  |  |  |                                             ), | 
		
	
		
			
				|  |  |  |  |                                           Row( | 
		
	
		
			
				|  |  |  |  |                                             mainAxisAlignment: MainAxisAlignment.end, | 
		
	
		
			
				|  |  |  |  |                                             children: [ | 
		
	
		
			
				|  |  |  |  |                                               getTicketTransactionsList![0].actionDate!.split(" ")[0].toText12(color: MyColors.grey70Color), | 
		
	
		
			
				|  |  |  |  |                                               getTicketTransactionsList![index].actionDate!.split(" ")[0].toText12(color: MyColors.grey70Color), | 
		
	
		
			
				|  |  |  |  |                                             ], | 
		
	
		
			
				|  |  |  |  |                                           ), | 
		
	
		
			
				|  |  |  |  |                                         ], | 
		
	
	
		
			
				
					|  |  |  | @ -212,4 +243,58 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> { | 
		
	
		
			
				|  |  |  |  |       Utils.handleException(ex, context, null); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   void getTransactionAttachment(int attachmentID) async { | 
		
	
		
			
				|  |  |  |  |     try { | 
		
	
		
			
				|  |  |  |  |       Utils.showLoading(context); | 
		
	
		
			
				|  |  |  |  |       getTransactionAttachmentModel = await MowadhafhiApiClient().getTransactionAttachments(attachmentID); | 
		
	
		
			
				|  |  |  |  |       Utils.hideLoading(context); | 
		
	
		
			
				|  |  |  |  |       handleTransactionAttachment(); | 
		
	
		
			
				|  |  |  |  |     } catch (ex) { | 
		
	
		
			
				|  |  |  |  |       Utils.hideLoading(context); | 
		
	
		
			
				|  |  |  |  |       Utils.handleException(ex, context, null); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   Future<String> _createFileFromString(String encodedStr, String ext) async { | 
		
	
		
			
				|  |  |  |  |     Uint8List bytes = base64.decode(encodedStr); | 
		
	
		
			
				|  |  |  |  |     String dir = (await getApplicationDocumentsDirectory()).path; | 
		
	
		
			
				|  |  |  |  |     File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); | 
		
	
		
			
				|  |  |  |  |     await file.writeAsBytes(bytes); | 
		
	
		
			
				|  |  |  |  |     return file.path; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   void handleTransactionAttachment() async { | 
		
	
		
			
				|  |  |  |  |     Permission.storage.isGranted.then((isGranted) { | 
		
	
		
			
				|  |  |  |  |       if (!isGranted) { | 
		
	
		
			
				|  |  |  |  |         Permission.manageExternalStorage.request().then((granted) async { | 
		
	
		
			
				|  |  |  |  |           if (granted == PermissionStatus.granted) { | 
		
	
		
			
				|  |  |  |  |             String ext = ''; | 
		
	
		
			
				|  |  |  |  |             String? rFile = getTransactionAttachmentModel!.base64String; | 
		
	
		
			
				|  |  |  |  |             String? rFileExt = getTransactionAttachmentModel!.fileName; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             ext = rFileExt!.split(".").last.toLowerCase(); | 
		
	
		
			
				|  |  |  |  |             try { | 
		
	
		
			
				|  |  |  |  |               String path = await _createFileFromString(rFile!.split("base64,").last ?? "", ext ?? ""); | 
		
	
		
			
				|  |  |  |  |               await OpenFile.open(path).catchError((err) { | 
		
	
		
			
				|  |  |  |  |                 print(err); | 
		
	
		
			
				|  |  |  |  |               }); | 
		
	
		
			
				|  |  |  |  |             } catch (ex) { | 
		
	
		
			
				|  |  |  |  |               Utils.showToast("Cannot open file."); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |           } else { | 
		
	
		
			
				|  |  |  |  |             showDialog( | 
		
	
		
			
				|  |  |  |  |               context: context, | 
		
	
		
			
				|  |  |  |  |               builder: (BuildContext cxt) => ConfirmDialog( | 
		
	
		
			
				|  |  |  |  |                 message: "You need to give storage permission to view files.", | 
		
	
		
			
				|  |  |  |  |                 onTap: () { | 
		
	
		
			
				|  |  |  |  |                   Navigator.pop(context); | 
		
	
		
			
				|  |  |  |  |                 }, | 
		
	
		
			
				|  |  |  |  |               ), | 
		
	
		
			
				|  |  |  |  |             ); | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         }); | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     }); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					|  |  |  | 
 |