@extends('layouts.app', ['class' => 'g-sidenav-show bg-gray-100']) @section('content') @include('layouts.navbars.auth.topnav', ['title' => ''])

Edit Penilaian

Periode Aktif: {{ date('d M Y', strtotime($period->start_date)) }} - {{ date('d M Y', strtotime($period->end_date)) }}

@include('components.alert') @php $isLocked = strtolower($period->status ?? '') === 'locked'; @endphp @if ($hasLateUnlock ?? false) @elseif ($isLocked) @endif
@php $currentPosition = $positionsData->last()['position_name'] ?? 'N/A'; @endphp

PENILAIAN STANDAR PA

@csrf @method('PUT') @if ($isMultiPosition) @php $latestAssignmentId = $positionsData->last()['id_for_tab']; @endphp {{-- Flex container for position tabs (left) and month tabs (right) --}}
{{-- Position tabs (left side, scrollable) --}}
{{-- Month tabs (right side) - one set per position, toggled via JS --}}
@foreach ($positionsData as $index => $pos) @php // Compute standardsDiffer for this position $_posStd = $pos['standardItems']; $_posRatings = $pos['ratingsByItem']; $_effFrom = \Carbon\Carbon::parse($pos['effective_from'])->startOfMonth(); $_effTo = $pos['effective_to'] ? \Carbon\Carbon::parse($pos['effective_to'])->startOfMonth() : null; $_evalIds = $pos['evaluatedMonthIds']; $_relMonths = $calendarMonths->filter(function($m) use ($restMonths, $_effFrom, $_effTo, $_evalIds) { if (in_array($m->id, $restMonths)) return false; $monthDate = \Carbon\Carbon::create($m->year, $m->month)->startOfMonth(); $inRange = $monthDate->greaterThanOrEqualTo($_effFrom) && ($_effTo === null || $monthDate->lessThanOrEqualTo($_effTo)); return $inRange || in_array($m->id, $_evalIds); }); $_mfp = collect(); foreach ($_relMonths as $m) { $_items = $_posStd->get($m->id) ?? collect(); $_fp = $_items->sortBy('name')->map(function ($item) use ($_posRatings) { $r = $_posRatings->get($item->id) ?? collect(); return $item->name . '::' . $r->pluck('label')->implode('|'); })->implode(';;'); $_mfp->put($m->id, $_fp); } $_posDiffer = $_mfp->unique()->count() > 1; @endphp @if ($_posDiffer) @php // Group months by fingerprint for tab labels $_grouped = $_mfp->mapToGroups(fn($fp, $monthId) => [$fp => $monthId]); $_gIdx = 0; $_tabGroups = collect(); foreach ($_grouped as $_fp => $_monthIds) { $_gMonths = $_relMonths->filter(fn($m) => $_monthIds->contains($m->id)); $_gLabel = $_gMonths->map(fn($m) => \Carbon\Carbon::create($m->year, $m->month)->translatedFormat('M Y'))->implode(' & '); $_gTabId = 'mgrp-' . $pos['id_for_tab'] . '-' . $_gIdx; $_tabGroups->push(['label' => $_gLabel, 'tabId' => $_gTabId, 'months' => $_gMonths]); $_gIdx++; } @endphp @endif @endforeach
@endif @php $hasAnyStandardItem = false; @endphp @foreach ($positionsData as $index => $pos) @php // Logic untuk menentukan apakah harus menggunakan wrapper tab atau tidak $isTabActive = $isMultiPosition ? $index === $positionsData->count() - 1 : true; $contentWrapperClass = $isMultiPosition ? 'tab-pane fade ' . ($isTabActive ? 'show active' : '') : ''; $contentWrapperId = $isMultiPosition ? 'content-' . $pos['id_for_tab'] : ''; // Extract data for the current position block $standardItems = $pos['standardItems']; $uniqueItems = $pos['uniqueItems']; $ratingsByItem = $pos['ratingsByItem']; $existing = $pos['existing'] ?? []; $existingWeights = $pos['existingWeights'] ?? []; $evaluatedMonthIds = $pos['evaluatedMonthIds']; // Filter calendar months: bukan bulan cuti DAN dalam masa berlaku posisi $posEffFrom = \Carbon\Carbon::parse($pos['effective_from'])->startOfMonth(); $posEffTo = $pos['effective_to'] ? \Carbon\Carbon::parse($pos['effective_to'])->startOfMonth() : null; $relevantMonths = $calendarMonths->filter(function ($m) use ($restMonths, $posEffFrom, $posEffTo, $evaluatedMonthIds) { if (in_array($m->id, $restMonths)) return false; $monthDate = \Carbon\Carbon::create($m->year, $m->month)->startOfMonth(); $inRange = $monthDate->greaterThanOrEqualTo($posEffFrom) && ($posEffTo === null || $monthDate->lessThanOrEqualTo($posEffTo)); // Show if within effective range OR already evaluated return $inRange || in_array($m->id, $evaluatedMonthIds); }); // Filter uniqueItems agar hanya menampilkan standar yang ada di bulan-bulan relevan $filteredUniqueItems = $uniqueItems->filter(function ($uniqueItem) use ( $relevantMonths, $standardItems, ) { return $relevantMonths->some(function ($m) use ($uniqueItem, $standardItems) { return $standardItems->get($m->id)?->contains('name', $uniqueItem->name); }); }); if ($filteredUniqueItems->isNotEmpty()) { $hasAnyStandardItem = true; } @endphp
{{-- Notifikasi bulan yang sudah dinilai (dikunci) --}} @php $evaluatedMonths = collect(); foreach ($relevantMonths as $m) { if (in_array($m->id, $evaluatedMonthIds)) { $evaluatedMonths->push( \Carbon\Carbon::create($m->year, $m->month)->translatedFormat( 'F Y', ), ); } } @endphp @if ($evaluatedMonths->isNotEmpty())
Penilaian untuk bulan {{ $evaluatedMonths->join(', ', ' dan ') }} sudah dilakukan.
@endif @php // Detect if standards differ across months // Group months by fingerprint (item names + ratings) $monthFingerprints = collect(); foreach ($relevantMonths as $m) { $itemsForM = $standardItems->get($m->id) ?? collect(); $fingerprint = $itemsForM->sortBy('name')->map(function ($item) use ($ratingsByItem) { $ratings = $ratingsByItem->get($item->id) ?? collect(); return $item->name . '::' . $ratings->pluck('label')->implode('|'); })->implode(';;'); $monthFingerprints->put($m->id, $fingerprint); } $standardsDiffer = $monthFingerprints->unique()->count() > 1; // Group months by fingerprint $monthGroups = collect(); if ($standardsDiffer) { $grouped = $monthFingerprints->mapToGroups(fn($fp, $monthId) => [$fp => $monthId]); $groupIndex = 0; foreach ($grouped as $fp => $monthIds) { $groupMonths = $relevantMonths->filter(fn($m) => $monthIds->contains($m->id)); $groupLabel = $groupMonths->map(fn($m) => \Carbon\Carbon::create($m->year, $m->month)->translatedFormat('M Y'))->implode(' & '); $groupTabId = 'mgrp-' . ($pos['id_for_tab'] ?? 0) . '-' . $groupIndex; $monthGroups->push([ 'label' => $groupLabel, 'tabId' => $groupTabId, 'months' => $groupMonths, 'monthIds' => $monthIds, ]); $groupIndex++; } } @endphp @if ($standardsDiffer) {{-- ===== GROUPED MONTH TABS: groups of months with same standards ===== --}} @unless ($isMultiPosition) {{-- Single position: show month group tabs inline --}} @endunless
@foreach ($monthGroups as $gIdx => $group)
@if ($group['months']->count() === 1) {{-- Single month in this group: simple table --}} @php $m = $group['months']->first(); $itemsForThisMonth = ($standardItems->get($m->id) ?? collect())->sortBy('seq'); $isRestMonth = in_array($m->id, $restMonths); $currentMonth = now()->startOfMonth(); @endphp
@if ($isRestMonth) @else @php $mCounter = 1; @endphp @foreach ($itemsForThisMonth as $item) @php $defaultWeight = $item->weight ?? 0; $finalWeight = $defaultWeight; if (is_array($existingWeights) && isset($existingWeights[$m->id]) && is_array($existingWeights[$m->id]) && isset($existingWeights[$m->id][$item->id])) { $finalWeight = $existingWeights[$m->id][$item->id]; } $isMonthEvaluated = isset($existing[$m->id][$item->id]); $isStandardUsed = $defaultWeight > 0; $monthDate = \Carbon\Carbon::create($m->year, $m->month)->startOfMonth(); $isStandardEditableWindow = (!$isLocked || ($hasLateUnlock ?? false)) && $monthDate->lessThanOrEqualTo($currentMonth); $isDisabled = $isMonthEvaluated || !$isStandardEditableWindow || !$isStandardUsed; $isWeightModified = $finalWeight != $defaultWeight; $isInactive = $finalWeight == 0; $ratingsForItem = $ratingsByItem->get($item->id) ?? collect(); @endphp @endforeach @endif
No Standar Bobot Nilai Deskripsi Penilaian
Bulan Cuti
{{ $mCounter++ }} {{ $item->name }} @if ($isInactive) Nonaktif @endif
@if ($isWeightModified && !$isDisabled && !$isInactive)
Terganti
@endif
@foreach ($ratingsForItem as $opt)
id][$item->id] ?? '') == $opt->score ? 'checked' : '' }} {{ $isDisabled || $isInactive ? 'disabled' : '' }}>
@endforeach
    @forelse ($ratingsForItem as $opt)

    {{ $opt->score }} = {{ $opt->label }}

    @empty

    Deskripsi tidak tersedia.

    @endforelse
Total Bobot
@else {{-- Multiple months with same standards: multi-column table --}} @php $grpMonths = $group['months']; // Use first month's items as the unique list (since they share standards) $firstGrpMonth = $grpMonths->first(); $grpUniqueItems = ($standardItems->get($firstGrpMonth->id) ?? collect())->sortBy('seq'); $currentMonth = now()->startOfMonth(); @endphp
@foreach ($grpMonths as $gm) @endforeach @foreach ($grpMonths as $gm) @endforeach @php $gCounter = 1; @endphp @foreach ($grpUniqueItems as $uniqueItem) @php $hasInactiveEntries = false; foreach ($grpMonths as $gm) { $itm = $standardItems->get($gm->id)?->firstWhere('name', $uniqueItem->name); if ($itm) { $fw = $itm->weight ?? 0; if (is_array($existingWeights) && isset($existingWeights[$gm->id][$itm->id])) { $fw = $existingWeights[$gm->id][$itm->id]; } if ($fw == 0) { $hasInactiveEntries = true; break; } } } @endphp @foreach ($grpMonths as $gm) @php $itemForMonth = $standardItems->get($gm->id)?->firstWhere('name', $uniqueItem->name); $defaultWeight = $itemForMonth->weight ?? 0; $finalWeight = $defaultWeight; if ($itemForMonth && is_array($existingWeights) && isset($existingWeights[$gm->id]) && is_array($existingWeights[$gm->id]) && isset($existingWeights[$gm->id][$itemForMonth->id])) { $finalWeight = $existingWeights[$gm->id][$itemForMonth->id]; } $isMonthEvaluated = $itemForMonth && isset($existing[$gm->id][$itemForMonth->id]); $isStandardUsed = $itemForMonth && $defaultWeight > 0; $monthDate = \Carbon\Carbon::create($gm->year, $gm->month)->startOfMonth(); $isStandardEditableWindow = (!$isLocked || ($hasLateUnlock ?? false)) && $monthDate->lessThanOrEqualTo($currentMonth); $isDisabled = $isMonthEvaluated || !$isStandardEditableWindow || !$isStandardUsed; $isWeightModified = $itemForMonth && ($finalWeight != $defaultWeight); $isInactive = $finalWeight == 0; @endphp @endforeach @endforeach @foreach ($grpMonths as $gm) @endforeach
No Standar {{ \Carbon\Carbon::create($gm->year, $gm->month)->translatedFormat('M Y') }} Deskripsi Penilaian
Bobot Nilai
{{ $gCounter++ }} {{ $uniqueItem->name }} @if ($hasInactiveEntries) Nonaktif @endif @if ($itemForMonth)
@if ($isWeightModified && !$isDisabled && !$isInactive)
Terganti
@endif
@else - @endif
@if ($itemForMonth)
@foreach ($ratingsByItem->get($itemForMonth->id) ?? [] as $opt)
id][$itemForMonth->id] ?? '') == $opt->score ? 'checked' : '' }} {{ $isDisabled || $isInactive ? 'disabled' : '' }}>
@endforeach
@else - @endif
@php $firstItem = $standardItems->get($firstGrpMonth->id)?->firstWhere('name', $uniqueItem->name); $ratings = $firstItem ? ($ratingsByItem->get($firstItem->id) ?? collect()) : collect(); @endphp
    @forelse ($ratings as $opt)

    {{ $opt->score }} = {{ $opt->label }}

    @empty

    Deskripsi tidak tersedia.

    @endforelse
Total Bobot
@endif
@endforeach
@else {{-- ===== UNIFIED TABLE MODE: standards same across months ===== --}}
@foreach ($relevantMonths as $m) @php $isRestMonth = in_array($m->id, $restMonths); @endphp @if ($isRestMonth) @else @endif @endforeach @foreach ($relevantMonths as $m) @endforeach @php $counter = 1; $currentMonth = now()->startOfMonth(); @endphp @foreach ($filteredUniqueItems as $uniqueItem) @php // Check if this item has any inactive (0 weight) entries for visual styling $hasInactiveEntries = false; foreach ($relevantMonths as $m) { $itemForMonth = $standardItems ->get($m->id) ?->firstWhere('name', $uniqueItem->name); if ($itemForMonth) { $finalWeight = $itemForMonth->weight ?? 0; if ( is_array($existingWeights) && isset($existingWeights[$m->id]) && is_array($existingWeights[$m->id]) && isset($existingWeights[$m->id][$itemForMonth->id]) ) { $finalWeight = $existingWeights[$m->id][$itemForMonth->id]; } if ($finalWeight == 0) { $hasInactiveEntries = true; break; } } } @endphp @foreach ($relevantMonths as $m) @php $itemForMonth = $standardItems ->get($m->id) ?->firstWhere('name', $uniqueItem->name); $defaultWeight = $itemForMonth->weight ?? 0; $finalWeight = $defaultWeight; // Default fallback if ( $itemForMonth && is_array($existingWeights) && isset($existingWeights[$m->id]) && is_array($existingWeights[$m->id]) && isset($existingWeights[$m->id][$itemForMonth->id]) ) { $finalWeight = $existingWeights[$m->id][$itemForMonth->id]; } $isMonthEvaluated = $itemForMonth && isset($existing[$m->id][$itemForMonth->id]); $isStandardUsed = $itemForMonth && $defaultWeight > 0; $monthDate = \Carbon\Carbon::create( $m->year, $m->month, )->startOfMonth(); $isStandardEditableWindow = (!$isLocked || ($hasLateUnlock ?? false)) && $monthDate->lessThanOrEqualTo($currentMonth); $isDisabled = $isMonthEvaluated || !$isStandardEditableWindow || !$isStandardUsed; $isRestMonth = in_array($m->id, $restMonths); @endphp @if ($isRestMonth) @else @endif @endforeach @endforeach @foreach ($relevantMonths as $m) @php $isRestMonth = in_array($m->id, $restMonths); @endphp @if ($isRestMonth) @else @endif @endforeach {{-- Empty cell for the 'Deskripsi Penilaian' column --}}
No Standar {{ \Carbon\Carbon::create($m->year, $m->month)->translatedFormat('M Y') }} {{ \Carbon\Carbon::create($m->year, $m->month)->translatedFormat('M Y') }} Deskripsi Penilaian
Bobot Nilai
{{ $counter++ }} {{ $uniqueItem->name }} @if ($hasInactiveEntries) Nonaktif @endif Cuti @if ($itemForMonth) @endif @if ($itemForMonth) @php $isWeightModified = $finalWeight != $defaultWeight; $isInactive = $finalWeight == 0; @endphp
@if ($isInactive && !$isDisabled)
Nonaktif
@elseif ($isWeightModified && !$isDisabled)
Terganti
@endif
@else - @endif
@if ($itemForMonth) @php $isInactive = $finalWeight == 0; @endphp
@foreach ($ratingsByItem->get($itemForMonth->id) ?? [] as $opt)
id][$itemForMonth->id] ?? '') == $opt->score ? 'checked' : '' }} {{ $isDisabled || $isInactive ? 'disabled' : '' }}>
@endforeach
@else - @endif
@php // Use first month's ratings since they're all the same $firstMonthItem = null; foreach ($relevantMonths as $m) { $firstMonthItem = $standardItems->get($m->id)?->firstWhere('name', $uniqueItem->name); if ($firstMonthItem) break; } $ratings = $firstMonthItem ? ($ratingsByItem->get($firstMonthItem->id) ?? collect()) : collect(); @endphp
    @if ($ratings->isNotEmpty()) @foreach ($ratings as $opt)

    {{ $opt->score }} = {{ $opt->label }}

    @endforeach @else

    Deskripsi tidak tersedia.

    @endif
Total Bobot 0% {{-- This span will be updated by JavaScript --}}
@endif
@endforeach @if ($isMultiPosition)
{{-- Tutup tab-content --}} @endif
@php $hasAnyEvaluated = $positionsData->some(fn($p) => !empty($p['evaluatedMonthIds'])); @endphp @if ($hasAnyEvaluated && !$isLocked) @endif @if ($hasAnyStandardItem) @endif
@endsection @push('js') @endpush