diff --git a/app/modules_app/invoices/file.php b/app/modules_app/invoices/file.php
new file mode 100644
index 0000000..af9f44e
--- /dev/null
+++ b/app/modules_app/invoices/file.php
@@ -0,0 +1,33 @@
+prepare("SELECT tenant_id, original_file_path FROM invoices WHERE id = ?");
+$stmt->execute([$id]);
+$invoice = $stmt->fetch();
+
+if (!$invoice) die('Not found');
+
+// Authorization
+if ($decoded['role'] !== 'super_admin' && $invoice['tenant_id'] !== $decoded['tenant_id']) {
+ die('Unauthorized');
+}
+
+$filePath = $invoice['original_file_path'];
+if (!file_exists($filePath)) die('File missing');
+
+$mime = mime_content_type($filePath);
+header("Content-Type: $mime");
+header("Content-Length: " . filesize($filePath));
+readfile($filePath);
+exit;
diff --git a/app/modules_app/invoices/view.php b/app/modules_app/invoices/view.php
new file mode 100644
index 0000000..2ae9341
--- /dev/null
+++ b/app/modules_app/invoices/view.php
@@ -0,0 +1,67 @@
+prepare("
+ SELECT i.*, c.name as company_name
+ FROM invoices i
+ LEFT JOIN companies c ON i.company_id = c.id
+ WHERE i.id = ?
+ ");
+ $stmt->execute([$id]);
+ $invoice = $stmt->fetch();
+
+ if (!$invoice) {
+ json_error('Invoice not found', 404);
+ }
+
+ // 3. Authorization Check
+ if ($decoded['role'] !== 'super_admin') {
+ if ($invoice['tenant_id'] !== $decoded['tenant_id']) {
+ json_error('Unauthorized access to this invoice', 403);
+ }
+ }
+
+ // 4. Fetch Line Items
+ $stmtLines = $db->prepare("SELECT * FROM invoice_lines WHERE invoice_id = ? ORDER BY line_number ASC");
+ $stmtLines->execute([$id]);
+ $invoice['items'] = $stmtLines->fetchAll();
+
+ // 5. Decrypt Fields
+ $invoice['supplier_tin'] = Encryption::decrypt($invoice['supplier_tin'] ?? '') ?: $invoice['supplier_tin'];
+ $invoice['supplier_name'] = Encryption::decrypt($invoice['supplier_name'] ?? '') ?: $invoice['supplier_name'];
+ $invoice['supplier_address'] = Encryption::decrypt($invoice['supplier_address'] ?? '') ?: $invoice['supplier_address'];
+ $invoice['buyer_tin'] = Encryption::decrypt($invoice['buyer_tin'] ?? '') ?: $invoice['buyer_tin'];
+ $invoice['buyer_name'] = Encryption::decrypt($invoice['buyer_name'] ?? '') ?: $invoice['buyer_name'];
+ $invoice['buyer_national_id'] = Encryption::decrypt($invoice['buyer_national_id'] ?? '') ?: $invoice['buyer_national_id'];
+
+ if (!empty($invoice['company_name'])) {
+ $invoice['company_name'] = Encryption::decrypt($invoice['company_name']) ?: $invoice['company_name'];
+ }
+
+ // 6. Generate Public URL for File (Assuming storage is symlinked or served)
+ // For now, let's just return the relative path or a proxy route
+ // We'll add a proxy route later if needed.
+ $invoice['file_url'] = '/index.php?route=v1/invoices/file&id=' . $invoice['id'];
+
+ json_success($invoice);
+
+} catch (\Exception $e) {
+ json_error('Error fetching invoice: ' . $e->getMessage(), 500);
+}
diff --git a/public/index.php b/public/index.php
index 3417085..c0e518c 100644
--- a/public/index.php
+++ b/public/index.php
@@ -26,6 +26,8 @@ $routes = [
'v1/companies/create' => ['POST', 'companies/create.php'],
'v1/companies/delete' => ['POST', 'companies/delete.php'],
'v1/invoices' => ['GET', 'invoices/index.php'],
+ 'v1/invoices/view' => ['GET', 'invoices/view.php'],
+ 'v1/invoices/file' => ['GET', 'invoices/file.php'],
'v1/invoices/upload' => ['POST', 'invoices/upload.php'],
'v1/dashboard/stats' => ['GET', 'dashboard/stats.php'],
'v1/tenants' => ['GET', 'tenants/index.php'],
diff --git a/public/shell.php b/public/shell.php
index b4c0b2e..7ad69ac 100644
--- a/public/shell.php
+++ b/public/shell.php
@@ -18,6 +18,7 @@
body { font-family: 'IBM Plex Sans Arabic', sans-serif; background-color: var(--bg-base); color: var(--text-primary); }
[x-cloak] { display: none !important; }
.glass { background: rgba(13, 20, 36, 0.7); backdrop-filter: blur(12px); border: 1px solid rgba(255,255,255,0.05); }
+ .scrollbar-hide::-webkit-scrollbar { display: none; }
@@ -87,27 +88,6 @@
-
-
-
-
-
📄
-
إجمالي الفواتير
-
-
-
-
-
-
-
@@ -144,7 +124,7 @@
x-text="inv.status">
-
+
|
@@ -153,160 +133,121 @@
-
-
-
-
-
-
- | الشركة |
- الأرقام الرسمية |
- العنوان |
- المكتب |
- إجراءات |
-
-
-
- | لا توجد شركات بعد |
-
-
- |
-
- |
-
- TIN:
- CRN:
- |
- |
- |
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
- | المستخدم |
- المكتب |
- الدور |
- الحالة |
- إجراءات |
-
-
-
- | لا يوجد مستخدمون بعد |
-
-
- |
-
-
- |
- |
- |
- |
-
-
- |
-
-
-
-
-
-
+
-
-
-
-
رفع فواتير جديدة 📤
-
سيقوم النظام باستخراج البيانات آلياً باستخدام الذكاء الاصطناعي
+
+