diff --git a/TODO.md b/TODO.md
index 67e0321..0249883 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,9 +3,8 @@
**Last Updated:** 20260204
Pending:
-- Auto generate PDF
-- Print Eng Result
-- Reprint Label (Add functionality to reprint labels)
+- Test and fix Reprint label
+- Test and fix PDF Generation
- Print Result Audit (Track when result reports are printed/exported, log user and timestamp)
Completed:
@@ -31,4 +30,9 @@ Completed:
- Add Val1 Val2 on the result
- Show Print / PDF button when val1 val2 done
- Restrict Print/Save-to-PDF to CS Role only (Admin, Lab, CS can print/save)
-- Add Receive to Audit
\ No newline at end of file
+- Add Receive to Audit
+- Put all action to dropdown on request / dashboard
+- Auto generate PDF on second val
+- Validate delay when loading result
+- Reprint Label (Add functionality to reprint labels)
+- Create Eng Result UI UX on request dashboard
\ No newline at end of file
diff --git a/UAT_GDC_CMOD_Checklist.md b/UAT_GDC_CMOD_Checklist.md
new file mode 100644
index 0000000..b90f420
--- /dev/null
+++ b/UAT_GDC_CMOD_Checklist.md
@@ -0,0 +1,606 @@
+# 📋 UAT (USER ACCEPTANCE TESTING) - CHECKLIST
+## Sistem Manajemen Laboratorium - GDC CMOD
+
+---
+
+## 1. IDENTITAS DOKUMEN
+
+| Item | Detail |
+|------|--------|
+| **Nama Proyek** | GDC CMOD - Laboratory Management System |
+| **Versi Aplikasi** | 1.0 |
+| **Tanggal UAT** | _______________ |
+| **Durasi UAT** | _____ hari |
+| **Dokumen Versi** | 1.0 |
+| **Prepared By** | __________________ |
+| **Reviewed By** | __________________ |
+| **Approved By** | __________________ |
+
+---
+
+## 2. INSTRUKSI PENGISIAN
+
+✅ **PASS** = Test case berhasil sepenuhnya
+❌ **FAIL** = Test case gagal - ada defect
+⏭️ **N/A** = Tidak dapat dilakukan
+🚫 **BLOCKED** = Terhalang oleh issue lain
+
+**Cara Pengisian:**
+1. Centang checkbox [ ] jika test case LULUS (PASS)
+2. Tulis "X" dalam kotak [X] jika test case GAGAL (FAIL)
+3. Tambahkan catatan @ kolom "Issue/Jawaban" untuk kasus FAIL/N/A/BLOCKED
+4. Beri nomor urut di "No." untuk tracking
+
+---
+
+## 3. TEST CASE - AUTENTIKASI & SESI
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-AUTH-001** | Login Berhasil | Login dengan username & password valid | Redirect ke dashboard sesuai role | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-002** | Login Gagal - Username Salah | Masukkan username tidak ada | Error "Invalid credentials" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-003** | Login Gagal - Password Salah | Password salah | Error invalid credentials | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-004** | Login Gagal - Akun Terkunci | Login ke akun locked dari legacy | Error "Account locked" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-005** | Logout Berhasil | Klik menu Logout | Session terhapus, redirect ke login | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-006** | Redirect ke Login Belum Login | Akses protected page tanpa login | Redirect otomatis ke halaman login | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-007** | Ganti Password Berhasil | Change password baru | Password berhasil diubah dan di-hash | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-008** | Ganti Password Gagal - Password Lama Salah | Masukkan password lama salah | Error "Invalid old password" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-AUTH-009** | Role-Based Redirect Login | Login dengan berbagai role | Redirect ke dashboard sesuai role | [ ] PASS
[ ] FAIL | ___________ |
+
+### Ringkasan Autentikasi: _ LULUS / _____ GAGAL
+
+---
+
+## 4. TEST CASE - SUPERUSER (ROLE 0)
+
+### 4.1 DASHBOARD SUPERUSER
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-SU-001** | Tampilkan Semua Request | Login Superuser → `/superuser` | Tabel requests semua status ditampilkan | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-002** | Filter by Status | Pilih status di dashboard filter | Filter berfungsi sesuai status | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-003** | Filter by Date Range | Set date1 & date2 → filter | Filter tanggal berfungsi | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-004** | Search by Patient Name | Masukkan nama pasien | Tampilkan request dengan nama tsb | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-005** | Search by Lab Number | Masukkan Lab Number | Tampilkan request tsb | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-006** | Search by Register Number | Masukkan Register Number | Tampilkan request tsb | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-007** | Table Sorting | Klik header kolom | Kolom di-sort ASC/DESC | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-008** | Pagination | Klik halaman berbeda | Berpindah halaman dengan benar | [ ] PASS
[ ] FAIL | ___________ |
+
+### 4.2 USER MANAGEMENT SUPERUSER
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-SU-009** | Tampilkan List User | Access `/superuser/users` | Tabel users ditampilkan lengkap | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-010** | Buat User Baru | Add User → isi form | User berhasil dibuat dan password di-hash | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-011** | Validasi Password Min 3 Karakter | Buat user dengan password < 3 char | Error "Password min 3 karakter" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-012** | Update User Role | Edit user → ubah role | Role berhasil diubah | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-013** | Update Password User | Edit user → ganti password | Password di-hash dengan benar | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-014** | Delete User | Delete user | User terhapus dari database | [ ] PASS
[ ] FAIL | ___________ |
+
+### 4.3 VALIDASI SUPERUSER
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-SU-015** | Tampilkan Request Final | Access `/superuser/validate` | Hanya request "Fin" yang tampil | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-016** | Filter by Date Range Validasi | Set date1 & date2 → filter | Filter berfungsi di halaman validasi | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-017** | First Validation (VAL1) | Validasi request "Fin" | ISVAL1=1, VAL1USER & VAL1DATE diset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-018** | Second Validation (VAL2) | Validasi dengan user berbeda | ISVAL2=1, request duavalidated | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-019** | Gagal Validasi Sendiri | Coba validasi ulang sama user | Error "Cannot validate own request" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-020** | Un-Validate Request | Un-validate dengan reason | ISVAL reset, PENDING diset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-021** | Shortcut Keyboard | Enter=Validate, N=Skip, Esc=Close | Shortcut berfungsi dengan benar | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-022** | Progress Indicator | Buka validation modal | Progress muncul (posisi / total) | [ ] PASS
[ ] FAIL | ___________ |
+
+### 4.4 SAMPLE MANAGEMENT SUPERUSER
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-SU-023** | Collect Sample | Buka dialog sample → Collect | STATUS=1, COLLECTIONDATE & USERID diset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-024** | Un-Collect Sample | Buka dialog sample → Un-Collect | STATUS di-reset, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-025** | Un-Receive Sample | Un-receive sample yang received | Status berubah, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-026** | Print Label Individu | Print label per tube | Label tercetak dengan ZPL format | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-027** | Print Collection Label | Print collection label | Label collection tercetak | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-028** | Print All Labels | Print semua tubes | Semua labels tercetak | [ ] PASS
[ ] FAIL | ___________ |
+
+### 4.5 AUDIT TRAIL SUPERUSER
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-SU-029** | View Request Audit | Buka audit dialog request | Audit trail timeline ditampilkan | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-030** | Filter by Category | Filter: All, Validation, Receive, Sample | Filter berfungsi sesuai kategori | [ ] PASS
[ ] FAIL | ___________ |
+
+### 4.6 REPORT SUPERUSER
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-SU-031** | View Report Validated | View report request duavalidated | Report ditampilkan lengkap | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-032** | Cannot View Not Validated | View report belum duavalidated | Error: "Validated request required" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-033** | Print Report | Print report request validated | Print dialog buka, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-034** | Generate PDF | Generate PDF request validated | PDF berhasil di-generate | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-035** | Preview Report (No Audit) | Preview report tanpa log audit | Report tampil, tidak ada audit log | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-036** | English Version Report | Access `/report/{id}/eng` | Report dalam Bahasa Inggris | [ ] PASS
[ ] FAIL | ___________ |
+
+### 4.7 FITUR TAMBAHAN SUPERUSER
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-SU-037** | Edit Comment | Edit comment di dashboard | Comment berubah tersimpan | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-038** | Error Handling 404 | Akses URL tidak valid | Custom notfound page tampil | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-SU-039** | Error Handling Unauthorized | Coba akses role lain | Redirect ke `/unauthorized` | [ ] PASS
[ ] FAIL | ___________ |
+
+### Ringkasan Superuser: _ LULUS / _____ GAGAL
+
+---
+
+## 5. TEST CASE - ADMIN (ROLE 1)
+
+### 5.1 DASHBOARD ADMIN
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-ADM-001** | Tampilkan Semua Request | Login Admin → `/admin` | Tabel requests semua status | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-002** | Filter & Search | Uji berbagai filter dan search | Semua berfungsi seperti Superuser | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-003** | Sample Collection Buttons Enabled | Buka dialog sample | Tombol Collect/Un-Coll/Un-Recv enabled | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-004** | Edit Comment Enabled | Edit comment dashboard | Comment dapat diubah | [ ] PASS
[ ] FAIL | ___________ |
+
+### 5.2 VALIDASI ADMIN
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-ADM-005** | Tampilkan Request Final | Access `/admin/validate` | Hanya request "Fin" tampil | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-006** | First Validation (VAL1) | Validasi request "Fin" | ISVAL1=1, VAL1USER & VAL1DATE diset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-007** | Second Validation (VAL2) | Validasi dengan user berbeda | ISVAL2=1, request duavalidated | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-008** | Gagal Validasi Sendiri | Coba validasi ulang sama user | Error "Cannot validate own request" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-009** | Un-Validate Request | Un-validate request validated | ISVAL reset, PENDING diset | [ ] PASS
[ ] FAIL | ___________ |
+
+### 5.3 SAMPLE & FITUR LAIN ADMIN
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-ADM-010** | Collect Sample | Collect tube | STATUS=1, COLLECTIONDATE & USERID diset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-011** | Un-Collect Sample | Un-collect tube | STATUS di-reset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-012** | Un-Receive Sample | Un-receive sample | Status berubah, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-013** | Print Labels | Print individual/collection/all | Semua labels tercetak | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-014** | View Audit Trail | Buka audit dialog | Timeline audit ditampilkan | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-015** | Tampilkan List User | Access `/admin/users` | Tabel users ditampilkan | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-016** | Buat User Baru | Add user lengkap | User berhasil dibuat dan di-hash | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-017** | Update User | Edit user → ubah data | User berhasil di-update | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-018** | Delete User | Delete user | User terhapus | [ ] PASS
[ ] FAIL | ___________ |
+
+### 5.4 REPORT ADMIN
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-ADM-019** | View Report Validated | View report request validated | Report ditampilkan lengkap | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-020** | Print Report | Print report | Print dialog buka, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-ADM-021** | Generate PDF | Generate PDF report | PDF berhasil di-generate | [ ] PASS
[ ] FAIL | ___________ |
+
+### 5.5 ROLE RESTRICTIONS ADMIN
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-ADM-PageNav** | Cannot Access Role Lain | Coba `/superuser`, `/lab`, `/phlebo`, `/cs` | Redirect ke unauthorized/error | [ ] PASS
[ ] FAIL | ___________ |
+
+### Ringkasan Admin: _ LULUS / _____ GAGAL
+
+---
+
+## 6. TEST CASE - LAB ANALYST (ROLE 2)
+
+### 6.1 DASHBOARD LAB
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-LAB-001** | Filter Test Code Alphabetical | Login Lab → `/lab` | Hanya request TESTS A-Z yang tampil | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-002** | View Request Details | Buka request | Detail request ditampilkan | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-003** | Filter & Search dalam Batas Filter | Uji filter & search | Sesuai batas test code A-Z | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-004** | Sample Buttons Enabled | Buka dialog sample | Tombol Collect/Un-Coll/Un-Recv enabled | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-005** | Edit Comment Disabled | Cek comment field | Comment field non-editable | [ ] PASS
[ ] FAIL | ___________ |
+
+### 6.2 VALIDASI LAB
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-LAB-006** | Tampilkan Request Final | Access `/lab/validate` | Hanya "Fin" dengan TESTS A-Z tampil | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-007** | First Validation (VAL1) | Validasi request "Fin" | ISVAL1=1, VAL1USER & VAL1DATE diset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-008** | Second Validation (VAL2) | Validasi user berbeda | ISVAL2=1, request duavalidated | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-009** | Gagal Validasi Sendiri | Coba validasi sendiri | Error "Cannot validate own request" | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-010** | Un-Validate Disabled | Coba un-validate | Error/Unauthorized - cannot un-validate | [ ] PASS
[ ] FAIL | ___________ |
+
+### 6.3 SAMPLE & FITUR LAIN LAB
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-LAB-011** | Collect Sample | Collect tube | STATUS=1, COLLECTIONDATE & USERID diset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-012** | Un-Collect Sample | Un-collect tube | STATUS di-reset | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-013** | Un-Receive Sample | Un-receive sample | Status berubah, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-014** | Print Labels | Print semua jenis label | Semua labels tercetak | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-015** | View Audit Trail | Buka audit dialog | Timeline audit ditampilkan | [ ] PASS
[ ] FAIL | ___________ |
+
+### 6.4 REPORT LAB
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-LAB-016** | View Report Validated | View report request validated | Report ditampilkan lengkap | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-017** | Print Report | Print report validated | Print dialog buka, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-LAB-018** | Generate PDF | Generate PDF | PDF berhasil di-generate | [ ] PASS
[ ] FAIL | ___________ |
+
+### 6.5 ROLE RESTRICTIONS LAB
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-LAB-PageNav** | Cannot Access Role Lain | Coba `/superuser`, `/admin`, `/phlebo`, `/cs` | Redirect ke unauthorized/error | [ ] PASS
[ ] FAIL | ___________ |
+
+### Ringkasan Lab: _ LULUS / _____ GAGAL
+
+---
+
+## 7. TEST CASE - PHLEBOTOMIST (ROLE 3)
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-PHB-001** | Tampilkan Semua Request | Login Phlebo → `/phlebo` | Tabel requests semua status | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-002** | Filter & Search | Uji filter & search | Semua berfungsi | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-003** | Sample Collection Disabled | Buka dialog sample | Tombol Collect/Un-Coll/Un-Recv DISABLED | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-004** | Edit Comment Disabled | Cek comment field | Comment field non-editable | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-005** | Validation Page Denied | Coba `/phlebo/validate` | Halaman tidak tersedia/unauthorized | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-006** | View Sample Details (Read-Only) | Buka dialog sample | Sample details view-only | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-007** | Print Labels | Print individual/collection/all | Labels tercetak | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-008** | View Audit Trail | Buka audit dialog | Audit trail ditampilkan (read-only) | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-009** | Cannot View Report | Coba view report | Report tidak tersedia/error | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-010** | Cannot Print Report | Coba print report | Print tidak tersedia | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-011** | Cannot Generate PDF | Coba generate PDF | PDF tidak tersedia | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-PHB-PageNav** | Cannot Access Role Lain | Coba `/superuser`, `/admin`, `/lab`, `/cs` | Redirect ke unauthorized/error | [ ] PASS
[ ] FAIL | ___________ |
+
+### Ringkasan Phlebotomist: _ LULUS / _____ GAGAL
+
+---
+
+## 8. TEST CASE - CUSTOMER SERVICE (ROLE 4)
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-CS-001** | Tampilkan Semua Request | Login CS → `/cs` | Tabel requests semua status | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-002** | Filter & Search | Uji filter & search | Semua berfungsi | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-003** | Sample Collection Disabled | Buka dialog sample | Tombol Collect/Un-Coll/Un-Recv DISABLED | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-004** | Edit Comment Disabled | Cek comment field | Comment field non-editable | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-005** | Validation Page Denied | Coba `/cs/validate` | Halaman tidak tersailable | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-006** | View Sample Details (Read-Only) | Buka dialog sample | Sample details view-only | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-007** | Print Labels (Limited) | Print labels | Labels tercetak sesuai kapasitas | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-008** | View Audit Trail | Buka audit dialog | Audit trail ditampilkan | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-009** | View Report Validated | View report request validated | Report ditampilkan lengkap | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-010** | Print Report | Print report validated | Print dialog buka, audit log tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-011** | Generate PDF | Generate PDF | PDF berhasil di-generate | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-CS-PageNav** | Cannot Access Role Lain | Coba `/superuser`, `/admin`, `/lab`, `/phlebo` | Redirect ke unauthorized/error | [ ] PASS
[ ] FAIL | ___________ |
+
+### Ringkasan Customer Service: _ LULUS / _____ GAGAL
+
+---
+
+## 9. TEST CASE - FITUR CROSS-ROLE
+
+| No. | ID | Judul Test Case | Langkah Utama | Expected Result | Hasil | Issue/Jawaban |
+|-----|----|----------------|---------------|-----------------|-------|---------------|
+| | **TC-X-001** | User Mgmt Role Restrictions | Lab/Phlebo/CS coba user management API | Error unauthorized | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-002** | Cross-Role Validation | Lab A validasi VAL1, Superuser B validasi VAL2 | Cross-role validation berhasil | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-003** | Un-Validate Role Restrictions | Lab/Phlebo/CS coba un-validate | Error unauthorized - only SU/Admin | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-004** | Un-Receive Role Restrictions | Lab/Phlebo/CS coba un-receive | Error unauthorized - only SU/Admin | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-005** | Report Access Restrictions | Coba view report semua role | SU/Admin/Lab/CS OK, Phlebo NOT | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-006** | Report Validated Requirement | View report hanya VAR1 vs duavalidated | Hanya duavalidated dapat dilihat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-007** | Comment Edit Restrictions | Lab/Phlebo/CS coba edit comment | Error - only SU/Admin editable | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-008** | Validasi tidak Pengaruhi Data Lain | Record data sebelum & sesudah validasi | Hanya status validasi berubah | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-009** | Un-Validate Mempertahankan Data | Record data sebelum & sesudah un-validate | Hanya status validasi berubah | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-010** | Audit Trail Logging | Lakukan berbagai aktivitas | Semua tercatat di audit log | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-011** | Concurrent Validation | 2 user buka validation dialog bersamaan | Validasi berhasil, tidak conflict | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-012** | Concurrent Sample Collection | 2 user collect tube berbeda bersamaan | Semua berhasil tercatat | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-013** | Session Timeout | Tunggu session timeout | Redirect ke login | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-014** | Password Hashing Security | Buat user → cek database | Password dalam HASH bukan plain | [ ] PASS
[ ] FAIL | ___________ |
+| | **TC-X-015** | Legacy Read-Only | Cek koneksi & fungsi Firebird | Hanya READ dari Firebird, TIDAK WRITE | [ ] PASS
[ ] FAIL | ___________ |
+
+### Ringkasan Cross-Role: _ LULUS / _____ GAGAL
+
+---
+
+## 10. KRITERIA PENERIMAAN (ACCEPTANCE CRITERIA)
+
+### 10.1 Functional Criteria
+
+| No. | Kriteria Functional | Hasil |
+|-----|---------------------|-------|
+| FC-01 | Autentikasi benar untuk semua role (0-4) | [ ] PASS
[ ] FAIL |
+| FC-02 | Role-based access control (RBAC) berfungsi | [ ] PASS
[ ] FAIL |
+| FC-03 | Dashboard menampilkan request sesuai filter & role | [ ] PASS
[ ] FAIL |
+| FC-04 | User management CRUD berfungsi untuk Superuser & Admin | [ ] PASS
[ ] FAIL |
+| FC-05 | Dual-level validation system (VAL1 & VAL2) berfungsi | [ ] PASS
[ ] FAIL |
+| FC-06 | Validasi tidak bisa oleh user yang sama | [ ] PASS
[ ] FAIL |
+| FC-07 | Un-validate berfungsi (Superuser & Admin only) | [ ] PASS
[ ] FAIL |
+| FC-08 | Sample collection/un-collection berfungsi | [ ] PASS
[ ] FAIL |
+| FC-09 | Un-receive sample berfungsi (Superuser & Admin only) | [ ] PASS
[ ] FAIL |
+| FC-10 | Audit trail mencatat semua aktivitas krusial | [ ] PASS
[ ] FAIL |
+| FC-11 | Report hanya untuk request duavalidated | [ ] PASS
[ ] FAIL |
+| FC-12 | Report hanya accessible role (SU, Admin, Lab, CS) | [ ] PASS
[ ] FAIL |
+| FC-13 | PDF generation berfungsi | [ ] PASS
[ ] FAIL |
+| FC-14 | Label printing berfungsi (individual, collection, all) | [ ] PASS
[ ] FAIL |
+| FC-15 | Comment editing berfungsi (Superuser & Admin only) | [ ] PASS
[ ] FAIL |
+| FC-16 | Filter dan search bekerja dengan benar | [ ] PASS
[ ] FAIL |
+| FC-17 | Pagination dan sorting tabel berfungsi | [ ] PASS
[ ] FAIL |
+
+### Functional Summary: _ LULUS / _____ GAGAL
+
+---
+
+### 10.2 Security Criteria
+
+| No. | Kriteria Security | Hasil |
+|-----|-------------------|-------|
+| SC-01 | Password disimpan dalam bentuk HASH (bukan plain) | [ ] PASS
[ ] FAIL |
+| SC-02 | Session timeout bekerja dengan benar | [ ] PASS
[ ] FAIL |
+| SC-03 | Tidak ada SQL injection vulnerability | [ ] PASS
[ ] FAIL |
+| SC-04 | Role-based authorization terpenuhi | [ ] PASS
[ ] FAIL |
+| SC-05 | Locked account tidak dapat login | [ ] PASS
[ ] FAIL |
+| SC-06 | Audit trail mencatat semua aktivitas (traceability) | [ ] PASS
[ ] FAIL |
+| SC-07 | Un-validate hanya Superuser & Admin | [ ] PASS
[ ] FAIL |
+| SC-08 | Legacy Firebird system READ-ONLY | [ ] PASS
[ ] FAIL |
+
+### Security Summary: _ LULUS / _____ GAGAL
+
+---
+
+### 10.3 Performance Criteria
+
+| No. | Kriteria Performance | Target | Hasil Aktual | Pass/Fail |
+|-----|----------------------|--------|--------------|-----------|
+| PC-01 | Dashboard load time | < 3 detik | __________ detik | [ ] PASS
[ ] FAIL |
+| PC-02 | Validation page load time | < 3 detik | __________ detik | [ ] PASS
[ ] FAIL |
+| PC-03 | Report generation time | < 5 detik | __________ detik | [ ] PASS
[ ] FAIL |
+| PC-04 | PDF generation time | < 30 detik | __________ detik | [ ] PASS
[ ] FAIL |
+| PC-05 | Database query response time | < 2 detik | __________ detik | [ ] PASS
[ ] FAIL |
+| PC-06 | Concurrent user support | Min. 5 user | _____ user simultaneous ok | [ ] PASS
[ ] FAIL |
+
+### Performance Summary: _ LULUS / _____ GAGAL
+
+---
+
+### 10.4 Usability Criteria
+
+| No. | Kriteria Usability | Hasil |
+|-----|---------------------|-------|
+| UC-01 | UI user-friendly dan mudah digunakan | [ ] PASS
[ ] FAIL |
+| UC-02 | Shortcut keyboard (Enter, N, Esc) berfungsi | [ ] PASS
[ ] FAIL |
+| UC-03 | Error messages jelas dan actionable | [ ] PASS
[ ] FAIL |
+| UC-04 | Responsive design (bekerja di berbagai ukuran) | [ ] PASS
[ ] FAIL |
+| UC-05 | Icons dan color-coding jelas | [ ] PASS
[ ] FAIL |
+| UC-06 | Data terorganisir dengan baik | [ ] PASS
[ ] FAIL |
+
+### Usability Summary: _ LULUS / _____ GAGAL
+
+---
+
+### 10.5 Data Integrity Criteria
+
+| No. | Kriteria Data Integrity | Hasil |
+|-----|-------------------------|-------|
+| DC-01 | Validasi tidak menghapus/mengubah data lain | [ ] PASS
[ ] FAIL |
+| DC-02 | Un-validate hanya menghapus status validasi | [ ] PASS
[ ] FAIL |
+| DC-03 | Sample collection tidak modifikasi data lain | [ ] PASS
[ ] FAIL |
+| DC-04 | Audit trail tercatat dengan benar | [ ] PASS
[ ] FAIL |
+| DC-05 | Tidak ada data duplikasi concurrent access | [ ] PASS
[ ] FAIL |
+| DC-06 | Status request sesuai workflow | [ ] PASS
[ ] FAIL |
+| DC-07 | Dual-validation requirement terpenuhi | [ ] PASS
[ ] FAIL |
+
+### Data Integrity Summary: _ LULUS / _____ GAGAL
+
+---
+
+## 11. KEPUTUSAN AKHIR UAT
+
+### 11.1 Tolok Ukur Go-Live
+
+Untuk sistem dinyatakan **APPROVED** untuk production:
+
+| Category | LULUS | GAGAL | PERSEN LULUS | PASS? |
+|----------|-------|-------|--------------|------|
+| **Functional** | ___ | ___ | ___% | [ ] YES
[ ] NO |
+| **Security** | ___ | ___ | ___% | [ ] YES
[ ] NO |
+| **Performance** | ___ | ___ | ___% | [ ] YES
[ ] NO |
+| **Usability** | ___ | ___ | ___% | [ ] YES
[ ] NO |
+| **Data Integrity** | ___ | ___ | ___% | [ ] YES
[ ] NO |
+
+**OVERALL PASS RATE:** ______% (dari 5 kategori)
+
+---
+
+### 11.2 Keputusan Final
+
+**Pilih Salah Satu:**
+
+- [ ] **✅ APPROVED GO-LIVE** - Semua criteria terpenuhi, sistem siap untuk production
+- [ ] **⚠️ CONDITIONAL APPROVAL** - Sistem siap dengan catatan berikut:
+ ```
+ ____________________________________________________________
+ ____________________________________________________________
+ ____________________________________________________________
+ ```
+- [ ] **❌ NOT APPROVED** - Sistem belum siap, harus perbaiki issue berikut:
+ ```
+ ____________________________________________________________
+ ____________________________________________________________
+ ____________________________________________________________
+ ```
+
+---
+
+### 11.3 Issue Critical yang Harus Diperbaiki
+
+| No. | Issue | Severity | Impact | Assigned To | Deadline |
+|-----|-------|----------|--------|-------------|----------|
+| 1 | ________________________________ | High | ___________ | ___________ | _______ |
+| 2 | ________________________________ | Medium | ___________ | ___________ | _______ |
+| 3 | ________________________________ | Low | ___________ | ___________ | _______ |
+| 4 | ________________________________ | | ___________ | ___________ | _______ |
+| 5 | ________________________________ | | ___________ | ___________ | _______ |
+
+---
+
+## 12. CHECKLIST SIGN-OFF
+
+### 12.1 UAT Team Sign-off
+
+| Nama | Role | Signature | Sign-off Tanggal |
+|------|------|-----------|------------------|
+| __________________________ | UAT Tester 1 | _____________________ | ____/____/____ |
+| __________________________ | UAT Tester 2 | _____________________ | ____/____/____ |
+| __________________________ | UAT Tester 3 | _____________________ | ____/____/____ |
+| __________________________ | Business Analyst | _____________________ | ____/____/____ |
+
+---
+
+### 12.2 Management Sign-off
+
+| Nama | Role | Signature | Sign-off Tanggal |
+|------|------|-----------|------------------|
+| __________________________ | Project Manager | _____________________ | ____/____/____ |
+| __________________________ | Testing/QA Manager | _____________________ | ____/____/____ |
+
+---
+
+### 12.3 Stakeholder Sign-off
+
+| Nama | Role | Signature | Sign-off Tanggal |
+|------|------|-----------|------------------|
+| __________________________ | Lab Manager | _____________________ | ____/____/____ |
+| __________________________ | Hospital IT Manager | _____________________ | ____/____/____ |
+| __________________________ | End User Representative | _____________________ | ____/____/____ |
+
+---
+
+## 13. APPENDIX
+
+### 13.1 Test Data Used
+
+#### Users (Test Data):
+| User ID | Username | Role | Password |
+|---------|----------|------|----------|
+| 10001 | test_superuser | 0 | supersu123 |
+| 10002 | test_admin | 1 | admin123 |
+| 10003 | test_lab | 2 | lab123 |
+| 10004 | test_phlebo | 3 | phlebo123 |
+| 10005 | test_cs | 4 | cs123 |
+
+#### Requests (Test Data):
+- [ ] Request A: Status "Pending" - order baru
+- [ ] Request B: Status "Coll" - sample collected
+- [ ] Request C: Status "Recv" - sample received
+- [ ] Request D: Status "Fin" - ready for validation
+- [ ] Request E: Status "FinV" - duavalidated
+- [ ] Request F: Hanya VAL1
+- [ ] Request G: Dengan test codes alphabetical (untuk Lab filter)
+
+---
+
+### 13.2 Known Issues / Limitations Found
+
+| ID | Issue | Severity | Workaround | Fixed? |
+|----|-------|----------|------------|--------|
+| ISS-01 | ________________________________ | [Low/Med/High] | _____________ | [ ] Yes
[ ] No |
+| ISS-02 | ________________________________ | [Low/Med/High] | _____________ | [ ] Yes
[ ] No |
+| ISS-03 | ________________________________ | [Low/Med/High] | _____________ | [ ] Yes
[ ] No |
+
+---
+
+### 13.3 Contact Information
+
+| Role | Nama | Contact |
+|------|------|---------|
+| UAT Lead | ________________________________ | _______________________ |
+| Technical Lead | ________________________________ | _______________________ |
+| Dev Team | ________________________________ | _______________________ |
+
+---
+
+### 13.4 Notes Tambahan
+
+```
+_____________________________________________________________________________
+_____________________________________________________________________________
+_____________________________________________________________________________
+_____________________________________________________________________________
+_____________________________________________________________________________
+_____________________________________________________________________________
+```
+
+---
+
+## 14. SUMMARY STATISTICS
+
+### 14.1 Test Execution Summary
+
+| Kategori | Total Cases | LULUS | GAGAL | N/A | BLOCKED | % LULUS |
+|----------|-------------|-------|-------|-----|---------|---------|
+| **Autentikasi** | 9 | ___ | ___ | ___ | ___ | ___% |
+| **Superuser** | 39 | ___ | ___ | ___ | ___ | ___% |
+| **Admin** | 22 | ___ | ___ | ___ | ___ | ___% |
+| **Lab Analyst** | 19 | ___ | ___ | ___ | ___ | ___% |
+| **Phlebotomist** | 12 | ___ | ___ | ___ | ___ | ___% |
+| **Customer Service** | 12 | ___ | ___ | ___ | ___ | ___% |
+| **Cross-Role** | 15 | ___ | ___ | ___ | ___ | ___% |
+| **TOTAL** | **128** | ___ | ___ | ___ | ___ | ___% |
+
+---
+
+### 14.2 Defect Summary
+
+| Severity | Jumlah |
+|----------|--------|
+| Critical | ___ |
+| High | ___ |
+| Medium | ___ |
+| Low | ___ |
+| **TOTAL DEFECTS** | ___ |
+
+---
+
+---
+
+## CATATAN PENTING
+
+1. ✅ **Centang checklist [ ]** untuk test case yang LULUS
+2. ❌ **Tulis "X" dalam kotak [X]** untuk test case yang GAGAL
+3. 📝 **Isi kolom "Issue/Jawaban"** untuk kasus FAIL/N/A/BLOCKED
+4. 📊 **Hitung total LULUS/GAGAL** di ringkasan setiap kategori
+5. 🎯 **Review kriteria penerimaan** di Section 10 sebelum keputusan
+6. ✍️ **Lakukan sign-off** di Section 12 jika semua criteria terpenuhi
+7. 📋 **Cetak dokumen ini** dan gunakan selama sesi UAT
+
+---
+
+**TOTAL ESTIMASI WAKTU UAT: 3-4 hari (dengan 3-5 tester dan 150+ test cases)**
+
+---
+
+### 🚀 GO-LIVE CHECKLIST (Final)
+
+Setelah sign-off, persiapan production:
+
+- [ ] Semua test case sudah dijalankan
+- [ ] Semua critical & high defects sudah diperbaiki
+- [ ] Security review selesai (password hashing, SQL injection, role access)
+- [ ] Performance test selesai (load time, concurrent users)
+- [ ] Data backup production-ready
+- [ ] Migration plan approved
+- [ ] Rollback plan ready
+- [ ] Training user sudah dilakukan
+- [ ] Documentation updated
+- [ ] Stakeholder approval obtained
+
+**Production Go-Live Date:** ____/____/____
+
+---
+
+**DOKUMEN INI MERUPAKAN MILIK PROPERTI INTELEKTUAL GDC CMOD LABORATORY MANAGEMENT SYSTEM**
+**BOLEH DISEBARKAN UNTUK KEPERLUAN UAT SAJA**
+
+---
+
+## END OF UAT CHECKLIST
+
+*Total: 150+ test cases organized dalam format checklist yang mudah di-print dan di-fill secara manual.*
diff --git a/app/Config/Printers.php b/app/Config/Printers.php
new file mode 100644
index 0000000..f2809c9
--- /dev/null
+++ b/app/Config/Printers.php
@@ -0,0 +1,48 @@
+ [
+ 'name' => 'Lab Printer',
+ 'command' => 'copy /B file.txt \\\\print-server\\lab-printer',
+ ],
+ 'phlebo' => [
+ 'name' => 'Phlebo Printer',
+ 'command' => 'copy /B file.txt \\\\print-server\\phlebo-printer',
+ ],
+ 'reception' => [
+ 'name' => 'Reception Printer',
+ 'command' => 'copy /B file.txt \\\\print-server\\reception-printer',
+ ],
+ ];
+
+ public array $roleDefaults = [
+ 0 => 'lab',
+ 1 => 'lab',
+ 2 => 'lab',
+ 3 => 'phlebo',
+ 4 => 'reception',
+ ];
+
+ public string $defaultPrinter = 'lab';
+
+ public function getPrinter(string $printerKey): ?array
+ {
+ return $this->printers[$printerKey] ?? null;
+ }
+
+ public function getCommand(string $printerKey): ?string
+ {
+ return $this->printers[$printerKey]['command'] ?? null;
+ }
+
+ public function getDefaultForRole(int $roleId): string
+ {
+ return $this->roleDefaults[$roleId] ?? $this->defaultPrinter;
+ }
+}
diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index 948eb50..1761284 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -16,9 +16,9 @@ $routes->post('/login', 'AuthController::login', ['filter' => 'guest']);
$routes->get('/logout', 'AuthController::logout');
$routes->patch('/setPassword', 'AuthController::setPassword');
-$routes->get('label/coll/(:any)', 'LabelController::coll/$1');
-$routes->get('label/dispatch/(:any)/(:any)', 'LabelController::dispatch/$1/$2');
-$routes->get('label/all/(:any)', 'LabelController::print_all/$1');
+$routes->get('label/coll/(:any)/(:any)', 'LabelController::coll/$1/$2');
+$routes->get('label/dispatch/(:any)/(:any)/(:any)', 'LabelController::dispatch/$1/$2/$3');
+$routes->get('label/all/(:any)/(:any)', 'LabelController::print_all/$1/$2');
$routes->get('print/(:num)', 'Home::printReport/$1', ['filter' => 'role:0,1,2,3,4']);
diff --git a/app/Controllers/LabelController.php b/app/Controllers/LabelController.php
index 9124fb1..537dd6b 100644
--- a/app/Controllers/LabelController.php
+++ b/app/Controllers/LabelController.php
@@ -3,8 +3,10 @@ namespace App\Controllers;
class LabelController extends BaseController
{
- public function coll($reqnum)
- {
+ use ResponseTrait;
+
+ public function coll($reqnum, $printer = 'lab')
+{
$db = \Config\Database::connect();
$userid = session()->get('userid') ?? 'system';
@@ -61,15 +63,21 @@ A10,195,0,1,1,1,N,\"HIS : $hospnum\"
A190,190,0,2,1,1,N,\"$date\"
P1\n]";
- $handle = fopen("./file.txt", "a+");
- fwrite($handle, $bar);
- fclose($handle);
- /*exec($command);*/
+ $printers = new \Config\Printers();
+ $command = $printers->getCommand($printer);
+ if ($command) {
+ $handle = fopen("./file.txt", "w+");
+ fwrite($handle, $bar);
+ fclose($handle);
+ exec($command);
+ return $this->respond(['status' => 'success', 'message' => 'Label printed'], 200);
+ }
+ return $this->respond(['status' => 'error', 'message' => 'Invalid printer'], 400);
}
- public function dispatch($reqnum, $samid)
- {
+ public function dispatch($reqnum, $samid, $printer = 'lab')
+{
$db = \Config\Database::connect();
$userid = session()->get('userid') ?? 'system';
@@ -140,24 +148,31 @@ A190,190,0,2,1,1,N,\"$date\"
P1
]";
- $handle = fopen("./file.txt", "a+");
- fwrite($handle, $bar);
- fclose($handle);
- //exec($command);
+ $printers = new \Config\Printers();
+ $command = $printers->getCommand($printer);
+ if ($command) {
+ $handle = fopen("./file.txt", "w+");
+ fwrite($handle, $bar);
+ fclose($handle);
+ exec($command);
+ return $this->respond(['status' => 'success', 'message' => 'Label printed'], 200);
+ }
+ return $this->respond(['status' => 'error', 'message' => 'Invalid printer'], 400);
}
- public function print_all($accessnumber)
+ public function print_all($accessnumber, $printer = 'lab')
{
$db = \Config\Database::connect();
$userid = session()->get('userid') ?? 'system';
- $this->coll($accessnumber);
+ $this->coll($accessnumber, $printer);
$sql = "select SAMPCODE from GDC_CMOD.dbo.v_sp_reqtube where SP_ACCESSNUMBER='$accessnumber'";
$rows = $db->query($sql)->getResultArray();
foreach ($rows as $row) {
$sampcode = $row['SAMPCODE'];
- $this->dispatch($accessnumber, $sampcode);
+ $this->dispatch($accessnumber, $sampcode, $printer);
}
+ return $this->respond(['status' => 'success', 'message' => 'All labels printed'], 200);
}
}
diff --git a/app/Controllers/ReportController.php b/app/Controllers/ReportController.php
index 735414e..9c6f924 100644
--- a/app/Controllers/ReportController.php
+++ b/app/Controllers/ReportController.php
@@ -21,6 +21,13 @@ class ReportController extends BaseController
$ispdf = $this->request->getVar('ispdf') ?? 0;
}
+ if ($eng == 0) {
+ // Read REPORT_LANG from CM_REQUESTS if not provided
+ $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
+ $row = $this->db->query($sql, [$accessnumber])->getRowArray();
+ $eng = $row['REPORT_LANG'] ?? 0;
+ }
+
return $this->renderReport($accessnumber, $eng, $ispdf, false);
}
@@ -30,6 +37,13 @@ class ReportController extends BaseController
$ispdf = $this->request->getVar('ispdf') ?? 0;
}
+ if ($eng == 0) {
+ // Read REPORT_LANG from CM_REQUESTS if not provided
+ $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
+ $row = $this->db->query($sql, [$accessnumber])->getRowArray();
+ $eng = $row['REPORT_LANG'] ?? 0;
+ }
+
return $this->renderReport($accessnumber, $eng, $ispdf, true);
}
@@ -62,6 +76,14 @@ class ReportController extends BaseController
public function preview($accessnumber)
{
$eng = $this->request->getVar('eng') ?? 0;
+
+ // If eng not provided, read REPORT_LANG from CM_REQUESTS
+ if ($eng == 0) {
+ $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
+ $row = $this->db->query($sql, [$accessnumber])->getRowArray();
+ $eng = $row['REPORT_LANG'] ?? 0;
+ }
+
return $this->renderReport($accessnumber, $eng, 0, false);
}
@@ -72,7 +94,17 @@ class ReportController extends BaseController
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'error' => 'Unauthorized']);
}
- $eng = $this->request->getVar('eng') ?? 0;
+ // Get language: URL parameter > REPORT_LANG > default (0)
+ $engParam = $this->request->getVar('eng') ?? null;
+ if ($engParam !== null) {
+ $eng = (int) $engParam;
+ } else {
+ // Read REPORT_LANG from CM_REQUESTS
+ $sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
+ $row = $this->db->query($sql, [$accessnumber])->getRowArray();
+ $eng = (int) ($row['REPORT_LANG'] ?? 0);
+ }
+
$data = $this->reportHelper->getReportData($accessnumber, $eng);
$data['eng'] = $eng;
$data['accessnumber'] = $accessnumber;
@@ -87,7 +119,8 @@ class ReportController extends BaseController
'success' => true,
'jobId' => $jobId,
'message' => 'PDF queued for generation',
- 'status' => 'queued'
+ 'status' => 'queued',
+ 'lang' => $eng == 1 ? 'English' : 'Indonesian'
]);
} catch (\Exception $e) {
log_message('error', "PDF generation failed: " . $e->getMessage());
diff --git a/app/Controllers/SamplesController.php b/app/Controllers/SamplesController.php
index 205dbdd..d5bf9a4 100644
--- a/app/Controllers/SamplesController.php
+++ b/app/Controllers/SamplesController.php
@@ -3,6 +3,8 @@ namespace App\Controllers;
use CodeIgniter\API\ResponseTrait;
use App\Controllers\BaseController;
+// This is just to add ResponseTrait import - actual edit will be in LabelController
+
class SamplesController extends BaseController
{
use ResponseTrait;
diff --git a/app/Views/admin/index.php b/app/Views/admin/index.php
index ebcdafd..abc877c 100644
--- a/app/Views/admin/index.php
+++ b/app/Views/admin/index.php
@@ -10,6 +10,7 @@ $roleConfig = $config['admin'];
= $this->include('shared/dialog_sample', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_unval'); ?>
= $this->include('shared/dialog_audit'); ?>
+ = $this->include('shared/dialog_results_generate'); ?>
= $this->endSection(); ?>
diff --git a/app/Views/cs/index.php b/app/Views/cs/index.php
index 1e6d816..6f48091 100644
--- a/app/Views/cs/index.php
+++ b/app/Views/cs/index.php
@@ -10,6 +10,7 @@ $roleConfig = $config['cs'];
= $this->include('shared/dialog_sample', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_unval'); ?>
= $this->include('shared/dialog_audit'); ?>
+ = $this->include('shared/dialog_results_generate'); ?>
= $this->endSection(); ?>
diff --git a/app/Views/lab/index.php b/app/Views/lab/index.php
index bb94393..ff8bf03 100644
--- a/app/Views/lab/index.php
+++ b/app/Views/lab/index.php
@@ -10,6 +10,7 @@ $roleConfig = $config['lab'];
= $this->include('shared/dialog_sample', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_unval'); ?>
= $this->include('shared/dialog_audit'); ?>
+ = $this->include('shared/dialog_results_generate'); ?>
= $this->endSection(); ?>
diff --git a/app/Views/phlebo/index.php b/app/Views/phlebo/index.php
index 5979ebb..b6cbb50 100644
--- a/app/Views/phlebo/index.php
+++ b/app/Views/phlebo/index.php
@@ -10,6 +10,7 @@ $roleConfig = $config['phlebo'];
= $this->include('shared/dialog_sample', ['config' => $roleConfig]); ?>
= $this->include('shared/dialog_unval'); ?>
= $this->include('shared/dialog_audit'); ?>
+ = $this->include('shared/dialog_results_generate'); ?>
= $this->endSection(); ?>
diff --git a/app/Views/shared/config.php b/app/Views/shared/config.php
index 7298366..7ff0a31 100644
--- a/app/Views/shared/config.php
+++ b/app/Views/shared/config.php
@@ -22,6 +22,7 @@ return [
'sampleDialog' => [
'commentEditable' => true,
'showCollectButtons' => true,
+ 'defaultPrinter' => 'lab',
],
'menuItems' => [
['label' => 'Dashboard', 'href' => 'admin', 'icon' => 'chart-bar'],
@@ -33,6 +34,7 @@ return [
'sampleDialog' => [
'commentEditable' => false,
'showCollectButtons' => false,
+ 'defaultPrinter' => 'reception',
],
'menuItems' => [
['label' => 'Dashboard', 'href' => 'cs', 'icon' => 'chart-bar'],
@@ -43,6 +45,7 @@ return [
'sampleDialog' => [
'commentEditable' => true,
'showCollectButtons' => true,
+ 'defaultPrinter' => 'lab',
],
'menuItems' => [
['label' => 'Dashboard', 'href' => 'lab', 'icon' => 'chart-bar'],
@@ -54,6 +57,7 @@ return [
'sampleDialog' => [
'commentEditable' => false,
'showCollectButtons' => false,
+ 'defaultPrinter' => 'phlebo',
],
'menuItems' => [
['label' => 'Dashboard', 'href' => 'phlebo', 'icon' => 'chart-bar'],
@@ -64,6 +68,7 @@ return [
'sampleDialog' => [
'commentEditable' => true,
'showCollectButtons' => true,
+ 'defaultPrinter' => 'lab',
],
'menuItems' => [
['label' => 'Dashboard', 'href' => 'superuser', 'icon' => 'chart-bar'],
diff --git a/app/Views/shared/content_requests.php b/app/Views/shared/content_requests.php
index ea9546c..b375e77 100644
--- a/app/Views/shared/content_requests.php
+++ b/app/Views/shared/content_requests.php
@@ -77,49 +77,46 @@
| + | - | + | - | + | - | + | - | + | - | + | - | + | - | - - | -- - | -- - | + | + + | ++ + | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| + | ||||||||||||||||||||
|
Order Datetime
@@ -145,7 +142,7 @@
:class="sortCol === 'REQDATE' ? (sortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort opacity-20'">
|
-
Patient Name
@@ -153,7 +150,7 @@
:class="sortCol === 'Name' ? (sortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort opacity-20'">
|
-
No Lab
@@ -161,7 +158,7 @@
:class="sortCol === 'SP_ACCESSNUMBER' ? (sortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort opacity-20'">
|
-
No Register
@@ -169,7 +166,7 @@
:class="sortCol === 'HOSTORDERNUMBER' ? (sortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort opacity-20'">
|
-
Reff
@@ -177,7 +174,7 @@
:class="sortCol === 'REFF' ? (sortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort opacity-20'">
|
-
Doctor
@@ -185,12 +182,10 @@
:class="sortCol === 'DOC' ? (sortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort opacity-20'">
|
- Tests | -ResTo | +Tests | +ResTo | Val | -Result | -- | + |
-
-
-
-
- 1: -2: -
- get('userlevel') <= 1): ?>
-
-
-
-
-
-
+
+
1: +2: |
- - | -- - | -- + + | diff --git a/app/Views/shared/dialog_results_generate.php b/app/Views/shared/dialog_results_generate.php new file mode 100644 index 0000000..07f53f9 --- /dev/null +++ b/app/Views/shared/dialog_results_generate.php @@ -0,0 +1,108 @@ +
|---|