done dashboard mutu

This commit is contained in:
JokoPrasetio 2025-12-16 09:37:16 +07:00
parent 846eb4cbca
commit 09f4ad6934
2 changed files with 89 additions and 90 deletions

View File

@ -24,8 +24,6 @@ class AdminController extends Controller
if (!$s) return ''; if (!$s) return '';
$s = Str::of($s)->lower()->trim(); $s = Str::of($s)->lower()->trim();
// buang teks dalam kurung: (SIMRS) dll
$s = $s->replaceMatches('/\s*\([^)]*\)\s*/u', ' '); $s = $s->replaceMatches('/\s*\([^)]*\)\s*/u', ' ');
// expand singkatan penting // expand singkatan penting
@ -34,23 +32,26 @@ class AdminController extends Controller
$s = $s->replaceMatches('/\bhumas\b/u', 'hubungan masyarakat'); $s = $s->replaceMatches('/\bhumas\b/u', 'hubungan masyarakat');
$s = $s->replaceMatches('/\bipt\b/u', 'instalasi perinatal terpadu'); $s = $s->replaceMatches('/\bipt\b/u', 'instalasi perinatal terpadu');
$s = $s->replaceMatches('/\bissb\b/u', 'instalasi sterilisasi sentral dan binatu'); $s = $s->replaceMatches('/\bissb\b/u', 'instalasi sterilisasi sentral dan binatu');
$s = $s->replaceMatches('/\bippb\b/u', 'instalasi pemasaran dan pengembangan bisnis');
$s = $s->replaceMatches('/\bipsprs\b/u', 'instalasi pemeliharaan sarana prasarana rumah sakit'); $s = $s->replaceMatches('/\bipsprs\b/u', 'instalasi pemeliharaan sarana prasarana rumah sakit');
$s = $s->replaceMatches('/\binstalasi\s+rawat\s+intensif\s*\/\s*icu\b/u', 'instalasi rawat intensif'); $s = $s->replaceMatches('/\binstalasi\s+rawat\s+intensif\s*\/\s*icu\b/u', 'instalasi rawat intensif');
$s = $s->replaceMatches( $s = $s->replaceMatches(
'/\binstalasi\s+kl\s*(?:&|\/)?\s*k3rs\b/u', '/\binstalasi\s+kl\s*(?:&|\/)?\s*k3rs\b/u',
'instalasi kesehatan lingkungan dan keselamatan dan kesehatan kerja rumah sakit' 'instalasi kesehatan lingkungan dan keselamatan dan kesehatan kerja rumah sakit'
); );
// samakan simbol
$s = $s->replace(['&', '/', '-', '.', ',', ':', ';'], ' '); $s = $s->replace(['&', '/', '-', '.', ',', ':', ';'], ' ');
// samakan kata penghubung
$s = $s->replace(' dan ', ' '); $s = $s->replace(' dan ', ' ');
// rapikan spasi
$s = $s->replaceMatches('/\s+/u', ' ')->trim(); $s = $s->replaceMatches('/\s+/u', ' ')->trim();
if (preg_match('/\bcl(ea|ae|e|a)?n(ing|er)?\s+ser(v|f)?(ice|is|vis|fis)\b/u', (string)$s)) {
return 'cleaning service';
}
// (opsional) kalau ada bentuk sangat sederhana
if (Str::contains((string)$s, ['cleaning service', 'cleaning servis', 'cleaner service', 'chelining servis'])) {
return 'cleaning service';
}
return (string) $s; return (string) $s;
} }
// //
@ -205,7 +206,19 @@ class AdminController extends Controller
$query->whereIn('unit', (array) $request->unit_kerja); $query->whereIn('unit', (array) $request->unit_kerja);
} }
$jawabanCounts = $query->groupBy('unit')->get(); $jawabanRaw = $query->groupBy('unit')->get();
$jawabanCounts = $jawabanRaw
->groupBy(fn($row) => $this->unitKey($row->unit)) // gabungkan berdasarkan key normalisasi
->map(function ($rows, $key) {
return (object) [
'unit_key' => $key,
// ambil nama display (pilih yang paling sering muncul)
'unit' => $rows->groupBy('unit')->sortByDesc(fn($g) => $g->sum('total_unit'))->keys()->first(),
'total_unit' => (int) $rows->sum('total_unit'),
];
})
->values();
// Map total karyawan: key(normalized) => total_karyawan (ini dari UnitKerja) // Map total karyawan: key(normalized) => total_karyawan (ini dari UnitKerja)
$unitTotalMaps = $unitTotals->mapWithKeys(function ($item) { $unitTotalMaps = $unitTotals->mapWithKeys(function ($item) {
@ -217,18 +230,15 @@ class AdminController extends Controller
$key = $this->unitKey($row->unit); $key = $this->unitKey($row->unit);
$sudahIsi = (int) $row->total_unit; $sudahIsi = (int) $row->total_unit;
$totalKaryawan = $unitTotalMaps[$key] ?? null;
$display = ($totalKaryawan && $totalKaryawan > 0)
? "{$sudahIsi} / {$totalKaryawan}"
: "{$sudahIsi}";
if (isset($unitTotalMaps[$key]) && (int)$unitTotalMaps[$key] > 0) {
$totalKaryawan = (int) $unitTotalMaps[$key];
$progress = $sudahIsi . ' / ' . $totalKaryawan;
} else {
$totalKaryawan = null; // tidak diketahui
$progress = (string) $sudahIsi; // hanya angka, tanpa /0
}
return [ return [
'unit' => $row->unit, 'unit' => $row->unit,
'total_unit' => $progress 'total_unit' => $display
]; ];
}) })
->values(); ->values();
@ -236,72 +246,40 @@ class AdminController extends Controller
return DataTables::of($data)->make(true); return DataTables::of($data)->make(true);
} }
public function download_report_data_pegawai_sudah_survey(Request $request) public function download_report_data_pegawai_sudah_survey(Request $request)
{ {
$masterUnits = [ $unitPegawai = UnitKerja::query()
"Direktur Utama dan Direksi", ->where('statusenabled', true)
"Satuan Pengawas Internal", ->with([
"Komite Mutu", 'mappingPegawai' => function ($q) {
"Komite Medik", $q->where('statusenabled', true)
"Komite Keperawatan", ->whereHas('pegawai', fn ($p) => $p->where('statusenabled', true)->where('kedudukanfk', 1))
"Komite PPI & PRA", ->with([
"KTKL", 'pegawai' => fn ($p) => $p->where('statusenabled', true)->where('kedudukanfk', 1)
"KFT", ->select('id', 'namalengkap')
"KEH", ]);
"ULP", }
"Timker Yankep", ])
"Timker Yanjang", ->get();
"Timker Perencanaan, Evaluasi dan Program",
"Timker Hukum dan Humas", $unitTotals = $unitPegawai->map(function ($unit) {
"Timker Yanmed", $pegawaiUnik = $unit->mappingPegawai
"Timker Perencanaan dan Evaluasi Anggaran", ->pluck('pegawai')
"Timker Akutansi dan BMN", ->filter()
"Timker Organisasi dan Sumber Daya Manusia", ->unique('id');
"Timker TU & RT",
"Timker Diklat", return [
"Timker Penelitian", 'name' => $unit->name,
"Timker Pelaksanan Keuangan", 'total_karyawan' => $pegawaiUnik->count(),
"Instalasi Rawat Inap", ];
"Instalasi Rawat Jalan Reguler", });
"Instalasi Rawat Intensif / ICU",
"Instalasi Rehabilitasi Medik", $unitTotalMaps = $unitTotals->mapWithKeys(function ($item) {
"Instalasi Gizi", return [$this->unitKey($item['name']) => (int) $item['total_karyawan']];
"Instalasi Laboratorium Terpadu", });
"Instalasi Sistem Informasi Manajemen Rumah Sakit (SIMRS)",
"Instalasi Bedah Sentral",
"Instalasi Radiologi",
"Instalasi Farmasi",
"Instalasi Rekam Medis",
"Instalasi Gawat Darurat",
"Instalasi Verifikasi dan Penjaminan Pasien",
"Instalasi KL & K3RS",
"ISSB",
"IPT",
"IPJNI",
"IPSPRS",
"IPPB",
"IPPISGB",
"Instalasi Rawat Jalan Eksekutif",
"Instalasi Teknologi Berbantu (TRB)",
"Klinik Utama Bintaro",
"KSM Anak",
"KSM Obstetri & Ginekologi",
"KSM Bedah",
"KSM Anestesi",
"KSM Gigi & Mulut",
"KSM Spesialis Lain",
"KSM Umum",
"Lainnya",
];
$query = Jawaban::query() $query = Jawaban::query()
->select([ ->select('unit', DB::raw('COUNT(*) as total_unit'))
'unit',
DB::raw('COUNT(*) as total'),
])
->whereNotNull('unit'); ->whereNotNull('unit');
if ($request->nama_pegawai) { if ($request->nama_pegawai) {
@ -309,30 +287,47 @@ class AdminController extends Controller
} }
if ($request->select_unit_kerja) { if ($request->select_unit_kerja) {
$selectedUnits = (array) $request->select_unit_kerja; $query->whereIn('unit', (array) $request->select_unit_kerja);
$query->whereIn('unit', $selectedUnits);
$masterUnits = array_values(array_intersect($masterUnits, $selectedUnits));
} }
$query->groupBy('unit'); $jawabanRaw = $query->groupBy('unit')->get();
$rekap = $query->get()->pluck('total', 'unit'); $jawabanCounts = $jawabanRaw
->groupBy(fn ($row) => $this->unitKey($row->unit))
->map(function ($rows, $key) {
return (object) [
'unit_key' => $key,
// nama display: pilih yang paling sering muncul
'unit' => $rows->groupBy('unit')
->sortByDesc(fn ($g) => (int) $g->sum('total_unit'))
->keys()
->first(),
'total_unit' => (int) $rows->sum('total_unit'),
];
})
->values();
$rows = []; $rows = [];
$rows[] = ['Unit Kerja', 'Total']; $rows[] = ['Unit Kerja', 'Total'];
foreach ($masterUnits as $unit) { foreach ($jawabanCounts as $row) {
$sudahIsi = (int) $row->total_unit;
// $totalKaryawan = $unitTotalMaps[$row->unit_key] ?? null;
// $display = ($totalKaryawan && $totalKaryawan > 0)
// ? "{$sudahIsi} / {$totalKaryawan}"
// : (string) $sudahIsi;
$rows[] = [ $rows[] = [
$unit, $row->unit,
(int) ($rekap[$unit] ?? 0), $sudahIsi,
]; ];
} }
return Excel::download(new DashboardExport($rows), 'data pegawai yang sudah survey.xlsx'); return Excel::download(new DashboardExport($rows), 'data pegawai yang sudah survey.xlsx');
} }
public function data_tidak_mau_survey(Request $request) public function data_tidak_mau_survey(Request $request)
{ {
$total_tidak = DB::table('lms_mutu_jawaban_detail as a') $total_tidak = DB::table('lms_mutu_jawaban_detail as a')

View File

@ -59,6 +59,10 @@
</thead> </thead>
</table> </table>
</div> </div>
<div class="mt-2 text-muted small">
<strong>Keterangan:</strong><br>
<span> Format <code>x / y</code> berarti <strong>x pegawai sudah mengisi</strong> dari <strong>total y pegawai aktif di SMART</strong>.</span><br>
</div>
</div> </div>
</div> </div>
</div> </div>