Files
ilycats/app/Http/Controllers/DashboardController.php
T
2026-02-08 15:16:35 +07:00

88 lines
3.5 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\{Cat, Medicine, Food, Supply, Matting, Treatment};
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class DashboardController extends Controller
{
public function index()
{
// 1. Statistik Utama
$stats = [
'total_cats' => Cat::count(),
'total_staff' => \App\Models\User::count(),
'sick_cats' => Cat::whereNotNull('riwayat_sakit_terakhir')->count(),
'total_mating' => Matting::where('status', 'proses')->count(),
];
// 2. Birth Watch: Persalinan 7 Hari ke Depan (Rumus: H+63)
$upcomingBirths = Matting::with(['dam', 'sire', 'pic'])
->where('status', 'proses')
->whereNotNull('tanggal_kawin')
->whereBetween('tanggal_kawin', [
now()->subDays(70)->toDateString(),
now()->subDays(56)->toDateString()
])
->get()
->map(function ($mating) {
$mating->edd = Carbon::parse($mating->tanggal_kawin)->addDays(63);
$mating->days_to_go = (int) now()->diffInDays($mating->edd, false);
return $mating;
})
->filter(fn($m) => $m->days_to_go >= -2 && $m->days_to_go <= 7)
->sortBy('days_to_go');
// 3. Medical Alerts
$medicalAlerts = [
'vaccine' => Cat::whereNotNull('jadwal_vaksin')->where('jadwal_vaksin', '<=', now()->addDays(3))->count(),
'flea' => Cat::whereNotNull('jadwal_obat_kutu')->where('jadwal_obat_kutu', '<=', now()->addDays(3))->count(),
'deworming' => Cat::whereNotNull('jadwal_obat_cacing')->where('jadwal_obat_cacing', '<=', now()->addDays(3))->count(),
'grooming' => Cat::whereNotNull('jadwal_grooming')->where('jadwal_grooming', '<=', now()->addDays(3))->count(),
];
// 4. Inventory Critical (Stok < 5)
$lowStock = [
'medicines' => Medicine::where('qty', '<', 5)->get(['nama_obat as name', 'qty', 'unit']),
'foods' => Food::where('qty', '<', 5)->get(['nama_makanan as name', 'qty', 'unit']),
'supplies' => Supply::where('qty', '<', 5)->get(['nama_perlengkapan as name', 'qty', 'unit']),
];
$totalLowStock = collect($lowStock)->flatten(1)->count();
// 5. Chart Data: Sebaran Ras (Persian, British Shorthair, dll)
$chartData = Cat::select('ras', DB::raw('count(*) as total'))->groupBy('ras')->get();
// 6. Weight Trends: Rata-rata Berat (6 Bulan Terakhir)
$weightTrends = DB::table('weight_histories')
->select(
DB::raw('AVG(berat) as avg_weight'),
DB::raw("DATE_FORMAT(tanggal_timbang, '%M') as month"),
DB::raw('MONTH(tanggal_timbang) as month_num')
)
->where('tanggal_timbang', '>=', now()->subMonths(6))
->groupBy('month', 'month_num')
->orderBy('month_num')
->get();
if ($weightTrends->isEmpty()) {
$weightTrends = collect([(object)['month' => now()->format('F'), 'avg_weight' => 0]]);
}
// 7. Recent Activity
$recentTreatments = Treatment::with(['cat', 'pic'])->latest()->take(5)->get();
return view('pages.dashboard.index', compact(
'stats',
'upcomingBirths',
'medicalAlerts',
'lowStock',
'totalLowStock',
'chartData',
'weightTrends',
'recentTreatments'
));
}
}