Update: 2026-05-07 02:01:59

This commit is contained in:
Hamza-Ayed
2026-05-07 02:01:59 +03:00
parent e5b70a01ef
commit 57ac6047b8
4 changed files with 143 additions and 37 deletions

View File

@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import '../../../core/utils/logger.dart';
@@ -15,6 +16,10 @@ class ScannerController extends GetxController {
var uploadProgress = 0.0.obs;
var companies = <Map<String, dynamic>>[].obs;
var isLoadingCompanies = false.obs;
var currentBatchId = ''.obs;
var processedImagesCount = 0.obs;
var totalImagesCount = 0.obs;
var isBatchDone = false.obs;
final InvoiceUploadService _uploadService = InvoiceUploadService();
@@ -22,6 +27,21 @@ class ScannerController extends GetxController {
void onInit() {
super.onInit();
fetchCompanies();
_initFcmListener();
}
void _initFcmListener() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
final data = message.data;
if (data['type'] == 'batch_progress' && data['batch_id'] == currentBatchId.value) {
processedImagesCount.value = int.tryParse(data['processed'].toString()) ?? 0;
totalImagesCount.value = int.tryParse(data['total'].toString()) ?? 0;
if (processedImagesCount.value >= totalImagesCount.value) {
isBatchDone.value = true;
}
}
});
}
Future<void> fetchCompanies() async {
@@ -96,23 +116,58 @@ class ScannerController extends GetxController {
);
if (batchId != null) {
currentBatchId.value = batchId;
totalImagesCount.value = capturedImages.length;
processedImagesCount.value = 0;
capturedImages.clear();
uploadProgress.value = 0.0;
Get.defaultDialog(
title: 'جاري المعالجة ⏳',
middleText: 'تم استلام الفواتير بنجاح وسيتم إشعارك فور الانتهاء من تدقيقها عبر الذكاء الاصطناعي.',
textConfirm: 'حسناً',
confirmTextColor: Colors.white,
buttonColor: const Color(0xFF0F4C81),
onConfirm: () {
if (Get.isDialogOpen ?? false) Get.back(); // close dialog
Get.back(); // go back to dashboard
},
Get.dialog(
AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
title: const Center(
child: Text('جاري المعالجة ⏳',
style: TextStyle(fontFamily: 'El Messiri', fontWeight: FontWeight.bold, fontSize: 18)
)
),
content: Obx(() => Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text('يتم الآن تدقيق الفواتير عبر الذكاء الاصطناعي...',
textAlign: TextAlign.center,
style: TextStyle(fontFamily: 'El Messiri', fontSize: 14)
),
const SizedBox(height: 20),
if (!isBatchDone.value) ...[
LinearProgressIndicator(
value: totalImagesCount.value > 0 ? processedImagesCount.value / totalImagesCount.value : 0,
backgroundColor: Colors.grey[200],
valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF0F4C81)),
),
const SizedBox(height: 10),
Text('${processedImagesCount.value} من ${totalImagesCount.value}',
style: const TextStyle(fontFamily: 'El Messiri', fontWeight: FontWeight.bold)
),
] else ...[
const Icon(Icons.check_circle, color: Colors.green, size: 50),
const SizedBox(height: 10),
const Text('اكتملت المعالجة بنجاح!',
style: TextStyle(fontFamily: 'El Messiri', color: Colors.green, fontWeight: FontWeight.bold)
),
],
],
)),
actions: [
TextButton(
onPressed: () {
Get.back(); // close dialog
Get.back(); // go back to dashboard
},
child: const Text('إغلاق', style: TextStyle(fontFamily: 'El Messiri', fontWeight: FontWeight.bold)),
)
],
),
barrierDismissible: false,
titleStyle: const TextStyle(fontFamily: 'El Messiri', fontWeight: FontWeight.bold, fontSize: 18),
middleTextStyle: const TextStyle(fontFamily: 'El Messiri', fontSize: 14),
radius: 12,
);
} else {
AppSnackbar.showError('خطأ', 'فشل رفع الفواتير، يرجى المحاولة لاحقاً');