import 'dart:io'; import 'package:csv/csv.dart'; import 'package:excel/excel.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:generp/Models/financeModels/paymentRequisitionPaymentsDetailsResponse.dart'; import 'package:generp/Models/financeModels/paymentRequisitionPaymentsListResponse.dart'; import 'package:generp/Notifiers/HomeScreenNotifier.dart'; import 'package:generp/services/api_calling.dart'; import 'package:path_provider/path_provider.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:permission_handler/permission_handler.dart'; import 'package:printing/printing.dart'; import 'package:provider/provider.dart'; import '../../Utils/commonServices.dart'; class Paymentrequisitionpaymentslistprovider extends ChangeNotifier{ bool _showMoreDetails = false; List _paymentsList = []; PaymentDetails _paymentDetails = PaymentDetails(); List _headings = []; List _subHeadings = []; List get paymentsList => _paymentsList; PaymentDetails get paymentDetails => _paymentDetails; bool _isLoading = true; List get Headings => _headings; List get subHeadings => _subHeadings; bool get isLoading => _isLoading; bool get showMoreDetails => _showMoreDetails; set showMoreDetails(bool value){ _showMoreDetails = value; notifyListeners(); } Future paymentsListAPI(context,from,to) async { try{ var prov = Provider.of(context,listen: false); _paymentsList.clear(); _isLoading = true; notifyListeners(); final data = await ApiCalling.paymentRequisitionPaymentListAPI(prov.empId, prov.session,from,to); if(data!=null){ if(data.error=="0"){ _isLoading = false; _paymentsList = data.paymentsList!; notifyListeners(); }else if(data.error=="1"){ _isLoading = false; } notifyListeners(); } }catch(e,s){ } } Future paymentsListDetailsAPI(context,paymentId) async { try{ var prov = Provider.of(context,listen: false); final data = await ApiCalling.paymentRequisitionPaymentDetailsAPI(prov.empId, prov.session,paymentId); if(data!=null){ if(data.error=="0"){ _paymentDetails = data.paymentDetails??PaymentDetails( accountId: "-", accountName: "-", amount: "-", attachmentDirFilePath: "-", attachmentViewFileName: "-", createdDatetime: "-", description: "-", id: "-", updatedDatetime: "-", refType: "-",refId: "-",paymentRemarks: "-",paymentReferenceNumber: "-",paymentModeId: "-",paymentEmployeeName: "-",paymentDate: "-",paymentAccountName: "-",paymentAccountId: "-",mode: "-",isExists: "-",createdEmployeeId: "-",bankUpiId: "-",bankName: "-",bankIfscCode:"-",bankBranchName: "-",bankAccountNumber: "-",bankAccountHolderName:"-" , ); _headings = [ "From Account", "Payment Mode", "Created Employee", "Attachment", "Payment Date", "Note", "Bank Name", "Bank Branch Name", "Bank IFSC Code", "Bank Holder Name", "Bank Account Number", "Bank UPI ID", "Payment Reference Number", "Created Date Time", "Updated Date Time" ]; _subHeadings = [ _paymentDetails.paymentAccountName??"-", _paymentDetails.mode??"-", _paymentDetails.paymentEmployeeName??"-", _paymentDetails.attachmentDirFilePath??"-", _paymentDetails.paymentDate??"-", _paymentDetails.paymentRemarks??"-", _paymentDetails.bankName??"-", _paymentDetails.bankBranchName??"-", _paymentDetails.bankIfscCode??"-", _paymentDetails.bankAccountHolderName??"-", _paymentDetails.bankAccountNumber??"-", _paymentDetails.bankUpiId??"-", _paymentDetails.paymentReferenceNumber??"-", _paymentDetails.createdDatetime??"-", _paymentDetails.updatedDatetime??"-" ]; notifyListeners(); } } }catch(e,s){ } } List> prepareExportData() { final headers = [ 'ID', 'Payment Account', 'Amount', 'Branch', 'Account Number', 'Description', 'Mode', 'Payment Reference Number', 'Created Employee', 'Date', ]; final rows = paymentsList .map( (item) => [ item.id ?? '', item.payAccount ?? '', item.amount ?? '', item.bankName??"", item.bankBranchName ?? '', item.bankAccountNumber ?? '', item.description ?? '', item.requestMode ?? '', item.paymentReferenceNumber ?? '', item.createdEmployee ?? '', item.createdDatetime ?? '', ], ) .toList(); return [headers, ...rows]; } void copyToClipboard(BuildContext context) async { try { if (paymentsList.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 (paymentsList.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 (paymentsList.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 (paymentsList.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 (paymentsList.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 resetForm() { _paymentsList = []; _paymentDetails = PaymentDetails(); _headings = []; _subHeadings = []; } }