tenantId; $role = $request->user->role ?? 'viewer'; $assignedCompanyId = $request->user->assigned_company_id ?? null; if ($role === 'super_admin') { $invoices = $this->invoiceModel->findByTenant($tenantId); } else { // Filter by assigned company for admin, accountant, etc. $db = \App\Core\Database::getInstance(); $stmt = $db->prepare("SELECT * FROM invoices WHERE tenant_id = ? AND company_id = ? AND deleted_at IS NULL ORDER BY created_at DESC"); $stmt->execute([$tenantId, $assignedCompanyId]); $invoices = $stmt->fetchAll(); } Response::json([ 'success' => true, 'data' => $invoices ]); } public function upload(Request $request): void { $files = $request->getFiles(); if (empty($files['invoice'])) { Response::error('يرجى اختيار ملف الفاتورة', 'MISSING_FILE', 422); return; } $companyId = $request->input('company_id'); if (!$companyId) { Response::error('يرجى تحديد الشركة', 'MISSING_COMPANY', 422); return; } try { $tenantId = $request->tenantId; $filePath = $this->storage->store($files['invoice'], $tenantId, $companyId); $fileHash = $this->storage->getHash($filePath); // Create invoice record $invoiceId = \Ramsey\Uuid\Uuid::uuid4()->toString(); $this->invoiceModel->create([ 'id' => $invoiceId, 'tenant_id' => $tenantId, 'company_id' => $companyId, 'uploaded_by' => $request->user->user_id, 'status' => 'uploaded', // Match schema ENUM 'original_file_path' => $filePath, 'original_file_hash' => $fileHash, 'idempotency_key' => bin2hex(random_bytes(16)) ]); // Push to Queue for AI Extraction \App\Services\QueueService::push('invoice_extraction', [ 'invoice_id' => $invoiceId, 'file_path' => $filePath, 'mime_type' => mime_content_type($filePath) ]); Response::json([ 'success' => true, 'data' => ['invoice_id' => $invoiceId], 'message' => 'تم رفع الفاتورة بنجاح وجاري استخراج البيانات بالذكاء الاصطناعي' ], 202); } catch (Throwable $e) { Response::error($e->getMessage(), 'UPLOAD_FAILED', 500); } } public function detail(Request $request, array $vars): void { $tenantId = $request->tenantId; $invoiceId = $vars['id'] ?? null; $db = \App\Core\Database::getInstance(); $stmt = $db->prepare("SELECT * FROM invoices WHERE id = ? AND tenant_id = ? AND deleted_at IS NULL LIMIT 1"); $stmt->execute([$invoiceId, $tenantId]); $invoice = $stmt->fetch(); if (!$invoice) { Response::error('الفاتورة غير موجودة', 'NOT_FOUND', 404); return; } // Additional authorization check based on assigned company if needed $role = $request->user->role ?? 'viewer'; if ($role !== 'super_admin' && $invoice['company_id'] !== $request->user->assigned_company_id) { Response::error('غير مصرح لك بمشاهدة هذه الفاتورة', 'FORBIDDEN', 403); return; } // Fetch lines $stmt = $db->prepare("SELECT * FROM invoice_lines WHERE invoice_id = ? ORDER BY id ASC"); $stmt->execute([$invoiceId]); $invoice['lines'] = $stmt->fetchAll(); Response::json([ 'success' => true, 'data' => $invoice ]); } public function submit(Request $request, array $vars): void { $tenantId = $request->tenantId; $invoiceId = $vars['id']; // Push to Queue for JoFotara Submission \App\Services\QueueService::push('submit_jofotara', [ 'invoice_id' => $invoiceId ]); Response::json([ 'success' => true, 'message' => 'Invoice submission queued.' ]); } }