import 'dart:io'; import 'package:camera/camera.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:generp/Notifiers/HomeScreenNotifier.dart'; import 'package:generp/Utils/commonServices.dart'; import 'package:generp/services/api_calling.dart'; import 'package:image_picker/image_picker.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:share_plus/share_plus.dart'; import '../../Models/financeModels/addPaymentRequestionResponse.dart'; import '../../Models/financeModels/paymentRequesitionListsResponse.dart'; import 'package:csv/csv.dart'; import 'package:excel/excel.dart'; import 'package:path_provider/path_provider.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; class Requestionlistprovider extends ChangeNotifier { TextEditingController reqPurposeController = TextEditingController(); TextEditingController descController = TextEditingController(); TextEditingController amountController = TextEditingController(); TextEditingController bankNameController = TextEditingController(); TextEditingController bankBranchController = TextEditingController(); TextEditingController bankAccNumberController = TextEditingController(); TextEditingController bankIfscController = TextEditingController(); TextEditingController bankAcHolderController = TextEditingController(); TextEditingController bankUpiController = TextEditingController(); List _accounts = []; List _paymentModes = []; List _requestingPurposes = []; List _requisitionList = []; Accounts? _selectedAccounts; PaymentModes? _selectedPayment; String? _selectReqPurpose; String _paymentModeId = ""; String _paymentModeValue = ""; String _accountId = ""; String _reqPurpose = ""; String? selectAccountError; String? reqPurposeError; String? descriptionError; String? amountError; String? selectPaymentError; String? bankNameError; String? bankBranchError; String? bankNumberError; String? bankIFSCError; String? bankHolderError; String? UPIError; String? FileError; bool buttonEnabled = false; // bool _submitClicked = false; var _image_picked = 0; final ImagePicker _picker = ImagePicker(); File? _image; String get paymentModeId => _paymentModeId; String get paymentModeValue => _paymentModeValue; get image_picked => _image_picked; File? get imagePath => _image; String get accountId => _accountId; String get reqPurpose => _reqPurpose; String? get selectReqPurpose => _selectReqPurpose; Accounts? get selectedAccount => _selectedAccounts; PaymentModes? get selectedPayment => _selectedPayment; List get accounts => _accounts; List get paymentModes => _paymentModes; List get requestingPurposes => _requestingPurposes; List get requisitionList => _requisitionList; // bool get submitClicked => _submitClicked; // set submitClicked(bool value){ // _submitClicked = value; // notifyListeners(); // } set selectedAccount(Accounts? value) { _selectedAccounts = value; _accountId = value!.id!; selectAccountError = null; notifyListeners(); } set selectedPayment(PaymentModes? value) { _selectedPayment = value; _paymentModeId = value!.id!; _paymentModeValue = value!.name!; selectPaymentError = null; notifyListeners(); } set selectReqPurpose(String? value) { _selectReqPurpose = value; reqPurposeError = null; notifyListeners(); } set paymentModeId(String value) { _paymentModeId = value; notifyListeners(); } set paymentModeValue(String value) { _paymentModeValue = value; notifyListeners(); } set accountId(String value) { _accountId = value; notifyListeners(); } set reqPurposeId(String value) { _reqPurpose = value; notifyListeners(); } imgFromCamera(context) async { // Capture a photo try { final XFile? galleryImage = await _picker.pickImage( source: ImageSource.camera, imageQuality: 50, ); debugPrint("added"); _image = File(galleryImage!.path); _image_picked = 1; FileError = null; notifyListeners(); } catch (e) { debugPrint("mmmm: ${e.toString()}"); } } imgFromGallery(context) async { // Pick an image try { final XFile? galleryImage = await _picker.pickImage( source: ImageSource.gallery, ); final bytes = (await galleryImage?.readAsBytes())?.lengthInBytes; final kb = bytes! / 1024; final mb = kb / 1024; debugPrint("Jenny: bytes:$bytes, kb:$kb, mb: $mb"); _image = File(galleryImage!.path); _image_picked = 1; FileError = null; notifyListeners(); // var file = FlutterImageCompress.compressWithFile(galleryImage!.path); } catch (e) { debugPrint("mmmm: ${e.toString()}"); } } Future addPaymentRequestionViewAPI(context, mode) async { try { var homeProvider = Provider.of( context, listen: false, ); final data = await ApiCalling.addPaymentRequestionViewAPI( homeProvider.empId, homeProvider.session, mode, ); if (data != null) { if (data.error == "0") { _accounts = data.accounts!; _paymentModes = data.paymentModes!; _requestingPurposes = data.requestingPurposes!; if (_selectedAccounts != null && !_accounts.contains(_selectedAccounts)) { _selectedAccounts = null; _accountId = ""; } if (_selectedPayment != null && !_paymentModes.contains(_selectedPayment)) { _selectedPayment = null; _paymentModeId = ""; } } else {} } } catch (e, s) {} } Future addPaymentRequestionSubmitAPI(context, mode) async { try { // _submitClicked = true; if (!validateForm(context, mode)) { // _submitClicked = false; return; } var homeProvider = Provider.of( context, listen: false, ); final data = await ApiCalling.addPaymentRequestionSubmitAPI( homeProvider.empId, homeProvider.session, mode, _accountId, ["self","admin"].contains(mode) ?_selectReqPurpose:reqPurposeController.text, descController.text, amountController.text, _paymentModeId, bankNameController.text, bankBranchController.text, bankAccNumberController.text, bankIfscController.text, bankAcHolderController.text, bankUpiController.text, _image ); if (data != null) { if (data['error'] == "0") { print(data['error']=="0"); toast(context, "Added Successfully"); resetForm(); Navigator.pop(context,true); notifyListeners(); } else {} } } catch (e, s) {} } Future paymentRequestionListsAPIFunction(context, mode) async { try { var homeProvider = Provider.of( context, listen: false, ); final data = await ApiCalling.paymentRequestionListsAPI( homeProvider.empId, homeProvider.session, mode, ); if (data != null) { if (data.error == "0") { _requisitionList = data.requistionList!; notifyListeners(); } else {} } } catch (e, s) {} } List> prepareExportData() { final headers = [ 'ID', 'Account Name', 'Branch', 'Purpose', 'Description', 'Amount', 'Mode', 'Status', 'Date', ]; final rows = requisitionList.map((item) => [ item.id ?? '', item.accountName ?? '', item.branch ?? '', item.requestingPurpose ?? '', item.description ?? '', item.amount ?? '', item.requestMode ?? '', item.status ?? '', item.date ?? '', ]).toList(); return [headers, ...rows]; } void copyToClipboard(BuildContext context) async { try { if (requisitionList.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("No data to copy")), ); return; } final data = prepareExportData(); String raw = data.map((row) => row.join('\t')).join('\n'); print('Clipboard data: $raw'); await Clipboard.setData(ClipboardData(text: raw)); toast(context, "Copied to Clipboard"); } catch (e) { print('Error copying to clipboard: $e'); } } Future getSaveDirectory() async { // Try Downloads directory first try { if (Platform.isAndroid) { // Request storage permission for Android if (await Permission.storage.request().isGranted || await Permission.manageExternalStorage.request().isGranted) { final dir = await getApplicationDocumentsDirectory(); if (dir != null) { print('Using Downloads directory: ${dir.path}'); return dir.path; } } } } catch (e) { print('Error accessing Downloads directory: $e'); } // Fallback to shared Documents directory try { final dir = await getDownloadsDirectory(); if (dir != null) { final customDir = Directory('${dir.path}/RequisitionData'); if (!await customDir.exists()) { await customDir.create(recursive: true); } print('Using custom Documents directory: ${customDir.path}'); return customDir.path; } } catch (e) { print('Error accessing Documents directory: $e'); } // Final fallback to app's Documents directory final dir = await getApplicationDocumentsDirectory(); print('Using app Documents directory: ${dir.path}'); return dir.path; } Future downloadCSV(BuildContext context) async { try { if (requisitionList.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("No data to export")), ); return; } final data = prepareExportData(); final csvData = const ListToCsvConverter().convert(data); final dirPath = await getSaveDirectory(); final file = File('$dirPath/requisition_data.csv'); await file.writeAsString(csvData); print('CSV saved at: ${file.path}'); bool exists = await file.exists(); print('File exists: $exists'); // await OpenFile.open(file.path); // Open the file // await Share.share(file.path); // Share the file toast(context, "CSV Downloaded"); } catch (e) { print('Error downloading CSV: $e'); } } Future downloadXLS(BuildContext context) async { try { if (requisitionList.isEmpty) { toast(context, "No Data to export"); return; } final data = prepareExportData(); var excel = Excel.createExcel(); Sheet sheet = excel['Sheet1']; for (var row in data) { sheet.appendRow(row.map((cell) => TextCellValue(cell)).toList()); } final dirPath = await getSaveDirectory(); final file = File('$dirPath/requisition_data.xlsx'); final bytes = excel.encode(); if (bytes == null) throw Exception("Excel encoding failed"); await file.writeAsBytes(bytes); print('XLSX saved at: ${file.path}'); bool exists = await file.exists(); print('File exists: $exists'); // await OpenFile.open(file.path); // Open the file // await Share.share([file.path], text: 'Requisition Data XLSX'); // Share the file toast(context, ("XLSX Downloaded and opened")); } catch (e) { print('Error downloading XLSX: $e'); } } Future downloadPDF(BuildContext context) async { try { if (requisitionList.isEmpty) { toast(context, "No Data to export"); return; } final data = prepareExportData(); final pdf = pw.Document(); pdf.addPage( pw.Page( build: (context) => pw.Table.fromTextArray(data: data), ), ); final dirPath = await getSaveDirectory(); final file = File('$dirPath/requisition_data.pdf'); await file.writeAsBytes(await pdf.save()); print('PDF saved at: ${file.path}'); bool exists = await file.exists(); print('File exists: $exists'); // await OpenFile.open(file.path); // Open the file // await Share.shareXFiles([file.path], text: 'Requisition Data PDF'); // Share the file toast(context, "PDF Downloaded "); } catch (e) { print('Error downloading PDF: $e'); } } Future printData(BuildContext context) async { try { if (requisitionList.isEmpty) { toast(context, "No Data to Print"); return; } final data = prepareExportData(); final pdf = pw.Document(); pdf.addPage( pw.Page( build: (context) => pw.Table.fromTextArray(data: data), ), ); await Printing.layoutPdf( onLayout: (PdfPageFormat format) async => pdf.save(), ); } catch (e) { print('Error printing data: $e'); } } // void copyToClipboard(context) { // final data = prepareExportData(); // String raw = data.map((row) => row.join('\t')).join('\n'); // Clipboard.setData(ClipboardData(text: raw)); // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Copied to clipboard"))); // } // // Future downloadCSV(context) async { // final data = prepareExportData(); // final csvData = const ListToCsvConverter().convert(data); // final dir = await getApplicationDocumentsDirectory(); // final file = File('${dir.path}/requisition_data.csv'); // await file.writeAsString(csvData); // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("CSV Downloaded"))); // } // // Future downloadXLS(context) async { // final data = prepareExportData(); // var excel = Excel.createExcel(); // Sheet sheet = excel['Sheet1']; // // for (var row in data) { // sheet.appendRow(row.map((cell) => TextCellValue(cell)).toList()); // } // final dir = await getApplicationDocumentsDirectory(); // final file = File('${dir.path}/requisition_data.xlsx'); // await file.writeAsBytes(excel.encode()!); // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("XLSX Downloaded"))); // } // // Future downloadPDF(context) async { // final data = prepareExportData(); // final pdf = pw.Document(); // pdf.addPage( // pw.Page( // build: (context) => pw.Table.fromTextArray(data: data), // ), // ); // final dir = await getApplicationDocumentsDirectory(); // final file = File('${dir.path}/requisition_data.pdf'); // await file.writeAsBytes(await pdf.save()); // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("PDF Downloaded"))); // } // // Future printData(context) async { // final data = prepareExportData(); // final pdf = pw.Document(); // pdf.addPage( // pw.Page( // build: (context) => pw.Table.fromTextArray(data: data), // ), // ); // await Printing.layoutPdf( // onLayout: (PdfPageFormat format) async => pdf.save(), // ); // } void resetForm() { reqPurposeController.clear(); descController.clear(); amountController.clear(); bankNameController.clear(); bankBranchController.clear(); bankAccNumberController.clear(); bankIfscController.clear(); bankAcHolderController.clear(); bankUpiController.clear(); _selectedAccounts = null; _selectedPayment = null; _selectReqPurpose = null; _paymentModeId = ""; _paymentModeValue = ""; _accountId = ""; _reqPurpose = ""; _image = null; _image_picked = 0; // _submitClicked = false; // Clear validation errors selectAccountError = null; reqPurposeError = null; descriptionError = null; amountError = null; selectPaymentError = null; bankNameError = null; bankBranchError = null; bankNumberError = null; bankIFSCError = null; bankHolderError = null; UPIError = null; FileError = null; buttonEnabled = false; notifyListeners(); } bool validateForm(BuildContext context, String mode) { // Reset all errors selectAccountError = null; reqPurposeError = null; descriptionError = null; amountError = null; selectPaymentError = null; bankNameError = null; bankBranchError = null; bankNumberError = null; bankIFSCError = null; bankHolderError = null; UPIError = null; FileError = null; bool isValid = true; if (_selectedAccounts == null || _accountId.isEmpty) { selectAccountError = "Please select an account"; isValid = false; } if (["self", "admin"].contains(mode)) { if (_selectReqPurpose == null || _selectReqPurpose!.isEmpty) { reqPurposeError = "Please select a requisition purpose"; isValid = false; } } else { if (reqPurposeController.text.trim().isEmpty) { reqPurposeError = "Please enter a requisition purpose"; isValid = false; } } if (descController.text.trim().isEmpty) { descriptionError = "Please enter a description"; isValid = false; } if (amountController.text.trim().isEmpty) { amountError = "Please enter an amount"; isValid = false; } if (_selectedPayment == null || _paymentModeId.isEmpty) { selectPaymentError = "Please select a payment mode"; isValid = false; } if (["Cheque", "RTGS", "IMPS", "NEFT"].contains(_paymentModeValue)) { if (bankNameController.text.trim().isEmpty) { bankNameError = "Please enter bank name"; isValid = false; } if (bankBranchController.text.trim().isEmpty) { bankBranchError = "Please enter bank branch"; isValid = false; } if (bankAccNumberController.text.trim().isEmpty) { bankNumberError = "Please enter account number"; isValid = false; } if (bankIfscController.text.trim().isEmpty) { bankIFSCError = "Please enter IFSC code"; isValid = false; } if (bankAcHolderController.text.trim().isEmpty) { bankHolderError = "Please enter account holder name"; isValid = false; } } if (_paymentModeValue == "UPI") { if (bankUpiController.text.trim().isEmpty) { UPIError = "Please enter UPI ID"; isValid = false; } } if (_image_picked == 0) { FileError = "Please attach a file"; isValid = false; } buttonEnabled = isValid; notifyListeners(); return isValid; } void updateReqPupose(String value) { reqPurposeError = null; notifyListeners(); } void updateDescription(String value) { descriptionError = null; notifyListeners(); } void updateAmount(String value) { amountError = null; notifyListeners(); } void updateBankName(String value) { bankNameError = null; notifyListeners(); } void updateBankBranch(String value) { bankBranchError = null; notifyListeners(); } void updateNumber(String value) { bankNumberError = null; notifyListeners(); } void updateIFSC(String value) { bankIFSCError = null; notifyListeners(); } void updateHolder(String value) { bankHolderError = null; notifyListeners(); } void updateUPI(String value) { UPIError = null; notifyListeners(); } }