diff --git a/app/modules_app/batches/upload_image.php b/app/modules_app/batches/upload_image.php
index 3bc4dbd..76576fd 100644
--- a/app/modules_app/batches/upload_image.php
+++ b/app/modules_app/batches/upload_image.php
@@ -47,10 +47,10 @@ if ($batch['status'] !== 'uploading') {
}
// 3. Validate file type
-$allowedTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/heic', 'image/heif'];
+$allowedTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/heic', 'image/heif', 'application/pdf'];
$mimeType = $_FILES['image']['type'];
if (!in_array($mimeType, $allowedTypes)) {
- json_error('نوع الملف غير مدعوم. المسموح: JPEG, PNG, WebP, HEIC', 422);
+ json_error('نوع الملف غير مدعوم. المسموح: صور و PDF', 422);
}
// 4. Validate file size (max 10MB)
diff --git a/public/shell.php b/public/shell.php
index 82c29fd..1572809 100644
--- a/public/shell.php
+++ b/public/shell.php
@@ -1137,6 +1137,9 @@
+
@@ -1925,6 +1928,57 @@
+
+
+
+
+
📁
+
+
رفع مجمع للفواتير (Batch Processing)
+
اختر عدة فواتير لمعالجتها في الخلفية
+
+
+
+
+
+
+
+
+ style="border:1px solid var(--border); border-radius:10px; overflow:hidden; display:flex; flex-direction:column; max-height:300px;">
+ style="padding:8px 12px; background:#f8fafc; font-size:11px; font-weight:700; color:var(--text-3); text-transform:uppercase; letter-spacing:0.06em; flex-shrink:0; position:sticky; top:0; z-index:2;">
بنود الفاتورة
-
-
-
- |
- البند |
-
- الكمية |
-
- السعر |
-
-
-
-
-
- |
- |
- |
- |
+
+
+
+
+ | البند |
+ الكمية |
+ السعر |
-
-
-
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
@@ -2298,7 +2345,8 @@
showAddUserModal: false, showAddCompanyModal: false, showConnectModal: false,
showUploadModal: false, showViewModal: false, showCompanyStatsModal: false,
- showExcelModal: false,
+ showExcelModal: false, showBatchUploadModal: false,
+ isUploadingBatch: false, batchProgress: { total: 0, current: 0 },
showAddTenantModal: false, showEditTenantModal: false, showTenantStatsModal: false,
acknowledgedWarnings: false,
isBusy: false, globalError: '',
@@ -2509,6 +2557,63 @@
}
},
+ async uploadBatchInvoices() {
+ const fileInput = document.getElementById('batchFileInput');
+ if (!fileInput.files.length) return alert('الرجاء اختيار ملفات');
+ if (!this.uploadData.company_id) return alert('الرجاء اختيار الشركة');
+
+ this.isUploadingBatch = true;
+ this.batchProgress = { total: fileInput.files.length, current: 0 };
+
+ try {
+ // 1. Create batch
+ const batchRes = await fetch('/index.php?route=v1/batches/create', {
+ method: 'POST',
+ headers: { 'Authorization': 'Bearer ' + this.token(), 'Content-Type': 'application/json' },
+ body: JSON.stringify({ company_id: this.uploadData.company_id, expected_images: fileInput.files.length, source: 'web_batch' })
+ }).then(r => r.json());
+
+ if (!batchRes.success) {
+ this.isUploadingBatch = false;
+ return this.showError(batchRes.message);
+ }
+
+ const batchId = batchRes.data.batch_id;
+
+ // 2. Upload files sequentially
+ for (let i = 0; i < fileInput.files.length; i++) {
+ const file = fileInput.files[i];
+ const formData = new FormData();
+ formData.append('batch_id', batchId);
+ formData.append('image_order', i+1);
+ formData.append('image', file);
+
+ await fetch('/index.php?route=v1/batches/upload-image', {
+ method: 'POST',
+ headers: { 'Authorization': 'Bearer ' + this.token() },
+ body: formData
+ });
+ this.batchProgress.current = i + 1;
+ }
+
+ // 3. Finalize
+ await fetch('/index.php?route=v1/batches/finalize', {
+ method: 'POST',
+ headers: { 'Authorization': 'Bearer ' + this.token(), 'Content-Type': 'application/json' },
+ body: JSON.stringify({ batch_id: batchId })
+ });
+
+ this.isUploadingBatch = false;
+ this.showBatchUploadModal = false;
+ alert('تم رفع الدفعة بنجاح! جاري معالجتها في الخلفية.');
+ this.loadAll();
+ fileInput.value = '';
+ } catch (e) {
+ this.isUploadingBatch = false;
+ this.showError('فشل الاتصال بالخادم أثناء الرفع المجمع');
+ }
+ },
+
async approveInvoice() {
if (!this.currentInvoice || this.isBusy) return;
this.isBusy = true;