Dokumentasi teknis untuk developer — arsitektur, pola query, alur request, dan daftar endpoint modul pelaporan Medicare.
Query hard-coded di PHP controller. Cocok untuk laporan dengan format tetap dan logika bisnis kompleks.
Laporan dikonfigurasi via UI editor, disimpan di database, dan dieksekusi secara runtime. Bisa dibuat tanpa deploy code baru.
Setiap sub-modul RS punya controller sendiri. Logika bisnis sepenuhnya dikontrol developer.
Konfigurasi via UI editor · Disimpan di database · Dieksekusi secara runtime · Role-based access
| Tabel | Fungsi |
|---|---|
_LIRA_RB_REPORT | Master laporan |
_LIRA_RB_KOMPONEN | Komponen (tabel/chart/teks) |
_LIRA_RB_PANEL | Panel/section laporan |
_LIRA_RB_KOMPONENHEADER | Kolom header |
_LIRA_RB_REPORTAKSES | Hak akses per role |
ReportBuilderController_LIRA_RB_PANEL_LIRA_RB_KOMPONENEXEC sp_report_xxx · Tabel: SELECT * FROM xxxReportEditorController · CRUD laporan, editor visual, import/export JSON, manajemen komponen
| APPROVE | Status | Keterangan |
|---|---|---|
2 | Pending | Baru dibuat, menunggu review |
1 | Aktif | Sudah di-approve, dapat diakses user |
0 | Non-Aktif | Dinonaktifkan |
3 | Rejected | Ditolak |
role_edit_rb_all yang bisa edit laporan yang sudah Aktif. User lain hanya View-Only.sp_report_EXEC sp_report_xxx @LIMIT=1000, @param=val
vw_laporan_kasirSELECT TOP 1000 cols FROM datasource() WHERE filter
| Fitur | Method | Fungsi |
|---|---|---|
| List | data() | DataTables — semua laporan + status |
| Create | simpanReport() | Nama, label, tipe laporan |
| Update | updateReport() | Edit metadata laporan |
| Quick Report | quick_report() | Generate dari template unit RS (GRPUNIT) |
| Editor drag-drop | editor() | Panel, card, komponen visual |
| View-only | view() | Read-only untuk laporan Aktif |
| Komponen | viewKomponen() · simpanKomponen() | CRUD datasource, filter, kolom |
| Export JSON | exportReport() | Backup / transfer definisi |
| Import JSON | importReport() | Restore + cek duplikasi |
ReportEditorExtController_lira_modulrole)simpanReportAkses()
AN=1 (aktif) dan APPROVE=1 (sudah approve) yang muncul di UI Report Akses.| Method | Fungsi |
|---|---|
reporttipe() | List semua tipe — DataTables (Tipe, Modul, Action) |
simpanReportTipe() | Tambah tipe baru |
updateReportTipe() | Edit nama/modul tipe |
removeReportTipe() | Hard delete |
IDMODUL dari tabel _LIRA_MODUL. Daftar sub-modul yang muncul diambil dari syspar idmodulreport (ID parent modul Report).ReportBuilderController · server-side DataTable, export Excel/PDF, cross-database query
REPORTAKSES + MODULROLEUSERSHOWTOC=1 → render TOC sidebar fixedTIPELINKEDSERVER/DBSOURCE · SP atau Tabel · Eksekusi query| Fitur | Detail |
|---|---|
| Server-side | AJAX ke dataTable() — filter, sort, paginasi di server |
| Format numerik | ISNUMERIC=1 → auto-format via accounting.js |
| Kolom warna | BACKGROUNDCOLOR per kolom — inject CSS class dinamis |
| Total footer | ISSUM=1 — hitung total kolom di footer |
| Export Excel | toExcel() — Spout XLSX + kop RS |
| Export PDF | toPDF() — snappy/wkhtmltopdf, A4 atau A5 |
| Sembunyikan export | Syspar is_hide_export_report_modul |
| Tipe | Render |
|---|---|
TEXT | <input type="text"> — input bebas |
COMBOBOX | <select> + Select2 · sumber: DATASOURCE atau VALUESDATA (semicolon-sep) |
DATE | jQuery datepicker — tanggal tunggal |
DEFAULTFILTER | DateRangePicker — field dari komponen, batas dari MAXRANGE |
LINKEDSERVER + DBSOURCE — query ke server/DB lain via _LIRA_RB_SERVERGROUPSUMMARY — group field1|field2, hasilkan baris unik + SUMGROUPSHOWTOC — TOC sidebar dengan anchor #panel_{ID}@LIMIT — auto-inject @LIMIT=1000 ke semua SPapp/Http/Controllers/Modul/Report/
Admission · Finance · Kasir · Lab · Rekam Medis · Mutu · PPI · TBDOTS · Laporan · ReportBuilder
RawatJalanControllerDATEDIFF SQL ServerWaktuTungguControllerReportPPIControllerGraphic · PhoneBookSatu template konsisten di 21 controller. Pelajari satu, paham semua.
class NamaController extends Controller
{
private $idmodul;
public function __construct(Request $request)
{
$this->idmodul = $request->input('idmodul');
}
// Step 1 — Form filter
public function index(Request $request)
{
$data['idmodul'] = $this->idmodul;
$data['bagian'] = Bagian::select()->get();
$data['dokter'] = Dokter::select()->get();
return view('modul.report.xxx.index', $data);
}
// Step 2 — Preview hasil
public function laporan_xxx(Request $request)
{
$data['data'] = self::query_data($request);
return view('modul.report.xxx.preview_laporan', $data);
}
// Step 3 — Export Excel
public function download_excel(Request $request)
{
$data['data'] = self::query_data($request);
return view('modul.report.xxx.preview_laporan_excel', $data);
}
}
App\Http\Controllers\Controller
DB::select()Eloquent hanya dipakai untuk dropdown master data. Query Builder hampir tidak ada.
// Build WHERE dari form filter
$where = " 1=1 ";
if ($request->tgl_dari) {
$where .= " AND TGLBAYAR >= '"
.$request->tgl_dari."'";
}
if ($request->bagian) {
$where .= " AND KDBAGIAN = '"
.$request->bagian."'";
}
$result = DB::select("
SELECT P.NMPASIEN, B.TGLBAYAR
FROM BAYAR B
INNER JOIN PASIEN P ON ...
WHERE $where
");
$request langsung di-concatenate di 15+ tempat. Gunakan parameter binding saat tambah kode baru.WITH (NOLOCK), dan 5 format export berbeda.Pola yang dipakai di Finance, Kasir, dan Rekam Medis — kombinasi CASE WHEN, ISNULL, dan DATEDIFF untuk laporan kompleks.
$result = DB::select("
SELECT
R.NOREG,
P.NMPASIEN,
ISNULL(B.JMLBAYAR, 0) AS JMLBAYAR,
ISNULL(I.NOMINVOICE, 0) AS NOMINVOICE,
CASE WHEN B.NOINVOICE IS NULL
THEN 'Belum Bayar'
ELSE 'Lunas' END AS STATUS
FROM REGDR R
INNER JOIN PASIEN P ON R.NOPASIEN = P.NOPASIEN
LEFT JOIN INVOICE I ON R.NOREG = I.NOREG
LEFT JOIN BAYAR B ON I.NOINVOICE = B.NOINVOICE
WHERE $where
ORDER BY R.NOREG DESC
");
REGDR → PASIEN → INVOICE → BAYAR. CASE WHEN untuk status, ISNULL untuk nilai default.| Teknik | Kapan Dipakai |
|---|---|
WITH (NOLOCK) | Laporan read-only — hindari blocking dari transaksi billing aktif |
SELECT TOP n | Batasi baris hasil — pengganti LIMIT MySQL |
LTRIM(RTRIM(col)) | Strip spasi data lama — TRIM() tidak ada di SQL Server 2014 ke bawah |
DATEDIFF(minute,…) | Selisih waktu — Lab: order → hasil |
Koneksi report | Query berat → DB replika, jangan bebani DB produksi |
| Format | Implementasi |
|---|---|
| HTML Blade | return view(...) — semua controller |
| Excel via Blade | Blade + header Content-Disposition: attachment |
| Excel Spout | Box\Spout\Writer\WriterFactory — Finance |
barryvdh/laravel-dompdf — LaporanKasir | |
| JSON DataTables | Yajra\DataTables — PhoneBook, PPI, RB |
GET form → POST query → GET download
index() — load dropdown Bagian, Dokter, Penjamin, lalu return form HTML ke browserlaporan_xxx() — build WHERE dari filter, DB::select(), return view preview dengan tabel hasildownload_excel() — query ulang, return Blade Excel + header Content-Disposition: attachmentanyData yang return JSON format Yajra DataTables.pasien_awal, pasien_masuk, pasien_pulang, pasien_pindah, pasien_pindahan, pasien_sisadetail_rekap_jasa() mencapai 1.276 baris — if-else berlapis untuk berbagai kombinasi filter.HTML Blade · Excel View · Excel Spout · PDF · JSON DataTable
Box\Spout\Writer\WriterFactory untuk xlsx terstruktur dengan formatting.barryvdh/laravel-dompdfYajra\DataTables server-side & response()->json()application/vnd.ms-excel — bukan xlsx asli, tapi browser membukanya di Excel.Semuanya terdaftar di routes/web.php dalam group prefix /report
SQL Server bukan MySQL · Throwable bukan Exception · Parameter binding bukan concatenation
| SQL Server ✓ | MySQL ✗ |
|---|---|
SELECT TOP 10 * | LIMIT 10 |
LTRIM(RTRIM(col)) | TRIM(col) |
ISNULL(col, '') | IFNULL(col, '') |
CONVERT(varchar,t,120) | DATE_FORMAT() |
DATEDIFF(minute,t1,t2) | TIMESTAMPDIFF() |
catch (\Throwable $e) bukan catch (\Exception $e) — tidak menangkap TypeError dan Error.hasil: 1 sukses · hasil: 0 gagal · hasil: 25 duplikat// JANGAN — rentan SQL injection
$where .= " AND KDBAGIAN = '".$request->bagian."'";
$result = DB::select("SELECT ... WHERE $where");
// GUNAKAN — aman dengan parameter binding
$params = [];
$where = " 1=1 ";
if ($request->bagian) {
$where .= " AND KDBAGIAN = ?";
$params[] = $request->bagian;
}
$result = DB::select(
"SELECT ... FROM ... WHERE $where",
$params
);
reportconfig/database.php di environment baru. Dipakai oleh StockObatController dan LaporanFormController. Tanpa ini, laporan stok & mutu akan error.Dokumentasi lengkap tersedia di REPORT_MODULE_DOCS.md
catch (\Throwable $e) untuk exceptionDB::select($q, $params)report ada di database.phpTOP n bukan LIMIT n