This commit is contained in:
Dwi Swandhana
2026-04-08 05:44:57 +07:00
parent 68f6ecc98e
commit 9751007863
4 changed files with 151 additions and 18 deletions

No files matched your search

+109 -16
View File
@@ -719,9 +719,13 @@ class DokterController extends Controller
protected function shouldMarkAsCritical(Request $request): bool protected function shouldMarkAsCritical(Request $request): bool
{ {
$flag = strtolower((string) $request->input('nilai_kritis', '0')); $flag = strtolower((string) $request->input('nilai_kritis', '0'));
$master = (string) $request->input('master_mikro', ''); $periksaId = $request->input('periksa_id');
$periksa = !empty($periksaId)
? Periksa::select('nm_spesimen')->find($periksaId)
: null;
$nmSpesimen = strtoupper(trim((string) ($periksa->nm_spesimen ?? '')));
if ($master !== 'buku03') { if (!str_contains($nmSpesimen, 'DARAH')) {
return false; return false;
} }
@@ -759,34 +763,119 @@ class DokterController extends Controller
} }
protected function getPendingCriticalValueItems() protected function getPendingCriticalValueItems()
{ {
return CriticalValueSample::whereNull('followed_up_at') return $this->appendCriticalValueTatMeta(
CriticalValueSample::whereNull('followed_up_at')
->orderBy('critical_set_at', 'asc') ->orderBy('critical_set_at', 'asc')
->get(); ->get()
);
} }
protected function getFollowedCriticalValueItems() protected function resolveCriticalValueReportRange(Request $request): array
{ {
return CriticalValueSample::whereNotNull('followed_up_at') $defaultStart = Carbon::now()->startOfMonth()->toDateString();
$defaultEnd = Carbon::now()->endOfMonth()->toDateString();
$startDate = trim((string) $request->query('start_date', $defaultStart));
$endDate = trim((string) $request->query('end_date', $defaultEnd));
try {
$start = Carbon::createFromFormat('Y-m-d', $startDate)->startOfDay();
} catch (\Throwable $e) {
$start = Carbon::createFromFormat('Y-m-d', $defaultStart)->startOfDay();
$startDate = $defaultStart;
}
try {
$end = Carbon::createFromFormat('Y-m-d', $endDate)->endOfDay();
} catch (\Throwable $e) {
$end = Carbon::createFromFormat('Y-m-d', $defaultEnd)->endOfDay();
$endDate = $defaultEnd;
}
if ($start->gt($end)) {
[$start, $end] = [$end->copy()->startOfDay(), $start->copy()->endOfDay()];
$startDate = $start->toDateString();
$endDate = $end->toDateString();
}
return [
'start_date' => $startDate,
'end_date' => $endDate,
'start_at' => $start,
'end_at' => $end,
];
}
protected function getFollowedCriticalValueItems(?Carbon $startAt = null, ?Carbon $endAt = null)
{
$query = CriticalValueSample::whereNotNull('followed_up_at');
if ($startAt !== null) {
$query->where('followed_up_at', '>=', $startAt);
}
if ($endAt !== null) {
$query->where('followed_up_at', '<=', $endAt);
}
return $this->appendCriticalValueTatMeta(
$query
->orderBy('followed_up_at', 'desc') ->orderBy('followed_up_at', 'desc')
->limit(100) ->limit(100)
->get(); ->get()
);
}
protected function appendCriticalValueTatMeta($items)
{
return $items->map(function ($item) {
$item->tat_minutes = null;
$item->tat_duration_label = '-';
$item->tat_status_label = '-';
if (!empty($item->critical_set_at) && !empty($item->followed_up_at)) {
$criticalSetAt = Carbon::parse($item->critical_set_at);
$followedUpAt = Carbon::parse($item->followed_up_at);
$diffMinutes = $criticalSetAt->diffInMinutes($followedUpAt);
$item->tat_minutes = $diffMinutes;
$item->tat_duration_label = $this->formatTatDuration($diffMinutes);
$item->tat_status_label = $diffMinutes <= 30 ? 'Memenuhi TAT' : 'Tidak Memenuhi TAT';
}
return $item;
});
}
protected function formatTatDuration(int $totalMinutes): string
{
$hours = intdiv($totalMinutes, 60);
$minutes = $totalMinutes % 60;
if ($hours > 0) {
return $hours.' jam '.$minutes.' menit';
}
return $minutes.' menit';
} }
public function criticalValueNotifications(Request $request) public function criticalValueNotifications(Request $request)
{ {
$highlightId = $request->query('highlight'); $highlightId = $request->query('highlight');
$reportRange = $this->resolveCriticalValueReportRange($request);
$items = $this->getPendingCriticalValueItems(); $items = $this->getPendingCriticalValueItems();
$followedItems = $this->getFollowedCriticalValueItems(); $followedItems = $this->getFollowedCriticalValueItems($reportRange['start_at'], $reportRange['end_at']);
return view('notifications.critical-values', [ return view('notifications.critical-values', [
'items' => $items, 'items' => $items,
'followedItems' => $followedItems, 'followedItems' => $followedItems,
'highlightId' => $highlightId, 'highlightId' => $highlightId,
'startDate' => $reportRange['start_date'],
'endDate' => $reportRange['end_date'],
]); ]);
} }
public function criticalValueNotificationExport(Request $request) public function criticalValueNotificationExport(Request $request)
{ {
$type = $request->query('type', 'pending'); $type = $request->query('type', 'pending');
$isFollowed = $type === 'followed'; $isFollowed = $type === 'followed';
$rows = $isFollowed ? $this->getFollowedCriticalValueItems() : $this->getPendingCriticalValueItems(); $reportRange = $this->resolveCriticalValueReportRange($request);
$rows = $isFollowed
? $this->getFollowedCriticalValueItems($reportRange['start_at'], $reportRange['end_at'])
: $this->getPendingCriticalValueItems();
$filename = $isFollowed $filename = $isFollowed
? 'notifikasi-nilai-kritis-riwayat-'.Carbon::now()->format('Ymd_His').'.xlsx' ? 'notifikasi-nilai-kritis-riwayat-'.Carbon::now()->format('Ymd_His').'.xlsx'
: 'notifikasi-nilai-kritis-belum-dilaporkan-'.Carbon::now()->format('Ymd_His').'.xlsx'; : 'notifikasi-nilai-kritis-belum-dilaporkan-'.Carbon::now()->format('Ymd_His').'.xlsx';
@@ -807,6 +896,8 @@ class DokterController extends Controller
'Diset Oleh', 'Diset Oleh',
'Waktu Ditindaklanjuti', 'Waktu Ditindaklanjuti',
'Ditindaklanjuti Oleh', 'Ditindaklanjuti Oleh',
'Selisih Waktu',
'Status TAT',
'Status Tindak Lanjut', 'Status Tindak Lanjut',
'Metode', 'Metode',
'Penerima Laporan', 'Penerima Laporan',
@@ -836,6 +927,8 @@ class DokterController extends Controller
$item->critical_set_by_name ?? '-', $item->critical_set_by_name ?? '-',
$item->followed_up_at ? Carbon::parse($item->followed_up_at)->format('d-m-Y H:i:s') : '-', $item->followed_up_at ? Carbon::parse($item->followed_up_at)->format('d-m-Y H:i:s') : '-',
$item->followed_up_by_name ?? '-', $item->followed_up_by_name ?? '-',
$item->tat_duration_label ?? '-',
$item->tat_status_label ?? '-',
$statusLabel, $statusLabel,
$item->follow_up_method ?? '-', $item->follow_up_method ?? '-',
$item->follow_up_recipient ?? '-', $item->follow_up_recipient ?? '-',
@@ -844,7 +937,7 @@ class DokterController extends Controller
$rowNumber++; $rowNumber++;
} }
foreach (range('A', 'N') as $col) { foreach (range('A', 'P') as $col) {
$sheet->getColumnDimension($col)->setAutoSize(true); $sheet->getColumnDimension($col)->setAutoSize(true);
} }
@@ -943,7 +1036,7 @@ class DokterController extends Controller
$updated = Periksa::where('id', $id)->update([ $updated = Periksa::where('id', $id)->update([
'noloket' => null, 'noloket' => null,
'status' => 'Batal', 'status' => 'Dibatalkan (Arsip)',
]); ]);
if (!$updated) { if (!$updated) {
@@ -1004,7 +1097,7 @@ class DokterController extends Controller
Periksa::where('id', $idperiksa)->orWhere('nofoto', $idperiksa)->update([ Periksa::where('id', $idperiksa)->orWhere('nofoto', $idperiksa)->update([
'keterangan' => $val01, 'keterangan' => $val01,
'admin' => Session('nama'), 'admin' => Session('nama'),
'status' => 'Batal' 'status' => 'Dibatalkan (Arsip)'
]); ]);
if ($pacsaddr == '' OR $pacsaddr === null){ if ($pacsaddr == '' OR $pacsaddr === null){
$pesan = ''; $pesan = '';
@@ -3546,9 +3639,9 @@ class DokterController extends Controller
if ($status == '' OR is_null($status)){ if ($status == '' OR is_null($status)){
$status = 'new'; $status = 'new';
} else { } else {
$cekbatal = explode('batalkan dengan alasan ', $status); $cekbatal = explode('batal', $status);
if (isset($cekbatal[1])){ if (isset($cekbatal[1])){
$keterangan = $cekbatal[1]; $keterangan = $status;
$status = 'Batal'; $status = 'Batal';
} else { } else {
if ($status == 'Arsip' OR $status == 'Selesai'){ if ($status == 'Arsip' OR $status == 'Selesai'){
@@ -3592,9 +3685,9 @@ class DokterController extends Controller
if ($status == '' OR is_null($status)){ if ($status == '' OR is_null($status)){
$status = 'new'; $status = 'new';
} else { } else {
$cekbatal = explode('batalkan dengan alasan ', $status); $cekbatal = explode('batal', $status);
if (isset($cekbatal[1])){ if (isset($cekbatal[1])){
$keterangan = $cekbatal[1]; $keterangan = $status;
$status = 'Batal'; $status = 'Batal';
} else { } else {
if ($status == 'Arsip' OR $status == 'Selesai'){ if ($status == 'Arsip' OR $status == 'Selesai'){
@@ -2376,7 +2376,7 @@
<button type="button" id="btnsavedraft" class="btn btn-success pull-right">Save as Draft</button> <button type="button" id="btnsavedraft" class="btn btn-success pull-right">Save as Draft</button>
</div> </div>
@if (Session('previlage') == 'supervisor' OR Session('previlage') == 'developer') @if (Session('previlage') == 'supervisor' OR Session('previlage') == 'developer')
<div class="col-auto"> <div class="col-auto" id="nilai_kritis_wrapper" style="display: none;">
<div class="form-check mb-2"> <div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="nilai_kritis" name="nilai_kritis"> <input class="form-check-input" type="checkbox" id="nilai_kritis" name="nilai_kritis">
<label class="form-check-label" for="nilai_kritis"> <label class="form-check-label" for="nilai_kritis">
@@ -5028,6 +5028,7 @@
$("#otheras").val(dataRecord.ppdsas); $("#otheras").val(dataRecord.ppdsas);
$("#kave").val(dataRecord.kd_spesimen); $("#kave").val(dataRecord.kd_spesimen);
$("#mas").val(dataRecord.nm_spesimen); $("#mas").val(dataRecord.nm_spesimen);
window.syncNilaiKritisVisibility(dataRecord.nm_spesimen);
$("#berat").val(dataRecord.berat); $("#berat").val(dataRecord.berat);
$("#klinis").val(dataRecord.klinis); $("#klinis").val(dataRecord.klinis);
$("#klinisi").html(dataRecord.klinisi); $("#klinisi").html(dataRecord.klinisi);
@@ -6039,6 +6040,16 @@
$("#btnopenmodalcancel").click(function() { $("#btnopenmodalcancel").click(function() {
$("#modalpembatalan").modal('show'); $("#modalpembatalan").modal('show');
}); });
window.syncNilaiKritisVisibility = function(spesimen) {
var normalized = ((spesimen || '') + '').trim().toUpperCase();
var isDarah = normalized.indexOf('DARAH') !== -1;
if (isDarah) {
$('#nilai_kritis_wrapper').show();
} else {
$('#nilai_kritis').prop('checked', false);
$('#nilai_kritis_wrapper').hide();
}
}
$("#btnshowtemplate").click(function() { $("#btnshowtemplate").click(function() {
$('#divtemplate').show(); $('#divtemplate').show();
}); });
@@ -112,10 +112,26 @@
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-3"> <div class="d-flex justify-content-between align-items-center mb-3">
<h5 class="card-title mb-0">Riwayat Nilai Kritis Yang Sudah Ditindaklanjuti</h5> <h5 class="card-title mb-0">Riwayat Nilai Kritis Yang Sudah Ditindaklanjuti</h5>
<a href="{{ route('criticalValueNotificationExport', ['type' => 'followed']) }}" class="btn btn-success btn-sm"> <a href="{{ route('criticalValueNotificationExport', ['type' => 'followed', 'start_date' => $startDate, 'end_date' => $endDate]) }}" class="btn btn-success btn-sm">
Export Excel Export Excel
</a> </a>
</div> </div>
<form method="GET" action="{{ route('criticalValueNotifications') }}" class="mb-3">
<div class="form-row align-items-end">
<div class="form-group col-md-3">
<label for="start_date">Start Date Report</label>
<input type="date" id="start_date" name="start_date" class="form-control" value="{{ $startDate }}">
</div>
<div class="form-group col-md-3">
<label for="end_date">End Date Report</label>
<input type="date" id="end_date" name="end_date" class="form-control" value="{{ $endDate }}">
</div>
<div class="form-group col-md-6">
<button type="submit" class="btn btn-primary btn-sm">Tampilkan</button>
<a href="{{ route('criticalValueNotifications') }}" class="btn btn-secondary btn-sm">Reset</a>
</div>
</div>
</form>
@if($followedItems->isEmpty()) @if($followedItems->isEmpty())
<div class="alert alert-secondary mb-0">Belum ada riwayat tindak lanjut.</div> <div class="alert alert-secondary mb-0">Belum ada riwayat tindak lanjut.</div>
@else @else
@@ -131,6 +147,8 @@
<th>Spesimen</th> <th>Spesimen</th>
<th>Waktu Set Nilai Kritis</th> <th>Waktu Set Nilai Kritis</th>
<th>Waktu Ditindaklanjuti</th> <th>Waktu Ditindaklanjuti</th>
<th>Selisih Waktu</th>
<th>Status TAT</th>
<th>Aksi</th> <th>Aksi</th>
</tr> </tr>
</thead> </thead>
@@ -155,6 +173,16 @@
<br><small>oleh {{ $item->followed_up_by_name }}</small> <br><small>oleh {{ $item->followed_up_by_name }}</small>
@endif @endif
</td> </td>
<td>{{ $item->tat_duration_label ?? '-' }}</td>
<td>
@if(($item->tat_status_label ?? '-') === 'Memenuhi TAT')
<span class="badge badge-success">{{ $item->tat_status_label }}</span>
@elseif(($item->tat_status_label ?? '-') === 'Tidak Memenuhi TAT')
<span class="badge badge-danger">{{ $item->tat_status_label }}</span>
@else
<span class="badge badge-secondary">-</span>
@endif
</td>
<td> <td>
@php @php
$status = $item->follow_up_status ?? ''; $status = $item->follow_up_status ?? '';
@@ -226,6 +226,7 @@
} }
}, },
{ text: 'Acc.No', datafield: 'nofoto', width: 100, cellsalign: 'left', align: 'center' }, { text: 'Acc.No', datafield: 'nofoto', width: 100, cellsalign: 'left', align: 'center' },
{ text: 'Order', datafield: 'tlsreques', width: 200, cellsalign: 'left', align: 'center' },
{ text: 'No.RM', datafield: 'tlsnoregister', width: 100, cellsalign: 'left', align: 'center' }, { text: 'No.RM', datafield: 'tlsnoregister', width: 100, cellsalign: 'left', align: 'center' },
{ text: 'Name', datafield: 'tlsnama', width: 150, cellsalign: 'left', align: 'center' }, { text: 'Name', datafield: 'tlsnama', width: 150, cellsalign: 'left', align: 'center' },
{ text: 'Gender', datafield: 'tlsjk', filtertype: 'checkedlist', width: 50, cellsalign: 'left', align: 'center' }, { text: 'Gender', datafield: 'tlsjk', filtertype: 'checkedlist', width: 50, cellsalign: 'left', align: 'center' },