Files
kent_logistics_app/lib/screens/invoice_detail_screen.dart

154 lines
4.1 KiB
Dart
Raw Normal View History

2025-12-11 18:36:11 +05:30
import 'dart:io';
2025-12-03 11:57:05 +05:30
import 'package:flutter/material.dart';
2025-12-11 18:36:11 +05:30
import 'package:path_provider/path_provider.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:share_plus/share_plus.dart';
2025-12-03 11:57:05 +05:30
import '../services/dio_client.dart';
import '../services/invoice_service.dart';
2025-12-11 18:36:11 +05:30
import '../widgets/invoice_detail_view.dart';
2025-12-03 11:57:05 +05:30
class InvoiceDetailScreen extends StatefulWidget {
final int invoiceId;
const InvoiceDetailScreen({super.key, required this.invoiceId});
@override
State<InvoiceDetailScreen> createState() => _InvoiceDetailScreenState();
}
class _InvoiceDetailScreenState extends State<InvoiceDetailScreen> {
bool loading = true;
Map invoice = {};
@override
void initState() {
super.initState();
load();
}
2025-12-11 18:36:11 +05:30
// -------------------------------------------------------
// ⭐ LOAD INVOICE FROM API
// -------------------------------------------------------
2025-12-03 11:57:05 +05:30
Future<void> load() async {
final service = InvoiceService(DioClient.getInstance(context));
2025-12-11 18:36:11 +05:30
try {
final res = await service.getInvoiceDetails(widget.invoiceId);
if (res['success'] == true) {
invoice = res['invoice'] ?? {};
} else {
invoice = {};
}
} catch (e) {
invoice = {};
} finally {
if (mounted) setState(() => loading = false);
2025-12-03 11:57:05 +05:30
}
}
2025-12-11 18:36:11 +05:30
// -------------------------------------------------------
// ⭐ GENERATE + SAVE PDF TO DOWNLOADS FOLDER
// (No Permission Needed)
// -------------------------------------------------------
Future<File> generatePDF() async {
final pdf = pw.Document();
pdf.addPage(
pw.Page(
build: (context) => pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
"INVOICE DETAILS",
style: pw.TextStyle(fontSize: 26, fontWeight: pw.FontWeight.bold),
2025-12-03 11:57:05 +05:30
),
2025-12-11 18:36:11 +05:30
pw.SizedBox(height: 20),
pw.Text("Invoice ID: ${invoice['id'] ?? '-'}"),
pw.Text("Amount: ₹${invoice['amount'] ?? '-'}"),
pw.Text("Status: ${invoice['status'] ?? '-'}"),
pw.Text("Date: ${invoice['date'] ?? '-'}"),
pw.Text("Customer: ${invoice['customer_name'] ?? '-'}"),
],
),
2025-12-03 11:57:05 +05:30
),
);
2025-12-11 18:36:11 +05:30
// ⭐ SAFEST WAY (Android 1014)
final downloadsDir = await getDownloadsDirectory();
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
final filePath = "${downloadsDir!.path}/invoice_${invoice['id']}.pdf";
final file = File(filePath);
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
await file.writeAsBytes(await pdf.save());
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("PDF saved to Downloads:\n$filePath")),
);
}
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
return file;
}
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
// -------------------------------------------------------
// ⭐ SHARE THE SAVED PDF FILE
// -------------------------------------------------------
Future<void> sharePDF() async {
final file = await generatePDF();
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
await Share.shareXFiles(
[XFile(file.path)],
text: "Invoice Details",
);
}
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
@override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
final scale = (width / 430).clamp(0.88, 1.08);
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
return Scaffold(
appBar: AppBar(
title: Text(
"Invoice Details",
style: TextStyle(
fontSize: 18 * scale,
fontWeight: FontWeight.w600,
),
),
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
// ⭐ PDF + SHARE BUTTONS
actions: [
IconButton(
icon: const Icon(Icons.picture_as_pdf),
onPressed: generatePDF,
),
IconButton(
icon: const Icon(Icons.share),
onPressed: sharePDF,
),
],
),
2025-12-03 11:57:05 +05:30
2025-12-11 18:36:11 +05:30
body: loading
? const Center(child: CircularProgressIndicator())
: invoice.isEmpty
? Center(
child: Text(
"No Invoice Data Found",
style: TextStyle(
fontSize: 18 * scale,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
2025-12-03 11:57:05 +05:30
),
2025-12-11 18:36:11 +05:30
)
: Padding(
padding: EdgeInsets.all(12 * scale),
child: InvoiceDetailView(invoice: invoice),
2025-12-03 11:57:05 +05:30
),
);
}
}