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

Report MSJ Gedung F Periode @php try { $selectedPeriodLabel = \Carbon\Carbon::createFromFormat('Ymd', ($yearMonth ?? getActiveYearMonth()) . '01')->translatedFormat('F Y'); } catch (\Exception $e) { $selectedPeriodLabel = $yearMonth ?? ''; } @endphp {{ $selectedPeriodLabel }}

Report MSJ Gedung F Pertahun

Per Month Per Year
{{-- Card Pending Approval --}}

Total Target

0
{{-- Card Approved --}}

Total Actual

0
{{-- Card Rejected --}}

Yield

0%
{{-- Tabel --}} {{-- ===================== SUMMARY PER MONTH ===================== --}}
Summary Per Month
@php $resourceSapArr = ['1A0051', '1F7272']; $resourceFesArr = ['1A0057', '1F72FB']; $resourceSap1 = '1F7171'; // SAP RAW $resourceFes1 = '1F71FA'; // FES RAW (XINYAN C-Fold) $targetsDetail = collect( $targets instanceof \Illuminate\Support\Collection ? $targets->get('detail') ?? [] : $targets['detail'] ?? [], ); $actualsDetail = collect( $actuals instanceof \Illuminate\Support\Collection ? $actuals->get('detail') ?? [] : $actuals['detail'] ?? [], ); $fmtNum = fn($v, $d = 2) => number_format((float) $v, $d); @endphp {{-- order type (Order, Sample, Refestooning) --}}
{{-- Tabs switcher konten (Yield/Waste) --}}
{{-- ===================== PANE: YIELD ===================== --}}
@php // ===== Util & sumber data ===== $resourceSapArr = ['1A0051', '1F7272']; $resourceFesArr = ['1A0057', '1F72FB']; $resourceSap1 = '1F7171'; // SAP PENDING $resourceFes1 = '1F71FA'; // FES RAW (XINYAN C-Fold) $periodYm = $filter_yearmonth ?? ($yearMonth ?? null); // Helper untuk ambil property dari array atau object $getResource = fn($r) => is_array($r) ? $r['resource'] ?? '' : (is_object($r) ? $r->resource ?? '' : ''); // Converter Collection/object -> array "bersih" $toArrayRow = function ($row) { if ($row instanceof \Illuminate\Support\Collection) { return $row->toArray(); } if (is_object($row)) { return json_decode(json_encode($row), true); } return (array) $row; }; // Ambil DETAIL target/actual $targetsDetail = collect( $targets instanceof \Illuminate\Support\Collection ? $targets->get('detail') ?? [] : $targets['detail'] ?? [], ); $actualsDetail = collect( $actuals instanceof \Illuminate\Support\Collection ? $actuals->get('detail') ?? [] : $actuals['detail'] ?? [], ); $fmtNum = fn($v, $d = 2) => number_format((float) $v, $d); // ===================== HASH MAP O(1) PRE-INDEXING ===================== $targetLookupMap = []; $targetOrderSumMap = []; $targetPrefixTotals = []; $catsByOrderMap = []; foreach ($targetsDetail as $td) { $td = (array) $td; $mat = (string) ($td['matnr'] ?? ''); $res = (string) ($td['resource'] ?? ''); $ord = (string) ($td['order'] ?? ''); $cat = (string) ($td['kategori'] ?? ''); $val = (float) ($td['target_kg'] ?? 0); $pfx = substr($ord, 0, 2); $kCat = "{$mat}|{$res}|{$ord}|{$cat}"; $targetLookupMap[$kCat] = ($targetLookupMap[$kCat] ?? 0) + $val; $kOrd = "{$mat}|{$res}|{$ord}"; $targetOrderSumMap[$kOrd] = ($targetOrderSumMap[$kOrd] ?? 0) + $val; $kPfx = "{$res}|{$pfx}"; $targetPrefixTotals[$kPfx] = ($targetPrefixTotals[$kPfx] ?? 0) + $val; if ($cat !== '') { $catsByOrderMap[$kOrd][$cat] = true; } } $actualLookupMap = []; $actualOrderSumMap = []; $actualPrefixTotals = []; foreach ($actualsDetail as $ad) { $ad = (array) $ad; $mat = (string) ($ad['matnr'] ?? ''); $res = (string) ($ad['resource'] ?? ''); $ord = (string) ($ad['order'] ?? ''); $cat = (string) ($ad['kategori'] ?? ''); $val = (float) ($ad['qty'] ?? 0); $pfx = substr($ord, 0, 2); $kCat = "{$mat}|{$res}|{$ord}|{$cat}"; $actualLookupMap[$kCat] = ($actualLookupMap[$kCat] ?? 0) + $val; $kOrd = "{$mat}|{$res}|{$ord}"; $actualOrderSumMap[$kOrd] = ($actualOrderSumMap[$kOrd] ?? 0) + $val; $kPfx = "{$res}|{$pfx}"; $actualPrefixTotals[$kPfx] = ($actualPrefixTotals[$kPfx] ?? 0) + $val; if ($cat !== '') { $catsByOrderMap[$kOrd][$cat] = true; } } // Normalisasi yieldSummary -> array baris per (resource, matnr, order) $ysRows = collect($yieldSummary ?? []) ->map($toArrayRow) ->values(); // Split SAP/FES - gunakan whereIn untuk multiple resources $sapRows = $ysRows ->filter(fn($r) => in_array($r['resource'] ?? '', $resourceSapArr)) ->values(); $fesRows = $ysRows ->filter(fn($r) => in_array($r['resource'] ?? '', $resourceFesArr)) ->values(); // Pending SAP RAW $sap1Rows = $ysRows ->filter(fn($r) => ($r['resource'] ?? '') === $resourceSap1) ->values(); // FES RAW (XINYAN C-Fold) $fes1Rows = $ysRows ->filter(fn($r) => ($r['resource'] ?? '') === $resourceFes1) ->values(); @endphp {{-- ===== Yield — SAP (per MATNR + ORDER) ===== --}}
JIA DE LI SAP (1A0051 & 1F7272)
Material Order Target Actual Yield @php // Pre-calculate avg yield per material+kategori untuk SAP $avgYieldBySapMatnr = []; foreach ($sapRows as $row) { $matnr = (string) ($row['matnr'] ?? ($row['matnr_sap'] ?? '')); $orderVal = (string) ($row['order'] ?? ''); $rowResource = (string) ($row['resource'] ?? ''); $prefix = substr($orderVal, 0, 2); $category = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Hitung yield untuk baris ini - gunakan resource dari row $tSum = round((float) ($targetOrderSumMap["{$matnr}|{$rowResource}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnr}|{$rowResource}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; if (!isset($avgYieldBySapMatnr[$matnr])) { $avgYieldBySapMatnr[$matnr] = []; } if (!isset($avgYieldBySapMatnr[$matnr][$category])) { $avgYieldBySapMatnr[$matnr][$category] = []; } $avgYieldBySapMatnr[$matnr][$category][] = $pSum; } // Hitung average per material per category foreach ($avgYieldBySapMatnr as $matnr => $categories) { foreach ($categories as $category => $yields) { $count = count($yields); $sum = array_sum($yields); $avgYieldBySapMatnr[$matnr][$category] = $count > 0 ? round($sum / $count, 2) : 0; } } $displayedSapMatnrCat = []; // Pre-compute rowspan counts for SAP $sapRowspanMap = []; foreach ($sapRows as $row) { $rowMat = (string) ($row['matnr'] ?? ($row['matnr_sap'] ?? '')); $rowOrder = (string) ($row['order'] ?? ''); $rowPrefix = substr($rowOrder, 0, 2); $key = $rowMat . '_' . $rowPrefix; if (!isset($sapRowspanMap[$key])) { $sapRowspanMap[$key] = 0; } $sapRowspanMap[$key]++; } @endphp @forelse ($sapRows as $i => $r) @php $matnrShow = (string) ($r['matnr'] ?? ($r['matnr_sap'] ?? '')); $orderVal = (string) ($r['order'] ?? ''); $prefix = substr($orderVal, 0, 2); $categoryKey = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Rowspan dari pre-computed map (O(1) lookup) $rowspanCount = $sapRowspanMap[$matnrShow . '_' . $prefix] ?? 1; // First row hanya dalam kategori yang sama $matCatKey = $matnrShow . '_' . $categoryKey; $isFirstMatnrRow = !in_array( $matCatKey, $displayedSapMatnrCat, ); if ($isFirstMatnrRow) { $displayedSapMatnrCat[] = $matCatKey; } $resNeed = (string) ($r['resource'] ?? $resourceSapArr[0]); $categoryClass = match ($prefix) { '13' => 'cat-13', // Sample '11' => 'cat-11', // Order default => 'cat-12', // Others (Default 12) }; // Status Komposisi & Missing (pre-loaded batch) $hasComp = ($compSapMap[$matnrShow] ?? false); $rowClass = $hasComp ? '' : 'table-danger'; $sapMissKey = "{$matnrShow}|{$resNeed}|{$orderVal}"; $sapHasMissing = (bool) ($missingSapMap[$sapMissKey] ?? false); $tSum = round((float) ($targetOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; $targetVal = (float) ($r['target'] ?? 0); $actualVal = (float) ($r['actual'] ?? 0); $yieldVal = (float) ($r['yield'] ?? 0); // dd($r['resource'], $resourceSapArr); $rid = 'detail-SAP-' . $i . '-' . preg_replace('/\W+/', '-', $orderVal ?: 'NOORD'); @endphp
{{ $matnrShow }} @php $compIdSel = $chosenSap[$matnrShow] ?? null; @endphp @if ($compIdSel) Comp: {{ $compIdSel }} @endif
{{-- Komposisi --}} {{-- Missing (always visible, data loaded via AJAX) --}}
{{ $orderVal ?: '-' }} {{ $fmtNum($tSum, 2) }} {{ $fmtNum($aSum, 2) }} {{ $fmtNum($pSum) }}% @php $allCatsSap = array_keys($catsByOrderMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? []); @endphp @foreach ($allCatsSap as $cat) @php $tKg = round((float) ($targetLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $aKg = round((float) ($actualLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $pc = $aKg > 0 ? round(($tKg / $aKg) * 100, 2) : 0; @endphp {{ $cat }} {{-- Kolom Target dengan ondblclick untuk Modal --}} {{ number_format($tKg, 2) }} {{-- Kolom Actual dengan ondblclick untuk Modal --}} {{ number_format($aKg, 2) }} {{ number_format($pc, 2) }}% @endforeach {{-- OUTPUT {{ number_format($targetVal, 2) }} {{ number_format($actualVal, 2) }} {{ number_format($yieldVal, 2) }}% --}} @empty Tidak ada data JIA DE LI SAP. @endforelse {{-- TOTAL ROW (Terpisah per Kategori) --}} @php // Hitung total untuk masing-masing kategori SAP (1A0051 & 1F7272) // Helper untuk filter berdasarkan order prefix $getOrderFromRow = fn($r) => is_array($r) ? $r['order'] ?? '' : (is_object($r) ? $r->order ?? '' : ''); // Total untuk Order (prefix 1 // Total untuk Order (prefix 11) $totalTargetSap11 = round((float) (($targetPrefixTotals['1A0051|11'] ?? 0) + ($targetPrefixTotals['1F7272|11'] ?? 0)), 2); $totalActualSap11 = round((float) (($actualPrefixTotals['1A0051|11'] ?? 0) + ($actualPrefixTotals['1F7272|11'] ?? 0)), 2); $totalYieldSap11 = $totalActualSap11 > 0 ? round(($totalTargetSap11 / $totalActualSap11) * 100, 2) : 0; // Total untuk Sample (prefix 13) $totalTargetSap13 = round((float) (($targetPrefixTotals['1A0051|13'] ?? 0) + ($targetPrefixTotals['1F7272|13'] ?? 0)), 2); $totalActualSap13 = round((float) (($actualPrefixTotals['1A0051|13'] ?? 0) + ($actualPrefixTotals['1F7272|13'] ?? 0)), 2); $totalYieldSap13 = $totalActualSap13 > 0 ? round(($totalTargetSap13 / $totalActualSap13) * 100, 2) : 0; // Total untuk Refestooning (semua prefix selain 11 dan 13) $totalTargetSap12 = round((float) collect($targetPrefixTotals)->filter(fn($v, $k) => (str_starts_with($k, '1A0051|') || str_starts_with($k, '1F7272|')) && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalActualSap12 = round((float) collect($actualPrefixTotals)->filter(fn($v, $k) => (str_starts_with($k, '1A0051|') || str_starts_with($k, '1F7272|')) && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalYieldSap12 = $totalActualSap12 > 0 ? round(($totalTargetSap12 / $totalActualSap12) * 100, 2) : 0; 0; // Hitung Avg Yield per kategori $allYieldsSap11 = []; $allYieldsSap13 = []; $allYieldsSap12 = []; foreach ($avgYieldBySapMatnr as $matnr => $categories) { if ( isset($categories['cat-11']) && is_numeric($categories['cat-11']) && $categories['cat-11'] > 0 ) { $allYieldsSap11[] = $categories['cat-11']; } if ( isset($categories['cat-13']) && is_numeric($categories['cat-13']) && $categories['cat-13'] > 0 ) { $allYieldsSap13[] = $categories['cat-13']; } if ( isset($categories['cat-12']) && is_numeric($categories['cat-12']) && $categories['cat-12'] > 0 ) { $allYieldsSap12[] = $categories['cat-12']; } } $avgYieldTotalSap11 = count($allYieldsSap11) > 0 ? round( array_sum($allYieldsSap11) / count($allYieldsSap11), 2, ) : 0; $avgYieldTotalSap13 = count($allYieldsSap13) > 0 ? round( array_sum($allYieldsSap13) / count($allYieldsSap13), 2, ) : 0; $avgYieldTotalSap12 = count($allYieldsSap12) > 0 ? round( array_sum($allYieldsSap12) / count($allYieldsSap12), 2, ) : 0; @endphp {{-- Total untuk Order (11) --}} TOTAL {{ number_format($totalTargetSap11, 2) }} {{ number_format($totalActualSap11, 2) }} {{ number_format($totalYieldSap11, 2) }}% {{-- Total untuk Sample (13) --}} TOTAL {{ number_format($totalTargetSap13, 2) }} {{ number_format($totalActualSap13, 2) }} {{ number_format($totalYieldSap13, 2) }}% {{-- Total untuk Refestooning (12) --}} TOTAL {{ number_format($totalTargetSap12, 2) }} {{ number_format($totalActualSap12, 2) }} {{ number_format($totalYieldSap12, 2) }}%
{{-- ===== Yield — FES (per MATNR + ORDER) ===== --}}
JIA DE LI C-Fold (1A0057 & 1F72FB)
Material Order Target Actual Yield @php // Pre-calculate avg yield per material+kategori untuk FES $avgYieldByFesMatnr = []; foreach ($fesRows as $row) { $matnr = (string) ($row['matnr'] ?? ($row['matnr_fes'] ?? '')); $orderVal = (string) ($row['order'] ?? ''); $rowResource = (string) ($row['resource'] ?? ''); $prefix = substr($orderVal, 0, 2); $category = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Hitung yield untuk baris ini - gunakan resource dari row $tSum = round((float) ($targetOrderSumMap["{$matnr}|{$rowResource}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnr}|{$rowResource}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; if (!isset($avgYieldByFesMatnr[$matnr])) { $avgYieldByFesMatnr[$matnr] = []; } if (!isset($avgYieldByFesMatnr[$matnr][$category])) { $avgYieldByFesMatnr[$matnr][$category] = []; } $avgYieldByFesMatnr[$matnr][$category][] = $pSum; } // Hitung average per material per category foreach ($avgYieldByFesMatnr as $matnr => $categories) { foreach ($categories as $category => $yields) { $count = count($yields); $sum = array_sum($yields); $avgYieldByFesMatnr[$matnr][$category] = $count > 0 ? round($sum / $count, 2) : 0; } } $displayedFesMatnrCat = []; // Pre-compute rowspan counts for FES $fesRowspanMap = []; foreach ($fesRows as $row) { $rowMat = (string) ($row['matnr'] ?? ($row['matnr_fes'] ?? '')); $rowOrder = (string) ($row['order'] ?? ''); $rowPrefix = substr($rowOrder, 0, 2); $key = $rowMat . '_' . $rowPrefix; if (!isset($fesRowspanMap[$key])) { $fesRowspanMap[$key] = 0; } $fesRowspanMap[$key]++; } @endphp @forelse ($fesRows as $i => $r) @php $matnrShow = (string) ($r['matnr'] ?? ($r['matnr_fes'] ?? '')); $orderVal = (string) ($r['order'] ?? ''); $prefix = substr($orderVal, 0, 2); $categoryKey = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Rowspan dari pre-computed map (O(1) lookup) $rowspanCount = $fesRowspanMap[$matnrShow . '_' . $prefix] ?? 1; // First row hanya dalam kategori yang sama $matCatKey = $matnrShow . '_' . $categoryKey; $isFirstMatnrRow = !in_array( $matCatKey, $displayedFesMatnrCat, ); if ($isFirstMatnrRow) { $displayedFesMatnrCat[] = $matCatKey; } $resNeed = (string) ($r['resource'] ?? $resourceFesArr[0]); $categoryClass = match ($prefix) { '13' => 'cat-13', // Sample '11' => 'cat-11', // Refestooning default => 'cat-12', // Order (Default) }; // Status Komposisi & Missing FES (pre-loaded batch) $hasComp = ($compFesMap[$matnrShow] ?? false); $rowClass = $hasComp ? '' : 'table-danger'; $fesMissKey = "{$matnrShow}|{$resNeed}|{$orderVal}"; $fesHasMissing = (bool) ($missingFesMap[$fesMissKey] ?? false); // 3. Perhitungan Summary Baris $tSum = round((float) ($targetOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; $targetVal = (float) ($r['target'] ?? 0); $actualVal = (float) ($r['actual'] ?? 0); $yieldVal = (float) ($r['yield'] ?? 0); $rid = 'detail-FES-' . $i . '-' . preg_replace('/\W+/', '-', $orderVal ?: 'NOORD'); @endphp
{{ $matnrShow }} @php $compIdSel = $chosenFes[$matnrShow] ?? null; @endphp @if ($compIdSel) Comp: {{ $compIdSel }} @endif
{{-- Komposisi --}} {{-- Missing (always visible, data loaded via AJAX) --}}
{{ $orderVal ?: '-' }} {{ $fmtNum($tSum) }} {{ $fmtNum($aSum) }} {{ $fmtNum($pSum) }}% @php $allCatsFes = array_keys($catsByOrderMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? []); @endphp @foreach ($allCatsFes as $cat) @php $tKg = round((float) ($targetLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $aKg = round((float) ($actualLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $pc = $aKg > 0 ? round(($tKg / $aKg) * 100, 2) : 0; @endphp {{ $cat }} {{ number_format($tKg, 2) }} {{ number_format($aKg, 2) }} {{ number_format($pc, 2) }}% @endforeach {{-- OUTPUT {{ number_format($targetVal, 2) }} {{ number_format($actualVal, 2) }} {{ number_format($yieldVal, 2) }}% --}} @empty Tidak ada data JIA DE LI C-Fold. @endforelse {{-- TOTAL ROW (Terpisah per Kategori) --}} @php // Hitung total untuk masing-masing kategori FES (1A0057 & 1F72FB) // Total untuk Order (prefix 11) $totalTargetFes11 = round((float) (($targetPrefixTotals['1A0057|11'] ?? 0) + ($targetPrefixTotals['1F72FB|11'] ?? 0)), 2); $totalActualFes11 = round((float) (($actualPrefixTotals['1A0057|11'] ?? 0) + ($actualPrefixTotals['1F72FB|11'] ?? 0)), 2); $totalYieldFes11 = $totalActualFes11 > 0 ? round(($totalTargetFes11 / $totalActualFes11) * 100, 2) : 0; // Total untuk Sample (prefix 13) $totalTargetFes13 = round((float) (($targetPrefixTotals['1A0057|13'] ?? 0) + ($targetPrefixTotals['1F72FB|13'] ?? 0)), 2); $totalActualFes13 = round((float) (($actualPrefixTotals['1A0057|13'] ?? 0) + ($actualPrefixTotals['1F72FB|13'] ?? 0)), 2); $totalYieldFes13 = $totalActualFes13 > 0 ? round(($totalTargetFes13 / $totalActualFes13) * 100, 2) : 0; // Total untuk Refestooning (semua prefix selain 11 dan 13) $totalTargetFes12 = round((float) collect($targetPrefixTotals)->filter(fn($v, $k) => (str_starts_with($k, '1A0057|') || str_starts_with($k, '1F72FB|')) && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalActualFes12 = round((float) collect($actualPrefixTotals)->filter(fn($v, $k) => (str_starts_with($k, '1A0057|') || str_starts_with($k, '1F72FB|')) && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalYieldFes12 = $totalActualFes12 > 0 ? round(($totalTargetFes12 / $totalActualFes12) * 100, 2) : 0; // Hitung Avg Yield per kategori $allYieldsFes11 = []; $allYieldsFes13 = []; $allYieldsFes12 = []; foreach ($avgYieldByFesMatnr as $matnr => $categories) { if ( isset($categories['cat-11']) && is_numeric($categories['cat-11']) && $categories['cat-11'] > 0 ) { $allYieldsFes11[] = $categories['cat-11']; } if ( isset($categories['cat-13']) && is_numeric($categories['cat-13']) && $categories['cat-13'] > 0 ) { $allYieldsFes13[] = $categories['cat-13']; } if ( isset($categories['cat-12']) && is_numeric($categories['cat-12']) && $categories['cat-12'] > 0 ) { $allYieldsFes12[] = $categories['cat-12']; } } $avgYieldTotalFes11 = count($allYieldsFes11) > 0 ? round( array_sum($allYieldsFes11) / count($allYieldsFes11), 2, ) : 0; $avgYieldTotalFes13 = count($allYieldsFes13) > 0 ? round( array_sum($allYieldsFes13) / count($allYieldsFes13), 2, ) : 0; $avgYieldTotalFes12 = count($allYieldsFes12) > 0 ? round( array_sum($allYieldsFes12) / count($allYieldsFes12), 2, ) : 0; @endphp {{-- Total untuk Order (11) --}} TOTAL {{ number_format($totalTargetFes11, 2) }} {{ number_format($totalActualFes11, 2) }} {{ number_format($totalYieldFes11, 2) }}% {{-- Total untuk Sample (13) --}} TOTAL {{ number_format($totalTargetFes13, 2) }} {{ number_format($totalActualFes13, 2) }} {{ number_format($totalYieldFes13, 2) }}% {{-- Total untuk Refestooning (12) --}} TOTAL {{ number_format($totalTargetFes12, 2) }} {{ number_format($totalActualFes12, 2) }} {{ number_format($totalYieldFes12, 2) }}%
{{-- ===== Yield — SAP 1 (1F7171) (per MATNR + ORDER) ===== --}}
XINYAN SAP (1F7171)
Material Order Target Actual Yield @php // 1. Pre-calculate avg yield untuk SAP 1 (1F7171) $avgYieldBySap1Matnr = []; foreach ($sap1Rows as $row) { // Ambil matnr (prioritas key matnr, fallback matnr_sap) $matnr = (string) ($row['matnr'] ?? ($row['matnr_sap'] ?? '')); $orderVal = (string) ($row['order'] ?? ''); $prefix = substr($orderVal, 0, 2); $category = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Hitung yield baris ini (Target vs Actual) $tSum = round((float) ($targetOrderSumMap["{$matnr}|{$resourceSap1}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnr}|{$resourceSap1}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; if (!isset($avgYieldBySap1Matnr[$matnr])) { $avgYieldBySap1Matnr[$matnr] = []; } if (!isset($avgYieldBySap1Matnr[$matnr][$category])) { $avgYieldBySap1Matnr[$matnr][$category] = []; } $avgYieldBySap1Matnr[$matnr][$category][] = $pSum; } // Hitung rata-rata akhirnya foreach ($avgYieldBySap1Matnr as $matnr => $categories) { foreach ($categories as $category => $yields) { $count = count($yields); $sum = array_sum($yields); $avgYieldBySap1Matnr[$matnr][$category] = $count > 0 ? round($sum / $count, 2) : 0; } } // Reset tracker rowspan untuk tabel ini $displayedSap1MatnrCat = []; // Pre-compute rowspan counts for SAP1 $sap1RowspanMap = []; foreach ($sap1Rows as $row) { $rowMat = (string) ($row['matnr'] ?? ($row['matnr_sap'] ?? '')); $rowOrder = (string) ($row['order'] ?? ''); $rowPrefix = substr($rowOrder, 0, 2); $key = $rowMat . '_' . $rowPrefix; if (!isset($sap1RowspanMap[$key])) { $sap1RowspanMap[$key] = 0; } $sap1RowspanMap[$key]++; } @endphp @forelse ($sap1Rows as $i => $r) @php $matnrShow = (string) ($r['matnr'] ?? ($r['matnr_sap'] ?? '')); $orderVal = (string) ($r['order'] ?? ''); $prefix = substr($orderVal, 0, 2); $categoryKey = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Rowspan dari pre-computed map (O(1) lookup) $rowspanCount = $sap1RowspanMap[$matnrShow . '_' . $prefix] ?? 1; // Cek First Row $matCatKey = $matnrShow . '_' . $categoryKey; $isFirstMatnrRow = !in_array( $matCatKey, $displayedSap1MatnrCat, ); if ($isFirstMatnrRow) { $displayedSap1MatnrCat[] = $matCatKey; } $resNeed = $resourceSap1; // Set resource ke 1F7171 $categoryClass = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Status Komposisi & Missing (pre-loaded batch) $hasComp = ($compSapMap[$matnrShow] ?? false); $rowClass = $hasComp ? '' : 'table-danger'; $sapMissKey = "{$matnrShow}|{$resNeed}|{$orderVal}"; $sapHasMissing = (bool) ($missingSapMap[$sapMissKey] ?? false); // Hitung Value Baris Utama $tSum = round((float) ($targetOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; $targetVal = (float) ($r['target'] ?? 0); $actualVal = (float) ($r['actual'] ?? 0); $yieldVal = (float) ($r['yield'] ?? 0); // Buat ID unik beda dari tabel atas (pakai SAP1) $rid = 'detail-SAP1-' . $i . '-' . preg_replace('/\W+/', '-', $orderVal ?: 'NOORD'); @endphp {{-- Render Baris Utama --}}
{{ $matnrShow }}
{{-- Button Comp --}} {{-- Button Missing (always visible, data loaded via AJAX) --}}
{{ $orderVal ?: '-' }} {{ $fmtNum($tSum, 2) }} {{ $fmtNum($aSum, 2) }} {{ $fmtNum($pSum) }}% {{-- Logic Detail per Kategori --}} @php $allCatsSap = array_keys($catsByOrderMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? []); @endphp @foreach ($allCatsSap as $cat) @php $tKg = round((float) ($targetLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $aKg = round((float) ($actualLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $pc = $aKg > 0 ? round(($tKg / $aKg) * 100, 2) : 0; @endphp {{ $cat }} {{ number_format($tKg, 2) }} {{ number_format($aKg, 2) }} {{ number_format($pc, 2) }}% @endforeach {{-- OUTPUT {{ number_format($targetVal, 2) }} {{ number_format($actualVal, 2) }} {{ number_format($yieldVal, 2) }}% --}} @empty Tidak ada data XINYAN SAP. @endforelse {{-- TOTAL ROW (Terpisah per Kategori) --}} @php // Hitung total untuk masing-masing kategori SAP1 (1F7171) // Total untuk Order (prefix 11) $totalTargetSap111 = round((float) ($targetPrefixTotals['1F7171|11'] ?? 0), 2); $totalActualSap111 = round((float) ($actualPrefixTotals['1F7171|11'] ?? 0), 2); $totalYieldSap111 = $totalActualSap111 > 0 ? round(($totalTargetSap111 / $totalActualSap111) * 100, 2) : 0; // Total untuk Sample (prefix 13) $totalTargetSap113 = round((float) ($targetPrefixTotals['1F7171|13'] ?? 0), 2); $totalActualSap113 = round((float) ($actualPrefixTotals['1F7171|13'] ?? 0), 2); $totalYieldSap113 = $totalActualSap113 > 0 ? round(($totalTargetSap113 / $totalActualSap113) * 100, 2) : 0; // Total untuk Refestooning (semua prefix selain 11 dan 13) $totalTargetSap112 = round((float) collect($targetPrefixTotals)->filter(fn($v, $k) => str_starts_with($k, '1F7171|') && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalActualSap112 = round((float) collect($actualPrefixTotals)->filter(fn($v, $k) => str_starts_with($k, '1F7171|') && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalYieldSap112 = $totalActualSap112 > 0 ? round(($totalTargetSap112 / $totalActualSap112) * 100, 2) : 0; // Hitung Avg Yield per kategori $allYieldsSap111 = []; $allYieldsSap113 = []; $allYieldsSap112 = []; foreach ($avgYieldBySap1Matnr as $matnr => $categories) { if ( isset($categories['cat-11']) && is_numeric($categories['cat-11']) && $categories['cat-11'] > 0 ) { $allYieldsSap111[] = $categories['cat-11']; } if ( isset($categories['cat-13']) && is_numeric($categories['cat-13']) && $categories['cat-13'] > 0 ) { $allYieldsSap113[] = $categories['cat-13']; } if ( isset($categories['cat-12']) && is_numeric($categories['cat-12']) && $categories['cat-12'] > 0 ) { $allYieldsSap112[] = $categories['cat-12']; } } $avgYieldTotalSap111 = count($allYieldsSap111) > 0 ? round( array_sum($allYieldsSap111) / count($allYieldsSap111), 2, ) : 0; $avgYieldTotalSap113 = count($allYieldsSap113) > 0 ? round( array_sum($allYieldsSap113) / count($allYieldsSap113), 2, ) : 0; $avgYieldTotalSap112 = count($allYieldsSap112) > 0 ? round( array_sum($allYieldsSap112) / count($allYieldsSap112), 2, ) : 0; @endphp {{-- Total untuk Order (11) --}} TOTAL {{ number_format($totalTargetSap111, 2) }} {{ number_format($totalActualSap111, 2) }} {{ number_format($totalYieldSap111, 2) }}% {{-- Total untuk Sample (13) --}} TOTAL {{ number_format($totalTargetSap113, 2) }} {{ number_format($totalActualSap113, 2) }} {{ number_format($totalYieldSap113, 2) }}% {{-- Total untuk Refestooning (12) --}} TOTAL {{ number_format($totalTargetSap112, 2) }} {{ number_format($totalActualSap112, 2) }} {{ number_format($totalYieldSap112, 2) }}%
{{-- ===== Yield — FES1 (1F71FA) XINYAN C-Fold (per MATNR + ORDER) ===== --}}
XINYAN C-Fold (1F71FA)
Material Order Target Actual Yield @php // 1. Pre-calculate avg yield untuk FES1 (1F71FA) $avgYieldByFes1Matnr = []; foreach ($fes1Rows as $row) { $matnr = (string) ($row['matnr'] ?? ($row['matnr_fes'] ?? '')); $orderVal = (string) ($row['order'] ?? ''); $prefix = substr($orderVal, 0, 2); $category = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Hitung yield baris ini (Target vs Actual) $tSum = round((float) ($targetOrderSumMap["{$matnr}|{$resourceFes1}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnr}|{$resourceFes1}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; if (!isset($avgYieldByFes1Matnr[$matnr])) { $avgYieldByFes1Matnr[$matnr] = []; } if (!isset($avgYieldByFes1Matnr[$matnr][$category])) { $avgYieldByFes1Matnr[$matnr][$category] = []; } $avgYieldByFes1Matnr[$matnr][$category][] = $pSum; } // Hitung rata-rata akhirnya foreach ($avgYieldByFes1Matnr as $matnr => $categories) { foreach ($categories as $category => $yields) { $count = count($yields); $sum = array_sum($yields); $avgYieldByFes1Matnr[$matnr][$category] = $count > 0 ? round($sum / $count, 2) : 0; } } // Reset tracker rowspan untuk tabel ini $displayedFes1MatnrCat = []; // Pre-compute rowspan counts for FES1 $fes1RowspanMap = []; foreach ($fes1Rows as $row) { $rowMat = (string) ($row['matnr'] ?? ($row['matnr_fes'] ?? '')); $rowOrder = (string) ($row['order'] ?? ''); $rowPrefix = substr($rowOrder, 0, 2); $key = $rowMat . '_' . $rowPrefix; if (!isset($fes1RowspanMap[$key])) { $fes1RowspanMap[$key] = 0; } $fes1RowspanMap[$key]++; } @endphp @forelse ($fes1Rows as $i => $r) @php $matnrShow = (string) ($r['matnr'] ?? ($r['matnr_fes'] ?? '')); $orderVal = (string) ($r['order'] ?? ''); $prefix = substr($orderVal, 0, 2); $categoryKey = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Rowspan dari pre-computed map (O(1) lookup) $rowspanCount = $fes1RowspanMap[$matnrShow . '_' . $prefix] ?? 1; // Cek First Row $matCatKey = $matnrShow . '_' . $categoryKey; $isFirstMatnrRow = !in_array( $matCatKey, $displayedFes1MatnrCat, ); if ($isFirstMatnrRow) { $displayedFes1MatnrCat[] = $matCatKey; } $resNeed = $resourceFes1; // Set resource ke 1F71FA $categoryClass = match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; // Status Komposisi & Missing FES1 (pre-loaded batch) $hasComp = ($compFesMap[$matnrShow] ?? false); $rowClass = $hasComp ? '' : 'table-danger'; $fesMissKey = "{$matnrShow}|{$resNeed}|{$orderVal}"; $fesHasMissing = (bool) ($missingFesMap[$fesMissKey] ?? false); // Hitung Value Baris Utama $tSum = round((float) ($targetOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $aSum = round((float) ($actualOrderSumMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? 0), 3); $pSum = $aSum > 0 ? round(($tSum / $aSum) * 100, 2) : 0; $targetVal = (float) ($r['target'] ?? 0); $actualVal = (float) ($r['actual'] ?? 0); $yieldVal = (float) ($r['yield'] ?? 0); // Buat ID unik (pakai FES1) $rid = 'detail-FES1-' . $i . '-' . preg_replace('/\W+/', '-', $orderVal ?: 'NOORD'); @endphp {{-- Render Baris Utama --}}
{{ $matnrShow }} @php $compIdSel = $chosenFes[$matnrShow] ?? null; @endphp @if ($compIdSel) Comp: {{ $compIdSel }} @endif
{{-- Button Comp --}} {{-- Button Missing (always visible, data loaded via AJAX) --}}
{{ $orderVal ?: '-' }} {{ $fmtNum($tSum, 2) }} {{ $fmtNum($aSum, 2) }} {{ $fmtNum($pSum) }}% {{-- Logic Detail per Kategori --}} @php $allCatsFes1 = array_keys($catsByOrderMap["{$matnrShow}|{$resNeed}|{$orderVal}"] ?? []); @endphp @foreach ($allCatsFes1 as $cat) @php $tKg = round((float) ($targetLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $aKg = round((float) ($actualLookupMap["{$matnrShow}|{$resNeed}|{$orderVal}|{$cat}"] ?? 0), 3); $pc = $aKg > 0 ? round(($tKg / $aKg) * 100, 2) : 0; @endphp {{ $cat }} {{ number_format($tKg, 2) }} {{ number_format($aKg, 2) }} {{ number_format($pc, 2) }}% @endforeach {{-- OUTPUT {{ number_format($targetVal, 2) }} {{ number_format($actualVal, 2) }} {{ number_format($yieldVal, 2) }}% --}} @empty Tidak ada data XINYAN C-Fold. @endforelse {{-- TOTAL ROW (Terpisah per Kategori) --}} @php // Hitung total untuk masing-masing kategori FES1 (1F71FA) // Total untuk Order (prefix 11) $totalTargetFes111 = round((float) ($targetPrefixTotals['1F71FA|11'] ?? 0), 2); $totalActualFes111 = round((float) ($actualPrefixTotals['1F71FA|11'] ?? 0), 2); $totalYieldFes111 = $totalActualFes111 > 0 ? round(($totalTargetFes111 / $totalActualFes111) * 100, 2) : 0; // Total untuk Sample (prefix 13) $totalTargetFes113 = round((float) ($targetPrefixTotals['1F71FA|13'] ?? 0), 2); $totalActualFes113 = round((float) ($actualPrefixTotals['1F71FA|13'] ?? 0), 2); $totalYieldFes113 = $totalActualFes113 > 0 ? round(($totalTargetFes113 / $totalActualFes113) * 100, 2) : 0; // Total untuk Refestooning (semua prefix selain 11 dan 13) $totalTargetFes112 = round((float) collect($targetPrefixTotals)->filter(fn($v, $k) => str_starts_with($k, '1F71FA|') && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalActualFes112 = round((float) collect($actualPrefixTotals)->filter(fn($v, $k) => str_starts_with($k, '1F71FA|') && !in_array(substr($k, -2), ['11', '13']))->sum(), 2); $totalYieldFes112 = $totalActualFes112 > 0 ? round(($totalTargetFes112 / $totalActualFes112) * 100, 2) : 0; // Hitung Avg Yield per kategori $allYieldsFes111 = []; $allYieldsFes113 = []; $allYieldsFes112 = []; foreach ($avgYieldByFes1Matnr as $matnr => $categories) { if ( isset($categories['cat-11']) && is_numeric($categories['cat-11']) && $categories['cat-11'] > 0 ) { $allYieldsFes111[] = $categories['cat-11']; } if ( isset($categories['cat-13']) && is_numeric($categories['cat-13']) && $categories['cat-13'] > 0 ) { $allYieldsFes113[] = $categories['cat-13']; } if ( isset($categories['cat-12']) && is_numeric($categories['cat-12']) && $categories['cat-12'] > 0 ) { $allYieldsFes112[] = $categories['cat-12']; } } $avgYieldTotalFes111 = count($allYieldsFes111) > 0 ? round( array_sum($allYieldsFes111) / count($allYieldsFes111), 2, ) : 0; $avgYieldTotalFes113 = count($allYieldsFes113) > 0 ? round( array_sum($allYieldsFes113) / count($allYieldsFes113), 2, ) : 0; $avgYieldTotalFes112 = count($allYieldsFes112) > 0 ? round( array_sum($allYieldsFes112) / count($allYieldsFes112), 2, ) : 0; @endphp {{-- Total untuk Order (11) --}} TOTAL {{ number_format($totalTargetFes111, 2) }} {{ number_format($totalActualFes111, 2) }} {{ number_format($totalYieldFes111, 2) }}% {{-- Total untuk Sample (13) --}} TOTAL {{ number_format($totalTargetFes113, 2) }} {{ number_format($totalActualFes113, 2) }} {{ number_format($totalYieldFes113, 2) }}% {{-- Total untuk Refestooning (12) --}} TOTAL {{ number_format($totalTargetFes112, 2) }} {{ number_format($totalActualFes112, 2) }} {{ number_format($totalYieldFes112, 2) }}%
{{-- ===== Yield — REFINNO (1F5151 & 1F51FA) ===== --}}
REFINNO (1F5151 & 1F51FA)
Material Order SFG FG Yield Main Extruder Jumbo %Jumbo Jumbo Rwd Roll FM %Roll FM @php // Build Roll FM lookup per (matnr|order) dari helper by-order (sesuai query referensi SQL) $rollFmByMatnrOrder = collect($refinnoRollFmByOrder ?? []) ->map(fn($r) => is_array($r) ? (object) $r : $r) ->filter(fn($r) => (string) ($r->material_fg ?? '') !== 'GRAND TOTAL') ->keyBy(fn($r) => (string) ($r->material_fg ?? '') . '|' . (string) ($r->order_fg ?? '')) ->map(fn($r) => round((float) ($r->total_qty_fm ?? 0), 3)); // Build Main Extruder lookup per order dari v_pivot_entry 1F5151 $mainExtByOrder = collect($refinnoMainExtByOrder ?? []) ->map(fn($r) => is_array($r) ? (object) $r : $r) ->keyBy(fn($r) => (string) ($r->order ?? '')) ->map(fn($r) => round((float) ($r->main_extruder ?? 0), 3)); // Build Jumbo Rwd Usage lookup per (matnr|order) dari v_pivot_usage 1F51FA $jumboRwdUsageByMatnrOrder = collect($refinnoJumboRwdUsage ?? []) ->keyBy(fn($r) => ($r->matnr ?? '') . '|' . ($r->order ?? '')) ->map(fn($r) => round((float) ($r->jumbo_rwd_usage ?? 0), 3)); // Build Jumbo Rwd Usage detail lookup per matnr (grouped by order) $jumboRwdUsageDetailByMatnr = $refinnoJumboRwdUsageDetail ?? collect(); $rfmDetailByMatnrOrder = collect($refinnoRollFmDetailByOrder ?? collect()); $orderCategoryRefinno = function ($order) { $prefix = substr((string) $order, 0, 2); return match ($prefix) { '13' => 'cat-13', '11' => 'cat-11', default => 'cat-12', }; }; // Base data per (matnr, order) $refinnoDataRaw = collect($refinnoRows ?? []) ->map(fn($r) => is_array($r) ? $r : (array) $r) ->groupBy(fn($r) => ($r['matnr'] ?? '') . '|' . ($r['order'] ?? '')) ->map(function ($group) { $first = $group->first(); return [ 'matnr' => (string) ($first['matnr'] ?? ''), 'order' => (string) ($first['order'] ?? ''), 'entry_qty' => round($group->sum(fn($r) => (float) ($r['entry_qty'] ?? 0)), 3), 'jumbo_rwd' => round($group->sum(fn($r) => (float) ($r['jumbo_rwd'] ?? 0)), 3), 'runtime' => round($group->sum(fn($r) => (float) ($r['runtm'] ?? $r['runtime'] ?? 0)), 3), 'totaltime' => round($group->unique(fn($r) => ($r['pdate'] ?? '') . '|' . ($r['sg'] ?? ''))->sum(fn($r) => (float) ($r['totaltime'] ?? 0)), 3), 'items' => $group->values()->all(), ]; }) ->values(); // Roll FM lookup sesuai SQL (core matnr + order prefix) $rollFmByCorePrefix = collect($refinnoRollFmByPrefix ?? []) ->map(fn($r) => is_array($r) ? (object) $r : $r) ->filter(fn($r) => (string) ($r->core_matnr ?? '') !== '') ->mapWithKeys(fn($r) => [ (string) ($r->core_matnr ?? '') . '|' . (string) ($r->order_prefix ?? '') => round((float) ($r->total_roll_fm ?? 0), 3), ]); $rollFmPrefixTotalsByCore = collect($refinnoRollFmByPrefix ?? []) ->map(fn($r) => is_array($r) ? (object) $r : $r) ->filter(fn($r) => (string) ($r->core_matnr ?? '') !== '') ->groupBy(fn($r) => (string) ($r->core_matnr ?? '')) ->map(function ($group) { return $group->mapWithKeys(function ($r) { $prefix = (string) ($r->order_prefix ?? ''); return [$prefix => round((float) ($r->total_roll_fm ?? 0), 3)]; }); }); $rollFmOthersByCore = $rollFmPrefixTotalsByCore->map(function ($prefixMap) { return $prefixMap ->filter(fn($v, $k) => !in_array((string) $k, ['11', '13'], true)) ->sum(); }); // Jumbo Rwd (usage) lookup sesuai SQL (core matnr + order prefix) $jumboRwdByCorePrefix = collect($refinnoJumboRwdByPrefix ?? []) ->map(fn($r) => is_array($r) ? (object) $r : $r) ->filter(fn($r) => (string) ($r->core_matnr ?? '') !== '') ->mapWithKeys(fn($r) => [ (string) ($r->core_matnr ?? '') . '|' . (string) ($r->order_prefix ?? '') => round((float) ($r->total_jumbo_rwd ?? 0), 3), ]); $jumboRwdPrefixTotalsByCore = collect($refinnoJumboRwdByPrefix ?? []) ->map(fn($r) => is_array($r) ? (object) $r : $r) ->filter(fn($r) => (string) ($r->core_matnr ?? '') !== '') ->groupBy(fn($r) => (string) ($r->core_matnr ?? '')) ->map(function ($group) { return $group->mapWithKeys(function ($r) { $prefix = (string) ($r->order_prefix ?? ''); return [$prefix => round((float) ($r->total_jumbo_rwd ?? 0), 3)]; }); }); $jumboRwdOthersByCore = $jumboRwdPrefixTotalsByCore->map(function ($prefixMap) { return $prefixMap ->filter(fn($v, $k) => !in_array((string) $k, ['11', '13'], true)) ->sum(); }); $coreMatnrFromFg = function (string $matnr) { $parts = array_values(array_filter(explode('-', $matnr), fn($p) => $p !== '')); if (count($parts) >= 3) { $core = implode('-', array_slice($parts, 0, 3)); if (str_starts_with($core, '7')) { $core = substr($core, 1); } return $core; } return $matnr; }; $catRankRefinno = ['cat-11' => 1, 'cat-13' => 2, 'cat-12' => 3]; // Group dashboard row per MATNR + kategori order (11/13/others), // tetap simpan list order unik untuk informasi dan detail. $refinnoData = $refinnoDataRaw ->groupBy(fn($r) => ($r['matnr'] ?? '') . '|' . $orderCategoryRefinno($r['order'] ?? '')) ->map(function ($group) use ( $orderCategoryRefinno, $mainExtByOrder, $rollFmByCorePrefix, $rollFmOthersByCore, $jumboRwdByCorePrefix, $jumboRwdOthersByCore, $coreMatnrFromFg, $jumboRwdUsageByMatnrOrder, $jumboRwdUsageDetailByMatnr, $rfmDetailByMatnrOrder, ) { $first = $group->first(); $matnr = (string) ($first['matnr'] ?? ''); $category = (string) $orderCategoryRefinno($first['order'] ?? ''); $orders = $group ->pluck('order') ->map(fn($o) => trim((string) $o)) ->filter() ->unique() ->sort() ->values(); $mainExtFromLookup = round((float) $orders->sum(fn($ord) => (float) $mainExtByOrder->get($ord, 0)), 3); $mainExtFallback = round((float) $group->sum(fn($r) => (float) ($r['entry_qty'] ?? 0)), 3); $mainExtruder = $mainExtFromLookup > 0 ? $mainExtFromLookup : $mainExtFallback; $jumboRwd = round((float) $group->sum(fn($r) => (float) ($r['jumbo_rwd'] ?? 0)), 3); $runtime = round((float) $group->sum(fn($r) => (float) ($r['runtime'] ?? 0)), 3); $allItemsInGroup = $group->flatMap(fn($item) => $item['items'] ?? [$item]); $totaltime = round((float) $allItemsInGroup ->unique(fn($r) => ($r['pdate'] ?? '') . '|' . ($r['sg'] ?? '')) ->sum(fn($r) => (float) ($r['totaltime'] ?? 0)), 3); // Derive core_matnr dari rfm item (resource 1F51FA) agar cocok // dengan SUBSTRING_INDEX(matnr, '-', 3) di SQL rollFmByCorePrefix. // Parent matnr (1F5151) = TE0RD0-H00W10-00020, tapi // rfm matnr (1F51FA) = 7TE0RD0-H00W10-00020-0000140L // → core = 7TE0RD0-H00W10-00020 $firstRfmItem = $orders ->map(fn($ord) => collect($rfmDetailByMatnrOrder->get($matnr . '|' . $ord, []))->first()) ->filter() ->first(); $coreMatnr = $firstRfmItem ? $coreMatnrFromFg((string) ($firstRfmItem['matnr'] ?? $matnr)) : $coreMatnrFromFg($matnr); $rollFmBase = match ($category) { 'cat-11' => (float) $rollFmByCorePrefix->get($coreMatnr . '|11', 0), 'cat-13' => (float) $rollFmByCorePrefix->get($coreMatnr . '|13', 0), default => (float) $rollFmOthersByCore->get($coreMatnr, 0), }; $rollFm = round($rollFmBase, 3); $jumboRwdUsageBase = match ($category) { 'cat-11' => (float) $jumboRwdByCorePrefix->get($coreMatnr . '|11', 0), 'cat-13' => (float) $jumboRwdByCorePrefix->get($coreMatnr . '|13', 0), default => (float) $jumboRwdOthersByCore->get($coreMatnr, 0), }; $jumboRwdUsage = round($jumboRwdUsageBase, 3); $categoryOrderPrefix = match ($category) { 'cat-11' => '11', 'cat-13' => '13', default => 'other', }; $rfmDetailItemsCollection = $orders ->flatMap(function ($orderToken) use ($rfmDetailByMatnrOrder, $matnr) { return collect($rfmDetailByMatnrOrder->get($matnr . '|' . $orderToken, [])); }) ->map(function ($item) use ($jumboRwdUsageDetailByMatnr, $categoryOrderPrefix) { $rfmMatnrStripped = substr((string) ($item['matnr'] ?? ''), 1, 19); $orderTokens = collect(explode(',', (string) ($item['order_list'] ?? ''))) ->map(fn($o) => trim((string) $o)) ->filter() ->values(); $filteredTokens = $orderTokens; if ($categoryOrderPrefix === '11' || $categoryOrderPrefix === '13') { $filteredTokens = $orderTokens->filter(function ($o) use ($categoryOrderPrefix) { return substr((string) $o, 0, 2) === $categoryOrderPrefix; })->values(); } elseif ($categoryOrderPrefix === 'other') { $filteredTokens = $orderTokens->filter(function ($o) { $prefix = substr((string) $o, 0, 2); return $prefix !== '11' && $prefix !== '13'; })->values(); } if ($filteredTokens->isEmpty()) { $filteredTokens = $orderTokens; } $jrdForRfm = collect($jumboRwdUsageDetailByMatnr->get($rfmMatnrStripped, [])) ->filter(function ($j) use ($filteredTokens) { $ord = (string) ($j['order'] ?? ''); return $ord !== '' && $filteredTokens->contains($ord); }); $item['order_prefix'] = $categoryOrderPrefix; $item['order_list'] = $filteredTokens->implode(', '); $item['jrd_val'] = (float) round($jrdForRfm->sum('jumbo_rwd_usage'), 3); return $item; }) ->filter(fn($item) => (string) ($item['matnr'] ?? '') !== '') ->unique(fn($item) => (string) ($item['matnr'] ?? '') . '|' . (string) ($item['order_list'] ?? '')) ->groupBy(fn($item) => (string) ($item['matnr'] ?? '') . '|' . (string) ($item['order_prefix'] ?? '')) ->map(function ($group) { $first = $group->first(); return [ 'matnr' => (string) ($first['matnr'] ?? ''), 'order_list' => $group->pluck('order_list')->filter()->flatMap(fn($s) => array_map('trim', explode(',', (string) $s)))->filter(fn($o) => $o !== '')->unique()->implode(', '), 'order_prefix' => (string) ($first['order_prefix'] ?? ''), 'kg_fm' => (float) round($group->sum('kg_fm'), 3), 'jrd_val' => (float) round($group->sum('jrd_val'), 3), 'items' => $group->values()->all(), ]; }) ->values(); // Override Jumbo Rwd Header dengan SUM(detail child) jika terdapat detail child untuk Tab Order / Sample if (in_array($category, ['cat-11', 'cat-13']) && $rfmDetailItemsCollection->isNotEmpty()) { $jumboRwdUsage = round((float) $rfmDetailItemsCollection->sum('jrd_val'), 3); } return [ 'matnr' => $matnr, 'order' => (string) ($orders->first() ?? ''), 'order_list' => $orders->implode(', '), 'orders' => $orders->all(), 'category' => $category, 'entry_qty' => $mainExtruder, 'main_extruder' => $mainExtruder, 'jumbo_rwd' => $jumboRwd, 'jumbo_rwd_usage' => $jumboRwdUsage, 'roll_fm' => $rollFm, 'runtime' => $runtime, 'totaltime' => $totaltime, 'rfm_detail_items' => $rfmDetailItemsCollection, ]; }) ->sortBy(function ($r) use ($catRankRefinno) { $matnr = (string) ($r['matnr'] ?? ''); $rank = (int) ($catRankRefinno[$r['category'] ?? 'cat-12'] ?? 99); return sprintf('%s|%02d', $matnr, $rank); }) ->values(); // Total per kategori $totalKgFmRefinno11 = 0; $totalKgFmRefinno13 = 0; $totalKgFmRefinno12 = 0; // Main Extruder total per kategori $totalMainExt11 = 0; $totalMainExt13 = 0; $totalMainExt12 = 0; // Jumbo Rwd total per kategori $totalJumboRwd11 = 0; $totalJumboRwd13 = 0; $totalJumboRwd12 = 0; // Jumbo Rwd Usage total per kategori $totalJumboRwdUsage11 = 0; $totalJumboRwdUsage13 = 0; $totalJumboRwdUsage12 = 0; @endphp @forelse ($refinnoData as $i => $rRow) @php $matnrRefinno = (string) ($rRow['matnr'] ?? ''); $orderRefinno = (string) ($rRow['order_list'] ?? ($rRow['order'] ?? '')); $ordersRefinno = collect($rRow['orders'] ?? []) ->map(fn($o) => trim((string) $o)) ->filter() ->values(); if ($ordersRefinno->isEmpty() && $orderRefinno !== '') { $ordersRefinno = collect(explode(',', $orderRefinno)) ->map(fn($o) => trim((string) $o)) ->filter() ->values(); } $categoryKeyRefinno = (string) ($rRow['category'] ?? 'cat-12'); $categoryClassRefinno = $categoryKeyRefinno; // Derive core_matnr dari rfm item (1F51FA) agar cocok dgn SQL $firstRfmForCore = $ordersRefinno ->map(fn($ord) => collect($rfmDetailByMatnrOrder->get($matnrRefinno . '|' . $ord, []))->first()) ->filter() ->first(); $coreMatnr = $firstRfmForCore ? $coreMatnrFromFg((string) ($firstRfmForCore['matnr'] ?? $matnrRefinno)) : $coreMatnrFromFg($matnrRefinno); // Nilai utama sudah diakumulasi pada level MATNR + kategori. $mainExtVal = round((float) ($rRow['main_extruder'] ?? $rRow['entry_qty'] ?? 0), 3); $jumboRwdVal = round((float) ($rRow['jumbo_rwd'] ?? 0), 3); $jumboRwdUsageVal = round((float) ($rRow['jumbo_rwd_usage'] ?? 0), 3); $rollFmVal = round((float) ($rRow['roll_fm'] ?? 0), 3); $pctJumboRwd = $mainExtVal > 0 ? round(($jumboRwdVal / $mainExtVal) * 100, 2) : 0; $yieldVal = $mainExtVal > 0 ? round(($rollFmVal / $mainExtVal) * 100, 2) : 0; // Akumulasi total per kategori. match ($categoryKeyRefinno) { 'cat-11' => $totalKgFmRefinno11 += $rollFmVal, 'cat-13' => $totalKgFmRefinno13 += $rollFmVal, default => $totalKgFmRefinno12 += $rollFmVal, }; // Akumulasi main extruder per kategori match ($categoryKeyRefinno) { 'cat-11' => $totalMainExt11 += $mainExtVal, 'cat-13' => $totalMainExt13 += $mainExtVal, default => $totalMainExt12 += $mainExtVal, }; match ($categoryKeyRefinno) { 'cat-11' => $totalJumboRwd11 += $jumboRwdVal, 'cat-13' => $totalJumboRwd13 += $jumboRwdVal, default => $totalJumboRwd12 += $jumboRwdVal, }; $categoryOrderPrefix = match ($categoryKeyRefinno) { 'cat-11' => '11', 'cat-13' => '13', default => 'other', }; $parentKeyRefinno = $matnrRefinno . '|' . $categoryKeyRefinno; $rfmDetailItemsCollection = collect($rRow['rfm_detail_items'] ?? []); match ($categoryKeyRefinno) { 'cat-11' => $totalJumboRwdUsage11 += $jumboRwdUsageVal, 'cat-13' => $totalJumboRwdUsage13 += $jumboRwdUsageVal, default => $totalJumboRwdUsage12 += $jumboRwdUsageVal, }; $pctFm = $jumboRwdUsageVal > 0 ? round(($rollFmVal / $jumboRwdUsageVal) * 100, 2) : 0; // Pisahkan item yang punya kedua value (jumbo rwd & roll fm) dan yang hanya roll fm $itemsWithBoth = $rfmDetailItemsCollection->filter(fn($item) => ($item['jrd_val'] ?? 0) > 0 && ($item['kg_fm'] ?? 0) > 0); $itemsRollFmOnly = $rfmDetailItemsCollection->filter(fn($item) => ($item['jrd_val'] ?? 0) <= 0 && ($item['kg_fm'] ?? 0) > 0); $rawRfmSum = round((float) $rfmDetailItemsCollection ->sum(fn($item) => (float) ($item['kg_fm'] ?? 0)), 3); $missingRollFm = round(max(0, (float) $rollFmVal - $rawRfmSum), 3); // Jumlahkan kg_fm dari item yang hanya punya Roll FM ke item pertama yang punya kedua value $extraKgFm = $itemsRollFmOnly->sum(fn($item) => (float) ($item['kg_fm'] ?? 0)) + $missingRollFm; // Kumpulkan matnr dan order_list dari item yang digabungkan untuk detail breakdown $mergedMatnrs = $itemsRollFmOnly->pluck('matnr')->filter()->values()->all(); $mergedOrderLists = $itemsRollFmOnly->pluck('order_list')->filter()->values()->all(); $rfmDetailItemsForRow = $itemsWithBoth->values()->map(function ($item, $index) use ($extraKgFm, $mergedMatnrs, $mergedOrderLists, $itemsWithBoth) { if ($index === 0 && $extraKgFm > 0) { $item['kg_fm'] = round((float) ($item['kg_fm'] ?? 0) + $extraKgFm, 3); $item['merged_matnrs'] = $mergedMatnrs; $item['merged_order_lists'] = $mergedOrderLists; $item['use_core'] = true; // Kumpulkan matnr sub-row lain untuk di-exclude dari query core $item['exclude_matnrs'] = $itemsWithBoth->values() ->filter(fn($it, $idx) => $idx !== 0) ->pluck('matnr') ->filter() ->values() ->all(); } return $item; })->all(); @endphp {{ $matnrRefinno }} {{ $orderRefinno ?: '-' }} {{ $mainExtVal > 0 ? number_format($mainExtVal, 2) : '-' }} {{ $jumboRwdVal > 0 ? number_format($jumboRwdVal, 2) : '-' }} {{ $pctJumboRwd > 0 ? number_format($pctJumboRwd, 2) . '%' : '-' }} @if ($jumboRwdUsageVal > 0) {{ number_format($jumboRwdUsageVal, 2) }} @else - @endif @if ($rollFmVal > 0 && count($rfmDetailItemsForRow) > 0) {{ number_format($rollFmVal, 2) }} @else {{ $rollFmVal > 0 ? number_format($rollFmVal, 2) : '-' }} @endif {{ $pctFm > 0 ? number_format($pctFm, 2) . '%' : '-' }} {{ $yieldVal > 0 ? number_format($yieldVal, 2) . '%' : '-' }} {{-- Detail sub-rows 1F51FA untuk matnr+order ini --}} @if (count($rfmDetailItemsForRow) > 0) @foreach ($rfmDetailItemsForRow as $rfmItem) {{ $rfmItem['matnr'] }} - - - - @if (($rfmItem['jrd_val'] ?? 0) > 0) {{ number_format((float) ($rfmItem['jrd_val'] ?? 0), 2) }} @else - @endif {{ number_format($rfmItem['kg_fm'], 2) }} - - @endforeach @endif @empty
Loading...
Memuat data REFINNO...
@endforelse @php $yieldTotal11 = $totalMainExt11 > 0 ? round(($totalKgFmRefinno11 / $totalMainExt11) * 100, 2) : 0; $yieldTotal13 = $totalMainExt13 > 0 ? round(($totalKgFmRefinno13 / $totalMainExt13) * 100, 2) : 0; $yieldTotal12 = $totalMainExt12 > 0 ? round(($totalKgFmRefinno12 / $totalMainExt12) * 100, 2) : 0; // %FM total = Total Roll FM / Total Jumbo * 100 $pctFmTotal11 = $totalJumboRwdUsage11 > 0 ? round(($totalKgFmRefinno11 / $totalJumboRwdUsage11) * 100, 2) : 0; $pctFmTotal13 = $totalJumboRwdUsage13 > 0 ? round(($totalKgFmRefinno13 / $totalJumboRwdUsage13) * 100, 2) : 0; $pctFmTotal12 = $totalJumboRwdUsage12 > 0 ? round(($totalKgFmRefinno12 / $totalJumboRwdUsage12) * 100, 2) : 0; // %Jumbo total = Total Jumbo (usage) / Total Main Ext * 100 $pctJumboRwdTotal11 = $totalMainExt11 > 0 ? round(($totalJumboRwd11 / $totalMainExt11) * 100, 2) : 0; $pctJumboRwdTotal13 = $totalMainExt13 > 0 ? round(($totalJumboRwd13 / $totalMainExt13) * 100, 2) : 0; $pctJumboRwdTotal12 = $totalMainExt12 > 0 ? round(($totalJumboRwd12 / $totalMainExt12) * 100, 2) : 0; @endphp {{-- Total untuk Order (11) --}} TOTAL {{ number_format($totalMainExt11, 2) }} {{ $totalJumboRwd11 > 0 ? number_format($totalJumboRwd11, 2) : '-' }} {{ $pctJumboRwdTotal11 > 0 ? number_format($pctJumboRwdTotal11, 2) . '%' : '-' }} {{ $totalJumboRwdUsage11 > 0 ? number_format($totalJumboRwdUsage11, 2) : '-' }} {{ $totalKgFmRefinno11 > 0 ? number_format($totalKgFmRefinno11, 2) : '-' }} {{ $pctFmTotal11 > 0 ? number_format($pctFmTotal11, 2) . '%' : '-' }} {{ $yieldTotal11 > 0 ? number_format($yieldTotal11, 2) . '%' : '-' }} {{-- Total untuk Sample (13) --}} TOTAL {{ number_format($totalMainExt13, 2) }} {{ $totalJumboRwd13 > 0 ? number_format($totalJumboRwd13, 2) : '-' }} {{ $pctJumboRwdTotal13 > 0 ? number_format($pctJumboRwdTotal13, 2) . '%' : '-' }} {{ $totalJumboRwdUsage13 > 0 ? number_format($totalJumboRwdUsage13, 2) : '-' }} {{ $totalKgFmRefinno13 > 0 ? number_format($totalKgFmRefinno13, 2) : '-' }} {{ $pctFmTotal13 > 0 ? number_format($pctFmTotal13, 2) . '%' : '-' }} {{ $yieldTotal13 > 0 ? number_format($yieldTotal13, 2) . '%' : '-' }} {{-- Total untuk Refestooning (12) --}} TOTAL {{ number_format($totalMainExt12, 2) }} {{ $totalJumboRwd12 > 0 ? number_format($totalJumboRwd12, 2) : '-' }} {{ $pctJumboRwdTotal12 > 0 ? number_format($pctJumboRwdTotal12, 2) . '%' : '-' }} {{ $totalJumboRwdUsage12 > 0 ? number_format($totalJumboRwdUsage12, 2) : '-' }} {{ $totalKgFmRefinno12 > 0 ? number_format($totalKgFmRefinno12, 2) : '-' }} {{ $pctFmTotal12 > 0 ? number_format($pctFmTotal12, 2) . '%' : '-' }} {{ $yieldTotal12 > 0 ? number_format($yieldTotal12, 2) . '%' : '-' }}
{{-- ===================== PANE: WASTE ===================== --}}
{{-- ========== Waste — SAP ========== --}}
Waste — SAP
Material Reject Tarikan Trim Others
Memuat Waste SAP...
{{-- ========== Waste — FES ========== --}}
Waste — FES
Material Reject Sisa Core Extra Length Others
Memuat Waste FES...
{{-- ========== Waste — SAP1 (1F7171) ========== --}}
Waste — XINYAN SAP (1F7171)
Material Reject Tarikan Trim Others
Memuat Waste SAP...
{{-- ========== Waste — FES1 (1F71FA) ========== --}}
Waste — XINYAN C-Fold (1F71FA)
Material Reject Sisa Core Extra Length Others
Memuat Waste FES1...
{{-- ========== Waste — REFINNO (1F5151 & 1F51FA) ========== --}} {{-- ========== Waste — REFINNO (1F5151 & 1F51FA) ========== --}}
Waste — REFINNO (1F5151 & 1F51FA)
Material Reject Trim Tambahan Sisa Waste
Memuat Waste REFINNO...
{{-- ===================== PANE: OEE ===================== --}}
{{-- ===== OEE — SAP (1A0051) ===== --}}
OEE — SAP (1A0051)
Material Order Main Extruder Jumbo SFG Jumbo Rwd Roll FM Runtime Downtime Totaltime Yield Data OEE OEE Availability Performance Quality Belum tersedia.
{{-- ===== OEE — FES (1A0057) ===== --}}
OEE — FES (1A0057)
Material Order Main Extruder Jumbo SFG Jumbo Rwd Roll FM Runtime Downtime Totaltime Yield Data OEE OEE Availability Performance Quality Belum tersedia.
{{-- ===== OEE — XINYAN SAP (1F7171) ===== --}}
OEE — XINYAN SAP (1F7171)
Material Order Main Extruder Jumbo SFG Jumbo Rwd Roll FM Runtime Totaltime Yield Data OEE OEE Availability Performance Quality Belum tersedia.
{{-- ===== OEE — XINYAN C-Fold (1F71FA) ===== --}}
OEE — XINYAN C-Fold (1F71FA)
Material Order Main Extruder Jumbo SFG Jumbo Rwd Roll FM Runtime Totaltime Yield Data OEE OEE Availability Performance Quality Belum tersedia.
{{-- ===== OEE — REFINNO (1F5151 & 1F51FA) ===== --}} @php $rawForGrandAll = collect($refinnoRows ?? [])->map(fn($r) => is_array($r) ? $r : (array) $r); $refinnoTotaltimeUnique = $rawForGrandAll ->unique(fn($r) => ($r['pdate'] ?? '') . '|' . ($r['sg'] ?? '')) ->sum(fn($r) => (float)($r['totaltime'] ?? 0)); @endphp
OEE — REFINNO (1F5151 & 1F51FA)
Material Order Main Extruder Jumbo SFG Jumbo Rwd Roll FM Runtime Totaltime Yield Data OEE OEE Availability Performance Quality @php // Re-use refinnoData from Yield pane (already computed above) $oeeRefinnoRows = collect($refinnoData ?? [])->values(); $oeeJumboRwdUsageDetailByMatnr = $jumboRwdUsageDetailByMatnr ?? ($refinnoJumboRwdUsageDetail ?? collect()); // Grand totals for OEE REFINNO $oeeGrandMainExt11 = 0; $oeeGrandMainExt13 = 0; $oeeGrandMainExt12 = 0; $oeeGrandJumboSfg11 = 0; $oeeGrandJumboSfg13 = 0; $oeeGrandJumboSfg12 = 0; $oeeGrandJumboRwd11 = 0; $oeeGrandJumboRwd13 = 0; $oeeGrandJumboRwd12 = 0; $oeeGrandRollFm11 = 0; $oeeGrandRollFm13 = 0; $oeeGrandRollFm12 = 0; $oeeGrandJumboRwdUsage11 = 0; $oeeGrandJumboRwdUsage13 = 0; $oeeGrandJumboRwdUsage12 = 0; $oeeGrandRuntime11 = 0; $oeeGrandRuntime13 = 0; $oeeGrandRuntime12 = 0; $oeeGrandTotaltime11 = 0; $oeeGrandTotaltime13 = 0; $oeeGrandTotaltime12 = 0; @endphp @forelse ($oeeRefinnoRows as $oeeRow) @php $oeeMatnr = (string) ($oeeRow['matnr'] ?? ''); $oeeOrder = (string) ($oeeRow['order_list'] ?? ($oeeRow['order'] ?? '')); $oeeCatKey = (string) ($oeeRow['category'] ?? 'cat-12'); // Nilai OEE mengikuti agregasi MATNR + kategori yang sama dengan tab Yield. $oeeMainExtVal = round((float) ($oeeRow['main_extruder'] ?? $oeeRow['entry_qty'] ?? 0), 3); $oeeJumboSfgVal = round((float) ($oeeRow['jumbo_rwd'] ?? 0), 3); $oeeJumboRwdVal = round((float) ($oeeRow['jumbo_rwd_usage'] ?? 0), 3); $oeeRuntimeSum = round((float) ($oeeRow['runtime'] ?? 0), 3); $oeeTotaltimeSum = round((float) ($oeeRow['totaltime'] ?? 0), 3); $oeeRollFmVal = round((float) ($oeeRow['roll_fm'] ?? 0), 3); $oeeJumboRwdUsageVal = $oeeJumboRwdVal; $oeeYieldVal = $oeeMainExtVal > 0 ? round(($oeeRollFmVal / $oeeMainExtVal) * 100, 2) : 0; $oeeAvailabilityVal = ($oeeRuntimeSum > 0 && $oeeTotaltimeSum > 0) ? round(($oeeRuntimeSum / $oeeTotaltimeSum) * 100, 2) : 0; $oeeQualityVal = $oeeJumboRwdUsageVal > 0 ? round(($oeeRollFmVal / $oeeJumboRwdUsageVal) * 100, 2) : 0; $oeeKapasitasVal = $oeeRuntimeSum > 0 ? ($oeeJumboSfgVal / $oeeRuntimeSum) : 0; $oeePerformanceVal = $oeeKapasitasVal > 0 ? round(($oeeKapasitasVal / 458) * 100, 2) : 0; $oeeVal = ($oeeAvailabilityVal > 0 && $oeePerformanceVal > 0 && $oeeQualityVal > 0) ? round(($oeeAvailabilityVal / 100) * ($oeePerformanceVal / 100) * ($oeeQualityVal / 100) * 100, 2) : 0; // Accumulate grand totals per category (per order row) match ($oeeCatKey) { 'cat-11' => [ $oeeGrandMainExt11 += $oeeMainExtVal, $oeeGrandJumboSfg11 += $oeeJumboSfgVal, $oeeGrandJumboRwd11 += $oeeJumboRwdVal, $oeeGrandRollFm11 += $oeeRollFmVal, $oeeGrandJumboRwdUsage11 += $oeeJumboRwdUsageVal, $oeeGrandRuntime11 += $oeeRuntimeSum, $oeeGrandTotaltime11 += $oeeTotaltimeSum, ], 'cat-13' => [ $oeeGrandMainExt13 += $oeeMainExtVal, $oeeGrandJumboSfg13 += $oeeJumboSfgVal, $oeeGrandJumboRwd13 += $oeeJumboRwdVal, $oeeGrandRollFm13 += $oeeRollFmVal, $oeeGrandJumboRwdUsage13 += $oeeJumboRwdUsageVal, $oeeGrandRuntime13 += $oeeRuntimeSum, $oeeGrandTotaltime13 += $oeeTotaltimeSum, ], default => [ $oeeGrandMainExt12 += $oeeMainExtVal, $oeeGrandJumboSfg12 += $oeeJumboSfgVal, $oeeGrandJumboRwd12 += $oeeJumboRwdVal, $oeeGrandRollFm12 += $oeeRollFmVal, $oeeGrandJumboRwdUsage12 += $oeeJumboRwdUsageVal, $oeeGrandRuntime12 += $oeeRuntimeSum, $oeeGrandTotaltime12 += $oeeTotaltimeSum, ], }; @endphp {{ $oeeMatnr }} {{ $oeeOrder ?: '-' }} {{ $oeeMainExtVal > 0 ? number_format($oeeMainExtVal, 2) : '-' }} {{ $oeeJumboSfgVal > 0 ? number_format($oeeJumboSfgVal, 2) : '-' }} {{ $oeeJumboRwdVal > 0 ? number_format($oeeJumboRwdVal, 2) : '-' }} {{ $oeeRollFmVal > 0 ? number_format($oeeRollFmVal, 2) : '-' }} {{ ($oeeCatKey !== 'cat-12' && $oeeRuntimeSum > 0) ? number_format($oeeRuntimeSum, 2) : '-' }} {{ ($oeeCatKey !== 'cat-12' && $oeeTotaltimeSum > 0) ? number_format($oeeTotaltimeSum, 2) : '-' }} {{ $oeeYieldVal > 0 ? number_format($oeeYieldVal, 2) . '%' : '-' }} {{ $oeeAvailabilityVal > 0 ? number_format($oeeAvailabilityVal, 2) . '%' : '-' }} {{ $oeePerformanceVal > 0 ? number_format($oeePerformanceVal, 2) . '%' : '-' }} {{ $oeeQualityVal > 0 ? number_format($oeeQualityVal, 2) . '%' : '-' }} {{ $oeeVal > 0 ? number_format($oeeVal, 2) . '%' : '-' }} @empty Tidak ada data OEE REFINNO untuk periode ini. @endforelse @php // Grand Yield per category = Roll FM / Main Extruder * 100 $oeeGrandYield11 = $oeeGrandMainExt11 > 0 ? round(($oeeGrandRollFm11 / $oeeGrandMainExt11) * 100, 2) : 0; $oeeGrandYield13 = $oeeGrandMainExt13 > 0 ? round(($oeeGrandRollFm13 / $oeeGrandMainExt13) * 100, 2) : 0; $oeeGrandYield12 = $oeeGrandMainExt12 > 0 ? round(($oeeGrandRollFm12 / $oeeGrandMainExt12) * 100, 2) : 0; // Grand Totaltime: per category based on unique shifts for that category, fallback to full month $orderCategoryRefinno = function($order) { $p = substr((string)$order, 0, 2); if ($p === '11') return 'cat-11'; if ($p === '13') return 'cat-13'; return 'cat-12'; }; $rawForGrand = collect($refinnoRows ?? [])->map(fn($r) => is_array($r) ? $r : (array) $r); $oeeGrandTotaltimeAll = $rawForGrand ->unique(fn($r) => ($r['pdate'] ?? '') . '|' . ($r['sg'] ?? '')) ->sum(fn($r) => (float)($r['totaltime'] ?? 0)); $oeeGrandTotaltime11 = $rawForGrand ->filter(fn($r) => $orderCategoryRefinno($r['order'] ?? '') === 'cat-11') ->unique(fn($r) => ($r['pdate'] ?? '') . '|' . ($r['sg'] ?? '')) ->sum(fn($r) => (float)($r['totaltime'] ?? 0)); if ($oeeGrandTotaltime11 <= 0) $oeeGrandTotaltime11 = $oeeGrandTotaltimeAll; $oeeGrandTotaltime13 = $rawForGrand ->filter(fn($r) => $orderCategoryRefinno($r['order'] ?? '') === 'cat-13') ->unique(fn($r) => ($r['pdate'] ?? '') . '|' . ($r['sg'] ?? '')) ->sum(fn($r) => (float)($r['totaltime'] ?? 0)); if ($oeeGrandTotaltime13 <= 0) $oeeGrandTotaltime13 = $oeeGrandTotaltimeAll; $oeeGrandTotaltime12 = $rawForGrand ->filter(fn($r) => $orderCategoryRefinno($r['order'] ?? '') === 'cat-12') ->unique(fn($r) => ($r['pdate'] ?? '') . '|' . ($r['sg'] ?? '')) ->sum(fn($r) => (float)($r['totaltime'] ?? 0)); if ($oeeGrandTotaltime12 <= 0) $oeeGrandTotaltime12 = $oeeGrandTotaltimeAll; $oeeGrandAvailability11 = ($oeeGrandRuntime11 > 0 && $oeeGrandTotaltime11 > 0) ? round(($oeeGrandRuntime11 / $oeeGrandTotaltime11) * 100, 2) : 0; $oeeGrandAvailability13 = ($oeeGrandRuntime13 > 0 && $oeeGrandTotaltime13 > 0) ? round(($oeeGrandRuntime13 / $oeeGrandTotaltime13) * 100, 2) : 0; $oeeGrandAvailability12 = ($oeeGrandRuntime12 > 0 && $oeeGrandTotaltime12 > 0) ? round(($oeeGrandRuntime12 / $oeeGrandTotaltime12) * 100, 2) : 0; // Grand Quality per category = Roll FM / Jumbo Rwd Usage * 100 $oeeGrandQuality11 = $oeeGrandJumboRwdUsage11 > 0 ? round(($oeeGrandRollFm11 / $oeeGrandJumboRwdUsage11) * 100, 2) : 0; $oeeGrandQuality13 = $oeeGrandJumboRwdUsage13 > 0 ? round(($oeeGrandRollFm13 / $oeeGrandJumboRwdUsage13) * 100, 2) : 0; $oeeGrandQuality12 = $oeeGrandJumboRwdUsage12 > 0 ? round(($oeeGrandRollFm12 / $oeeGrandJumboRwdUsage12) * 100, 2) : 0; // Grand Performance per category = (kapasitas / 458) * 100 $oeeGrandKapasitas11 = $oeeGrandRuntime11 > 0 ? ($oeeGrandJumboSfg11 / $oeeGrandRuntime11) : 0; $oeeGrandPerformance11 = $oeeGrandKapasitas11 > 0 ? round(($oeeGrandKapasitas11 / 458) * 100, 2) : 0; $oeeGrandKapasitas13 = $oeeGrandRuntime13 > 0 ? ($oeeGrandJumboSfg13 / $oeeGrandRuntime13) : 0; $oeeGrandPerformance13 = $oeeGrandKapasitas13 > 0 ? round(($oeeGrandKapasitas13 / 458) * 100, 2) : 0; $oeeGrandKapasitas12 = $oeeGrandRuntime12 > 0 ? ($oeeGrandJumboSfg12 / $oeeGrandRuntime12) : 0; $oeeGrandPerformance12 = $oeeGrandKapasitas12 > 0 ? round(($oeeGrandKapasitas12 / 458) * 100, 2) : 0; // Alinyemen OEE Grand totals dengan query database langsung untuk mencegah disparitas data $refinnoShiftColl = collect($refinnoDetailShift ?? getRefinnoDetailShift($yearMonth ?? getActiveYearMonth(), $filterMatnr ?? null)); $shiftTotalRollFm = round((float) $refinnoShiftColl->sum('roll_fm_kg'), 3); $shiftTotalJumboRwdUsage = round((float) $refinnoShiftColl->sum('jumbo_rwd_usage'), 3); // Nilai Roll FM & Jumbo Rwd dari tabel aktual (per kategori) // 1. Order (cat-11) & Sample (cat-13) mengambil langsung hasil penjumlahan baris tabel aktual // 2. Others (cat-12) mengambil sisa dari total shift detail agar 100% konsisten secara akumulatif if ($shiftTotalRollFm > 0 && ($oeeGrandRollFm11 + $oeeGrandRollFm13 + $oeeGrandRollFm12) > 0) { $oeeGrandRollFm12 = max(0, round($shiftTotalRollFm - $oeeGrandRollFm11 - $oeeGrandRollFm13, 3)); } if ($shiftTotalJumboRwdUsage > 0) { $oeeGrandJumboRwd12 = max(0, round($shiftTotalJumboRwdUsage - $oeeGrandJumboRwd11 - $oeeGrandJumboRwd13, 3)); $oeeGrandJumboRwdUsage11 = $oeeGrandJumboRwd11; $oeeGrandJumboRwdUsage13 = $oeeGrandJumboRwd13; $oeeGrandJumboRwdUsage12 = $oeeGrandJumboRwd12; } $oeeGrandQuality11 = $oeeGrandJumboRwdUsage11 > 0 ? round(($oeeGrandRollFm11 / $oeeGrandJumboRwdUsage11) * 100, 2) : 0; $oeeGrandQuality13 = $oeeGrandJumboRwdUsage13 > 0 ? round(($oeeGrandRollFm13 / $oeeGrandJumboRwdUsage13) * 100, 2) : 0; $oeeGrandQuality12 = $oeeGrandJumboRwdUsage12 > 0 ? round(($oeeGrandRollFm12 / $oeeGrandJumboRwdUsage12) * 100, 2) : 0; $oeeGrandOee11 = ($oeeGrandAvailability11 > 0 && $oeeGrandPerformance11 > 0 && $oeeGrandQuality11 > 0) ? round(($oeeGrandAvailability11 / 100) * ($oeeGrandPerformance11 / 100) * ($oeeGrandQuality11 / 100) * 100, 2) : 0; $oeeGrandOee13 = ($oeeGrandAvailability13 > 0 && $oeeGrandPerformance13 > 0 && $oeeGrandQuality13 > 0) ? round(($oeeGrandAvailability13 / 100) * ($oeeGrandPerformance13 / 100) * ($oeeGrandQuality13 / 100) * 100, 2) : 0; $oeeGrandOee12 = ($oeeGrandAvailability12 > 0 && $oeeGrandPerformance12 > 0 && $oeeGrandQuality12 > 0) ? round(($oeeGrandAvailability12 / 100) * ($oeeGrandPerformance12 / 100) * ($oeeGrandQuality12 / 100) * 100, 2) : 0; @endphp {{-- Total OEE untuk Order (11) --}} TOTAL {{ $oeeGrandMainExt11 > 0 ? number_format($oeeGrandMainExt11, 2) : '-' }} {{ $oeeGrandJumboSfg11 > 0 ? number_format($oeeGrandJumboSfg11, 2) : '-' }} {{ $oeeGrandJumboRwd11 > 0 ? number_format($oeeGrandJumboRwd11, 2) : '-' }} {{ $oeeGrandRollFm11 > 0 ? number_format($oeeGrandRollFm11, 2) : '-' }} {{ $oeeGrandRuntime11 > 0 ? number_format($oeeGrandRuntime11, 2) : '-' }} {{ $oeeGrandTotaltime11 > 0 ? number_format($oeeGrandTotaltime11, 2) : '-' }} {{ $oeeGrandYield11 > 0 ? number_format($oeeGrandYield11, 2) . '%' : '-' }} {{ $oeeGrandAvailability11 > 0 ? number_format($oeeGrandAvailability11, 2) . '%' : '-' }} {{ $oeeGrandPerformance11 > 0 ? number_format($oeeGrandPerformance11, 2) . '%' : '-' }} {{ $oeeGrandQuality11 > 0 ? number_format($oeeGrandQuality11, 2) . '%' : '-' }} {{ $oeeGrandOee11 > 0 ? number_format($oeeGrandOee11, 2) . '%' : '-' }} {{-- Total OEE untuk Sample (13) --}} TOTAL {{ $oeeGrandMainExt13 > 0 ? number_format($oeeGrandMainExt13, 2) : '-' }} {{ $oeeGrandJumboSfg13 > 0 ? number_format($oeeGrandJumboSfg13, 2) : '-' }} {{ $oeeGrandJumboRwd13 > 0 ? number_format($oeeGrandJumboRwd13, 2) : '-' }} {{ $oeeGrandRollFm13 > 0 ? number_format($oeeGrandRollFm13, 2) : '-' }} {{ $oeeGrandRuntime13 > 0 ? number_format($oeeGrandRuntime13, 2) : '-' }} {{ $oeeGrandTotaltime13 > 0 ? number_format($oeeGrandTotaltime13, 2) : '-' }} {{ $oeeGrandYield13 > 0 ? number_format($oeeGrandYield13, 2) . '%' : '-' }} {{ $oeeGrandAvailability13 > 0 ? number_format($oeeGrandAvailability13, 2) . '%' : '-' }} {{ $oeeGrandPerformance13 > 0 ? number_format($oeeGrandPerformance13, 2) . '%' : '-' }} {{ $oeeGrandQuality13 > 0 ? number_format($oeeGrandQuality13, 2) . '%' : '-' }} {{ $oeeGrandOee13 > 0 ? number_format($oeeGrandOee13, 2) . '%' : '-' }} {{-- Total OEE untuk Refestooning (12) --}} TOTAL {{ $oeeGrandMainExt12 > 0 ? number_format($oeeGrandMainExt12, 2) : '-' }} {{ $oeeGrandJumboSfg12 > 0 ? number_format($oeeGrandJumboSfg12, 2) : '-' }} {{ $oeeGrandJumboRwd12 > 0 ? number_format($oeeGrandJumboRwd12, 2) : '-' }} {{ $oeeGrandRollFm12 > 0 ? number_format($oeeGrandRollFm12, 2) : '-' }} - - {{ $oeeGrandYield12 > 0 ? number_format($oeeGrandYield12, 2) . '%' : '-' }} {{ $oeeGrandAvailability12 > 0 ? number_format($oeeGrandAvailability12, 2) . '%' : '-' }} {{ $oeeGrandPerformance12 > 0 ? number_format($oeeGrandPerformance12, 2) . '%' : '-' }} {{ $oeeGrandQuality12 > 0 ? number_format($oeeGrandQuality12, 2) . '%' : '-' }} {{ $oeeGrandOee12 > 0 ? number_format($oeeGrandOee12, 2) . '%' : '-' }}
@php $tvA = $chart_tvA ?? []; $materials = (array) ($tvA['materials'] ?? []); $defaultKey = $tvA['default_key'] ?? null; @endphp
Trend Target vs Actual / Roll FM vs Main Extruder — per Material
Summary Per Year (Resource)
Yearly Trend Table by Resource -
Bulan Target Actual Yield
Memuat data...
Trend Target vs Actual / Roll FM vs Main Extruder by Resource - Last 12 Months
Yearly Trend Table by Material
Bulan Target / Main Extruder Actual / Roll FM Yield
Memuat data...
Trend Target vs Actual / Roll FM vs Main Extruder by Material - Last 12 Months
@endsection @push('js') @endpush