kjcDashboardRepository = $kjcDashboardRepository; } /** * Get total KJC assets count */ public function getTotalAssets(array $filters = [], $user = null): int { return $this->kjcDashboardRepository->getTotalHoldings($filters, $user); } /** * Get operational KJC assets count (BP status) */ public function getOperationalAssets(array $filters = [], $user = null): int { $holdings = $this->kjcDashboardRepository->getHoldingsBySpecificStatus('BP', $filters, $user); return $holdings['pagination']['total']; } /** * Get under repair KJC assets count (BDG status) */ public function getUnderRepairAssets(array $filters = [], $user = null): int { $holdings = $this->kjcDashboardRepository->getHoldingsBySpecificStatus('BDG', $filters, $user); return $holdings['pagination']['total']; } /** * Get maintenance due KJC assets count (TBDG status) */ public function getMaintenanceDueAssets(array $filters = [], $user = null): int { $holdings = $this->kjcDashboardRepository->getHoldingsBySpecificStatus('TBDG', $filters, $user); return $holdings['pagination']['total']; } /** * Get active KJC repairs count */ public function getActiveRepairs(array $filters = []): int { $query = KJCRepair::whereIn('status', ['pending', 'in_progress']); $this->applyCommonFilters($query, $filters); return $query->count(); } /** * Get pending KJC reports count */ public function getPendingReports(array $filters = []): int { $query = KJCReport::where('status', 'pending'); $this->applyCommonFilters($query, $filters); return $query->count(); } /** * Get KJC entitlement vs holdings pie chart */ public function getEntitlementVsHoldingsPieChart(array $filters = [], $user = null): array { // Get total entitlement $totalEntitlement = $this->kjcDashboardRepository->getTotalEntitlement($filters, $user); // Get total holdings $totalHoldings = $this->kjcDashboardRepository->getTotalHoldings($filters, $user); // Prepare data for pie chart (only showing Perjawatan and Pegangan) $data = [ [ 'name' => 'Perjawatan', 'value' => $totalEntitlement, 'color' => '#4caf50' ], [ 'name' => 'Pegangan', 'value' => $totalHoldings, 'color' => '#2196f3' ] ]; return $this->formatPieChartData( 'Perjawatan vs Pegangan KJC', $data, '/v1/dashboard/kjc/drill-down/entitlement-vs-holdings', ['type'] ); } /** * Get KJC holdings status breakdown pie chart */ public function getHoldingsStatusBreakdownPieChart(array $filters = [], $user = null): array { $statusCounts = $this->kjcDashboardRepository->getHoldingsByStatus($filters, $user); $statusNames = [ 'BP' => 'BP', 'BDG' => 'BDG', 'TBDG' => 'TBDG', 'BT' => 'BT', 'TBT' => 'TBT', 'BG' => 'BG', 'TBG' => 'TBG', ]; $data = []; foreach ($statusCounts as $item) { $statusCode = $item['status']; if ($statusCode === null || $statusCode === '') { $statusName = 'Belum Diberi Status'; } else { $statusName = $statusNames[$statusCode] ?? $statusCode; } $data[] = [ 'name' => $statusName, 'value' => $item['count'], 'percentage' => 0, 'status_code' => $statusCode, ]; } // Calculate percentages $total = array_sum(array_column($data, 'value')); foreach ($data as &$row) { $row['percentage'] = $total > 0 ? round(($row['value'] / $total) * 100, 2) : 0; } return $this->formatPieChartData( 'KJC Status Pegangan', $data, '/v1/dashboard/kjc/drill-down/holdings-status', ['status'] ); } /** * Get KJC unit performance chart */ public function getUnitPerformanceChart(array $filters = []): array { $units = Unit::withCount([ 'kjcAssetHoldings as bp_count' => function ($query) use ($filters) { $query->where('status', 'BP'); $this->applyCommonFilters($query, $filters); }, 'kjcAssetHoldings as bdg_count' => function ($query) use ($filters) { $query->where('status', 'BDG'); $this->applyCommonFilters($query, $filters); }, 'kjcAssetHoldings as tbdg_count' => function ($query) use ($filters) { $query->where('status', 'TBDG'); $this->applyCommonFilters($query, $filters); } ])->get(); $unitNames = []; $bpCounts = []; $bdgCounts = []; $tbdgCounts = []; foreach ($units as $unit) { $unitNames[] = $unit->name; $bpCounts[] = $unit->bp_count; $bdgCounts[] = $unit->bdg_count; $tbdgCounts[] = $unit->tbdg_count; } return $this->formatBarChartData( 'KJC Unit 2025', [ ['name' => 'Baik dalam Perhatian (BP)', 'data' => $bpCounts], ['name' => 'Boleh Digunakan (BDG)', 'data' => $bdgCounts], ['name' => 'Tidak Boleh Digunakan (TBDG)', 'data' => $tbdgCounts] ], $unitNames, '/v1/dashboard/kjc/drill-down/unit-performance', ['unit_id'] ); } /** * Get KJC monthly trends chart */ public function getMonthlyTrendsChart(array $filters = [], $user = null): array { $dateRange = $this->getDateRange($filters); $categories = $this->getMonthlyCategories($filters); $monthlyData = $this->kjcDashboardRepository->getMonthlyTrends($filters, $user); // Initialize data arrays $bpData = array_fill(0, count($categories), 0); $bdgData = array_fill(0, count($categories), 0); $tbdgData = array_fill(0, count($categories), 0); // Fill data arrays foreach ($monthlyData as $item) { $index = array_search($item['month'], $categories); if ($index !== false) { switch ($item['status']) { case 'BP': $bpData[$index] = $item['count']; break; case 'BDG': $bdgData[$index] = $item['count']; break; case 'TBDG': $tbdgData[$index] = $item['count']; break; } } } return $this->formatLineChartData( 'KJC Trend Bulanan 2025', [ ['name' => 'Baik dalam Perhatian (BP)', 'data' => $bpData], ['name' => 'Boleh Digunakan (BDG)', 'data' => $bdgData], ['name' => 'Tidak Boleh Digunakan (TBDG)', 'data' => $tbdgData] ], $categories, '/v1/dashboard/kjc/drill-down/monthly-trends', ['month', 'status'] ); } /** * Get KJC historical metrics bar chart (KEUPAYAAN, KESIAGAAN, SERVISIBILITI) */ public function getHistoricalMetricsBarChart(array $filters = [], $user = null): array { $monthlyData = $this->kjcDashboardRepository->getHistoricalMetricsByMonth($filters, $user); // Extract data for chart $categories = []; $keupayaanData = []; $kesiagaanData = []; $servisibilitiData = []; foreach ($monthlyData as $data) { $monthDate = Carbon::createFromFormat('Y-m', $data['month']); $categories[] = $monthDate->format('M'); // Remove year from categories $keupayaanData[] = $data['keupayaan']; $kesiagaanData[] = $data['kesiagaan']; $servisibilitiData[] = $data['servisibiliti']; } // Use year from user selection (date_from/date_to) or fall back to current year $year = Carbon::now()->year; if (!empty($filters['date_from'])) { $year = Carbon::parse($filters['date_from'])->year; } elseif (!empty($filters['date_to'])) { $year = Carbon::parse($filters['date_to'])->year; } return $this->formatBarChartData( "Metrik Tahunan KJC {$year}", [ ['name' => 'KEUPAYAAN (%)', 'data' => $keupayaanData], ['name' => 'KESIAGAAN (%)', 'data' => $kesiagaanData], ['name' => 'SERVISIBILITI (%)', 'data' => $servisibilitiData] ], $categories ); } /** * Get unit ID column name for KJC */ protected function getUnitIdColumn(): string { return 'kjc_asset_holdings.unit_id'; } /** * Get asset model class for KJC */ protected function getAssetModelClass(): string { return KJCAssetHolding::class; } /** * Get repair model class for KJC */ protected function getRepairModelClass(): string { return KJCRepair::class; } }