This commit is contained in:
Dwi Swandhana
2026-04-04 06:43:44 +07:00
parent a979b16df4
commit 80d03ac5c1
8 changed files with 7584 additions and 466 deletions
@@ -53,6 +53,8 @@ use Session;
use QrCode;
use Exception;
use PDFCREATOR;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
define( 'API_ACCESS_KEY', 'AAAA6YBXh1k:APA91bFL0q7QAXQGohXMpTwHco79f13C8PFk1Oo8kKhg1JerOulT9-37dxyP8X5ibABI0NuQ4ZsVxKQKCt7HuR7lUdJJuB-hTVnBmOUIBYfBlHb-Lcp6aGkj4erfF7J__A5hufXjF8Vt' );
@@ -717,6 +719,11 @@ class DokterController extends Controller
protected function shouldMarkAsCritical(Request $request): bool
{
$flag = strtolower((string) $request->input('nilai_kritis', '0'));
$master = (string) $request->input('master_mikro', '');
if ($master !== 'buku03') {
return false;
}
return in_array($flag, ['1', 'true', 'on', 'yes'], true);
}
@@ -750,16 +757,24 @@ class DokterController extends Controller
$criticalSample->followed_up_by_name = Session('nama');
$criticalSample->save();
}
public function criticalValueNotifications(Request $request)
protected function getPendingCriticalValueItems()
{
$highlightId = $request->query('highlight');
$items = CriticalValueSample::whereNull('followed_up_at')
return CriticalValueSample::whereNull('followed_up_at')
->orderBy('critical_set_at', 'asc')
->get();
$followedItems = CriticalValueSample::whereNotNull('followed_up_at')
}
protected function getFollowedCriticalValueItems()
{
return CriticalValueSample::whereNotNull('followed_up_at')
->orderBy('followed_up_at', 'desc')
->limit(100)
->get();
}
public function criticalValueNotifications(Request $request)
{
$highlightId = $request->query('highlight');
$items = $this->getPendingCriticalValueItems();
$followedItems = $this->getFollowedCriticalValueItems();
return view('notifications.critical-values', [
'items' => $items,
@@ -767,6 +782,80 @@ class DokterController extends Controller
'highlightId' => $highlightId,
]);
}
public function criticalValueNotificationExport(Request $request)
{
$type = $request->query('type', 'pending');
$isFollowed = $type === 'followed';
$rows = $isFollowed ? $this->getFollowedCriticalValueItems() : $this->getPendingCriticalValueItems();
$filename = $isFollowed
? 'notifikasi-nilai-kritis-riwayat-'.Carbon::now()->format('Ymd_His').'.xlsx'
: 'notifikasi-nilai-kritis-belum-dilaporkan-'.Carbon::now()->format('Ymd_His').'.xlsx';
return response()->streamDownload(function () use ($rows, $isFollowed) {
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle($isFollowed ? 'Riwayat Nilai Kritis' : 'Nilai Kritis');
$headers = [
'No',
'No Foto',
'No Register',
'Pasien',
'Asal Pasien',
'Spesimen',
'Waktu Set Nilai Kritis',
'Diset Oleh',
'Waktu Ditindaklanjuti',
'Ditindaklanjuti Oleh',
'Status Tindak Lanjut',
'Metode',
'Penerima Laporan',
'Alasan',
];
$sheet->fromArray($headers, null, 'A1');
$rowNumber = 2;
foreach ($rows as $index => $item) {
$status = $item->follow_up_status ?? '';
if ($status === 'reported') {
$statusLabel = 'Dilaporkan';
} elseif ($status === 'not_reported') {
$statusLabel = 'Belum Dilaporkan';
} else {
$statusLabel = '-';
}
$sheet->fromArray([
$index + 1,
$item->nofoto ?? '-',
$item->noregister ?? '-',
$item->nmpasien ?? '-',
$item->asalpasien ?? '-',
$item->nm_spesimen ?? '-',
$item->critical_set_at ? Carbon::parse($item->critical_set_at)->format('d-m-Y H:i:s') : '-',
$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_by_name ?? '-',
$statusLabel,
$item->follow_up_method ?? '-',
$item->follow_up_recipient ?? '-',
$item->follow_up_reason ?? '-',
], null, 'A'.$rowNumber);
$rowNumber++;
}
foreach (range('A', 'N') as $col) {
$sheet->getColumnDimension($col)->setAutoSize(true);
}
$writer = new Xlsx($spreadsheet);
$writer->save('php://output');
$spreadsheet->disconnectWorksheets();
unset($spreadsheet);
}, $filename, [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
]);
}
public function criticalValueNotificationSummary()
{
if (Session::get('id') === null) {
@@ -36,6 +36,142 @@ use Carbon\Carbon;
class FrontpageController extends Controller
{
protected function buildMikroViewData($master, array $extra = [])
{
$data = [
'dokters' => User::where('previlage', 'supervisor')->get(),
'allppds' => User::where('previlage', 'ppds')->get(),
'allanalis' => User::where('previlage', 'analis')->get(),
'lokasi' => 'Lab Mikrobiologi',
'master' => $master,
'antrkrmsitu' => 0,
'focusPeriksaId' => null,
'expertiseReturnUrl' => null,
'openExpertiseOnLoad' => false,
];
$allOrganisms = Organisms::orderBy('name', 'ASC')->get();
$allASTManual = SiraB::whereNotNull('setmanual')->select('setmanual')->groupBy('setmanual')->get();
$groupOrganisms = function ($kelompok) use ($allOrganisms) {
$organisms = $allOrganisms->where('kelompok', $kelompok);
if ($organisms->isEmpty()) {
return [
'organismes' => [[['id' => 0, 'name' => 'No Data']]],
'categories' => ['No Data'],
];
}
$grouped = $organisms->groupBy('category');
$organismes = [];
$categories = [];
$i = 0;
foreach ($grouped as $category => $items) {
$categories[] = $category;
$j = 0;
foreach ($items as $item) {
$organismes[$i][$j] = ['id' => $item->id, 'name' => $item->name];
$j++;
}
$i++;
}
return [
'organismes' => $organismes,
'categories' => $categories,
];
};
$biakankulturData = $groupOrganisms('biakankultur');
$mikroorganismeData = $groupOrganisms('mikroorganisme');
$data = array_merge($data, [
'organismes' => $biakankulturData['organismes'],
'bacterycateggories' => $biakankulturData['categories'],
'mikroorganismes' => $mikroorganismeData['organismes'],
'mikroorganismestlist' => $mikroorganismeData['categories'],
]);
$kelompokMapping = [
'jsonsputum' => 'Sputum',
'jsonswabtenggorok' => 'Swab Tenggorok',
'jsonurine' => 'Urine',
'jsonswabperineum' => 'Swab perineum',
'jsonselepitel' => 'Sel Epitel',
'jsonselradang' => 'Sel Radang',
'jsonmikroorganisme' => 'Q Mikroorganisme',
'jsonjumlahlactobacillus' => 'Lactobacillus',
'jsonjumlahgardnerella' => 'Gardnerella',
'jsonjumlahmobiluncus' => 'Mobiluncus',
'jsonpewarnaanziehlnielsen' => 'Pewarnaan Ziehl Nielsen',
'jsonpewarnaanneisser' => 'Pewarnaan Neisser',
'jsonpewarnaannegatif' => 'Pewarnaan Negatif',
'jsonpewarnaanspora' => 'Pewarnaan Spora',
'jsonpewarnaankoh' => 'Pewarnaan KOH',
'jsonpewarnaangiemsa' => 'Pewarnaan Giemsa',
'jsonmediabap' => 'Media BAP',
'jsonmediacap' => 'Media CAP',
'jsonmediamcconkey' => 'Media Mc Conkey',
'jsonpemeriksaantl' => 'Pemeriksaan Tambahan Lainnya',
'jsonbiakankultur' => 'Biakan Kultur',
'jsonvlparameter' => 'Paramater Viral Load',
];
foreach ($kelompokMapping as $key => $kelompok) {
$data[$key] = $allOrganisms->where('kelompok', $kelompok)->values();
}
$data['antibiotics'] = $allASTManual;
return array_merge($data, $extra);
}
protected function mikroViewName()
{
return Session::get('previlage') == 'developer' ? 'dokter.ppdsdeveloper' : 'dokter.ppds';
}
protected function mikroExpertiseViewName()
{
return 'dokter.mikro-expertise';
}
protected function mikroBookPoliMap(): array
{
return [
'buku01' => [15,16,43,47,48,66,96,205,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223],
'buku02' => [20],
'buku03' => [7,8,13,17,29,33,44,107,114,115,199,200,201,202],
'buku04' => [30],
'buku05' => [165,179,180,181,183,184,185,187,188,189,190,192,194,195,196,198],
'buku06' => [26,40,45,52,53,56,60,61,68,69,75,92,102,122,123,136,137,144,145,152,153,233],
'buku07' => [18,19,32,35,46,49,50,54,57,58,59,72,160,182,186,191,193,197,206,207,208,224,225,226,227,228,234,235,236,237],
'buku08' => [1,12,23,24,36,39,229,230,231,232],
'buku09' => [2,4,5,9,10,11,12,21,22,27,34,41,42,51,63,64,65,85,86,87,88,93,97,118,67,121,125,126,127,128,129,130,132,133,134,135,140,147,158,159,161,162,163,164,166,167,168,169,170,171,172,173,174,175,176,177,178],
'buku10' => [14,28,55,62,94,104,105,124,138,146],
'buku11' => [79,80,81,82,83,84,203],
'buku12' => [3,6,25,31,154,155,156,157],
'buku13' => [37,38,148,149,204],
];
}
protected function resolveMikroMasterFromPoliId($poliId): string
{
foreach ($this->mikroBookPoliMap() as $master => $poliIds) {
if (in_array((int) $poliId, $poliIds, true)) {
return $master;
}
}
return 'buku0';
}
protected function resolveExpertiseReturnUrl(Request $request, string $master): string
{
$returnTo = trim((string) $request->query('return_to', ''));
if ($returnTo === 'dashboard') {
return url('/');
}
if ($returnTo !== '') {
if (str_starts_with($returnTo, '/')) {
return url($returnTo);
}
$appUrl = rtrim((string) config('app.url', url('/')), '/');
if (str_starts_with($returnTo, $appUrl)) {
return $returnTo;
}
}
return url('/mikro/'.$master);
}
public function index() {
$data = [];
@@ -79,6 +215,7 @@ class FrontpageController extends Controller
$rawEarlyWarnings = Periksa::leftJoin('poli', 'periksa.poli_id', '=', 'poli.id')
->select(
'periksa.id',
'periksa.poli_id',
'periksa.nofoto',
'periksa.noregister',
'periksa.nmpasien',
@@ -111,6 +248,7 @@ class FrontpageController extends Controller
if ($sisaMenit <= 60) {
$earlyWarnings[] = [
'id' => $row->id,
'mikro_master' => $this->resolveMikroMasterFromPoliId($row->poli_id),
'subpoli' => $row->subpoli ?? 'Tanpa Subpoli',
'nofoto' => $row->nofoto,
'noregister' => $row->noregister,
@@ -537,83 +675,30 @@ class FrontpageController extends Controller
if (!Session::has('previlage')) {
return redirect('/login');
}
$data = [
'dokters' => User::where('previlage', 'supervisor')->get(),
'allppds' => User::where('previlage', 'ppds')->get(),
'allanalis' => User::where('previlage', 'analis')->get(),
'lokasi' => 'Lab Mikrobiologi',
'master' => $master,
'antrkrmsitu' => 0,
];
$allOrganisms = Organisms::orderBy('name', 'ASC')->get();
$allASTManual = SiraB::whereNotNull('setmanual')->select('setmanual')->groupBy('setmanual')->get();
$groupOrganisms = function ($kelompok) use ($allOrganisms) {
$organisms = $allOrganisms->where('kelompok', $kelompok);
if ($organisms->isEmpty()) {
return [
'organismes' => [[['id' => 0, 'name' => 'No Data']]],
'categories' => ['No Data'],
];
}
$grouped = $organisms->groupBy('category');
$organismes = [];
$categories = [];
$i = 0;
foreach ($grouped as $category => $items) {
$categories[] = $category;
$j = 0;
foreach ($items as $item) {
$organismes[$i][$j] = ['id' => $item->id, 'name' => $item->name];
$j++;
}
$i++;
}
return [
'organismes' => $organismes,
'categories' => $categories,
];
};
$biakankulturData = $groupOrganisms('biakankultur');
$mikroorganismeData = $groupOrganisms('mikroorganisme');
$data = array_merge($data, [
'organismes' => $biakankulturData['organismes'],
'bacterycateggories' => $biakankulturData['categories'],
'mikroorganismes' => $mikroorganismeData['organismes'],
'mikroorganismestlist' => $mikroorganismeData['categories'],
]);
$kelompokMapping = [
'jsonsputum' => 'Sputum',
'jsonswabtenggorok' => 'Swab Tenggorok',
'jsonurine' => 'Urine',
'jsonswabperineum' => 'Swab perineum',
'jsonselepitel' => 'Sel Epitel',
'jsonselradang' => 'Sel Radang',
'jsonmikroorganisme' => 'Q Mikroorganisme',
'jsonjumlahlactobacillus' => 'Lactobacillus',
'jsonjumlahgardnerella' => 'Gardnerella',
'jsonjumlahmobiluncus' => 'Mobiluncus',
'jsonpewarnaanziehlnielsen' => 'Pewarnaan Ziehl Nielsen',
'jsonpewarnaanneisser' => 'Pewarnaan Neisser',
'jsonpewarnaannegatif' => 'Pewarnaan Negatif',
'jsonpewarnaanspora' => 'Pewarnaan Spora',
'jsonpewarnaankoh' => 'Pewarnaan KOH',
'jsonpewarnaangiemsa' => 'Pewarnaan Giemsa',
'jsonmediabap' => 'Media BAP',
'jsonmediacap' => 'Media CAP',
'jsonmediamcconkey' => 'Media Mc Conkey',
'jsonpemeriksaantl' => 'Pemeriksaan Tambahan Lainnya',
'jsonbiakankultur' => 'Biakan Kultur',
'jsonvlparameter' => 'Paramater Viral Load',
];
foreach ($kelompokMapping as $key => $kelompok) {
$data[$key] = $allOrganisms->where('kelompok', $kelompok)->values();
return view($this->mikroViewName(), $this->buildMikroViewData($master));
}
public function viewMikroExpertise(Request $request, $periksaId)
{
if (!Session::has('previlage')) {
return redirect('/login');
}
$data['antibiotics'] = $allASTManual;
if (Session::get('previlage') == 'developer'){
return view('dokter.ppdsdeveloper', $data);
} else {
return view('dokter.ppds', $data);
$periksa = Periksa::select('id', 'poli_id')->find($periksaId);
if (!$periksa) {
abort(404);
}
$requestedMaster = trim((string) $request->query('from', ''));
$validMasters = array_keys($this->mikroBookPoliMap());
$validMasters[] = 'buku0';
$master = in_array($requestedMaster, $validMasters, true)
? $requestedMaster
: $this->resolveMikroMasterFromPoliId($periksa->poli_id);
$returnUrl = $this->resolveExpertiseReturnUrl($request, $master);
return view($this->mikroExpertiseViewName(), $this->buildMikroViewData($master, [
'focusPeriksaId' => (string) $periksaId,
'expertiseReturnUrl' => $returnUrl,
'openExpertiseOnLoad' => true,
]));
}
public function pengambilan() {
if (Session::get('previlage') == ''){