This commit is contained in:
Dwi Swandhana
2026-03-06 12:40:29 +07:00
parent 27ef021783
commit 3754ae3531
3 changed files with 244 additions and 114 deletions
@@ -114,6 +114,7 @@ class FrontpageController extends Controller
if ($sisaMenit <= 60) { if ($sisaMenit <= 60) {
$earlyWarnings[] = [ $earlyWarnings[] = [
'id' => $row->id, 'id' => $row->id,
'subpoli' => $row->subpoli ?? 'Tanpa Subpoli',
'nofoto' => $row->nofoto, 'nofoto' => $row->nofoto,
'noregister' => $row->noregister, 'noregister' => $row->noregister,
'nmpasien' => $row->nmpasien, 'nmpasien' => $row->nmpasien,
@@ -128,7 +129,21 @@ class FrontpageController extends Controller
]; ];
} }
} }
$data['earlyWarnings'] = $earlyWarnings; $earlyWarningGroups = collect($earlyWarnings)
->groupBy(function ($item) {
return !empty($item['subpoli']) ? $item['subpoli'] : 'Tanpa Subpoli';
})
->map(function ($items, $subpoli) {
return [
'subpoli' => $subpoli,
'total' => count($items),
'items' => array_values($items->toArray()),
];
})
->values()
->toArray();
$data['earlyWarningGroups'] = $earlyWarningGroups;
return view('dokter.dashborad', $data); return view('dokter.dashborad', $data);
} else { } else {
try { try {
@@ -47,84 +47,86 @@
<div class="ribbon ribbon-danger">Rekapitulasi Penerimaan Sample {{$tanggal}}</div> <div class="ribbon ribbon-danger">Rekapitulasi Penerimaan Sample {{$tanggal}}</div>
<p></p> <p></p>
<div class="table-responsive"> <div class="table-responsive">
<div class="rekap-toolbar"> <div class="rekap-toolbar">
<button type="button" class="btn btn-primary" id="btnexport"><i class="fa fa-file-excel-o"></i> Export</button> <button type="button" class="btn btn-primary" id="btnexport"><i class="fa fa-file-excel-o"></i> Export</button>
<select id="printOrientation" class="btn btn-default"> <select id="printOrientation" class="btn btn-default">
<option value="landscape">Landscape</option> <option value="landscape">Landscape</option>
<option value="portrait">Portrait</option> <option value="portrait">Portrait</option>
</select> </select>
<button type="button" class="btn btn-success" id="btnprintselected"><i class="fa fa-print"></i> Cetak Terpilih</button> <select id="sortStatus" class="btn btn-default">
</div> <option value="default">Sort Status (Default)</option>
<option value="asc">Sort Status A-Z</option>
<option value="desc">Sort Status Z-A</option>
</select>
<select id="filterStatus" class="btn btn-default">
<option value="">Filter Status: Semua</option>
</select>
<button type="button" class="btn btn-success" id="btnprintselected"><i class="fa fa-print"></i> Cetak Terpilih</button>
</div>
<div class="rekap-table-wrap"> <div class="rekap-table-wrap">
<table class="table table-bordered table-striped" id="penerimaansamplereport"> <table class="table table-bordered table-striped" id="penerimaansamplereport">
<thead> <thead>
<tr> <tr>
<th style="width: 40px; text-align:center;"> <th style="width: 40px; text-align:center;">
<input type="checkbox" id="checkAllRows"> <input type="checkbox" id="checkAllRows">
</th> </th>
<th>Keterangan Cetak</th> <th>Keterangan Cetak</th>
<th>No.RM</th> <th>No.RM</th>
<th>Nama</th> <th>Nama</th>
<th>No.Sample</th> <th>No.Sample</th>
<th>Asal Pasien</th> <th>Asal Pasien</th>
<th>Daftar</th> <th>Daftar</th>
<th>Order</th> <th>Order</th>
<th>Kode</th> <th>Kode</th>
<th>Spesimen</th> <th>Spesimen</th>
<th>Status</th> <th>Status</th>
<th>Tanggal Terima</th> <th>Tanggal Terima</th>
<th>Petugas</th> <th>Petugas</th>
</tr>
</thead>
<tbody>
@foreach($detail as $r)
@php
$isPrinted = !empty($r['ppdsjunior2']) && $r['ppdsjunior2'] != '0';
@endphp
<tr data-id="{{ $r['id'] }}" class="{{ $isPrinted ? 'printed-row' : '' }}">
<td style="text-align:center;">
<input type="checkbox" class="row-check">
</td>
<td>{{ $r['noregister'] }}</td>
<td>{{ $r['nmpasien'] }}</td>
<td>{{ $r['nofoto'] }}</td>
<td>{{ $r['asalpasien'] }}</td>
<td>{{ $r['daftar'] }}</td>
<td>{{ $r['reques'] }}</td>
<td>{{ $r['kd_spesimen'] }}</td>
<td>{{ $r['nm_spesimen'] }}</td>
<td>{{ $r['status'] }}</td>
<td class="print-status-cell">
@if($isPrinted)
<span class="status-print-badge done">Sudah Dicetak</span>
@else
<span class="status-print-badge pending">Belum Dicetak</span>
@endif
</td>
<td>{{ $r['tgldraft'] }}</td>
<td class="petugas-cell">
@php
$petugas = '';
if ($r['nmppdsmiddle2'] != '') {
$petugas = $r['nmppdsmiddle2'];
}
if ($r['nmppdsjunior2'] != '') {
$petugas = $petugas.' '.$r['nmppdsjunior2'];
}
echo $petugas;
@endphp
</td>
</tr> </tr>
@endforeach </thead>
</tbody> <tbody>
</table> @foreach($detail as $r)
</div> @php
</div> $isPrinted = !empty($r['ppdsjunior2']) && $r['ppdsjunior2'] != '0';
<div class="card-footer"> $statusValue = trim((string)($r['status'] ?? '-'));
$petugas = '';
if ($r['nmppdsmiddle2'] != '') {
$petugas = $r['nmppdsmiddle2'];
}
if ($r['nmppdsjunior2'] != '') {
$petugas = trim($petugas.' '.$r['nmppdsjunior2']);
}
@endphp
<tr data-id="{{ $r['id'] }}" data-status="{{ strtolower($statusValue) }}" data-order="{{ $loop->index }}" class="{{ $isPrinted ? 'printed-row' : '' }}">
<td style="text-align:center;">
<input type="checkbox" class="row-check" {{ $isPrinted ? 'disabled' : '' }}>
</td>
<td class="print-status-cell">
@if($isPrinted)
<span class="status-print-badge done">Sudah Dicetak</span>
@else
<span class="status-print-badge pending">Belum Dicetak</span>
@endif
</td>
<td>{{ $r['noregister'] }}</td>
<td>{{ $r['nmpasien'] }}</td>
<td>{{ $r['nofoto'] }}</td>
<td>{{ $r['asalpasien'] }}</td>
<td>{{ $r['daftar'] }}</td>
<td>{{ $r['reques'] }}</td>
<td>{{ $r['kd_spesimen'] }}</td>
<td>{{ $r['nm_spesimen'] }}</td>
<td>{{ $statusValue }}</td>
<td>{{ $r['tgldraft'] }}</td>
<td class="petugas-cell">{{ $petugas }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div> </div>
<div class="card-footer"></div>
</div> </div>
</div> </div>
</div> </div>
@@ -138,8 +140,11 @@
<script type="text/javascript"> <script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
var table = document.getElementById('penerimaansamplereport'); var table = document.getElementById('penerimaansamplereport');
var tableBody = table ? table.querySelector('tbody') : null;
var checkAllRows = document.getElementById('checkAllRows'); var checkAllRows = document.getElementById('checkAllRows');
var printOrientation = document.getElementById('printOrientation'); var printOrientation = document.getElementById('printOrientation');
var sortStatus = document.getElementById('sortStatus');
var filterStatus = document.getElementById('filterStatus');
var token = document.getElementById('token').value; var token = document.getElementById('token').value;
var markPrintedUrl = @json(route('markRekapPenerimaanSamplePrinted')); var markPrintedUrl = @json(route('markRekapPenerimaanSamplePrinted'));
var appName = @json(config('global.namaapps')); var appName = @json(config('global.namaapps'));
@@ -149,19 +154,85 @@
var appAddress = @json(config('global.addressapps')); var appAddress = @json(config('global.addressapps'));
var petugasCetak = @json(Session('nama')); var petugasCetak = @json(Session('nama'));
function getEnabledVisibleChecks() {
return table ? table.querySelectorAll('tbody tr:not([style*="display: none"]) .row-check:not(:disabled)') : [];
}
function updateCheckAllState() { function updateCheckAllState() {
if (!table || !checkAllRows) { if (!checkAllRows) {
return; return;
} }
var rowChecks = table.querySelectorAll('tbody .row-check:not(:disabled)'); var rowChecks = getEnabledVisibleChecks();
var checkedRows = table.querySelectorAll('tbody .row-check:not(:disabled):checked'); var checkedCount = 0;
checkAllRows.checked = rowChecks.length > 0 && rowChecks.length === checkedRows.length; rowChecks.forEach(function(cb) {
if (cb.checked) {
checkedCount++;
}
});
checkAllRows.checked = rowChecks.length > 0 && rowChecks.length === checkedCount;
}
function initStatusFilterOptions() {
if (!table || !filterStatus) {
return;
}
var statusSet = new Set();
table.querySelectorAll('tbody tr').forEach(function(row) {
var statusText = (row.children[10] ? row.children[10].innerText : '').trim();
if (statusText !== '') {
statusSet.add(statusText);
}
});
Array.from(statusSet).sort().forEach(function(status) {
var opt = document.createElement('option');
opt.value = status.toLowerCase();
opt.textContent = 'Status: ' + status;
filterStatus.appendChild(opt);
});
}
function applyStatusSortFilter() {
if (!tableBody) {
return;
}
var rows = Array.from(tableBody.querySelectorAll('tr'));
var sortMode = sortStatus ? sortStatus.value : 'default';
var selectedStatus = filterStatus ? filterStatus.value : '';
rows.sort(function(a, b) {
if (sortMode === 'asc') {
return (a.dataset.status || '').localeCompare(b.dataset.status || '');
}
if (sortMode === 'desc') {
return (b.dataset.status || '').localeCompare(a.dataset.status || '');
}
return parseInt(a.dataset.order || '0', 10) - parseInt(b.dataset.order || '0', 10);
});
rows.forEach(function(row) {
tableBody.appendChild(row);
var rowStatus = row.dataset.status || '';
var show = selectedStatus === '' || rowStatus === selectedStatus;
row.style.display = show ? '' : 'none';
if (!show) {
var cb = row.querySelector('.row-check');
if (cb) {
cb.checked = false;
}
}
});
if (checkAllRows) {
checkAllRows.checked = false;
}
updateCheckAllState();
} }
if (checkAllRows && table) { if (checkAllRows && table) {
checkAllRows.addEventListener('change', function() { checkAllRows.addEventListener('change', function() {
var rowChecks = table.querySelectorAll('tbody .row-check:not(:disabled)'); getEnabledVisibleChecks().forEach(function(cb) {
rowChecks.forEach(function(cb) {
cb.checked = checkAllRows.checked; cb.checked = checkAllRows.checked;
}); });
}); });
@@ -172,15 +243,22 @@
} }
}); });
} }
updateCheckAllState();
if (sortStatus) {
sortStatus.addEventListener('change', applyStatusSortFilter);
}
if (filterStatus) {
filterStatus.addEventListener('change', applyStatusSortFilter);
}
initStatusFilterOptions();
applyStatusSortFilter();
document.getElementById('btnexport').addEventListener('click', function() { document.getElementById('btnexport').addEventListener('click', function() {
var table = document.getElementById('penerimaansamplereport');
if (table) { if (table) {
var wb = XLSX.utils.table_to_book(table, { sheet: "Report" }); var wb = XLSX.utils.table_to_book(table, { sheet: "Report" });
XLSX.writeFile(wb, "Rekap_Penerimaan_Sample_{{$tanggal}}.xlsx"); XLSX.writeFile(wb, "Rekap_Penerimaan_Sample_{{$tanggal}}.xlsx");
} else {
console.error('Tabel dengan ID "penerimaansamplereport" tidak ditemukan.');
} }
}); });
@@ -195,6 +273,9 @@
var selectedRowElements = []; var selectedRowElements = [];
selectedRows.forEach(function(row) { selectedRows.forEach(function(row) {
if (row.style.display === 'none') {
return;
}
var rowCheck = row.querySelector('.row-check'); var rowCheck = row.querySelector('.row-check');
if (rowCheck && rowCheck.checked) { if (rowCheck && rowCheck.checked) {
var cells = row.querySelectorAll('td'); var cells = row.querySelectorAll('td');
@@ -256,7 +337,9 @@
} }
}); });
checkAllRows.checked = false; if (checkAllRows) {
checkAllRows.checked = false;
}
updateCheckAllState(); updateCheckAllState();
var now = new Date(); var now = new Date();
@@ -116,43 +116,75 @@
<table class="table table-bordered table-striped table-sm"> <table class="table table-bordered table-striped table-sm">
<thead> <thead>
<tr> <tr>
<th>No</th> <th style="width: 70px;">No</th>
<th>No.Sample</th> <th>Subpoli</th>
<th>No.RM</th> <th style="width: 180px;">Jumlah Warning</th>
<th>Nama</th> <th style="width: 160px;">Aksi</th>
<th>Order</th>
<th>Asal Pasien</th>
<th>Status</th>
<th>Daftar</th>
<th>Target (Hari)</th>
<th>Estimasi Selesai</th>
<th>Warning</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@forelse($earlyWarnings as $i => $row) @forelse($earlyWarningGroups as $i => $group)
<tr> <tr>
<td>{{ $i + 1 }}</td> <td>{{ $i + 1 }}</td>
<td>{{ $row['nofoto'] }}</td>
<td>{{ $row['noregister'] }}</td>
<td>{{ $row['nmpasien'] }}</td>
<td>{{ $row['reques'] }}</td>
<td>{{ $row['asalpasien'] }}</td>
<td>{{ $row['status'] }}</td>
<td>{{ $row['daftar'] }}</td>
<td>{{ $row['target_hari'] }}</td>
<td>{{ $row['target_selesai'] }}</td>
<td> <td>
@if($row['sisa_menit'] <= 0) <strong>{{ $group['subpoli'] }}</strong>
<span class="badge badge-danger">{{ $row['warning_label'] }}</span> </td>
@else <td><span class="badge badge-danger">{{ $group['total'] }} kasus</span></td>
<span class="badge badge-warning">{{ $row['warning_label'] }} ({{ $row['sisa_menit'] }} menit)</span> <td>
@endif <button class="btn btn-sm btn-info" type="button" data-toggle="collapse" data-target="#ews-group-{{ $i }}" aria-expanded="false" aria-controls="ews-group-{{ $i }}">
Lihat Detail
</button>
</td>
</tr>
<tr class="collapse" id="ews-group-{{ $i }}">
<td colspan="4">
<div class="table-responsive">
<table class="table table-bordered table-striped table-sm mb-0">
<thead>
<tr>
<th>No</th>
<th>No.Sample</th>
<th>No.RM</th>
<th>Nama</th>
<th>Order</th>
<th>Asal Pasien</th>
<th>Status</th>
<th>Daftar</th>
<th>Target (Hari)</th>
<th>Estimasi Selesai</th>
<th>Warning</th>
</tr>
</thead>
<tbody>
@foreach($group['items'] as $j => $row)
<tr>
<td>{{ $j + 1 }}</td>
<td>{{ $row['nofoto'] }}</td>
<td>{{ $row['noregister'] }}</td>
<td>{{ $row['nmpasien'] }}</td>
<td>{{ $row['reques'] }}</td>
<td>{{ $row['asalpasien'] }}</td>
<td>{{ $row['status'] }}</td>
<td>{{ $row['daftar'] }}</td>
<td>{{ $row['target_hari'] }}</td>
<td>{{ $row['target_selesai'] }}</td>
<td>
@if($row['sisa_menit'] <= 0)
<span class="badge badge-danger">{{ $row['warning_label'] }}</span>
@else
<span class="badge badge-warning">{{ $row['warning_label'] }} ({{ $row['sisa_menit'] }} menit)</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</td> </td>
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="11" class="text-center">Tidak ada data Early Warning.</td> <td colspan="4" class="text-center">Tidak ada data Early Warning.</td>
</tr> </tr>
@endforelse @endforelse
</tbody> </tbody>