315 lines
10 KiB
PHP
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;
|
|
}
|
|
} |