invoiceModel->findByTenant($request->tenantId); 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, 'invoice_uuid' => \Ramsey\Uuid\Uuid::uuid4()->toString(), 'tenant_id' => $tenantId, 'company_id' => $companyId, 'uploaded_by' => $request->user->user_id, 'status' => 'PROCESSING', 'original_file_path' => $filePath, 'original_file_hash' => $fileHash, 'idempotency_key' => bin2hex(random_bytes(16)) ]); // Attempt AI Extraction try { $mimeType = mime_content_type($filePath); $extractedData = $this->aiExtraction->extractInvoiceData($filePath, $mimeType); // Update Invoice with extracted data $this->invoiceModel->update($invoiceId, [ 'status' => 'EXTRACTED', 'extracted_data' => json_encode($extractedData, JSON_UNESCAPED_UNICODE) ]); Response::json([ 'success' => true, 'data' => [ 'invoice_id' => $invoiceId, 'extracted_data' => $extractedData ], 'message' => 'تم رفع الفاتورة واستخراج البيانات بنجاح بالذكاء الاصطناعي' ]); } catch (Throwable $aiError) { // Keep it uploaded, maybe manual retry later $this->invoiceModel->update($invoiceId, [ 'status' => 'AI_FAILED' ]); Response::json([ 'success' => true, 'data' => ['invoice_id' => $invoiceId], 'message' => 'تم الرفع ولكن فشل استخراج البيانات. ' . $aiError->getMessage() ]); } } catch (Throwable $e) { Response::error($e->getMessage(), 'UPLOAD_FAILED', 500); } } }