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 '';
$s = Str::of($s)->lower()->trim();
// buang teks dalam kurung: (SIMRS) dll
$s = $s->replaceMatches('/\s*\([^)]*\)\s*/u', ' ');
// expand singkatan penting
@ -34,23 +32,26 @@ class AdminController extends Controller
$s = $s->replaceMatches('/\bhumas\b/u', 'hubungan masyarakat');
$s = $s->replaceMatches('/\bipt\b/u', 'instalasi perinatal terpadu');
$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('/\binstalasi\s+rawat\s+intensif\s*\/\s*icu\b/u', 'instalasi rawat intensif');
$s = $s->replaceMatches(
'/\binstalasi\s+kl\s*(?:&|\/)?\s*k3rs\b/u',
'instalasi kesehatan lingkungan dan keselamatan dan kesehatan kerja rumah sakit'
);
// samakan simbol
$s = $s->replace(['&', '/', '-', '.', ',', ':', ';'], ' ');
// samakan kata penghubung
$s = $s->replace(' dan ', ' ');
// rapikan spasi
$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;
}
//
@ -205,7 +206,19 @@ class AdminController extends Controller
$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)
$unitTotalMaps = $unitTotals->mapWithKeys(function ($item) {
@ -217,18 +230,15 @@ class AdminController extends Controller
$key = $this->unitKey($row->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 [
'unit' => $row->unit,
'total_unit' => $progress
'total_unit' => $display
];
})
->values();
@ -236,72 +246,40 @@ class AdminController extends Controller
return DataTables::of($data)->make(true);
}
public function download_report_data_pegawai_sudah_survey(Request $request)
{
$masterUnits = [
"Direktur Utama dan Direksi",
"Satuan Pengawas Internal",
"Komite Mutu",
"Komite Medik",
"Komite Keperawatan",
"Komite PPI & PRA",
"KTKL",
"KFT",
"KEH",
"ULP",
"Timker Yankep",
"Timker Yanjang",
"Timker Perencanaan, Evaluasi dan Program",
"Timker Hukum dan Humas",
"Timker Yanmed",
"Timker Perencanaan dan Evaluasi Anggaran",
"Timker Akutansi dan BMN",
"Timker Organisasi dan Sumber Daya Manusia",
"Timker TU & RT",
"Timker Diklat",
"Timker Penelitian",
"Timker Pelaksanan Keuangan",
"Instalasi Rawat Inap",
"Instalasi Rawat Jalan Reguler",
"Instalasi Rawat Intensif / ICU",
"Instalasi Rehabilitasi Medik",
"Instalasi Gizi",
"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",
];
$unitPegawai = UnitKerja::query()
->where('statusenabled', true)
->with([
'mappingPegawai' => function ($q) {
$q->where('statusenabled', true)
->whereHas('pegawai', fn ($p) => $p->where('statusenabled', true)->where('kedudukanfk', 1))
->with([
'pegawai' => fn ($p) => $p->where('statusenabled', true)->where('kedudukanfk', 1)
->select('id', 'namalengkap')
]);
}
])
->get();
$unitTotals = $unitPegawai->map(function ($unit) {
$pegawaiUnik = $unit->mappingPegawai
->pluck('pegawai')
->filter()
->unique('id');
return [
'name' => $unit->name,
'total_karyawan' => $pegawaiUnik->count(),
];
});
$unitTotalMaps = $unitTotals->mapWithKeys(function ($item) {
return [$this->unitKey($item['name']) => (int) $item['total_karyawan']];
});
$query = Jawaban::query()
->select([
'unit',
DB::raw('COUNT(*) as total'),
])
->select('unit', DB::raw('COUNT(*) as total_unit'))
->whereNotNull('unit');
if ($request->nama_pegawai) {
@ -309,30 +287,47 @@ class AdminController extends Controller
}
if ($request->select_unit_kerja) {
$selectedUnits = (array) $request->select_unit_kerja;
$query->whereIn('unit', $selectedUnits);
$masterUnits = array_values(array_intersect($masterUnits, $selectedUnits));
$query->whereIn('unit', (array) $request->select_unit_kerja);
}
$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[] = ['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[] = [
$unit,
(int) ($rekap[$unit] ?? 0),
$row->unit,
$sudahIsi,
];
}
return Excel::download(new DashboardExport($rows), 'data pegawai yang sudah survey.xlsx');
}
public function data_tidak_mau_survey(Request $request)
{
$total_tidak = DB::table('lms_mutu_jawaban_detail as a')

View File

@ -59,6 +59,10 @@
</thead>
</table>
</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>