getFilteredConsultations()->count(); if ($count === 0) { $this->dispatch('notify', type: 'info', message: __('export.no_consultations_match')); return null; } $locale = auth()->user()->preferred_language ?? 'ar'; return response()->streamDownload(function () use ($locale) { // UTF-8 BOM for Excel Arabic support echo "\xEF\xBB\xBF"; $csv = Writer::createFromString(); // Headers based on admin language $csv->insertOne([ __('export.client_name', [], $locale), __('export.date', [], $locale), __('export.time', [], $locale), __('export.consultation_type', [], $locale), __('export.status', [], $locale), __('export.payment_status', [], $locale), __('export.problem_summary', [], $locale), ]); $this->getFilteredConsultations()->cursor()->each(function ($consultation) use ($csv, $locale) { $csv->insertOne([ $consultation->user->full_name, $consultation->booking_date->format('Y-m-d'), $consultation->booking_time, __('export.type_'.$consultation->consultation_type->value, [], $locale), __('export.status_'.$consultation->status->value, [], $locale), $this->getPaymentStatusLabel($consultation->payment_status, $locale), $consultation->problem_summary, ]); }); echo $csv->toString(); }, 'consultations-export-'.now()->format('Y-m-d').'.csv', [ 'Content-Type' => 'text/csv; charset=UTF-8', ]); } public function exportPdf(): ?StreamedResponse { $consultations = $this->getFilteredConsultations()->get(); if ($consultations->isEmpty()) { $this->dispatch('notify', type: 'info', message: __('export.no_consultations_match')); return null; } if ($consultations->count() > 500) { $this->dispatch('notify', type: 'warning', message: __('export.large_export_warning')); } $locale = auth()->user()->preferred_language ?? 'ar'; $pdf = Pdf::loadView('pdf.consultations-export', [ 'consultations' => $consultations, 'locale' => $locale, 'generatedAt' => now(), 'filters' => $this->getActiveFilters(), 'totalCount' => $consultations->count(), ]); $pdf->setOption('isHtml5ParserEnabled', true); $pdf->setOption('defaultFont', 'DejaVu Sans'); return response()->streamDownload( fn () => print($pdf->output()), 'consultations-export-'.now()->format('Y-m-d').'.pdf' ); } public function clearFilters(): void { $this->consultationType = 'all'; $this->status = 'all'; $this->paymentStatus = 'all'; $this->dateFrom = ''; $this->dateTo = ''; } public function with(): array { return [ 'consultationTypes' => [ 'all' => __('export.all_consultation_types'), 'free' => __('export.type_free'), 'paid' => __('export.type_paid'), ], 'statuses' => [ 'all' => __('export.all_statuses'), 'pending' => __('export.status_pending'), 'approved' => __('export.status_approved'), 'completed' => __('export.status_completed'), 'cancelled' => __('export.status_cancelled'), 'no_show' => __('export.status_no_show'), 'rejected' => __('export.status_rejected'), ], 'paymentStatuses' => [ 'all' => __('export.all_payment_statuses'), 'pending' => __('export.payment_pending'), 'received' => __('export.payment_received'), 'na' => __('export.payment_not_applicable'), ], 'previewCount' => $this->getFilteredConsultations()->count(), ]; } private function getFilteredConsultations() { return Consultation::query() ->with('user:id,full_name') ->when($this->consultationType !== 'all', fn ($q) => $q->where('consultation_type', $this->consultationType)) ->when($this->status !== 'all', fn ($q) => $q->where('status', $this->status)) ->when($this->paymentStatus !== 'all', fn ($q) => $q->where('payment_status', $this->paymentStatus)) ->when($this->dateFrom, fn ($q) => $q->whereDate('booking_date', '>=', $this->dateFrom)) ->when($this->dateTo, fn ($q) => $q->whereDate('booking_date', '<=', $this->dateTo)) ->orderBy('booking_date', 'desc'); } private function getActiveFilters(): array { $filters = []; if ($this->consultationType !== 'all') { $filters['consultation_type'] = __('export.type_'.$this->consultationType); } if ($this->status !== 'all') { $filters['status'] = __('export.status_'.$this->status); } if ($this->paymentStatus !== 'all') { $filters['payment_status'] = $this->getPaymentStatusLabel(PaymentStatus::from($this->paymentStatus)); } if ($this->dateFrom) { $filters['date_from'] = $this->dateFrom; } if ($this->dateTo) { $filters['date_to'] = $this->dateTo; } return $filters; } private function getPaymentStatusLabel(PaymentStatus $status, ?string $locale = null): string { return match ($status) { PaymentStatus::Pending => __('export.payment_pending', [], $locale), PaymentStatus::Received => __('export.payment_received', [], $locale), PaymentStatus::NotApplicable => __('export.payment_not_applicable', [], $locale), }; } }; ?>
{{ __('export.export_consultations') }} {{ __('export.export_consultations_description') }}
{{ __('export.filters_applied') }}
@foreach ($consultationTypes as $value => $label) {{ $label }} @endforeach
@foreach ($statuses as $value => $label) {{ $label }} @endforeach
@foreach ($paymentStatuses as $value => $label) {{ $label }} @endforeach
@if ($consultationType !== 'all' || $status !== 'all' || $paymentStatus !== 'all' || $dateFrom || $dateTo)
{{ __('export.clear_filters') }}
@endif
{{ __('export.total_records') }}: {{ $previewCount }}
{{ __('export.export_csv') }} {{ __('export.exporting') }} {{ __('export.export_pdf') }} {{ __('export.exporting') }}
@if ($previewCount === 0)
{{ __('export.no_consultations_match') }}
@endif