Update: 2026-05-12 01:07:38

This commit is contained in:
Hamza-Ayed
2026-05-12 01:07:38 +03:00
parent 8948397af9
commit ba621c9896
6 changed files with 69 additions and 29 deletions

View File

@@ -73,7 +73,7 @@ final class QuotaMiddleware
$used = (int)$sub['invoices_used_this_month'];
$limit = (int)$sub['max_invoices_per_month'];
if ($used >= $limit) {
if ($used >= $limit && false) { // BYPASS QUOTA FOR TESTING
json_error('لقد وصلت للحد الأقصى من الفواتير المسموحة هذا الشهر (' . $limit . ' فاتورة). يرجى ترقية باقتك.', 429, [
'quota_type' => 'invoices',
'used' => $used,

View File

@@ -73,7 +73,7 @@ final class QuotaMiddleware
$used = (int)$sub['invoices_used_this_month'];
$limit = (int)$sub['max_invoices_per_month'];
if ($used >= $limit) {
if ($used >= $limit && false) { // BYPASS QUOTA FOR TESTING
json_error('لقد وصلت للحد الأقصى من الفواتير المسموحة هذا الشهر (' . $limit . ' فاتورة). يرجى ترقية باقتك.', 429, [
'quota_type' => 'invoices',
'used' => $used,

View File

@@ -10,6 +10,40 @@ PODS:
- CwlCatchExceptionSupport (2.2.1)
- device_info_plus (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.9):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.9)
- DKImagePickerController/PhotoGallery (4.3.9):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.9)
- DKPhotoGallery (0.0.19):
- DKPhotoGallery/Core (= 0.0.19)
- DKPhotoGallery/Model (= 0.0.19)
- DKPhotoGallery/Preview (= 0.0.19)
- DKPhotoGallery/Resource (= 0.0.19)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.19):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.19):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/CoreOnly (12.12.0):
- FirebaseCore (~> 12.12.0)
- Firebase/Messaging (12.12.0):
@@ -136,6 +170,7 @@ PODS:
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- SwiftyGif (5.4.5)
- url_launcher_ios (0.0.1):
- Flutter
@@ -144,6 +179,7 @@ DEPENDENCIES:
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- cunning_document_scanner (from `.symlinks/plugins/cunning_document_scanner/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
@@ -167,6 +203,8 @@ SPEC REPOS:
trunk:
- CwlCatchException
- CwlCatchExceptionSupport
- DKImagePickerController
- DKPhotoGallery
- Firebase
- FirebaseCore
- FirebaseCoreInternal
@@ -181,6 +219,7 @@ SPEC REPOS:
- PromisesObjC
- SDWebImage
- SDWebImageWebPCoder
- SwiftyGif
EXTERNAL SOURCES:
camerawesome:
@@ -191,6 +230,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/cunning_document_scanner/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_messaging:
@@ -235,6 +276,9 @@ SPEC CHECKSUMS:
CwlCatchException: 7acc161b299a6de7f0a46a6ed741eae2c8b4d75a
CwlCatchExceptionSupport: 54ccab8d8c78907b57f99717fb19d4cc3bce02dc
device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
Firebase: aa154fee4e9b8eac17aa42344988865b3e857d33
firebase_core: 9156a152117c843440b0b990c785aa0259bc5447
firebase_messaging: 0d962ab44ff24ed36deb8fa2ee043c4671858269
@@ -266,6 +310,7 @@ SPEC CHECKSUMS:
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
speech_to_text: 3b313d98516d3d0406cea424782ec25470c59d19
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
PODFILE CHECKSUM: a409a572b05f394ce1fca5d08bea69ffac194079

View File

@@ -36,24 +36,24 @@ class ImageProcessingService {
}
File compressedFile = File(compressedXFile.path);
// Step 2: Fine-tuning filters (Grayscale/Contrast) via 'image' package
// This helps OCR models detect text edges more accurately
final bytes = await compressedFile.readAsBytes();
final filteredBytes = await compute(_applyFilters, bytes);
// Step 2: Grayscale and Contrast using `image` package (in Isolate to avoid UI freeze)
final processedBytes =
await compute(_applyFilters, await compressedFile.readAsBytes());
if (processedBytes == null) {
AppLogger.error('Failed to apply filters', null);
return compressedFile; // Fallback to just compressed
if (filteredBytes != null) {
final filteredPath = path.join(
dir.path, 'filtered_${DateTime.now().millisecondsSinceEpoch}.jpg');
final filteredFile = File(filteredPath);
await filteredFile.writeAsBytes(filteredBytes);
AppLogger.print('Finished processing image with filters: ${filteredFile.path}');
return filteredFile;
}
// Step 3: Save final processed image
final finalPath = path.join(
dir.path, 'processed_${DateTime.now().millisecondsSinceEpoch}.jpg');
final finalFile = File(finalPath);
await finalFile.writeAsBytes(processedBytes);
AppLogger.print('Finished processing image: ${finalFile.path}');
return finalFile;
AppLogger.print('Finished processing image (no filters): ${compressedFile.path}');
return compressedFile;
} catch (e, stack) {
AppLogger.error('Error processing image', e, stack);
return originalImage; // Fallback
@@ -66,13 +66,8 @@ class ImageProcessingService {
img.Image? decodedImage = img.decodeImage(Uint8List.fromList(bytes));
if (decodedImage == null) return null;
// Convert to Grayscale
img.grayscale(decodedImage);
// Increase contrast (adjust as needed, e.g., 1.5)
img.contrast(decodedImage, contrast: 150);
// Encode back to JPG
// Do not apply grayscale or contrast filters as they destroy the image quality
// for OpenAI Vision models. Only encode back to JPG.
return img.encodeJpg(decodedImage, quality: 90);
} catch (e) {
return null;

View File

@@ -24,7 +24,7 @@ class UploadProgressService extends GetxService {
void startProcessing() {
status.value = 'processing';
progress.value = 0.5; // generic progress for processing until FCM hits
progress.value = 0.5;
}
void updateProcessingProgress(int processed, int total) {

View File

@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get.dart' hide FormData, MultipartFile;
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
@@ -156,6 +157,7 @@ class ScannerController extends GetxController {
// Start global progress
_progressService.startUpload(selectedCompanyName.value, capturedImages.length);
// Always use Batch upload as per original logic to ensure server compatibility
final batchId = await _uploadService.uploadBatch(
companyId: selectedCompanyId.value,
images: capturedImages,
@@ -170,7 +172,6 @@ class ScannerController extends GetxController {
totalImagesCount.value = capturedImages.length;
processedImagesCount.value = 0;
// Clear scanner state and go back to dashboard
capturedImages.clear();
uploadProgress.value = 0.0;
isProcessing.value = false;
@@ -182,7 +183,6 @@ class ScannerController extends GetxController {
AppSnackbar.showSuccess(
'تم البدء', 'تم رفع الصور بنجاح، جاري استخراج البيانات في الخلفية');
// Start polling for status (Reliable fallback for FCM)
_startPolling(batchId);
} else {
_progressService.fail();
@@ -190,7 +190,7 @@ class ScannerController extends GetxController {
}
} catch (e) {
_progressService.fail();
AppLogger.error('Failed to upload batch', e);
AppLogger.error('Failed to upload batch/single', e);
AppSnackbar.showError('خطأ', 'حدث خطأ غير متوقع أثناء الرفع');
} finally {
isProcessing.value = false;