@if (session()->has('error'))
{{ session('error') }}
@endif @if (session()->has('success'))
{{ session('success') }}
@endif @can('finance')
{{-- اجمالي الطلبات --}}
{{$countorder}} اجمالي الطلبات
{{-- الفواتير الصادرة --}}
{{$countbills}} الفواتير الصادرة
{{-- الفواتير المدفوعة --}}
{{$countpaid}} الفواتير المدفوعة
{{-- فواتير بإنتظار الدفع --}}
{{$countunderpaid}} فواتير بإنتظار الدفع
{{-- الفواتير الملغية --}}
{{$coundcancelled}} الفواتير الملغية
{{-- الطلبات اليوم --}}
{{$countorder_today}} الطلبات اليوم
{{-- الفواتير الصادرة اليوم --}}
{{$countbills_today}} الفواتير الصادرة اليوم
{{-- الفواتير المدفوعة اليوم --}}
{{$countpaid_today}} الفواتير المدفوعة اليوم
{{-- فواتير بإنتظار الدفع اليوم --}}
{{$countunderpaid_today}} فواتير بإنتظار الدفع اليوم
{{-- الفواتير الملغية اليوم --}}
{{$coundcancelled_today}} الفواتير الملغية اليوم
@endcan
{{-- ======================= وضع القائمة ======================= --}} @if($mode === 'list')
@can('controller')
المحدد: {{ count($selected) }} {{-- إضافة رد جماعي --}} {{-- تغيير حالة جماعي --}} {{-- ======= إصدار فاتورة جماعي ======= --}}
جاري الإصدار...
@endcan

طلباتي

@can('filters') {{-- 👇👇 فلتر حالة الفاتورة (للجدول كله) 👇👇 --}} {{-- ↑ هذا ما ينفّذ أكشن، هو بس يفلتر --}} {{-- Livewire model.live => يطلق updatedInvoiceFilter() ويعيد تحميل القائمة --}} {{-- 🔍 بحث برقم الطلب/الطلب --}} {{-- 🔍 بحث برقم الخدمة (service_no) --}} {{-- بحث بالبريد (للموظفين فقط) --}} {{-- فلتر العضوية (جديد) --}} @endcan @can('filters') {{-- اختيار خدمة (filter by service_id) --}} {{-- فلترة بالحالة --}} @endcan @if($isStaff) {{-- عدد الصفوف لكل صفحة --}} @endif
{{-- =================== عرض القائمة حسب الدور =================== --}} @if($isStaff) {{-- ======= جدول للموظفين (نفس القديم) ======= --}}
@if($isStaff) @endif @if($isStaff) @endif @forelse ($orders as $order) @php $s = $statusMap[$order->status] ?? ['label' => $order->status, 'class' => 'kt-badge-outline']; $i = $invoiceMap[$order->invoice_status] ?? ['label' => $order->invoice_status, 'class' => 'kt-badge-outline']; // ===== حالة دعم الشهادة الاحترافية (104598) لكل صف ===== $supportLabel = null; $supportClass = 'kt-badge-secondary'; if (($order->service->service_no ?? null) === '104598') { // ✅ جيب سجل الدعم الخاص بهالطلب فقط // غيّر اسم الموديل لو عندك مختلف (مثلاً CertSupportRequest أو غيره) $certRow = \App\Models\CertificationSupportRequest::where('order_id', $order->id)->first(); if ($certRow) { $reqStatusKey = $certRow->request_status ?: 'pending'; $reqStatusMap = [ 'pending' => ['label' => 'طلب جديد', 'class' => 'kt-badge-outline'], 'under_review' => ['label' => 'قيد التحقق', 'class' => 'kt-badge-warning'], // جديد: 're_check' => ['label' => 'معاد للتحقق', 'class' => 'kt-badge-warning'], 're_complete' => ['label' => 'معاد للإستكمال', 'class' => 'kt-badge-warning'], 'approved' => ['label' => 'مقبول', 'class' => 'kt-badge-success'], 'rejected' => ['label' => 'مرفوض', 'class' => 'kt-badge-destructive'], ]; $supportMeta = $reqStatusMap[$reqStatusKey] ?? $reqStatusMap['pending']; $supportLabel = $supportMeta['label']; $supportClass = $supportMeta['class']; } } @endphp @if($isStaff) @endif {{-- حالة دعم الشهادة الاحترافية --}} {{-- حالة دعم الشهادة الاحترافية --}} @if($isStaff) @endif @empty @endforelse
@if($isStaff) @endif رقم الطلب رقم الخدمة بريد المستخدمالعضويةعنوان الطلب الحالة حالة الفاتورةحالة الدعمالإجراءات
@if($isStaff) @endif {{ $order->order_no ?? '—' }} {{ $order->service->service_no ?? '—' }} {{ $order->user->email ?? '—' }} @php $member = $this->isActiveGoviMember($order->user->id ?? null); @endphp @if($member) GOVI @else غير عضو @endif
{{ $order->service->title ?? '—' }}
{{ $s['label'] }} {{ $i['label'] }} @if($supportLabel) {{-- عنده طلب دعم فعلي --}} {{ $supportLabel }} @else {{-- مو خدمة دعم / ما عنده سجل دعم --}} غير متاح @endif
لا توجد طلبات حتى الآن.
{{-- سبينر الجدول --}}
@else {{-- ======= بطاقات للعميل (Customer Cards View) ======= --}}
@forelse($orders as $order) @php // حالة الطلب + حالة الفاتورة $s = $statusMap[$order->status] ?? ['label' => $order->status, 'class' => 'kt-badge-outline']; $i = $invoiceMap[$order->invoice_status] ?? ['label' => $order->invoice_status, 'class' => 'kt-badge-outline']; // ===== حالة دعم الشهادة الاحترافية (للبطاقات) ===== $supportLabel = null; $supportClass = 'kt-badge-secondary'; if (($order->service->service_no ?? null) === '104598') { $certRow = \App\Models\CertificationSupportRequest::where('order_id', $order->id)->first(); if ($certRow) { $reqStatusKey = $certRow->request_status ?: 'pending'; $reqStatusMap = [ 'pending' => ['label' => 'طلب جديد', 'class' => 'kt-badge-outline'], 'under_review' => ['label' => 'قيد التحقق', 'class' => 'kt-badge-warning'], // جديد: 're_check' => ['label' => 'معاد للتحقق', 'class' => 'kt-badge-warning'], 're_complete' => ['label' => 'معاد للإستكمال', 'class' => 'kt-badge-warning'], 'approved' => ['label' => 'مقبول', 'class' => 'kt-badge-success'], 'rejected' => ['label' => 'مرفوض', 'class' => 'kt-badge-destructive'], ]; $supportMeta = $reqStatusMap[$reqStatusKey] ?? $reqStatusMap['pending']; $supportLabel = $supportMeta['label']; $supportClass = $supportMeta['class']; } } @endphp
{{-- أعلى البطاقة: رقم الطلب + رقم الخدمة --}}
رقم الطلب {{ $order->order_no ?? '—' }}
رقم الخدمة {{ $order->service->service_no ?? '—' }}
{{-- عنوان الخدمة --}}
عنوان الطلب
{{ $order->service->title ?? '—' }}
{{-- الحالة + الفاتورة --}}
حالة الطلب {{ $s['label'] }}
{{-- حالة دعم الشهادة الاحترافية تظهر فقط لو الطلب تابع للبرنامج وفيه سجل دعم --}} @if(($order->service->service_no ?? null) === '104598' && $supportLabel)
حالة دعم الشهادة {{ $supportLabel }}
@endif
حالة الفاتورة {{ $i['label'] }}
{{-- تاريخ إنشاء مبسط --}}
تاريخ التقديم {{ $order->created_at?->format('Y-m-d') ?? '—' }}
{{-- فوتر البطاقة: زر عرض التفاصيل --}}
@empty
لا توجد طلبات حتى الآن.
@endforelse
{{-- سبينر بسيط للبطاقات --}}
تحميل الطلبات...
@endif {{-- ======= فوتر موحد (pagination + perPage) لكلا الحالتين ======= --}}
@endif {{-- ======================= وضع التفاصيل ======================= --}} @if($mode === 'detail' && $current)

تفاصيل الطلب

{{-- العمود الرئيسي --}}
{{-- بطاقة تفاصيل عامة --}}

بيانات الطلب

رقم الطلب
{{ $current->order_no }}
رقم الخدمة
{{ $current->service->service_no ?? '—' }}
تاريخ التقديم
{{ $current->created_at?->format('Y-m-d H:i') }}
عنوان الخدمة
{{ $current->service->title ?? '—' }}
وصف الخدمة
{{ $current->service->description ?? '—' }}
{{-- ================= بطاقة المرفقات + الردود ================= --}} {{-- ================= بطاقة المرفقات + الردود ================= --}} @if(($current->service->service_no ?? null) === '104598') {{-- ===== برنامج دعم الشهادة الاحترافية (شكل جديد مرتب) ===== --}}

برنامج دعم الشهادة الاحترافية

@php $reqStatusKey = $certRequest->request_status ?? 'pending'; $reqStatusMap = [ 'pending' => ['label' => 'طلب جديد', 'class' => 'kt-badge-outline'], 'under_review' => ['label' => 'قيد التحقق', 'class' => 'kt-badge-warning'], // جديد: 're_check' => ['label' => 'معاد للتحقق', 'class' => 'kt-badge-warning'], 're_complete' => ['label' => 'معاد للإستكمال', 'class' => 'kt-badge-warning'], 'approved' => ['label' => 'مقبول', 'class' => 'kt-badge-success'], 'rejected' => ['label' => 'مرفوض', 'class' => 'kt-badge-destructive'], ]; $reqBadge = $reqStatusMap[$reqStatusKey] ?? $reqStatusMap['pending']; $usedAttempts = (int) ($certRequest->attempt_number ?? 0); $maxAttempts = $this->certMaxAttempts ?? 3; $leftAttempts = max(0, $maxAttempts - $usedAttempts); $examStatusKey = $certRequest->exam_status ?? 'not_taken'; $examStatusMap = [ 'not_taken' => ['label' => 'لم يختبر بعد', 'class' => 'kt-badge-secondary'], 'scheduled' => ['label' => 'اختبار مجدول', 'class' => 'kt-badge-info'], 'passed' => ['label' => 'اجتاز الاختبار', 'class' => 'kt-badge-success'], 'failed' => ['label' => 'لم يجتز الاختبار','class' => 'kt-badge-destructive'], ]; $examBadge = $examStatusMap[$examStatusKey] ?? $examStatusMap['not_taken']; $firstAttemptText = $certRequest?->first_attempt_at ? optional($certRequest->first_attempt_at)->timezone('Asia/Riyadh')->format('Y-m-d H:i') : null; $secondAttemptText = $certRequest?->second_attempt_at ? optional($certRequest->second_attempt_at)->timezone('Asia/Riyadh')->format('Y-m-d H:i') : null; $banUntilText = $certRequest?->banned_until ? optional($certRequest->banned_until)->timezone('Asia/Riyadh')->format('Y-m-d H:i') : null; @endphp {{-- تنبيه الإيقاف المؤقت (سطر واحد ومرتب) --}} @if($this->certIsBanned && $banUntilText)
تم إيقاف دعم الشهادة مؤقتاً حتى {{ $banUntilText }}. يمكنك الاستمرار في إضافة الردود ورفع المرفقات، لكن معالجة الطلب قد تتأخر حتى انتهاء هذه الفترة.
@endif {{-- جدول معلومات برنامج الدعم (عمودين متجاوبين) --}}
{{-- الشهادة الاحترافية --}} {{-- حالة طلب الدعم --}} {{-- حالة الاختبار --}} {{-- نتيجة الاختبار --}} {{-- المحاولات (مسموحة / مستخدمة / متبقية) --}} {{-- موعد المحاولة الأولى --}} {{-- موعد المحاولة الثانية --}} {{-- الإيقاف المؤقت --}}
الشهادة الاحترافية @if(!$certRequest?->selected_certificate) {{-- لم يتم اختيار الشهادة بعد --}}
اختر شهادة احترافية واحدة، وبعد تأكيد الاختيار لا يمكن تغييرها إلا عن طريق فريق GOVI.
@error('selectedCertificate') {{ $message }} @enderror
جاري الحفظ...
@else {{-- تم اختيار الشهادة --}}
{{ $certRequest->selected_certificate }}
تم تثبيت اختيار الشهادة، ولا يمكن تعديله من قبل المتقدم.
@if($isStaff)
اضغط زر "حفظ إعدادات طلب الدعم" بالأسفل لحفظ التعديل.
@endif
@endif
حالة طلب دعم الشهادة
{{ $reqBadge['label'] }} @if($isStaff) @endif
حالة الاختبار
{{ $examBadge['label'] }} @if($isStaff) @endif
نتيجة الاختبار
{{ $certRequest->exam_result ?: '—' }}
@if($isStaff) @endif
عدد المحاولات
المسموح: {{ $maxAttempts }}
المستخدمة: {{ $usedAttempts }}
المتبقية: {{ $leftAttempts }}
@if($isStaff)
@endif
موعد المحاولة الأولى
{{ $firstAttemptText ?: 'لم يتم تحديد الموعد بعد' }}
@if($isStaff) @endif
موعد المحاولة الثانية
{{ $secondAttemptText ?: 'لم يتم تحديد الموعد بعد' }}
@if($isStaff) @endif
الإيقاف المؤقت للدعم
@if($banUntilText) {{ $banUntilText }} @else لا يوجد إيقاف مؤقت حاليًا. @endif
@if($isStaff) أثناء الإيقاف المؤقت قد يتم تعليق معالجة الطلب من فريق العمل. @endif
@if($isStaff && $certRequest)
جاري الحفظ...
@endif
{{-- ===== بطاقة مرفقات برنامج الدعم ===== --}}

مرفقات برنامج دعم الشهادة

@if(!$certRequest)
سيتم تفعيل المرفقات بعد اختيار الشهادة.
@else @php $lockedStatuses = ['cancelled','closed','completed','finished']; $isLockedStatus = in_array($current->status ?? '', $lockedStatuses, true); $lockedLabels = [ 'cancelled' => 'ملغي', 'closed' => 'مغلق', 'completed' => 'مكتمل', 'finished' => 'منتهية', ]; $lockedLabel = $lockedLabels[$current->status ?? 'closed'] ?? 'مغلق'; @endphp {{-- 🔒 نفس منطق الطلب العادي: لو الحالة مقفلة والعميل مو موظف → منع إضافة مرفقات جديدة --}} @if(!$isStaff && $isLockedStatus)
الطلب {{ $lockedLabel }} — لا يمكن إضافة مرفقات جديدة.
@else {{-- تنبيه الحظر (معلومة فقط) --}} @if($this->certIsBanned)
تنبيه: تم إيقاف دعم الشهادة مؤقتاً حتى {{ optional($certRequest->banned_until)->timezone('Asia/Riyadh')->format('Y-m-d H:i') }} . يمكنك رفع المرفقات كالمعتاد، لكن معالجة الطلب قد تتأخر حتى انتهاء فترة الإيقاف المؤقت.
@endif {{-- رفع مرفق --}}
@if(!$certFile) @endif
جاري تحميل ورفع الملف ...
@error('certFile') {{ $message }} @enderror @if (session()->has('success'))
{{ session('success') }}
@endif
@endif {{-- قائمة المرفقات (تظهر دائماً حتى لو الطلب مغلق) --}}
@php $atts = is_array($certRequest->attachments) ? $certRequest->attachments : (json_decode($certRequest->attachments, true) ?: []); @endphp @if(empty($atts))
لا توجد مرفقات.
@else @php $atts = collect($atts)->sortByDesc(function ($a) { $t = $a['ts'] ?? ($a['created_at'] ?? ($a['at'] ?? null)); if (is_numeric($t)) return (int) $t; if (!empty($t)) { try { return \Carbon\Carbon::parse($t, 'Asia/Riyadh')->timestamp; } catch (\Throwable $e) {} } $path = (string)($a['path'] ?? ''); if (preg_match('/(\d{8})_(\d{6})/', $path, $m)) { try { return \Carbon\Carbon::createFromFormat('YmdHis', $m[1].$m[2], 'Asia/Riyadh')->timestamp; } catch (\Throwable $e) {} } return 0; })->values()->all(); $idCandidates = []; foreach ($atts as $a) { if (isset($a['user_id']) && is_numeric($a['user_id'])) { $idCandidates[] = (int) $a['user_id']; } if (!empty($a['by'])) { $by = $a['by']; if (is_int($by)) { $idCandidates[] = $by; } elseif (is_string($by)) { if (ctype_digit($by)) { $idCandidates[] = (int) $by; } elseif (preg_match('/^user:(\d+)$/i', $by, $m)) { $idCandidates[] = (int) $m[1]; } } } } $idCandidates = array_values(array_unique(array_filter($idCandidates))); $userMap = collect(); if (!empty($idCandidates)) { $userMap = \App\Models\User::whereIn('id', $idCandidates) ->get(['id','name','role']) ->keyBy('id'); } $isSystem = fn($v) => is_string($v) && (strtolower($v) === 'system' || str_starts_with(strtolower($v), 'system_')); $isNumericString = fn($v) => is_string($v) && ctype_digit($v); @endphp
@foreach($atts as $a) @php $path = (string)($a['path'] ?? ''); $fullName = (string)($a['name'] ?? 'مرفق'); $shortName = \Illuminate\Support\Str::limit($fullName, 20, '…'); if ($path !== '' && preg_match('#^https?://#', $path)) { $url = $path; } else { $file = basename($path); $orderId = null; if (preg_match('#^/?(?:storage/)?orders/(\d+)/#', ltrim($path,'/'), $m)) { $orderId = (int) $m[1]; } if (\Illuminate\Support\Str::startsWith($file, ['certificate', 'شهادة'])) { $url = asset('storage/' . ltrim($path, '/')); } elseif ($orderId) { $url = route('files.show', ['order' => $orderId, 'file' => $file]); } else { $url = asset('storage/' . ltrim($path, '/')); } } $rawBy = $a['by'] ?? null; $uid = null; if (isset($a['user_id']) && is_numeric($a['user_id'])) { $uid = (int) $a['user_id']; } elseif (is_int($rawBy)) { $uid = $rawBy; } elseif ($isNumericString($rawBy)) { $uid = (int) $rawBy; } elseif (is_string($rawBy) && preg_match('/^user:(\d+)$/i', $rawBy, $m)) { $uid = (int) $m[1]; } if ($isSystem($rawBy)) { $authorText = 'system'; } elseif ($uid !== null && $userMap->has($uid)) { $u = $userMap->get($uid); $authorText = (strtolower($u->role ?? '') === 'customer') ? ($u->name ?: '—') : 'GOVI Support'; } else { $authorText = 'GOVI Support'; } $atRaw = $a['at'] ?? ($a['created_at'] ?? ($a['ts'] ?? null)); try { $at = $atRaw ? \Carbon\Carbon::parse($atRaw)->timezone('Asia/Riyadh')->format('Y-m-d H:i') : ''; } catch (\Exception $e) { $at = (is_numeric($atRaw) ? \Carbon\Carbon::createFromTimestamp((int)$atRaw, 'Asia/Riyadh')->format('Y-m-d H:i') : ''); } @endphp
{{ $shortName }}
{{ $authorText }} @if($at) @endif
@endforeach
@endif
@endif
{{-- ===== بطاقة الردود لبرنامج الدعم ===== --}}

محادثة برنامج دعم الشهادة

@if(!$certRequest)
سيتم فتح المحادثة بعد اختيار الشهادة.
@else @php $lockedStatuses = ['cancelled','closed','completed','finished']; $isLockedStatus = in_array($current->status ?? '', $lockedStatuses, true); $lockedLabels = [ 'cancelled' => 'ملغي', 'closed' => 'مغلق', 'completed' => 'مكتمل', 'finished' => 'منتهية', ]; $lockedLabel = $lockedLabels[$current->status ?? 'closed'] ?? 'مغلق'; @endphp {{-- تنبيه الحظر (المستخدم يمكنه الرد رغم ذلك إذا الحالة ليست مغلقة) --}} @if($this->certIsBanned)
تنبيه: تم إيقاف دعم الشهادة مؤقتاً حتى {{ optional($certRequest->banned_until)->timezone('Asia/Riyadh')->format('Y-m-d H:i') }} . يمكنك كتابة الردود وإرفاق الملفات، لكن قد يتم تأجيل معالجة الطلب حتى انتهاء هذه المدة.
@endif {{-- 🔒 نفس منطق الطلب العادي للردود --}} @if(!$isStaff && $isLockedStatus)
الطلب {{ $lockedLabel }} — لا يمكن إضافة ردود جديدة.
@else {{-- صندوق الردود --}}
@error('certReplyText') {{ $message }} @enderror
جاري الإرسال...
@endif {{-- قائمة الردود (تظهر دائماً) --}}
@php $notes = is_array($certRequest->notes) ? $certRequest->notes : (json_decode($certRequest->notes, true) ?: []); @endphp @if(empty($notes))
لا توجد ردود.
@else @php $notes = collect($notes)->sortByDesc(function ($n) { $t = $n['ts'] ?? ($n['created_at'] ?? ($n['at'] ?? null)); if (is_numeric($t)) return (int) $t; try { return \Carbon\Carbon::parse($t)->timestamp; } catch (\Exception $e) { return 0; } })->values()->all(); $ownerId = (int) ($certRequest->user_id ?? 0); $idCandidates = [$ownerId]; foreach ($notes as $n) { if (isset($n['user_id']) && is_numeric($n['user_id'])) { $idCandidates[] = (int) $n['user_id']; } if (!empty($n['by'])) { $by = $n['by']; if (is_int($by)) { $idCandidates[] = $by; } elseif (is_string($by)) { if (ctype_digit($by)) { $idCandidates[] = (int) $by; } elseif (preg_match('/^user:(\d+)$/i', $by, $m)) { $idCandidates[] = (int) $m[1]; } } } } $idCandidates = array_values(array_unique(array_filter($idCandidates))); $userMap = collect(); if (!empty($idCandidates)) { $userMap = \App\Models\User::whereIn('id', $idCandidates) ->get(['id','name','role']) ->keyBy('id'); } $isSystem = fn($v) => is_string($v) && (strtolower($v) === 'system' || str_starts_with(strtolower($v), 'system_')); $isNumericString = fn($v) => is_string($v) && ctype_digit($v); @endphp
@foreach($notes as $n) @php $rawBy = $n['by'] ?? null; $uid = null; if (isset($n['user_id']) && is_numeric($n['user_id'])) { $uid = (int) $n['user_id']; } elseif (is_int($rawBy)) { $uid = $rawBy; } elseif ($isNumericString($rawBy)) { $uid = (int) $rawBy; } elseif (is_string($rawBy) && preg_match('/^user:(\d+)$/i', $rawBy, $m)) { $uid = (int) $m[1]; } if ($isSystem($rawBy)) { $authorText = 'system'; } elseif ($uid !== null && $userMap->has($uid)) { $u = $userMap->get($uid); $authorText = (strtolower($u->role ?? '') === 'customer') ? ($u->name ?: '—') : 'GOVI Support'; } else { $authorText = 'GOVI Support'; } $atRaw = $n['at'] ?? ($n['created_at'] ?? ($n['ts'] ?? null)); try { $at = $atRaw ? \Carbon\Carbon::parse($atRaw)->timezone('Asia/Riyadh')->format('Y-m-d H:i') : ''; } catch (\Exception $e) { $at = (is_numeric($atRaw) ? \Carbon\Carbon::createFromTimestamp((int)$atRaw, 'Asia/Riyadh')->format('Y-m-d H:i') : ''); } @endphp
{{ $n['body'] ?? '' }}
{{ $authorText }} @if($at) @endif
@endforeach
@endif
@endif
@else {{-- بطاقة المرفقات --}}

المرفقات

{{-- رفع مرفق --}} @if ($isStaff || !in_array($current->status ?? '', ['cancelled','closed','completed','finished'], true))
{{-- زر اختر ملف (primary) يختفي أثناء/بعد اختيار الملف المؤقت --}} @if(!$file) @endif {{-- تحميل الملف المؤقت --}}
جاري تحميل ورفع الملف ...
{{-- بعد اكتمال الرفع المؤقت --}} @if($file) @endif @error('file') {{ $message }} @enderror
@if (session()->has('success'))
{{ session('success') }}
@endif
@else
@php $lockedLabels = ['cancelled'=>'ملغي','closed'=>'مغلق','completed'=>'مكتمل','finished'=>'منتهية']; $label = $lockedLabels[$current->status ?? 'closed'] ?? 'مغلق'; @endphp الطلب {{ $label }} — لا يمكن إضافة مرفقات جديدة.
@endif {{-- قائمة المرفقات --}} {{-- قائمة المرفقات --}}
@php // فكّ المرفقات لأي شكل (array/JSON) $atts = is_array($current->attachments) ? $current->attachments : (json_decode($current->attachments, true) ?: []); @endphp @if(empty($atts))
لا توجد مرفقات.
@else @php // ترتيب تنازلي بالزمن: ts | created_at | at | التاريخ داخل الاسم (YYYYMMDD_HHMMSS) $atts = collect($atts)->sortByDesc(function ($a) { $t = $a['ts'] ?? ($a['created_at'] ?? ($a['at'] ?? null)); if (is_numeric($t)) return (int)$t; if (!empty($t)) { try { return \Carbon\Carbon::parse($t, 'Asia/Riyadh')->timestamp; } catch (\Throwable $e) {} } $path = (string)($a['path'] ?? ''); if (preg_match('/(\d{8})_(\d{6})/', $path, $m)) { try { return \Carbon\Carbon::createFromFormat('YmdHis', $m[1].$m[2], 'Asia/Riyadh')->timestamp; } catch (\Throwable $e) {} } return 0; })->values()->all(); // اجمع كل الـ IDs المحتملة لجلب الأسماء والأدوار مرة واحدة $idCandidates = []; foreach ($atts as $a) { if (isset($a['user_id']) && is_numeric($a['user_id'])) { $idCandidates[] = (int) $a['user_id']; } if (!empty($a['by'])) { $by = $a['by']; if (is_int($by)) { $idCandidates[] = $by; } elseif (is_string($by)) { if (ctype_digit($by)) { $idCandidates[] = (int) $by; } elseif (preg_match('/^user:(\d+)$/i', $by, $m)) { $idCandidates[] = (int) $m[1]; } } } } $idCandidates = array_values(array_unique(array_filter($idCandidates))); // جلب الاسم + الدور مرة واحدة $userMap = collect(); if (!empty($idCandidates)) { $userMap = \App\Models\User::whereIn('id', $idCandidates) ->get(['id','name','role']) ->keyBy('id'); } // Helpers $isSystem = fn($v) => is_string($v) && (strtolower($v) === 'system' || str_starts_with(strtolower($v), 'system_')); $isEmail = fn($v) => is_string($v) && str_contains($v, '@'); $isNumericString = fn($v) => is_string($v) && ctype_digit($v); @endphp
@foreach($atts as $a) @php // بناء رابط التحميل/المشاهدة $path = (string)($a['path'] ?? ''); $fullName = (string)($a['name'] ?? 'مرفق'); $shortName = \Illuminate\Support\Str::limit($fullName, 20, '…'); if ($path !== '' && preg_match('#^https?://#', $path)) { // رابط خارجي $url = $path; } else { // اسم الملف + رقم الطلب من المسار orders/{id}/... $file = basename($path); $orderId = null; if (preg_match('#^/?(?:storage/)?orders/(\d+)/#', ltrim($path,'/'), $m)) { $orderId = (int)$m[1]; } if (\Illuminate\Support\Str::startsWith($file, ['certificate', 'شهادة'])) { // شهادات: افتح مباشرة $url = asset('storage/' . ltrim($path, '/')); } elseif ($orderId) { // غير الشهادات داخل مجلد الطلب: عبر الراوت الآمن $url = route('files.show', ['order' => $orderId, 'file' => $file]); } else { // أي مسار عام آخر $url = asset('storage/' . ltrim($path, '/')); } } // تحديد الرافع (by) -> اسم $rawBy = $a['by'] ?? null; $uid = null; if (isset($a['user_id']) && is_numeric($a['user_id'])) { $uid = (int) $a['user_id']; } elseif (is_int($rawBy)) { $uid = $rawBy; } elseif ($isNumericString($rawBy)) { $uid = (int) $rawBy; } elseif (is_string($rawBy) && preg_match('/^user:(\d+)$/i', $rawBy, $m)) { $uid = (int) $m[1]; } if ($isSystem($rawBy)) { $authorText = 'system'; } elseif ($uid !== null && $userMap->has($uid)) { $u = $userMap->get($uid); // نعرض الاسم فقط إذا role = customer $authorText = (strtolower($u->role ?? '') === 'customer') ? ($u->name ?: '—') : 'GOVI Support'; } else { // أي قيمة أخرى (staff/admin/email/نص حر) => فريق $authorText = 'GOVI Support'; } // تنسيق الوقت $atRaw = $a['at'] ?? ($a['created_at'] ?? ($a['ts'] ?? null)); try { $at = $atRaw ? \Carbon\Carbon::parse($atRaw)->timezone('Asia/Riyadh')->format('Y-m-d H:i') : ''; } catch (\Exception $e) { $at = (is_numeric($atRaw) ? \Carbon\Carbon::createFromTimestamp((int)$atRaw, 'Asia/Riyadh')->format('Y-m-d H:i') : ''); } @endphp
{{ $shortName }}
{{ $authorText }} @if($at) @endif
@endforeach
@endif
{{-- بطاقة الردود --}}

الردود

@if ($isStaff || !in_array($current->status ?? '', ['cancelled','closed','completed','finished'], true))
@error('replyText') {{ $message }} @enderror
جاري الإرسال...
@else
@php $lockedLabels = [ 'cancelled' => 'ملغي', 'closed' => 'مغلق', 'completed' => 'مكتمل', 'finished' => 'منتهية', ]; $label = $lockedLabels[$current->status ?? 'closed'] ?? 'مغلق'; @endphp الطلب {{ $label }} — لا يمكن إضافة ردود جديدة.
@endif {{-- قائمة الردود --}} {{-- قائمة الردود --}}
@php // فكّ الملاحظات لأي شكل (array/JSON) $notes = is_array($current->notes) ? $current->notes : (json_decode($current->notes, true) ?: []); @endphp @if(empty($notes))
لا توجد ردود.
@else
@php // ترتيب الأحدث أولاً $notes = collect($notes)->sortByDesc(function ($n) { $t = $n['ts'] ?? ($n['created_at'] ?? ($n['at'] ?? null)); if (is_numeric($t)) return (int) $t; try { return \Carbon\Carbon::parse($t)->timestamp; } catch (\Exception $e) { return 0; } })->values()->all(); // نجمع كل الـ IDs المحتملة من الملاحظات $ownerId = (int) ($current->user->id ?? $current->user_id ?? 0); $idCandidates = [$ownerId]; foreach ($notes as $n) { if (isset($n['user_id']) && is_numeric($n['user_id'])) { $idCandidates[] = (int) $n['user_id']; } if (!empty($n['by'])) { $by = $n['by']; if (is_int($by)) { $idCandidates[] = $by; } elseif (is_string($by)) { if (ctype_digit($by)) { $idCandidates[] = (int) $by; } elseif (preg_match('/^user:(\d+)$/i', $by, $m)) { $idCandidates[] = (int) $m[1]; } } } } $idCandidates = array_values(array_unique(array_filter($idCandidates))); // نجلب الاسم + الدور مرة وحدة $userMap = collect(); if (!empty($idCandidates)) { $userMap = \App\Models\User::whereIn('id', $idCandidates) ->get(['id','name','role']) ->keyBy('id'); } // Helpers $isSystem = fn($v) => is_string($v) && (strtolower($v) === 'system' || str_starts_with(strtolower($v), 'system_')); $isEmail = fn($v) => is_string($v) && str_contains($v, '@'); $isNumericString = fn($v) => is_string($v) && ctype_digit($v); @endphp @foreach($notes as $n) @php $rawBy = $n['by'] ?? null; // تحديد الـ UID (إن وُجد) $uid = null; if (isset($n['user_id']) && is_numeric($n['user_id'])) { $uid = (int) $n['user_id']; } elseif (is_int($rawBy)) { $uid = $rawBy; } elseif ($isNumericString($rawBy)) { $uid = (int) $rawBy; } elseif (is_string($rawBy) && preg_match('/^user:(\d+)$/i', $rawBy, $m)) { $uid = (int) $m[1]; } // تحديد نص المرسل حسب الدور if ($isSystem($rawBy)) { $authorText = 'system'; } elseif ($uid !== null && $userMap->has($uid)) { $u = $userMap->get($uid); // نعرض الاسم فقط إذا role = customer $authorText = (strtolower($u->role ?? '') === 'customer') ? ($u->name ?: '—') : 'GOVI Support'; } else { // أي قيمة أخرى (staff/admin/email/نص حر) => فريق $authorText = 'GOVI Support'; } // تنسيق الوقت $atRaw = $n['at'] ?? ($n['created_at'] ?? ($n['ts'] ?? null)); try { $at = $atRaw ? \Carbon\Carbon::parse($atRaw)->timezone('Asia/Riyadh')->format('Y-m-d H:i') : ''; } catch (\Exception $e) { $at = (is_numeric($atRaw) ? \Carbon\Carbon::createFromTimestamp((int)$atRaw, 'Asia/Riyadh')->format('Y-m-d H:i') : ''); } @endphp
{{ $n['body'] ?? '' }}
{{ $authorText }} @if($at) @endif
@endforeach
@endif
@endif
{{-- العمود الجانبي (ملخص الطلب + أدوات الموظف/الفاتورة) --}}
{{-- ملخص الطلب --}}

ملخص الطلب

@php $s = $statusMap[$current->status] ?? ['label' => $current->status, 'class' => 'kt-badge-outline']; $i = $invoiceMap[$current->invoice_status] ?? ['label' => $current->invoice_status, 'class' => 'kt-badge-outline']; @endphp
رقم الطلب {{ $current->order_no }}
رقم الخدمة {{ $current->service->service_no ?? '—' }}
الحالة {{ $s['label'] }}
حالة الفاتورة {{ $i['label'] }}
@if(($current->service->service_no ?? null) === '104598' && $certRequest) @php $usedAttempts = (int) ($certRequest->attempt_number ?? 0); $maxAttempts = $this->certMaxAttempts ?? 3; $leftAttempts = max(0, $maxAttempts - $usedAttempts); @endphp
Selected certificate {{ $certRequest->selected_certificate ?: '—' }}
المحاولات المتبقية للاختبار {{ $leftAttempts }} / {{ $maxAttempts }}
@endif @if(($current->invoice_status ?? null) === 'issued' && ($current->bill ?? 0) > 0)
مبلغ الفاتورة {{ number_format($current->bill, 2) }} ر.س
@endif
{{-- ===== Apple Pay Button ===== --}}
@endif

{{-- فورم الدفع (Moyasar) --}} @if($showPayForm && $isOwner && ($current->invoice_status === 'issued') && ($current->bill ?? 0) > 0)

إتمام الدفع

المبلغ المستحق: {{ number_format($current->bill, 2) }} ر.س
@error('customer_name') {{ $message }} @enderror @error('card_number') {{ $message }} @enderror
@error('expiry_month') {{ $message }} @enderror @error('expiry_year') {{ $message }} @enderror @error('cvc') {{ $message }} @enderror
جاري تحويلك لبوابة الدفع...
تتم معالجة الدفع عبر Moyasar وفق معايير أمان عالية.
@endif {{-- بطاقات مرتبطة (للموظفين فقط) --}} @if($isStaff) {{-- بطاقة: هل هناك طلبات أخرى لنفس الخدمة لنفس المستخدم؟ --}}

طلبات أخرى لنفس الخدمة (لنفس المستخدم)

@if (empty($sameServiceOrders))
لا يوجد طلب لنفس الخدمة للمستخدم.
@else {{-- عرض مبسّط ومتجاوب: رقم الطلب + زر عرض + وصف صغير لاسم الخدمة --}}
@foreach($sameServiceOrders as $o)
{{ $o['order_no'] }}
{{ \Illuminate\Support\Str::limit($o['title'] ?? '—', 60, '…') }}
@endforeach
@endif
{{-- بطاقة: طلبات نفس المستخدم لخدمات أخرى --}}

طلبات أخرى لنفس المستخدم (خدمات مختلفة)

@if (empty($otherServiceOrders))
لا يوجد طلبات لنفس المستخدم في خدمات أخرى.
@else {{-- عرض مبسّط ومتجاوب: رقم الطلب + زر عرض + وصف صغير لاسم الخدمة --}}
@foreach($otherServiceOrders as $o)
{{ $o['order_no'] }}
{{ \Illuminate\Support\Str::limit($o['title'] ?? '—', 60, '…') }}
@endforeach
@endif
@endif {{-- أدوات الموظف (تظهر فقط للموظفين) --}} @if($isStaff)

إدارة الطلب (للموظفين)

جاري التحديث...
@can('InvoiceOrders')
@if(($current->invoice_status ?? 'not_issued') === 'issued')
مبلغ الفاتورة الحالي: {{ number_format($current->bill ?? 0, 2) }}
جاري الإلغاء...
@else @error('invoiceAmount') {{ $message }} @enderror
جاري الإصدار...
@endif
@endcan
@if($isStaff) @if(($current->service->service_no ?? null) === '104598') @can('CertSupport')
@endcan @endif @endif @if($isStaff && ($current->service->service_no ?? null) == '173323' && !in_array($current->status, ['cancelled','closed'])) @can('CertGOVI')
@error('certName') {{ $message }} @enderror @error('certMajor') {{ $message }} @enderror
{{-- فئة حامل الوثيقة --}} @error('certCategory') {{ $message }} @enderror {{-- نوع الوثيقة --}} @error('certDocType') {{ $message }} @enderror
@php $mno = $current->user->membership_no ?? $current->user->member_no ?? ('USR-'.$current->user->id); @endphp
رقم العضوية (سيُطبع تلقائياً): {{ $mno }}
جاري التوليد...
@endcan @endif @endif
@endif
@if(!empty($cleanUrl) && $cleanUrl !== request()->fullUrl()) @endif