subMonth(); $curr = self::calculate($now); $past = self::calculate($prev); return [ 'pendapatan' => $curr['income'], 'pendapatan_grow' => self::growth($curr['income'], $past['income']), 'masuk_count' => $curr['total'], 'masuk_grow' => self::growth($curr['total'], $past['total']), 'selesai_count' => $curr['done'], 'selesai_grow' => self::growth($curr['done'], $past['done']), 'batal_count' => $curr['cancel'], 'batal_grow' => self::growth($curr['cancel'], $past['cancel']), ]; } private static function calculate($date) { $m = $date->month; $y = $date->year; // Gabungan query Buket & Foto return [ 'income' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_transaksi', 'diterima')->sum('total_bayar') + BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_booking', 'diterima')->sum('total_bayar'), 'total' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->count() + BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->count(), 'done' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_transaksi', 'selesai')->count() + BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_booking', 'selesai')->count(), 'cancel' => TransaksiBuket::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_transaksi', 'ditolak')->count() + BookingFoto::whereMonth('created_at', $m)->whereYear('created_at', $y)->where('status_booking', 'ditolak')->count(), ]; } private static function growth($current, $previous) { if ($previous <= 0) return $current > 0 ? 100 : 0; return round((($current - $previous) / $previous) * 100, 1); } }