Files
ilycats/app/Exports/TreatmentExport.php
T

142 lines
4.4 KiB
PHP
Raw Normal View History

2026-09-23 12:45:02 +07:00
<?php
namespace App\Exports;
use App\Models\Treatment;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class TreatmentExport implements FromQuery, WithHeadings, WithMapping, WithStyles, ShouldAutoSize
{
protected $request;
public function __construct($request)
{
// Kita bisa menerima objek Request atau Query Builder hasil clone dari Controller
$this->request = $request;
}
/**
* Query data dengan filter yang sinkron dengan tampilan UI
*/
public function query()
{
$query = Treatment::query()->with(['cat', 'user', 'details.medicine']);
// Filter 1: Pencarian Nama Kucing
if ($this->request->filled('search')) {
$query->whereHas('cat', function($q) {
$q->where('nama_kucing', 'like', '%' . $this->request->search . '%');
});
}
// Filter 2: Nama PIC (Staf)
if ($this->request->filled('pic_id')) {
$query->where('user_id', $this->request->pic_id);
}
// Filter 3: Rentang Tanggal
if ($this->request->filled('start_date') && $this->request->filled('end_date')) {
$query->whereBetween('tanggal', [$this->request->start_date, $this->request->end_date]);
}
// Filter 4: Kondisi (Healthy / Under Treatment)
if ($this->request->filled('status')) {
$query->whereHas('cat', function($q) {
$q->where('treatment_status', $this->request->status);
});
}
return $query->latest('tanggal');
}
/**
* Header Tabel Excel
*/
public function headings(): array
{
return [
"TANGGAL",
"NAMA KUCING",
"STATUS KESEHATAN",
"KELUHAN",
"DIAGNOSA & TINDAKAN",
"DAFTAR OBAT (QTY)",
"DOSIS & KET",
"PIC / STAF"
];
}
/**
* Transformasi Data per Baris
*/
public function map($t): array
{
// Menggabungkan daftar obat menjadi satu string jika ada multi-medicine
$medicineList = $t->details->map(function($d) {
$namaObat = $d->medicine->nama_obat ?? 'Obat Terhapus';
return "{$namaObat} ({$d->qty_used})";
})->implode(", ");
// Jika data detail kosong, gunakan data fallback (legacy support)
if ($medicineList === "") {
$medicineList = $t->nama_obat ? "{$t->nama_obat} ({$t->qty_used})" : "-";
}
// Mengambil deskripsi dosis/keterangan dari detail pertama atau header
$dosisKet = $t->details->map(function($d) {
return "{$d->dosis} [{$d->keterangan}]";
})->implode(" | ");
return [
$t->tanggal->format('d/m/Y'),
$t->cat->nama_kucing ?? 'N/A',
($t->cat->treatment_status == 1) ? 'UNDER TREATMENT' : 'HEALTHY',
$t->keluhan,
$t->diagnosa,
$medicineList,
$dosisKet ?: $t->dosis,
$t->user->name ?? 'System'
];
}
/**
* Memberikan Styling pada file Excel
*/
public function styles(Worksheet $sheet)
{
return [
// Style Header (Baris 1)
1 => [
'font' => [
'bold' => true,
'color' => ['rgb' => 'FFFFFF'],
'size' => 11
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['rgb' => '4F46E5'] // Indigo-600
],
'alignment' => [
'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
],
],
// Memberikan border ke seluruh data yang ada
'A1:H' . ($sheet->getHighestRow()) => [
'borders' => [
'allBorders' => [
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
'color' => ['rgb' => 'E2E8F0'], // Slate-200
],
],
],
];
}
}