@php
$filterMonth = request()->input('bulan', now()->format('m'));
$filterYear = request()->input('tahun', now()->format('Y'));
$monthNames = [
'01' => 'Januari',
'02' => 'Februari',
'03' => 'Maret',
'04' => 'April',
'05' => 'Mei',
'06' => 'Juni',
'07' => 'Juli',
'08' => 'Agustus',
'09' => 'September',
'10' => 'Oktober',
'11' => 'November',
'12' => 'Desember',
];
@endphp
@php
$selectedMonthLabel = $monthNames[$filterMonth] ?? now()->translatedFormat('F');
$selectedPeriodLabel = $selectedMonthLabel . ' ' . $filterYear;
$monthScope = function ($query) use ($filterMonth, $filterYear) {
$query->where(function ($q) {
$q->where('is_active', 1)->orWhereNull('is_active');
});
$query->whereMonth('created_at', $filterMonth)
->whereYear('created_at', $filterYear);
};
// 1. APPROVAL STATISTICS (scoped)
$totalApprovalNeeded = \Illuminate\Support\Facades\DB::table('tr_non_periodic')
->where($monthScope)
->whereIn('request_status', ['review', 'pending', 'approved'])
->whereNotNull('head_approval_date')
->whereNull('hrd_approval_date')
->count();
$approvedRequests = \Illuminate\Support\Facades\DB::table('tr_non_periodic')
->where($monthScope)
->whereIn('request_status', ['pengadaan', 'pengerjaan'])
->count();
$rejectedRequests = \Illuminate\Support\Facades\DB::table('tr_non_periodic')
->where($monthScope)
->where('request_status', 'LIKE', '%reject%')
->count();
$completedRequests = \Illuminate\Support\Facades\DB::table('tr_non_periodic')
->where($monthScope)
->where('request_status', 'completed')
->count();
// 2. PERIODIC SCHEDULE STATS
$periodicHeaders = \Illuminate\Support\Facades\DB::table('tr_periodic_header')
->count();
$periodicDetails = \Illuminate\Support\Facades\DB::table('tr_periodic_detail')
->count();
$generatedItems = \Illuminate\Support\Facades\DB::table('tr_periodic_items')
->count();
$unrealizedItems = \Illuminate\Support\Facades\DB::table('tr_periodic_items')
->whereNull('realization_date')
->count();
// 3. DAILY TASK STATS
$totalDailyTasks = \Illuminate\Support\Facades\DB::table('ms_daily')
->where('is_active', 1)
->count();
$todayLoggedTasks = \Illuminate\Support\Facades\DB::table('rp_daily_log')
->whereDate('work_date', \Illuminate\Support\Carbon::today()->toDateString())
->distinct()
->count('daily_task_id');
$todayCompleted = \Illuminate\Support\Facades\DB::table('rp_daily_log')
->whereDate('work_date', \Illuminate\Support\Carbon::today()->toDateString())
->whereRaw('LOWER(COALESCE(job_status, \'\')) = ?', ['completed'])
->distinct()
->count('daily_task_id');
$dailyTarget = $totalDailyTasks;
$completionRate = $dailyTarget > 0 ? round(($todayCompleted / $dailyTarget) * 100) : 0;
$dailyRateLabels = [];
$dailyRateData = [];
$dailyCompletedData = [];
$dailyTargetData = [];
$dailyStartDate = \Illuminate\Support\Carbon::createFromDate((int) $filterYear, (int) $filterMonth, 1)->startOfMonth();
$dailyEndDate = $dailyStartDate->copy()->endOfMonth();
$dailyCompletedRows = \Illuminate\Support\Facades\DB::table('rp_daily_log')
->whereBetween('work_date', [$dailyStartDate->toDateString(), $dailyEndDate->toDateString()])
->whereRaw('LOWER(COALESCE(job_status, \'\')) = ?', ['completed'])
->select(
'work_date',
\Illuminate\Support\Facades\DB::raw('COUNT(DISTINCT daily_task_id) as completed_count')
)
->groupBy('work_date')
->get()
->keyBy('work_date');
$dailyCursorDate = $dailyStartDate->copy();
while ($dailyCursorDate->lte($dailyEndDate)) {
$dailyDate = $dailyCursorDate->toDateString();
$dailyCompletedCount = isset($dailyCompletedRows[$dailyDate])
? (int) $dailyCompletedRows[$dailyDate]->completed_count
: 0;
$dailyRateLabels[] = $dailyCursorDate->format('d M');
$dailyCompletedData[] = $dailyCompletedCount;
$dailyTargetData[] = $dailyTarget;
$dailyRateData[] = $dailyTarget > 0
? round(($dailyCompletedCount / $dailyTarget) * 100, 1)
: 0;
$dailyCursorDate->addDay();
}
$dailyMonthlyAverage = count($dailyRateData) > 0
? round(array_sum($dailyRateData) / count($dailyRateData), 1)
: 0;
// 4. AREA & WORKERS
$totalAreas = \Illuminate\Support\Facades\DB::table('ms_area')->count();
$totalWorkers = \Illuminate\Support\Facades\DB::table('users')
->whereRaw("FIND_IN_SET('ptgoff', REPLACE(idroles, ' ', '')) OR FIND_IN_SET('ptgspu', REPLACE(idroles, ' ', ''))")
->count();
// 5. TOP AREAS by Requests
$topAreas = \Illuminate\Support\Facades\DB::table('tr_non_periodic')
->where($monthScope)
->select('area_id', \Illuminate\Support\Facades\DB::raw('COUNT(*) as count'))
->groupBy('area_id')
->orderBy('count', 'desc')
->limit(5)
->get();
$selectedRequests = \Illuminate\Support\Facades\DB::table('tr_non_periodic')
->where($monthScope)
->select('user_id')
->get();
$selectedUserIds = $selectedRequests->pluck('user_id')->filter()->unique()->values()->all();
$departmentMap = [];
if (!empty($selectedUserIds)) {
$departmentMap = \Illuminate\Support\Facades\DB::table('ms_employee')
->whereIn('user_id', $selectedUserIds)
->join('ms_department', 'ms_employee.departemen_id', '=', 'ms_department.id')
->pluck('ms_department.nama_departemen', 'ms_employee.user_id')
->toArray();
}
$allDepartments = \Illuminate\Support\Facades\DB::table('ms_department')
->where(fn ($q) => $q->where('is_active', '1')->orWhereNull('is_active'))
->orderBy('nama_departemen')
->pluck('nama_departemen')
->toArray();
$deptCounts = array_fill_keys($allDepartments, 0);
$deptCounts['Tidak Diketahui'] = 0;
foreach ($selectedRequests as $requestRow) {
if (isset($requestRow->user_id) && isset($departmentMap[$requestRow->user_id])) {
$deptName = $departmentMap[$requestRow->user_id];
if (!array_key_exists($deptName, $deptCounts)) {
$deptCounts[$deptName] = 0;
}
$deptCounts[$deptName]++;
} else {
$deptCounts['Tidak Diketahui']++;
}
}
$deptLabels = array_keys($deptCounts);
$deptData = array_values($deptCounts);
$chartColors = [
'rgba(15,98,254,0.75)', 'rgba(66,190,101,0.75)', 'rgba(255,131,43,0.75)',
'rgba(250,77,86,0.75)', 'rgba(138,63,252,0.75)', 'rgba(51,177,255,0.75)',
'rgba(255,193,7,0.75)', 'rgba(233,30,99,0.75)', 'rgba(0,150,136,0.75)',
'rgba(121,85,72,0.75)',
];
$deptBgColors = [];
foreach ($deptLabels as $idx => $label) {
$deptBgColors[] = $label === 'Tidak Diketahui'
? 'rgba(158,158,158,0.4)'
: $chartColors[$idx % count($chartColors)];
}
$periodicYearLabels = [];
$periodicYearTotalData = [];
$periodicYearDoneData = [];
$periodicYearPendingData = [];
$periodicYearRateData = [];
$periodicYearSummary = [];
for ($month = 1; $month <= 12; $month++) {
$monthKey = str_pad((string) $month, 2, '0', STR_PAD_LEFT);
$periodicYearLabels[] = $monthNames[$monthKey] ?? $monthKey;
$periodicYearSummary[$monthKey] = [
'total' => 0,
'done' => 0,
'pending' => 0,
];
}
$periodicYearRows = \Illuminate\Support\Facades\DB::table('tr_periodic_items')
->where(function ($query) {
$query->where('is_active', 1)->orWhereNull('is_active');
})
->whereNotNull('planned_date')
->whereYear('planned_date', $filterYear)
->select(
\Illuminate\Support\Facades\DB::raw('MONTH(planned_date) as month_number'),
\Illuminate\Support\Facades\DB::raw('COUNT(*) as total_count'),
\Illuminate\Support\Facades\DB::raw('SUM(CASE WHEN realization_date IS NOT NULL THEN 1 ELSE 0 END) as done_count')
)
->groupBy(\Illuminate\Support\Facades\DB::raw('MONTH(planned_date)'))
->get();
foreach ($periodicYearRows as $row) {
$monthKey = str_pad((string) $row->month_number, 2, '0', STR_PAD_LEFT);
$totalCount = (int) $row->total_count;
$doneCount = (int) $row->done_count;
$periodicYearSummary[$monthKey] = [
'total' => $totalCount,
'done' => $doneCount,
'pending' => max(0, $totalCount - $doneCount),
];
}
foreach ($periodicYearSummary as $summary) {
$periodicYearTotalData[] = $summary['total'];
$periodicYearDoneData[] = $summary['done'];
$periodicYearPendingData[] = $summary['pending'];
$periodicYearRateData[] = $summary['total'] > 0
? round(($summary['done'] / $summary['total']) * 100, 1)
: 0;
}
$periodicYearTotal = array_sum($periodicYearTotalData);
$periodicYearDone = array_sum($periodicYearDoneData);
$periodicYearRate = $periodicYearTotal > 0
? round(($periodicYearDone / $periodicYearTotal) * 100, 1)
: 0;
@endphp
@php
$approvalUrl = url('pengajuan-hrd') . '#list_hrd_approval';
$approvedUrl = url('pengajuan-hrd') . '#list_hrd_pending';
$rejectedUrl = url('pengajuan-hrd') . '?status=rejected#list_hrd_history';
$completedUrl = url('pengajuan-hrd') . '?status=completed#list_hrd_history';
@endphp
@if (($overdue_estimation_alerts ?? collect())->isNotEmpty())
| Pekerjaan |
Area |
Tahap |
Estimasi Selesai |
Aksi |
@foreach ($overdue_estimation_alerts as $alert)
|
{{ $alert->job_description ?? '-' }}
|
{{ $alert->area_name ?? '-' }} |
{{ $alert->overdue_stage ?? '-' }}
|
{{ $alert->overdue_date ? \Illuminate\Support\Carbon::parse($alert->overdue_date)->format('d-m-Y') : '-' }}
|
Detail
|
@endforeach
@endif
Template Aktif
{{ $periodicDetails }}
Item Generated
{{ $generatedItems }}
{{ $unrealizedItems }} item belum direalisasikan
Progress Completion
{{ $completionRate }}%
{{ $todayCompleted }} dari {{ $dailyTarget }} task hari ini
@if ($todayLoggedTasks < $dailyTarget)
{{ $todayLoggedTasks }} task sudah diinput hari ini
@endif
@if($topAreas->count() > 0)
@foreach($topAreas as $area)
@php
$areaName = \Illuminate\Support\Facades\DB::table('ms_area')
->where('id', $area->area_id)
->value('nama_area') ?? 'Area ' . $area->area_id;
@endphp
{{ $areaName }}
{{ $area->count }}
@endforeach
@else
Tidak ada data permintaan
@endif
Petugas Aktif
{{ $totalWorkers }}
Area Kerja
{{ $totalAreas }}
Daily Task Master
{{ $totalDailyTasks }}
@php
$startDate = \Illuminate\Support\Carbon::createFromDate((int) $filterYear, (int) $filterMonth, 1)->startOfMonth();
$endDate = (clone $startDate)->endOfMonth();
$range = [];
$cursor = $startDate->copy();
while ($cursor->lte($endDate)) {
$d = $cursor->copy();
$range[] = $d->toDateString();
$cursor->addDay();
}
$raw = \Illuminate\Support\Facades\DB::table('tr_non_periodic')
->where($monthScope)
->select(\Illuminate\Support\Facades\DB::raw('DATE(created_at) as date'), \Illuminate\Support\Facades\DB::raw('COUNT(*) as count'))
->groupBy(\Illuminate\Support\Facades\DB::raw('DATE(created_at)'))
->orderBy('date')
->get()
->keyBy('date');
$trendLabels = [];
$trendData = [];
foreach ($range as $d) {
$trendLabels[] = \Illuminate\Support\Carbon::parse($d)->format('d M');
$trendData[] = isset($raw[$d]) ? (int) $raw[$d]->count : 0;
}
@endphp