Update: 2026-05-08 02:11:29
This commit is contained in:
@@ -67,6 +67,79 @@ class InvoiceDetailController extends GetxController {
|
||||
}
|
||||
|
||||
Future<void> approveInvoice() async {
|
||||
// First check for duplicates
|
||||
try {
|
||||
final dupRes = await DioClient().client.post('invoices/check-duplicate', data: {
|
||||
'invoice_number': invoice['invoice_number'],
|
||||
'supplier_tin': invoice['supplier_tin'],
|
||||
'grand_total': invoice['grand_total'],
|
||||
'invoice_date': invoice['invoice_date'],
|
||||
'exclude_id': invoiceId,
|
||||
});
|
||||
|
||||
if (dupRes.data['success'] == true) {
|
||||
final matches = dupRes.data['data']?['matches'] as List? ?? [];
|
||||
if (matches.isNotEmpty) {
|
||||
// Show duplicate warning
|
||||
final proceed = await Get.dialog<bool>(
|
||||
AlertDialog(
|
||||
title: const Row(
|
||||
children: [
|
||||
Icon(Icons.warning_amber, color: Colors.orange, size: 28),
|
||||
SizedBox(width: 8),
|
||||
Text('تحذير — فاتورة مكررة!', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||||
],
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('تم العثور على ${matches.length} فاتورة مشابهة:', style: const TextStyle(fontWeight: FontWeight.w600)),
|
||||
const SizedBox(height: 12),
|
||||
...matches.take(3).map((m) => Container(
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.orange.withValues(alpha: 0.08),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: Colors.orange.withValues(alpha: 0.3)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('رقم: ${m['invoice_number'] ?? '—'}', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600)),
|
||||
Text('المورد: ${m['supplier_name'] ?? '—'}', style: const TextStyle(fontSize: 12)),
|
||||
Text('المبلغ: ${m['grand_total'] ?? '—'} | نوع التطابق: ${m['match_type'] ?? '—'}', style: const TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
],
|
||||
),
|
||||
)),
|
||||
const SizedBox(height: 8),
|
||||
const Text('هل تريد الاستمرار بالاعتماد؟', style: TextStyle(fontWeight: FontWeight.w600)),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Get.back(result: false),
|
||||
child: const Text('إلغاء'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () => Get.back(result: true),
|
||||
style: ElevatedButton.styleFrom(backgroundColor: Colors.orange),
|
||||
child: const Text('اعتماد رغم التكرار', style: TextStyle(color: Colors.white)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (proceed != true) return;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// If duplicate check fails, proceed with approval anyway
|
||||
AppLogger.error('Duplicate check failed (proceeding)', e);
|
||||
}
|
||||
|
||||
// Proceed with approval
|
||||
try {
|
||||
final res = await DioClient()
|
||||
.client
|
||||
@@ -130,13 +203,16 @@ class InvoiceDetailController extends GetxController {
|
||||
final bytes = List<int>.from(res.data);
|
||||
await file.writeAsBytes(bytes);
|
||||
|
||||
// Try share, fallback to success message
|
||||
// Share via native sheet (share_plus v12 API)
|
||||
try {
|
||||
await Share.shareXFiles(
|
||||
[XFile(file.path, mimeType: 'text/csv', name: fileName)],
|
||||
subject: 'تصدير فواتير مُصادَق',
|
||||
await SharePlus.instance.share(
|
||||
ShareParams(
|
||||
files: [XFile(file.path, mimeType: 'text/csv', name: fileName)],
|
||||
title: 'تصدير فواتير مُصادَق',
|
||||
),
|
||||
);
|
||||
} catch (_) {
|
||||
} catch (shareErr) {
|
||||
AppLogger.error('Share fallback', shareErr);
|
||||
AppSnackbar.showSuccess('تم الحفظ', 'تم حفظ الملف: ${file.path}');
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user