Files
ISMAIL MASSERAN 94ecbe5887 first init
2026-06-08 11:37:14 +08:00

315 lines
10 KiB
PHP

<?php
namespace Modules\Dashboard\Services\KJC;
use Modules\Dashboard\Services\DashboardService;
use Modules\Dashboard\Repositories\Contracts\KJCDashboardRepositoryInterface;
use Modules\KJCRepair\Entities\KJCRepair;
use Modules\KJCReport\Entities\KJCReport;
use Modules\Unit\Entities\Unit;
use App\Services\VisibilityService;
use Carbon\Carbon;
class KJCDashboardService extends DashboardService
{
protected KJCDashboardRepositoryInterface $kjcDashboardRepository;
public function __construct(
VisibilityService $visibilityService,
KJCDashboardRepositoryInterface $kjcDashboardRepository
) {
parent::__construct($visibilityService);
$this->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;
}
}