01Informasi Dokumen
| Informasi | Nilai |
|---|---|
| Nama Fitur | Laporan Kerusakan Asset Karyawan (UI: "Laporan Kerusakan Asset"; menu "Kerusakan") |
| Kode Fitur | KRY06 (nomor transaksi KRY06-YYYYMMNNN; docblock model menyebut ALK-KRY06) |
| Modul | Asset Management |
| Backend | Laravel Lumen ^10.0, PHP ^8.1, JWT, Query Builder |
| Database | API/diagram-asset.dbml + migration 2026_09_25_000001_add_workflow_fields_to_asset_rusak_karyawan.php. ⚠️ Asumsi: MySQL/MariaDB |
| Mobile | Flutter (professional_flutter_3_35), flutter_bloc, dio |
| Web | ⚠️ Belum ditemukan: tidak ada source web di workspace |
| Test otomatis | API/tests/Asset/AssetRusakKaryawanTest.php (15 test) |
| Versi Dokumen | 1.6 |
| Tanggal Dokumentasi | 2026-10-22 |
| Dokumen terkait | Onboarding (KRY01), Offboarding (KRY02), Upgrade (KRY03), Retur (KRY04), Peminjaman (KRY05), Request/Penambahan |
03Quick Overview
| Item | Informasi |
|---|---|
| Feature | Pelaporan kerusakan satu asset milik karyawan, per komponen (unit utama / kelengkapan) |
| Module | Asset Management |
| Actor | Karyawan (pelapor, serah terima, checklist), Admin Asset (review, jadwal, pengganti; penyelesaian otomatis bila checklist normal), System |
| Main Transaction | asset_trx_rusak_karyawan |
| Detail Transaction | asset_trx_rusak_karyawan_item — item laporan (urutan_penggantian = 0) + histori unit pengganti (urutan_penggantian ≥ 1, parent_id ke baris sebelumnya) |
| Sumber komponen | asset_data_item (json_value.flag_spesifikasi 1 = unit utama, 2 = kelengkapan) |
| Asset Master | asset_data |
| Log | asset_trx_log jenis_log = rusak_karyawan |
| Status | status_approval (int: 1 proses, 2 ditolak, 3 disetujui) + status_transaksi (pengajuan → menunggu_pengambilan → menunggu_checklist → menunggu_review_checklist → selesai) |
| Keputusan admin | Per item: Setujui/Tolak; item disetujui: Diganti / Tidak Diganti; unit utama diganti → pilih Unit Pengganti sekategori |
| Siklus pengganti | Unit pengganti dicek karyawan saat serah terima (satu langkah). Normal → laporan selesai otomatis. Rusak → admin Pilih Pengganti Lain (berulang) |
| API | 7 endpoint admin + 6 endpoint karyawan |
| Mobile Screen | Karyawan: Laporan Kerusakan Asset (list), Lapor Kerusakan Asset (form), Detail Laporan Kerusakan. Admin: list & detail |
Karyawan: pilih 1 asset terpakai → pilih Unit Utama ATAU Kelengkapan → centang item + keterangan → Kirim Laporan
proses(1) / pengajuan · asset TIDAK berubah
Admin: per item Setujui/Tolak (+alasan); disetujui → Diganti / Tidak Diganti
unit utama diganti → Pilih Unit Pengganti (sekategori, tersedia @gudang) → pengganti = proses
→ Jadwal Serah Terima (tanggal, jam, catatan)
├─ semua ditolak ─────────────────────────────────────── ditolak(2) / selesai
└─ ada disetujui ─────────────────────────────────────── disetujui(3) / menunggu_pengambilan
Karyawan: Konfirmasi Serah Terima
• unit utama disetujui → asset lama = rusak @gudang • hanya kelengkapan → asset tetap @karyawan (ket_rusak dicatat)
├─ tanpa pengganti ──────────────────────────────────────── selesai
└─ ada pengganti ────────────────────────────────────────── checklist unit pengganti diisi bersamaan
Karyawan: Serah Terima & Kirim Checklist Unit Pengganti (Normal/Rusak per item)
• semua normal → pengganti = terpakai @karyawan ─────────── selesai (otomatis, admin hanya dinotifikasi)
• ada yang rusak ────────────────────────────────────────── menunggu_review_checklist
Admin: Pilih Pengganti Lain + jadwal → pengganti lama = rusak @gudang menunggu_pengambilan (ulang)
04Ringkasan Fitur
Karyawan melaporkan kerusakan pada satu asset yang sedang dipakainya (status_asset = terpakai). Laporan bersifat per komponen: unit utama dan/atau kelengkapan (misalnya charger, adaptor) yang diambil dari asset_data_item. Setiap item wajib diberi keterangan kerusakan.
Admin meninjau setiap item. Untuk item yang disetujui admin menentukan apakah item diganti. Hanya unit utama yang diganti yang memicu penukaran unit: admin memilih unit pengganti dari gudang dengan kategori sama. Kelengkapan yang "diganti" hanya dicatat.
Serah terima dikonfirmasi karyawan. Jika ada unit pengganti, karyawan wajib mengecek kondisi setiap komponen unit pengganti (checklist) pada saat serah terima yang sama. Bila semua normal, laporan selesai otomatis. Bila ada yang rusak, admin memilih unit pengganti lain dan siklus berulang sampai unit pengganti dinyatakan normal — seluruh percobaan tersimpan sebagai histori.
05Tujuan Fitur
5.1 Tujuan Bisnis (diturunkan dari kode)
- Karyawan dapat melaporkan kerusakan asset secara terstruktur per komponen.
- Admin memutuskan penarikan dan penggantian unit secara terkontrol.
- Unit pengganti dipastikan dalam kondisi baik sebelum menjadi milik karyawan.
- Riwayat penggantian berulang dapat ditelusuri.
5.2 Tujuan Sistem
- Menyimpan laporan per komponen dengan snapshot data komponen (JSON).
- Mereservasi unit pengganti (
proses) hingga lolos checklist. - Memperbarui
asset_datadan mencatatasset_trx_logpada setiap perpindahan. - Mencegah asset diproses di laporan kerusakan lain, retur, upgrade, atau offboarding saat laporan dibuat.
06Aktor
| Aktor | Role | Fungsi |
|---|---|---|
| Karyawan | User login, pemegang asset | Melapor, konfirmasi serah terima, checklist unit pengganti |
| Admin Asset | asset_admin + karyawan aktif |
Review, jadwal, pilih/ganti unit pengganti, selesaikan laporan |
| System | Backend + FCM | Validasi, lock, penomoran, update asset, log, notifikasi |
07Hak Akses
| Action | Admin Asset | Karyawan | Keterangan |
|---|---|---|---|
| Melihat semua laporan | ✅ | ❌ | /asset/rusak-karyawan |
| Melihat laporan sendiri | – | ✅ | Tanpa cek karyawan aktif (INC-05) |
| Melapor kerusakan | – | ✅ | Karyawan aktif, asset miliknya, terpakai |
| Edit / batalkan laporan | ❌ | ❌ | ⚠️ Belum ditemukan (RISK-003) |
| Review (setujui/tolak, diganti, pengganti, jadwal) | ✅ | ❌ | status_approval = 1 |
| Ubah jadwal | ✅ | ❌ | menunggu_pengambilan |
| Konfirmasi serah terima | ❌ | ✅ | menunggu_pengambilan, karyawan aktif |
| Checklist unit pengganti | ❌ | ✅ | menunggu_pengambilan (bersama serah terima) atau menunggu_checklist (alur lama), karyawan aktif |
| Selesaikan laporan | ✅ | ❌ | Hanya laporan lama: menunggu_review_checklist + checklist normal (checklist normal baru selesai otomatis) |
| Pilih pengganti lain | ✅ | ❌ | menunggu_review_checklist + checklist rusak |
08Terminologi
| Istilah | Arti di sistem |
|---|---|
Unit Utama (aset_utama) |
Komponen asset_data_item dengan flag_spesifikasi = 1; bila tidak ada, sistem menambahkan baris sintetis dengan id_item = id_asset_data |
Kelengkapan (kelengkapan) |
Komponen dengan flag_spesifikasi = 2 |
| Item laporan | Baris item urutan_penggantian = 0 |
| Unit pengganti | Baris item urutan_penggantian ≥ 1; parent_id = baris sebelumnya |
status_diganti |
'1' diganti, '0' tidak diganti (diisi saat disetujui) |
| Pelepasan / Serah terima | Karyawan menyerahkan item rusak (dan menerima pengganti) — tgl_pelepasan |
| Checklist | Pemeriksaan kondisi setiap komponen unit pengganti oleh karyawan |
| Unit ditarik | Minimal satu unit utama disetujui → asset lama ditarik ke gudang saat serah terima |
09Business Rules
BR-001 — Asset yang boleh dilaporkan
Milik karyawan login (pemegang_asset = karyawan, id_pemegang_asset = id_karyawan) dan status_asset = terpakai → "Asset bukan milik karyawan atau tidak ditemukan." / "Hanya asset berstatus terpakai yang dapat dilaporkan rusak." Asset pinjaman (dipinjam) tidak bisa dilaporkan di sini. Karyawan harus aktif.
BR-002 — Asset tidak sedang di flow lain (assetBlockMessage)
Dicek saat opsi dan simpan: laporan kerusakan aktif, retur aktif, upgrade aktif, offboarding aktif, pemeliharaan terjadwal (PML01) aktif → "Asset sedang diproses pada laporan kerusakan lain." / "…pada retur." / "…pada upgrade." / "…pada offboarding." / "…pada pemeliharaan."
BR-003 — Item laporan
Minimal 1; setiap id_item harus komponen asset tersebut; tanpa duplikat; keterangan wajib → "Minimal satu item rusak wajib dipilih." / "Item rusak harus berupa unit utama atau kelengkapan asset." / "Item yang sama tidak boleh dipilih lebih dari sekali." / "Keterangan kerusakan setiap item wajib diisi." Snapshot komponen disimpan di kelengkapan_item (JSON). Mobile membatasi satu jenis per laporan (INC-01).
BR-004 — Laporan tidak mengubah asset
Saat laporan dikirim, asset_data tetap terpakai @karyawan.
BR-005 — Review seluruh item
Semua item wajib diputuskan → "Seluruh item kerusakan wajib direview."; tolak wajib alasan; disetujui wajib status_diganti 0/1. Asset harus masih dipegang karyawan → "Asset sudah tidak dipegang oleh karyawan."
BR-006 — Unit pengganti
Hanya bila ada unit utama disetujui dan diganti. Pengganti wajib dipilih, belum pernah dipakai di laporan ini, tersedia @gudang, kategori sama dengan asset rusak → "Asset pengganti wajib dipilih." / "Asset pengganti hanya dipilih jika unit utama diganti." / "Asset pengganti sudah pernah dipakai pada laporan ini." / "Aset sudah tidak tersedia. Silakan pilih unit lain." / "Kategori asset pengganti harus sama dengan asset yang rusak." Pengganti → status_asset = proses.
BR-007 — Jadwal serah terima
Wajib bila ada item disetujui (review), dan pada pilih pengganti lain; tanggal ≥ tanggal pengajuan → "Tanggal dan jam serah terima wajib diisi." / "Format jadwal serah terima tidak valid." / "Tanggal serah terima tidak boleh sebelum tanggal pengajuan." Satu jadwal untuk pengambilan item rusak dan kedatangan pengganti (docblock: "SOP: hari yang sama").
BR-008 — Hasil review
Semua ditolak → status_approval = 2, selesai (asset tidak berubah). Ada disetujui → 3, menunggu_pengambilan.
BR-009 — Serah terima pertama (karyawan)
- Unit utama disetujui (diganti atau tidak) → asset lama
rusak,pemegang = gudang. - Hanya kelengkapan disetujui → asset tetap dipegang karyawan (status tetap), hanya
ket_rusakdiisi. ket_rusakasset = ringkasan "nama: keterangan; …" (maks 255).- Log
rusak_karyawan. Ada pengganti →tgl_serah_terimapengganti + checklist unit pengganti (BR-011) pada langkah yang sama; tanpa pengganti →selesai.
BR-010 — Serah terima pengganti berikutnya
Bila tgl_pelepasan sudah terisi, konfirmasi serah terima hanya mencatat penerimaan pengganti terbaru → "Tidak ada unit pengganti yang perlu diserahterimakan." bila tidak ada.
BR-011 — Checklist pengganti (karyawan)
Dikirim bersama serah terima (items opsional pada pelepasan) atau lewat endpoint checklist (alur lama, menunggu_checklist); semua komponen unit pengganti wajib dicek; kondisi normal/rusak; rusak wajib keterangan → "Seluruh item unit pengganti wajib dicek." Hasil disimpan sebagai JSON di kelengkapan_item; status_checklist = rusak bila ada satu saja rusak. Normal → laporan selesai otomatis (pengganti terpakai @karyawan + log; admin hanya dinotifikasi). Rusak → menunggu_review_checklist. Bila checklist tidak lengkap, seluruh serah terima dibatalkan.
BR-012 — Keputusan setelah checklist (admin)
- Checklist
normal→ selesai otomatis (tanpa langkah admin): penggantiterpakai@karyawan + log →selesai. Selesaikan Laporan hanya tersisa untuk laporan lama yang sudah menunggu review. - Checklist
rusak→ Pilih Pengganti Lain: pengganti lamarusak@gudang (+ket_rusak) + log; baris pengganti baru (urutan + 1); jadwal baru →menunggu_pengambilan. - Tombol salah → "Unit pengganti masih memiliki item rusak. Pilih unit pengganti lain." / "Seluruh item unit pengganti normal. Selesaikan laporan." Pengganti harus masih
proses@gudang → "Status asset pengganti sudah berubah."
BR-013 — Penomoran
Header & item id_company + YYYYMM + 3 digit; no_trx = KRY06-YYYYMMNNN; log 5 digit.
10Business Flow
1. Karyawan: Asset Saya → Kerusakan → (+) Lapor Kerusakan Asset
→ Pilih Asset yang Rusak → Unit Utama / Kelengkapan → centang item + Keterangan Kerusakan
→ Atribut Lainnya / Keterangan Umum → Kirim Laporan [Menunggu Review · notif admin]
2. Admin: Asset Karyawan → Kerusakan → Detail
→ per item Setujui/Tolak; disetujui: Diganti / Tidak Diganti
→ (unit utama diganti) Pilih Unit Pengganti
→ Simpan Review → Jadwal Serah Terima [Menunggu Serah Terima / Ditolak · notif karyawan]
3. Karyawan: serahkan item rusak, terima pengganti, isi Checklist Unit Pengganti → Serah Terima & Kirim Checklist
[Selesai bila normal / Menunggu Review Checklist bila rusak · notif admin]
4. Admin (hanya bila checklist rusak): Pilih Pengganti Lain + jadwal → kembali ke langkah 3 [notif karyawan]
11Flow Berdasarkan Role
11.1 Karyawan
- Asset Saya → menu Kerusakan → Laporan Kerusakan Asset → tombol Lapor Kerusakan.
- Banner di Asset Saya: Serah Terima Asset Rusak ("{asset}: serahkan item rusak sesuai jadwal, lalu konfirmasi.") dan Checklist Unit Pengganti ("Cek kondisi unit pengganti untuk {asset}.").
- Detail → Serah Terima & Kirim Checklist (bila ada unit pengganti) atau Konfirmasi Serah Terima.
11.2 Admin Asset
- Asset Karyawan → aksi Kerusakan, atau panel Kerusakan Perlu Diproses (laporan baru + checklist yang perlu direview).
- Detail → review → Simpan Review; Ubah Jadwal; Selesaikan Laporan / Pilih Pengganti Lain.
11.3 System
Deteksi komponen, cek flow lain, reservasi pengganti, update asset & log, notifikasi.
12Flow Diagram
flowchart TD
A[Karyawan pilih asset + item rusak + keterangan] --> B{Validasi}
B -->|Gagal| X[Pesan error]
B -->|OK| C[Menunggu Review, notif admin]
C --> D{Admin review per item}
D -->|Semua ditolak| E[Ditolak, asset tidak berubah]
D -->|Ada disetujui| F{Unit utama diganti?}
F -->|Ya| G[Pilih unit pengganti sekategori, pengganti proses]
F -->|Tidak| H[Tanpa pengganti]
G --> I[Jadwal serah terima, Menunggu Serah Terima]
H --> I
I --> J[Karyawan: Konfirmasi Serah Terima]
J --> K{Unit utama disetujui?}
K -->|Ya| L[Asset lama rusak di gudang]
K -->|Tidak, hanya kelengkapan| M[Asset tetap di karyawan, ket_rusak dicatat]
L --> N{Ada pengganti?}
M --> N
N -->|Tidak| Z[Selesai]
N -->|Ya| P[Karyawan: serah terima + checklist unit pengganti]
P --> Q{Hasil checklist}
Q -->|Normal| R[Otomatis selesai: pengganti terpakai di karyawan]
R --> Z
Q -->|Rusak| S[Admin: Pilih Pengganti Lain + jadwal, pengganti lama rusak di gudang]
S --> I
13Sequence Diagram
sequenceDiagram
actor K as Karyawan
actor A as Admin
participant M as Mobile
participant CK as AssetKaryawanRusak_c
participant CA as AssetAdminRusak_c
participant R as AssetRusakKaryawan_m
participant DB
participant N as AssetNotification
K->>M: Pilih asset, item, keterangan, Kirim Laporan
M->>CK: POST /asset/karyawan/rusak
CK->>R: store()
R->>DB: lock company, karyawan aktif, asset terpakai milik karyawan, cek flow lain
R->>DB: INSERT header (1, pengajuan) + item laporan
CK->>N: kerusakan.diajukan (admin)
A->>M: Keputusan item, diganti, unit pengganti, jadwal
M->>CA: POST /asset/rusak-karyawan/{id}/review
CA->>R: review()
R->>DB: UPDATE item, INSERT baris pengganti, pengganti jadi proses
R->>DB: UPDATE header (3, menunggu_pengambilan) + jadwal
CA->>N: kerusakan.disetujui atau kerusakan.ditolak (karyawan)
K->>M: Serah terima + checklist unit pengganti
M->>CK: POST /asset/karyawan/rusak/{id}/pelepasan (items)
CK->>R: pelepasan()
R->>DB: asset lama rusak di gudang atau tetap, INSERT asset_trx_log
R->>DB: tgl_serah_terima pengganti + hasil checklist (status_checklist)
R->>DB: normal: pengganti terpakai di karyawan + asset_trx_log, header selesai
R->>DB: rusak: header menunggu_review_checklist
CK->>N: kerusakan.selesai_otomatis atau kerusakan.checklist (admin)
A->>M: Pilih Pengganti Lain (hanya bila rusak)
14Status Transaksi
Dua kolom: status_approval (tinyint, konstanta Asset_m) dan status_transaksi (enum, dari migration).
| status_approval | status_transaksi | Label API | Tab | Arti | Aksi berikutnya |
|---|---|---|---|---|---|
| 1 (proses) | pengajuan | Menunggu Review | pengajuan | Menunggu admin | Admin: review |
| 2 (ditolak) | selesai | Ditolak | selesai | Semua item ditolak | – |
| 3 (disetujui) | menunggu_pengambilan | Menunggu Serah Terima | proses | Menunggu serah terima | Karyawan: serah terima; Admin: ubah jadwal |
| 3 | menunggu_checklist | Menunggu Checklist | proses | Pengganti sudah diterima tanpa checklist (alur lama) | Karyawan: checklist |
| 3 | menunggu_review_checklist | Menunggu Review Checklist | proses | Checklist rusak terkirim (atau laporan lama dengan checklist normal) | Admin: pilih pengganti lain (rusak) / selesaikan (laporan lama normal) |
| 3 | selesai | Selesai | selesai | Laporan tuntas | – |
Status item: laporan status_approval NULL → disetujui/ditolak; pengganti status_checklist belum_dicek → normal/rusak.
Detail API juga mengembalikan objek aksi (review, ubah_jadwal, pelepasan, checklist, pelepasan_checklist, selesai, ganti_pengganti) sebagai penentu tombol.
15State Transition
stateDiagram-v2
[*] --> pengajuan: Kirim Laporan (Karyawan)
pengajuan --> ditolak: Review, semua ditolak (Admin)
pengajuan --> menunggu_pengambilan: Review, ada disetujui (Admin)
menunggu_pengambilan --> menunggu_pengambilan: Ubah jadwal (Admin)
menunggu_pengambilan --> selesai: Serah terima tanpa pengganti (Karyawan)
menunggu_pengambilan --> selesai: Serah terima + checklist normal (Karyawan)
menunggu_pengambilan --> menunggu_review_checklist: Serah terima + checklist rusak (Karyawan)
menunggu_pengambilan --> menunggu_checklist: Serah terima tanpa checklist, alur lama (Karyawan)
menunggu_checklist --> selesai: Kirim checklist normal (Karyawan)
menunggu_checklist --> menunggu_review_checklist: Kirim checklist rusak (Karyawan)
menunggu_review_checklist --> selesai: Selesaikan, laporan lama checklist normal (Admin)
menunggu_review_checklist --> menunggu_pengambilan: Pilih pengganti lain, checklist rusak (Admin)
ditolak --> [*]
selesai --> [*]
Status asset_data:
| Asset | Dari | Ke | Trigger |
|---|---|---|---|
| Asset dilaporkan | terpakai @karyawan | tidak berubah | Lapor, review |
| Asset dilaporkan (unit utama disetujui) | terpakai @karyawan | rusak @gudang | Serah terima pertama |
| Asset dilaporkan (hanya kelengkapan) | terpakai @karyawan | tetap, ket_rusak diisi | Serah terima pertama |
| Unit pengganti | tersedia @gudang | proses @gudang | Review / pilih pengganti lain |
| Unit pengganti (checklist normal) | proses @gudang | terpakai @karyawan | Checklist normal (otomatis) |
| Unit pengganti (checklist rusak) | proses @gudang | rusak @gudang | Pilih pengganti lain |
16Struktur Database
| Table | Type | Fungsi |
|---|---|---|
asset_trx_rusak_karyawan |
Transaction Header | Laporan, jadwal, status, pelepasan |
asset_trx_rusak_karyawan_item |
Transaction Detail | Item laporan + histori unit pengganti + hasil checklist |
asset_data |
Master | Status & pemegang asset |
asset_data_item |
Master komponen | Unit utama / kelengkapan (json_value) |
asset_kategori_m |
Master | Kategori (syarat pengganti) |
asset_trx_log |
Log | rusak_karyawan (enum ditambah oleh migration) |
data_karyawan, master_cabang, master_departemen |
Master HR | Karyawan, cabang, divisi |
asset_admin, master_company |
Akses / lock | |
notif_data, users |
Notifikasi |
17Relasi Database
erDiagram
ASSET_TRX_RUSAK_KARYAWAN ||--o{ ASSET_TRX_RUSAK_KARYAWAN_ITEM : "id_asset_trx_rusak"
ASSET_TRX_RUSAK_KARYAWAN_ITEM |o--o| ASSET_TRX_RUSAK_KARYAWAN_ITEM : "parent_id (rantai pengganti)"
ASSET_DATA ||--o{ ASSET_TRX_RUSAK_KARYAWAN_ITEM : "id_asset_data"
ASSET_DATA ||--o{ ASSET_DATA_ITEM : "id_asset_data"
DATA_KARYAWAN ||--o{ ASSET_TRX_RUSAK_KARYAWAN : "id_karyawan (logis)"
ASSET_DATA ||--o{ ASSET_TRX_LOG : "id_asset_data"
ASSET_TRX_RUSAK_KARYAWAN {
varchar id_asset_trx_rusak_karyawan PK
varchar no_trx
date tgl_pengajuan
date tgl_serah_terima
time jam_serah_terima
timestamp tgl_pelepasan
tinyint status_approval
enum status_transaksi
}
ASSET_TRX_RUSAK_KARYAWAN_ITEM {
varchar id_asset_trx_rusak_item PK
varchar parent_id
int urutan_penggantian
varchar id_asset_trx_rusak FK
varchar id_asset_data FK
enum status_approval
enum status_diganti
enum flag_jenis_komponen
text kelengkapan_item
enum status_checklist
}
ASSET_DATA {
varchar id_asset_data PK
enum status_asset
enum pemegang_asset
varchar ket_rusak
}
ASSET_DATA_ITEM {
varchar id_asset_data_item PK
varchar id_asset_data FK
text json_value
}
ASSET_TRX_LOG {
varchar id_asset_trx_log PK
varchar id_asset_data FK
enum jenis_log
}
18Data Dictionary
18.1 asset_trx_rusak_karyawan
| Field | Type | Null | Default | Key | Description |
|---|---|---|---|---|---|
| id_asset_trx_rusak_karyawan | varchar(50) | No | – | PK | id_company + YYYYMM + 3 digit |
| no_trx | varchar(50) | No | '' | – | KRY06-YYYYMMNNN |
| keterangan | text | Yes | – | – | Atribut Lainnya / Keterangan Umum (maks 1000 di API) |
| id_karyawan, nik_karyawan, nama_karyawan | varchar | – | '' | IDX | Snapshot pelapor |
| tgl_pengajuan | date | No | CURRENT_DATE | – | |
| flag_jadwalkan | kondisi_on_off ('0'/'1') | – | – | – | '1' bila jadwal diisi |
| tgl_serah_terima / jam_serah_terima | date / time | No | 0000-00-00 / 00:00:00 | – | Jadwal serah terima |
| keterangan_serah_terima | varchar(255) | – | '' | – | Catatan jadwal |
| tgl_pelepasan / user_pelepasan | timestamp / varchar(255) | Yes | NULL / '' | – | Serah terima pertama (migration) |
| status_approval | tinyint(1) | No | 1 | IDX | 1 proses, 2 ditolak, 3 disetujui |
| status_transaksi | enum(pengajuan, menunggu_pengambilan, menunggu_checklist, menunggu_review_checklist, selesai) | No | pengajuan | IDX | Progres (migration) |
| user_approval / tgl_approval | varchar / timestamp | – | '' / NULL | – | Admin peninjau |
| id_company, tgl_input, user_input, tgl_update, user_update | – | – | – | IDX | Audit |
18.2 asset_trx_rusak_karyawan_item
| Field | Type | Default | Description |
|---|---|---|---|
| id_asset_trx_rusak_item | varchar(50) PK | – | id_company + YYYYMM + 3 digit |
| parent_id | varchar(50) | NULL | Item laporan: NULL; pengganti: baris sebelumnya |
| urutan_penggantian | int unsigned | 0 | 0 = item laporan; 1, 2, … = pengganti ke-n (migration) |
| id_asset_trx_rusak | varchar(50) | – | → header |
| id_asset_data | varchar(50) | – | Asset dilaporkan / unit pengganti |
| nama_asset, deskripsi_asset, kategori_asset | varchar(255) | '' | Snapshot |
| status_approval | enum(disetujui, ditolak) | NULL | Keputusan admin (pengganti langsung disetujui) |
| ket_tolak | varchar(255) | '' | Alasan penolakan |
| status_diganti | '0'/'1' | '0' | Diganti atau tidak |
| ket_rusak | varchar(255) | '' | Keterangan item / ringkasan hasil checklist rusak |
| status_checklist | enum(normal, rusak, belum_dicek) | NULL | Hanya baris pengganti (migration) |
| tgl_serah_terima | timestamp | NULL | Pengganti diterima karyawan (migration) |
| tgl_checklist | timestamp | NULL | Checklist dikirim (migration) |
| flag_jenis_komponen | '0'/'1' | '0' | 0 unit utama, 1 kelengkapan |
| kelengkapan_item | text (JSON) | '' | Item laporan: {id_item, nama_item, jenis, detail}; pengganti: array hasil checklist [{id_item, nama_item, jenis, kondisi, ket_rusak}] |
| id_company, tgl_input, user_input | – | – | – |
18.3 asset_trx_log (jenis_log = rusak_karyawan)
| Kejadian | kondisi awal → akhir | posisi |
|---|---|---|
| Serah terima, unit utama | kondisi_awal → rusak | karyawan → gudang |
| Serah terima, hanya kelengkapan | kondisi_awal → rusak | karyawan → karyawan |
| Selesaikan (pengganti normal) | kondisi_awal → normal | gudang → karyawan |
| Pilih pengganti lain (pengganti rusak) | kondisi_awal → rusak | gudang → gudang |
19Database Index
| Index | Table | Columns | Tujuan |
|---|---|---|---|
atrsk_admin_list_idx |
header | (id_company, status_approval, status_transaksi, tgl_input, id_asset_trx_rusak_karyawan) | List admin |
atrsk_employee_list_idx |
header | (id_company, id_karyawan, status_approval, status_transaksi, tgl_input, id_asset_trx_rusak_karyawan) | List karyawan |
atrski_report_idx |
item | (id_asset_trx_rusak, id_company, urutan_penggantian, id_asset_data) | Item per laporan & cek asset aktif |
20Backend Architecture
RouteAsset.php (prefix /asset, jwt.api + jwt.ctx)
↓
AssetAdminRusak_c (validateRequest → mutateAssetTrx: accessError + notifikasi)
AssetKaryawanRusak_c (validateRequest → store / mutateTrxSaya)
↓
AssetRusakKaryawan_m ← Asset_m (lockCompany, nextSequence, komponenAssets, parseJadwalValue,
↓ insertAssetLog, getLockedAssets, findActiveKaryawan, findAssetAdmin)
↓ ↔ AssetReturKaryawan_m / AssetUpgradeKaryawan_m / AssetOffboardingKaryawan_m (cek flow lain)
DB::transaction (retry 3) → ApiResponse + AssetNotification
| Layer | File/Class | Function |
|---|---|---|
| Controller | AssetAdminRusak_c |
getRusakKaryawan, getDetailRusakKaryawan, getRusakPenggantiOptions, reviewRusakKaryawan, updateJadwalRusakKaryawan, selesaiRusakKaryawan, gantiPenggantiRusakKaryawan |
| Controller | AssetKaryawanRusak_c |
getRusakOptions, getRusakSaya, storeRusakSaya, getDetailRusakSaya, pelepasanRusakSaya, checklistRusakSaya |
| Model | AssetRusakKaryawan_m |
getOptions, getPage, getDetail, getPenggantiOptions, store, review, updateJadwal, pelepasan, submitChecklist, selesai, gantiPengganti, getPendingForEmployee, getPendingForAdmin, countPendingForAdmin, hasActiveRusakAsset + helper |
| Support | AssetNotification |
kerusakan.* |
21Backend Business Logic
21.1 Lapor — store
Lock → karyawan aktif → asset milik karyawan (FOR UPDATE), terpakai → assetBlockMessage → komponenAssets → normalizeReportItems → ID + KRY06-… → INSERT header (1, pengajuan, jadwal nol) → INSERT item (urutan 0, snapshot JSON, flag_jenis_komponen) → notifikasi kerusakan.diajukan.
21.2 Review — review
Admin → header status_approval = 1 → item laporan (FOR UPDATE) → semua diputuskan → validasi keputusan → asset masih dipegang karyawan → jadwal (bila ada disetujui) → pengganti (bila unit utama diganti; lockReplacementCandidate) → UPDATE item → insertReplacement (urutan 1, pengganti proses) → UPDATE header (2/selesai atau 3/menunggu_pengambilan + jadwal) → notifikasi. Response +jumlah_disetujui, jumlah_ditolak, perlu_pengganti.
21.3 Ubah jadwal — updateJadwal
Status menunggu_pengambilan → "Jadwal hanya dapat diubah sebelum serah terima dilakukan." → update jadwal → kerusakan.dijadwalkan.
21.4 Serah terima — pelepasan (karyawan)
Karyawan aktif, laporan miliknya, menunggu_pengambilan → pengganti terbaru yang belum diterima → bila tgl_pelepasan kosong: releaseOriginalAsset → set tgl_serah_terima pengganti → bila items dikirim: simpan checklist (applyChecklist), normal → selesai otomatis (completeReplacement), rusak → menunggu_review_checklist; tanpa items: menunggu_checklist (alur lama) atau selesai bila tanpa pengganti → tgl/user_pelepasan (hanya pertama kali) → notifikasi kerusakan.selesai_otomatis / kerusakan.checklist / kerusakan.diserahkan. items tanpa unit pengganti ditolak; checklist tidak lengkap membatalkan seluruh transaksi.
21.5 Checklist — submitChecklist (karyawan)
menunggu_checklist → pengganti terbaru sudah diterima & belum_dicek → komponen pengganti (komponenAssets) harus lengkap → simpan hasil JSON, status_checklist, ringkasan ket_rusak, tgl_checklist → normal: selesai otomatis (pengganti terpakai @karyawan + log); rusak: header menunggu_review_checklist → kerusakan.checklist. Response +status_checklist.
21.6 Selesaikan — selesai (admin)
Hanya laporan lama (checklist normal baru selesai otomatis): menunggu_review_checklist + checklist normal → pengganti masih proses @gudang → pengganti terpakai @karyawan + log → header selesai → kerusakan.selesai.
21.7 Pilih pengganti lain — gantiPengganti (admin)
menunggu_review_checklist + checklist rusak → jadwal baru → pengganti baru (sekategori, belum dipakai di laporan) → pengganti lama rusak @gudang + log → INSERT baris pengganti (urutan + 1, parent_id = pengganti lama) → header menunggu_pengambilan → kerusakan.pengganti_ulang. Response +urutan_penggantian.
21.8 Query baca
- Opsi karyawan: asset
terpakaimiliknya yang tidak diblokir flow lain, beserta komponen (items). - Opsi pengganti (admin): asset
tersedia@gudang, kategori sama dengan asset dilaporkan, belum dipakai di laporan ini. - List: tab
pengajuan(approval 1),proses(approval 3 & belum selesai),selesai(status_transaksi selesai — termasuk ditolak).jumlah_item= item laporan. - Detail: header, karyawan, asset,
items,pengganti(histori; komponen hanya untuk pengganti terbaru yang belum dicek),perlu_pengganti,unit_ditarik,aksi. - Pending: karyawan (
menunggu_pengambilan→ aksipelepasan,menunggu_checklist→checklist) di Asset Saya; admin (approval 1 ataumenunggu_review_checklist) di summary.
22Dampak terhadap asset_data
| Field | Sebelum | Sesudah | Trigger |
|---|---|---|---|
| (asset dilaporkan) semua | terpakai @karyawan | tidak berubah | Lapor, review, ubah jadwal |
| status_asset / pemegang (unit utama disetujui) | terpakai / karyawan | rusak / gudang, id_pemegang_asset = '' |
Serah terima pertama |
| ket_rusak (asset dilaporkan) | – | ringkasan item disetujui (≤255) | Serah terima pertama |
| status_asset (pengganti) | tersedia | proses | Review / pilih pengganti lain |
| status_asset / pemegang (pengganti normal) | proses / gudang | terpakai / karyawan | Selesaikan |
| status_asset / ket_rusak (pengganti rusak) | proses / – | rusak / ringkasan checklist | Pilih pengganti lain |
| tgl_update / user_update | – | now / pelaku | Setiap update |
23API Documentation
| ID | Method | Endpoint | Function | Auth |
|---|---|---|---|---|
| API-001 | GET | /asset/rusak-karyawan |
List laporan | Admin |
| API-002 | GET | /asset/rusak-karyawan/{id} |
Detail | Admin |
| API-003 | GET | /asset/rusak-karyawan/{id}/options |
Opsi unit pengganti | Admin |
| API-004 | POST | /asset/rusak-karyawan/{id}/review |
Review | Admin |
| API-005 | PUT | /asset/rusak-karyawan/{id}/jadwal |
Ubah jadwal | Admin |
| API-006 | POST | /asset/rusak-karyawan/{id}/selesai |
Selesaikan (laporan lama, checklist normal) | Admin |
| API-007 | POST | /asset/rusak-karyawan/{id}/ganti-pengganti |
Pilih pengganti lain (checklist rusak) | Admin |
| API-008 | GET | /asset/karyawan/rusak/options |
Asset & komponen yang bisa dilaporkan | JWT |
| API-009 | GET | /asset/karyawan/rusak |
List laporan saya | JWT |
| API-010 | POST | /asset/karyawan/rusak |
Kirim laporan | JWT |
| API-011 | GET | /asset/karyawan/rusak/{id} |
Detail laporan saya | JWT, pemilik |
| API-012 | POST | /asset/karyawan/rusak/{id}/pelepasan |
Konfirmasi serah terima (+ checklist opsional) | JWT, pemilik |
| API-013 | POST | /asset/karyawan/rusak/{id}/checklist |
Checklist unit pengganti | JWT, pemilik |
Terkait: GET /asset/karyawan/onboarding (Asset Saya, key kerusakan) dan GET /asset/summary (kerusakan_perlu_proses, kerusakan_pending).
24Detail Setiap API
Header umum: Authorization: Bearer <token>, Content-Type: application/json, Accept, locale, versi-app. Format { code, message, data }.
API-008 — Opsi Laporan (Karyawan)
GET /asset/karyawan/rusak/options
{
"code": "SUCCESS",
"message": "Opsi laporan kerusakan berhasil ditemukan.",
"data": {
"assets": [
{
"id_asset_data": "CMP00120260100012",
"kode_asset": "LPT-0012",
"nama_asset": "Laptop 14 inch",
"kategori_asset": "Laptop",
"merek": "MerekX",
"deskripsi": "",
"status_asset": "terpakai",
"items": [
{"id_item": "CMP001ITEM0101", "nama_item": "Laptop 14 inch", "jenis": "aset_utama", "detail": "RAM: 16 GB, SSD: 512 GB"},
{"id_item": "CMP001ITEM0102", "nama_item": "Charger", "jenis": "kelengkapan", "detail": "Daya: 65 W"}
]
}
]
}
}
API-010 — Kirim Laporan
POST /asset/karyawan/rusak
{
"id_asset_data": "CMP00120260100012",
"keterangan": "Terjadi setelah update sistem",
"items": [
{"id_item": "CMP001ITEM0101", "ket_rusak": "Ada garis pada layar"}
]
}
| Field | Rule | Message |
|---|---|---|
| id_asset_data | required|string|max:50 | Asset wajib dipilih. |
| keterangan | nullable|string|max:1000 | – |
| items | required|array|min:1 | Minimal satu item rusak wajib dipilih. |
| items.*.id_item | required|string|max:50|distinct | Item yang sama tidak boleh dipilih lebih dari sekali. |
| items.*.ket_rusak | required|string|max:255 | Keterangan kerusakan setiap item wajib diisi. / Keterangan kerusakan maksimal 255 karakter. |
Pesan umum: "Data laporan kerusakan belum lengkap." Database impact: INSERT header, INSERT item, INSERT notif (asset tidak berubah).
{ "code": "CREATED", "message": "Laporan kerusakan asset berhasil dikirim.",
"data": { "id": "CMP001202609005", "no_trx": "KRY06-202609005", "status_approval": 1,
"status_transaksi": "pengajuan", "status_label": "Menunggu Review", "tab": "pengajuan" } }
422: "Karyawan tidak ditemukan atau tidak aktif.", "Asset bukan milik karyawan atau tidak ditemukan.", "Hanya asset berstatus terpakai yang dapat dilaporkan rusak.", "Asset sedang diproses pada laporan kerusakan lain." / "…retur." / "…upgrade." / "…offboarding." / "…pemeliharaan.", "Item rusak harus berupa unit utama atau kelengkapan asset." 500: "Terjadi kesalahan saat menyimpan laporan kerusakan."
API-001 / API-009 — List
GET /asset/rusak-karyawan?tab=proses&limit=20&offset=0
GET /asset/karyawan/rusak?tab=pengajuan
tab: pengajuan | proses | selesai ("Filter laporan kerusakan tidak valid.").
{
"filters": [
{"value": "pengajuan", "label": "Pengajuan"},
{"value": "proses", "label": "Proses"},
{"value": "selesai", "label": "Selesai"}
],
"records": [
{
"id": "CMP001202609005",
"no_trx": "KRY06-202609005",
"tgl_pengajuan": "2026-09-28",
"flag_jadwalkan": "1",
"tgl_serah_terima": "2026-09-30",
"jam_serah_terima": "10:00:00",
"status_approval": 3,
"status_transaksi": "menunggu_pengambilan",
"status_label": "Menunggu Serah Terima",
"tab": "proses",
"jumlah_item": 1,
"asset": {"id_asset_data": "CMP00120260100012", "nama_asset": "Laptop 14 inch", "kategori_asset": "Laptop"},
"karyawan": {"id_karyawan": "KRY0009", "nik": "EMP-009", "nama_karyawan": "Sari Contoh"}
}
],
"pagination": {"limit": 20, "offset": 0, "next_offset": 1, "has_more": false}
}
API-002 / API-011 — Detail
{
"id": "CMP001202609005",
"no_trx": "KRY06-202609005",
"tgl_pengajuan": "2026-09-28",
"keterangan": "Terjadi setelah update sistem",
"flag_jadwalkan": "1",
"tgl_serah_terima": "2026-09-30",
"jam_serah_terima": "10:00:00",
"keterangan_serah_terima": "Ambil di ruang IT",
"tgl_pelepasan": "",
"status_approval": 3,
"status_transaksi": "menunggu_pengambilan",
"status_label": "Menunggu Serah Terima",
"tab": "proses",
"perlu_pengganti": true,
"unit_ditarik": true,
"karyawan": {"id_karyawan": "KRY0009", "nik": "EMP-009", "nama_karyawan": "Sari Contoh", "cabang": "Kantor Pusat", "divisi": "Marketing"},
"asset": {"id_asset_data": "CMP00120260100012", "kode_asset": "LPT-0012", "nama_asset": "Laptop 14 inch", "kategori_asset": "Laptop", "merek": "MerekX", "deskripsi": ""},
"items": [
{"id_item": "CMP001202609011", "id_asset_data_item": "CMP001ITEM0101", "nama_item": "Laptop 14 inch", "jenis": "aset_utama",
"detail": "RAM: 16 GB, SSD: 512 GB", "ket_rusak": "Ada garis pada layar", "status_item": "disetujui", "ket_tolak": "", "status_diganti": true}
],
"pengganti": [
{"id_item": "CMP001202609012", "urutan": 1, "id_asset_data": "CMP00120260100020", "kode_asset": "LPT-0020", "nama_asset": "Laptop 14 inch",
"kategori_asset": "Laptop", "merek": "MerekX", "deskripsi": "", "status_checklist": "belum_dicek", "tgl_serah_terima": "",
"tgl_checklist": "", "ket_rusak": "", "checklist": [],
"komponen": [{"id_item": "CMP001ITEM0201", "nama_item": "Laptop 14 inch", "jenis": "aset_utama", "detail": ""}]}
],
"aksi": {"review": false, "ubah_jadwal": true, "pelepasan": true, "checklist": false, "selesai": false, "ganti_pengganti": false}
}
Karyawan tidak menerima karyawan.id_karyawan. 404: "Laporan kerusakan tidak ditemukan."
API-003 — Opsi Unit Pengganti (Admin)
GET /asset/rusak-karyawan/{id}/options
data.assets[]: id_asset_data, kode_asset, nama_asset, kategori_asset, merek, deskripsi, status_asset, id_asset_kategori_m (tersedia @gudang, kategori sama, belum dipakai di laporan). 404 bila laporan tidak punya item.
API-004 — Review
POST /asset/rusak-karyawan/{id}/review
{
"items": [
{"id_item": "CMP001202609011", "status_item": "disetujui", "ket_tolak": "", "status_diganti": "1"}
],
"id_asset_pengganti": "CMP00120260100020",
"tgl_serah_terima": "2026-09-30",
"jam_serah_terima": "10:00",
"keterangan_serah_terima": "Ambil di ruang IT"
}
| Field | Rule | Message |
|---|---|---|
| items | required|array|min:1 | Keputusan item kerusakan wajib diisi. |
| items.*.id_item | required|max:50|distinct | Item yang sama tidak boleh dikirim lebih dari sekali. |
| items.*.status_item | required|in:disetujui,ditolak | Keputusan item harus disetujui atau ditolak. |
| items.*.ket_tolak | nullable|max:255|required_if ditolak | Alasan penolakan item wajib diisi. |
| items.*.status_diganti | nullable|in:0,1|required_if disetujui | Item yang disetujui wajib memilih diganti atau tidak. |
| id_asset_pengganti | nullable|max:50 | – |
| tgl_serah_terima | nullable|date_format:Y-m-d | Format tanggal serah terima harus YYYY-MM-DD. |
| jam_serah_terima | nullable|date_format:H:i | Format jam serah terima harus HH:MM. |
| keterangan_serah_terima | nullable|max:255 | – |
Database impact: UPDATE item, INSERT item pengganti, UPDATE asset pengganti → proses, UPDATE header, INSERT notif.
{ "code": "UPDATED", "message": "Review laporan kerusakan berhasil disimpan.",
"data": { "id": "CMP001202609005", "no_trx": "KRY06-202609005", "status_approval": 3,
"status_transaksi": "menunggu_pengambilan", "status_label": "Menunggu Serah Terima", "tab": "proses",
"jumlah_disetujui": 1, "jumlah_ditolak": 0, "perlu_pengganti": true } }
422: "Laporan kerusakan sudah direview.", "Seluruh item kerusakan wajib direview.", "Asset sudah tidak dipegang oleh karyawan.", "Asset pengganti hanya dipilih jika unit utama diganti.", "Asset pengganti wajib dipilih.", "Aset sudah tidak tersedia. Silakan pilih unit lain.", "Kategori asset pengganti harus sama dengan asset yang rusak.", "Tanggal dan jam serah terima wajib diisi.", "Tanggal serah terima tidak boleh sebelum tanggal pengajuan.", "Pengguna tidak terdaftar sebagai admin asset." 500: "Terjadi kesalahan saat memproses transaksi asset."
API-005 — Ubah Jadwal
PUT /asset/rusak-karyawan/{id}/jadwal
{ "tgl_serah_terima": "2026-10-01", "jam_serah_terima": "14:00", "keterangan_serah_terima": "" }
"Jadwal serah terima berhasil diperbarui." 422: "Jadwal hanya dapat diubah sebelum serah terima dilakukan."
API-012 — Konfirmasi Serah Terima (Karyawan)
POST /asset/karyawan/rusak/{id}/pelepasan
Body opsional items (format sama dengan API-013; kirim bila aksi.pelepasan_checklist true): checklist unit pengganti dikirim bersama serah terima. Normal → laporan selesai otomatis, rusak → menunggu_review_checklist; response +status_checklist bila items dikirim. Database impact: asset dilaporkan (rusak @gudang atau ket_rusak saja), asset_trx_log, item pengganti tgl_serah_terima, header. "Serah terima asset rusak berhasil dikonfirmasi." 422: "Laporan kerusakan belum siap diserahterimakan.", "Tidak ada unit pengganti yang perlu diserahterimakan.", "Tidak ada unit pengganti yang perlu dicek.", "Seluruh item unit pengganti wajib dicek.", "Asset sudah tidak dipegang oleh karyawan.", "Karyawan tidak ditemukan atau tidak aktif."
API-013 — Checklist Unit Pengganti (Karyawan)
POST /asset/karyawan/rusak/{id}/checklist
{
"items": [
{"id_item": "CMP001ITEM0201", "kondisi": "normal", "ket_rusak": ""},
{"id_item": "CMP001ITEM0202", "kondisi": "rusak", "ket_rusak": "Kabel charger terkelupas"}
]
}
| Field | Rule | Message |
|---|---|---|
| items | required|array|min:1 | Kondisi unit pengganti wajib diisi. |
| items.*.id_item | required|max:50|distinct | Item yang sama tidak boleh dikirim lebih dari sekali. |
| items.*.kondisi | required|in:normal,rusak | Kondisi item harus normal atau rusak. |
| items.*.ket_rusak | nullable|max:255|required_if rusak | Keterangan kerusakan wajib diisi. |
Response +status_checklist; checklist normal langsung menyelesaikan laporan (status_transaksi = selesai). "Checklist unit pengganti berhasil dikirim." 422: "Unit pengganti belum siap dicek.", "Unit pengganti belum diserahterimakan.", "Seluruh item unit pengganti wajib dicek."
API-006 — Selesaikan (Admin)
POST /asset/rusak-karyawan/{id}/selesai
Tanpa body. Hanya untuk laporan lama yang menunggu review dengan checklist normal. "Laporan kerusakan berhasil diselesaikan." 422: "Checklist unit pengganti belum dikirim karyawan.", "Unit pengganti masih memiliki item rusak. Pilih unit pengganti lain.", "Status asset pengganti sudah berubah."
API-007 — Pilih Pengganti Lain (Admin)
POST /asset/rusak-karyawan/{id}/ganti-pengganti
{ "id_asset_pengganti": "CMP00120260100021", "tgl_serah_terima": "2026-10-02", "jam_serah_terima": "09:00", "keterangan_serah_terima": "" }
id_asset_pengganti required ("Asset pengganti wajib dipilih."). Response +urutan_penggantian. "Unit pengganti baru berhasil dipilih." 422: "Seluruh item unit pengganti normal. Selesaikan laporan.", "Asset pengganti sudah pernah dipakai pada laporan ini.", "Kategori asset pengganti harus sama dengan asset yang rusak.", "Tanggal dan jam serah terima wajib diisi."
25Mobile Architecture
Page → AssetKerusakanBloc / AssetKerusakanAdminBloc → AssetKerusakanApi / AssetKerusakanAdminApi → ApiClient → Backend
| Layer | File | Function |
|---|---|---|
| Api | Repository/Service/assetKerusakanApi.dart |
Karyawan: getList, getOptions, store, getDetail, pelepasan, checklist. Admin: getList, getDetail, getPenggantiOptions, review, updateJadwal, selesai, gantiPengganti |
| Model | Repository/Model/Asset/mAssetKerusakan.dart |
AssetKerusakanTrx, …Komponen, …Asset, …Item, …ChecklistHasil, …Pengganti, …Aksi, …Karyawan, …Record, …Page, …ReportItem, …Request, …Jadwal, …Decision, …ReviewRequest, …ChecklistItem |
| Bloc | Bloc/Asset/AssetKerusakanBloc.dart |
LoadAssetKerusakanList, LoadMore…, LoadAssetKerusakanOptions, LoadAssetKerusakanDetail, SubmitAssetKerusakan, PelepasanAssetKerusakan, ChecklistAssetKerusakan |
| Bloc | Bloc/Asset/AssetKerusakanAdminBloc.dart |
LoadAssetKerusakanAdminList, LoadMore…, LoadAssetKerusakanAdminDetail, LoadAssetKerusakanPengganti, ReviewAssetKerusakan, UbahJadwalAssetKerusakan, SelesaiAssetKerusakan, GantiPenggantiAssetKerusakan |
| UI | UI/Modul/Asset/AssetSaya/Kerusakan/*, AssetAdmin/AssetAdminKaryawan/Kerusakan/*, UI/Modul/Asset/Shared/Widgets/AssetKerusakanWidgets.dart |
List, form, detail, sheet jadwal, kartu |
| Route | Page | Event awal |
|---|---|---|
/asset_kerusakan |
Laporan Kerusakan Asset (karyawan) | LoadAssetKerusakanList |
/asset_tambah_kerusakan |
Lapor Kerusakan Asset | LoadAssetKerusakanOptions |
/asset_detail_kerusakan |
Detail (karyawan) | LoadAssetKerusakanDetail(id) |
/asset_admin_kerusakan |
List admin | LoadAssetKerusakanAdminList |
/asset_admin_detail_kerusakan |
Detail admin | LoadAssetKerusakanAdminDetail(id) + LoadAssetKerusakanPengganti(id) |
26Mobile Screen
26.1 Laporan Kerusakan Asset — list (karyawan & admin)
Tab Pengajuan / Proses / Selesai; kartu: nomor, asset, "{jumlah} item rusak", status (Menunggu Review, Menunggu Serah Terima, Menunggu Checklist, Menunggu Review Checklist, Selesai, Ditolak), jadwal. Karyawan: tombol Lapor Kerusakan. Kosong: "Belum ada laporan kerusakan asset."
26.2 Lapor Kerusakan Asset (karyawan)
| Field UI | Widget | Required | Source |
|---|---|---|---|
| Pilih Asset yang Rusak | Picker ("Ketuk untuk memilih asset", cari nama/kode/merek) | Ya | options.assets ("Tidak ada aset aktif yang dapat dilaporkan.") |
| Jenis | Segmented Unit Utama / Kelengkapan (berpindah jenis mengosongkan pilihan) | Ya | items[].jenis |
| Item Rusak | Checkbox per komponen + Keterangan Kerusakan ("Contoh: Ada garis pada layar") | Min 1 ("Pilih minimal satu item yang rusak.") | items[] |
| Atribut Lainnya / Keterangan Umum | Text, maks 1000 | Tidak | → keterangan |
| Tombol | Kirim Laporan | – | – |
26.3 Detail Laporan Kerusakan (karyawan)
Info laporan, Jadwal Serah Terima ("Serah terima dijadwalkan pada {tanggal}, jam {jam}."), item (Disetujui Admin / Ditolak Admin, Diganti / Tidak Diganti, Alasan Penolakan), info "Unit akan ditarik ke gudang saat serah terima." atau "Unit tetap digunakan karyawan; hanya kelengkapan rusak yang diserahkan.", Histori Unit Pengganti ("Pengganti ke-{urutan}").
- aksi.pelepasan → Konfirmasi Serah Terima (info serah terima + dialog "Pastikan item rusak sudah diserahkan kepada Admin/HR.").
- aksi.pelepasan_checklist (bersama aksi.pelepasan) → Checklist Unit Pengganti tampil di bawah histori pengganti dan tombol menjadi Serah Terima & Kirim Checklist (satu langkah; checklist dikirim lewat pelepasan). aksi.checklist (alur lama) → Checklist Unit Pengganti (Normal/Rusak per komponen + keterangan) → Terima & Kirim Checklist.
Alur status: di bawah header tampil AssetAlurStepper.kerusakan (Laporan → Review → Serah Terima → Selesai; disembunyikan bila laporan ditolak) dan kartu aset AssetKerusakanTimelineCard berisi timeline vertikal: Laporan (tanggal, jumlah item, keterangan) · Review (jumlah item disetujui/ditolak, jadwal; chip Ditolak) · Serah Terima (tanggal diserahkan, status unit utama, unit pengganti + hasil checklist; chip Checklist Rusak) · Selesai (unit pengganti). Checklist unit pengganti memakai komponen bersama AssetKondisiChecklist (kartu berikon, pilihan Normal / Rusak berwarna hijau/merah, keterangan muncul saat Rusak). File: Shared/Widgets/AssetAlurWidgets.dart, Shared/Widgets/AssetKerusakanTimeline.dart, Shared/Widgets/AssetFormWidgets.dart.
26.4 Detail admin
- Kartu Data Karyawan menampilkan tiga baris berurutan: Jabatan, Cabang, Departemen (label "Divisi" diganti "Departemen"; nilai kosong tampil
-). Mobile (AssetKerusakanKaryawan.jabatan) membacakaryawan.jabatanlalukaryawan.nama_jabatan, sedangkancabang/divisidarikaryawan. API:AssetRusakKaryawan_m::getDetail(endpoint detail admin Kerusakan) menambahkaryawan.jabatanlewat joinmaster_jabatan(data_karyawan.id_jabatan);''bila jabatan kosong. aksi.review: per item Tolak (+Alasan Penolakan) / Setujui → Diganti / Tidak Diganti; bila unit utama diganti → Pilih Unit Pengganti ("Tidak ada unit pengganti yang tersedia untuk kategori ini."); Simpan Review → sheet Jadwal Serah Terima (tanggal mulai hari ini, jam, catatan) bila ada yang disetujui.aksi.ubah_jadwal→ Ubah Jadwal.aksi.selesai(hanya laporan lama) → info "Seluruh item unit pengganti normal." + Selesaikan Laporan (dialog "Unit pengganti akan menjadi asset aktif karyawan.").aksi.ganti_pengganti→ info "Unit pengganti masih memiliki item rusak. Pilih unit pengganti lain." + Pilih Pengganti Lain → pilih unit + jadwal.
Stepper dan kartu timeline sama seperti §26.3.
26.5 Entry point
Asset Saya: menu Kerusakan + banner Serah Terima Asset Rusak / Checklist Unit Pengganti. Asset Karyawan (admin): aksi Kerusakan + panel Kerusakan Perlu Diproses.
27Mobile → API
| UI Field | Mobile Variable | JSON Field | Type | Required |
|---|---|---|---|---|
| Asset dipilih | AssetKerusakanRequest.idAssetData |
id_asset_data |
string | Ya |
| Item dicentang | AssetKerusakanReportItem.idItem |
items[].id_item |
string | Min 1 |
| Keterangan Kerusakan | ketRusak |
items[].ket_rusak |
string | Ya |
| Keterangan Umum | keterangan |
keterangan |
string | Tidak |
| Setujui / Tolak | AssetKerusakanDecision.statusItem |
items[].status_item |
string | Ya |
| Alasan Penolakan | ketTolak |
items[].ket_tolak |
string | Bila tolak |
| Diganti / Tidak Diganti | diganti |
items[].status_diganti |
'1'/'0' | Bila setuju |
| Unit Pengganti | idAssetPengganti |
id_asset_pengganti |
string | Bila unit utama diganti |
| Jadwal (sheet) | AssetKerusakanJadwal |
tgl_serah_terima, jam_serah_terima, keterangan_serah_terima |
Y-m-d, H:i, string | Bila ada disetujui |
| Checklist | AssetKerusakanChecklistItem |
items[].id_item, kondisi, ket_rusak |
– | Semua komponen |
28API → Mobile
| API JSON | Mobile Model | UI |
|---|---|---|
records[] |
AssetKerusakanPage / AssetKerusakanRecord | Kartu list |
status_label, tab |
AssetKerusakanRecord | Badge, tab |
items[] |
AssetKerusakanItem | Item rusak & keputusan |
pengganti[] |
AssetKerusakanPengganti | Histori Unit Pengganti |
pengganti[].komponen |
AssetKerusakanKomponen | Form checklist |
pengganti[].checklist |
AssetKerusakanChecklistHasil | Hasil checklist |
aksi |
AssetKerusakanAksi | Tombol |
perlu_pengganti, unit_ditarik |
AssetKerusakanRecord | Info unit ditarik / tetap |
assets[].items (options) |
AssetKerusakanAsset / Komponen | Pilihan item |
29Mapping Mobile → API → Database
| UI | JSON | Backend | Table | Column |
|---|---|---|---|---|
| Asset | id_asset_data |
store() |
item | id_asset_data + snapshot |
| Item | items[].id_item |
normalizeReportItems |
item | kelengkapan_item (JSON), flag_jenis_komponen |
| Keterangan Kerusakan | items[].ket_rusak |
trim | item | ket_rusak |
| Keterangan Umum | keterangan |
trim | header | keterangan |
| Setujui/Tolak | items[].status_item |
review() |
item | status_approval |
| Alasan Penolakan | items[].ket_tolak |
trim | item | ket_tolak |
| Diganti | items[].status_diganti |
review() |
item | status_diganti |
| Unit Pengganti | id_asset_pengganti |
insertReplacement |
item (baru) / asset_data | urutan_penggantian, parent_id / status_asset = proses |
| Jadwal | tgl/jam/keterangan_serah_terima |
parseJadwal |
header | tgl_serah_terima, jam_serah_terima, flag_jadwalkan, keterangan_serah_terima |
| Konfirmasi Serah Terima (+ checklist) | items[].kondisi, ket_rusak (opsional) |
pelepasan() |
header / asset_data / asset_trx_log / item | tgl_pelepasan / status & pemegang / log / tgl_serah_terima, kelengkapan_item, status_checklist |
| Checklist | items[].kondisi, ket_rusak |
submitChecklist() |
item pengganti | kelengkapan_item (JSON), status_checklist, ket_rusak, tgl_checklist |
30Mapping Database → API → Mobile
| Table | Column | API JSON | Mobile | UI |
|---|---|---|---|---|
| header | status_approval + status_transaksi | status_label, tab, aksi |
Record | Badge, tab, tombol |
| header | tgl/jam_serah_terima (nol → '') | idem | Record | Jadwal |
| item (urutan 0) | kelengkapan_item | items[].nama_item, jenis, detail |
Item | Nama komponen |
| item (urutan 0) | status_diganti | items[].status_diganti (bool) |
Item | Diganti / Tidak Diganti |
| item (urutan ≥1) | urutan_penggantian, status_checklist, kelengkapan_item | pengganti[] |
Pengganti | Histori, hasil checklist |
| asset_data_item | json_value | pengganti[].komponen (hanya terbaru & belum dicek) |
Komponen | Form checklist |
31Validation
31.1 Mobile
| Lokasi | Aturan | Pesan |
|---|---|---|
| Form lapor | Asset wajib, min 1 item | "Pilih minimal satu item yang rusak." |
| Form lapor | Keterangan per item | "Keterangan kerusakan wajib diisi." |
| Form lapor | Satu jenis per laporan (unit utama atau kelengkapan) | Pilihan dikosongkan saat ganti jenis |
| Form lapor | Keterangan umum maks 1000 | – |
| Review | Semua item diputuskan; tolak wajib alasan; setuju wajib diganti/tidak; pengganti wajib bila unit utama diganti | "Pilih keputusan untuk seluruh asset." / "Alasan penolakan wajib diisi." / "Pilih diganti atau tidak untuk item yang disetujui." / "Asset pengganti wajib dipilih." |
| Sheet jadwal | Tanggal (mulai hari ini) & jam wajib | "Tanggal serah terima wajib dipilih." / "Jam serah terima wajib dipilih." |
| Checklist | Semua komponen; rusak wajib keterangan | "Pilih kondisi untuk seluruh asset." / "Keterangan kerusakan wajib diisi." |
31.2 Backend — §9 & §24.
31.3 Database — enum status_transaksi, status_checklist, approval_item; jenis_log enum ditambah rusak_karyawan.
32Error Handling
| Error | HTTP | Backend | Mobile |
|---|---|---|---|
| Field tidak valid | 422 | VALIDATION_ERROR | Pesan field |
| Aturan bisnis | 422 | BUSINESS_RULE_VIOLATION | Snackbar |
| Tidak ditemukan | 404 | NOT_FOUND | Halaman error ("Detail laporan kerusakan tidak dapat dimuat.") |
| Token / bukan admin | 401 / 403 | UNAUTHORIZED / FORBIDDEN | Pesan |
| Exception | 500 | SYSTEM_ERROR ("Terjadi kesalahan saat memproses transaksi asset.") + log | Snackbar |
33Audit Trail
| Data | Disimpan? | Lokasi |
|---|---|---|
| Pelapor & waktu | ✅ | user_input, tgl_input, tgl_pengajuan |
| Admin peninjau | ✅ | user_approval, tgl_approval |
| Keputusan per item | ✅ | item status_approval, ket_tolak, status_diganti |
| Serah terima pertama | ✅ | tgl_pelepasan, user_pelepasan |
| Histori unit pengganti & checklist | ✅ | item urutan ≥ 1 (user_input admin, tgl_serah_terima, tgl_checklist, hasil JSON) |
| Perubahan asset | ✅ | asset_trx_log rusak_karyawan |
| Riwayat perubahan jadwal | ❌ | ⚠️ Belum ditemukan (tertimpa) |
34Notification
| Event | Trigger | Penerima | Judul | Pesan | Rute |
|---|---|---|---|---|---|
kerusakan.diajukan |
Kirim laporan | Admin | Laporan Kerusakan Asset | {nama} melaporkan kerusakan asset {no_trx}. | asset_admin_detail_kerusakan |
kerusakan.ditolak |
Review semua ditolak | Karyawan | Laporan Kerusakan Ditolak | Laporan kerusakan {no_trx} ditolak admin. | asset_detail_kerusakan |
kerusakan.disetujui |
Review ada disetujui | Karyawan | Jadwal Pengambilan Asset Rusak | Laporan kerusakan {no_trx} disetujui. Cek jadwal pengambilan. | asset_detail_kerusakan |
kerusakan.dijadwalkan |
Ubah jadwal | Karyawan | Jadwal Pengambilan Diperbarui | Jadwal pengambilan laporan kerusakan {no_trx} telah diperbarui. | asset_detail_kerusakan |
kerusakan.diserahkan |
Konfirmasi serah terima | Admin | Asset Rusak Diserahkan | {nama} telah menyerahkan asset rusak {no_trx}. | asset_admin_detail_kerusakan |
kerusakan.checklist |
Kirim checklist rusak (bersama serah terima atau alur lama) | Admin | Checklist Unit Pengganti | {nama} telah mengirim checklist unit pengganti {no_trx}. | asset_admin_detail_kerusakan |
kerusakan.selesai_otomatis |
Checklist normal terkirim | Admin | Laporan Kerusakan Selesai | Unit pengganti {no_trx} normal dan telah diterima {nama}. Laporan selesai. | asset_admin_detail_kerusakan |
kerusakan.pengganti_ulang |
Pilih pengganti lain | Karyawan | Unit Pengganti Baru | Unit pengganti baru untuk {no_trx} telah dijadwalkan. | asset_detail_kerusakan |
kerusakan.selesai |
Selesaikan (laporan lama) | Karyawan | Laporan Kerusakan Selesai | Laporan kerusakan {no_trx} telah selesai. | asset_detail_kerusakan |
35Security
| Aspek | Implementasi |
|---|---|
| Autentikasi | Bearer JWT |
| Isolasi company | id_company dari token di semua query |
| Otorisasi admin | accessError (controller) + actorAdmin (model) |
| Kepemilikan | Karyawan: filter id_karyawan pada list/detail/mutasi; asset harus miliknya |
| Karyawan aktif | Dicek di simpan, serah terima, checklist; tidak di opsi/list/detail |
| Integritas | Lock company, FOR UPDATE header/item/asset, cek status pengganti |
36Manual Book User/Admin
A. Karyawan — Melapor Kerusakan
- Asset Saya → Kerusakan → Lapor Kerusakan.
- Pilih Asset yang Rusak (hanya asset aktif yang tidak sedang diproses).
- Pilih Unit Utama atau Kelengkapan, centang item yang rusak, isi Keterangan Kerusakan setiap item.
- Isi Atribut Lainnya / Keterangan Umum bila perlu → Kirim Laporan.
B. Admin — Review
- Asset Karyawan → Kerusakan → pilih laporan (tab Pengajuan).
- Setiap item: Tolak (isi alasan) atau Setujui lalu Diganti / Tidak Diganti.
- Bila unit utama diganti → Pilih Unit Pengganti (kategori sama).
- Simpan Review → isi Jadwal Serah Terima (tanggal, jam, catatan).
C. Karyawan — Serah Terima
- Pada jadwal, serahkan item rusak ke Admin/HR (dan terima unit pengganti bila ada).
- Detail → Konfirmasi Serah Terima.
D. Karyawan — Serah Terima + Checklist Unit Pengganti
Detail → isi kondisi Normal/Rusak tiap komponen unit pengganti → Serah Terima & Kirim Checklist (satu langkah dengan serah terima).
E. Admin — Menyelesaikan
- Checklist normal → laporan selesai otomatis: unit pengganti menjadi asset karyawan (admin hanya mendapat notifikasi).
- Checklist rusak → Pilih Pengganti Lain + jadwal baru; ulangi C–E.
- Sebelum serah terima, jadwal dapat diubah dengan Ubah Jadwal.
37Kondisi Button
| Button | Role | Condition (aksi) |
Action |
|---|---|---|---|
| Lapor Kerusakan | Karyawan | Selalu | Form |
| Kirim Laporan | Karyawan | Tidak submitting | POST laporan |
| Setujui / Tolak / Diganti / Pilih Unit Pengganti / Simpan Review | Admin | review (approval 1) |
POST review |
| Ubah Jadwal | Admin | ubah_jadwal (menunggu_pengambilan) |
PUT jadwal |
| Konfirmasi Serah Terima | Karyawan | pelepasan (menunggu_pengambilan) |
POST pelepasan |
| Serah Terima & Kirim Checklist | Karyawan | pelepasan + pelepasan_checklist (menunggu_pengambilan, ada pengganti) |
POST pelepasan (items) |
| Terima & Kirim Checklist (alur lama) | Karyawan | checklist (menunggu_checklist) |
POST checklist |
| Selesaikan Laporan | Admin | selesai (laporan lama: review checklist + normal) |
POST selesai |
| Pilih Pengganti Lain | Admin | ganti_pengganti (review checklist + rusak) |
POST ganti-pengganti |
| Batalkan laporan | – | ⚠️ Belum ditemukan | – |
38Testing Scenario
Test otomatis yang ada (AssetRusakKaryawanTest): test_options_only_list_used_assets_with_unit_and_kelengkapan_items, test_submit_stores_snapshot_without_changing_asset_status, test_submit_rejects_foreign_asset_invalid_item_and_duplicate_report, test_rejecting_every_item_closes_report_without_touching_asset, test_replacement_must_be_available_and_same_category, test_full_replacement_loop_until_replacement_is_normal, test_kelengkapan_replaced_needs_no_replacement_unit, test_kelengkapan_without_replacement_keeps_unit_with_employee, test_unit_utama_without_replacement_is_withdrawn, test_employee_routes_submit_report_and_notify_admin.
| TC | Scenario | Expected |
|---|---|---|
| TC-01 | Lapor unit utama | 201; Menunggu Review; asset tetap terpakai; notif admin |
| TC-02 | Lapor asset milik orang lain / dipinjam | 422 |
| TC-03 | Lapor asset yang sudah ada laporan aktif | 422 "…laporan kerusakan lain." |
| TC-04 | Lapor asset dalam retur / upgrade / offboarding / pemeliharaan | 422 |
| TC-05 | Item bukan komponen asset / duplikat / tanpa keterangan | 422 |
| TC-06 | Review semua ditolak | Ditolak/selesai; asset tidak berubah |
| TC-07 | Unit utama disetujui, tidak diganti → serah terima | Asset rusak @gudang; selesai |
| TC-08 | Hanya kelengkapan disetujui → serah terima | Asset tetap @karyawan, ket_rusak terisi; selesai |
| TC-09 | Kelengkapan disetujui + diganti | Tidak butuh unit pengganti; selesai setelah serah terima |
| TC-10 | Unit utama diganti tanpa pengganti | 422 "Asset pengganti wajib dipilih." |
| TC-11 | Pengganti beda kategori / tidak tersedia | 422 |
| TC-12 | Review ada disetujui tanpa jadwal | 422 |
| TC-13 | Unit utama diganti → serah terima + checklist | Asset lama rusak @gudang; checklist ikut tersimpan |
| TC-14 | Checklist sebagian komponen | 422 |
| TC-15 | Checklist normal | Selesai otomatis; pengganti terpakai @karyawan + log |
| TC-16 | Checklist rusak → Selesaikan | 422 "…Pilih unit pengganti lain." |
| TC-17 | Checklist rusak → Pilih Pengganti Lain | Pengganti lama rusak @gudang; pengganti ke-2; Menunggu Serah Terima |
| TC-18 | Serah terima ke-2 | Hanya menerima pengganti; checklist dikirim bersamaan |
| TC-19 | Pilih pengganti yang sudah dipakai | 422 |
| TC-20 | Ubah jadwal setelah serah terima | 422 |
| TC-21 | Asset dalam laporan aktif lalu diajukan Retur / Offboarding | Keduanya ditolak "…sedang diproses pada laporan kerusakan." |
| TC-22 | Asset dalam laporan aktif lalu diajukan Upgrade | Ditolak Upgrade |
| TC-23 | Tanpa token / bukan admin | 401 / 403 |
| TC-24 | Serah terima + checklist normal | Laporan selesai otomatis; pengganti terpakai @karyawan |
| TC-25 | Serah terima + checklist rusak | menunggu_review_checklist; pengganti tetap proses; admin Pilih Pengganti Lain |
| TC-26 | Serah terima + checklist tidak lengkap | 422; seluruh transaksi dibatalkan (unit rusak tetap di karyawan) |
| TC-27 | items dikirim tanpa unit pengganti |
422 "Tidak ada unit pengganti yang perlu dicek." |
| TC-28 | Route pelepasan + checklist normal | 200 selesai; notifikasi kerusakan.selesai_otomatis ke admin |
39Temuan Ketidaksesuaian
| ID | Component | Finding | Impact | Recommendation |
|---|---|---|---|---|
| INC-01 | Mobile ↔ Backend | Mobile membatasi satu jenis (unit utama atau kelengkapan) per laporan; backend menerima campuran | Aturan hanya di UI | Tegaskan di backend atau izinkan di UI |
| INC-02 | Backend | Kelengkapan "Diganti" hanya dicatat (status_diganti = 1); tidak ada proses penggantian kelengkapan |
Harapan pengguna vs sistem berbeda | Dokumentasikan SOP / tambah alur |
| INC-03 | DBML ↔ Migration | DBML tidak memuat kolom workflow (status_transaksi, tgl_pelepasan, user_pelepasan, urutan_penggantian, status_checklist, tgl_serah_terima, tgl_checklist); catatan parent_id "grouping item" tidak sesuai (rantai pengganti) |
Skema tidak akurat | Perbarui DBML |
| INC-04 | Backend (lintas modul) | status_approval header berupa angka (1/2/3), modul lain memakai enum string |
Inkonsisten, rawan salah baca | Samakan |
| INC-05 | Backend | Endpoint karyawan (opsi, list, detail) tidak mengecek karyawan aktif | Karyawan nonaktif masih bisa membaca | Tambah cek aktif bila perlu |
| INC-06 | Backend | Validasi request sebelum cek admin (review, jadwal, ganti pengganti) | 422 bukan 403 | Pindahkan cek |
| INC-07 | Backend | Opsi unit pengganti tetap tersedia untuk laporan berstatus apa pun | Data tidak relevan | Batasi status |
| INC-08 | Backend | ket_rusak asset berupa ringkasan yang dipotong 255 karakter |
Informasi terpotong | Tampilkan detail dari tabel transaksi |
| INC-09 | Backend | Tab selesai mencampur Ditolak dan Selesai |
Riwayat tercampur | Pisahkan filter |
40Edge Case
| Edge Case | Current Behavior | Impact | Recommendation |
|---|---|---|---|
| Laporan disetujui tapi karyawan tidak pernah konfirmasi serah terima | Menunggu Serah Terima selamanya; pengganti proses |
Unit pengganti terkunci | Admin dapat konfirmasi / batal |
| Karyawan nonaktif sebelum serah terima/checklist | actorKaryawan gagal |
Transaksi macet | Aksi admin pengganti |
| Pengganti sudah dipegang fisik karyawan (setelah serah terima, hanya saat checklist rusak atau laporan lama) tapi laporan belum diselesaikan | asset_data pengganti masih proses @gudang |
Tidak terlihat sebagai milik karyawan; tidak ikut offboarding | Pindahkan pemegang saat serah terima |
| Unit utama disetujui "Tidak Diganti" | Asset ditarik ke gudang, karyawan tanpa unit | Sesuai test; perlu SOP | Konfirmasi ke bisnis |
| Retur dibuat saat laporan aktif | Ditolak "…pada laporan kerusakan." | Aman | – |
| Offboarding dibuat saat laporan aktif | Ditolak (v1.1) | Aman | – |
| Tidak ada unit pengganti sekategori | Admin tidak bisa menyetujui "diganti" | Harus pilih "Tidak Diganti" atau menunggu stok | – |
41Potential Bug / Technical Risk
RISK-001 — Laporan kerusakan aktif dicek Retur dan Offboarding (SELESAI)
Lokasi: AssetRusakKaryawan_m::hasActiveRusakAsset dipanggil oleh AssetUpgradeKaryawan_m, AssetPemeliharaanKaryawan_m, dan — sejak v1.1 — AssetOffboardingKaryawan_m::assertNoCrossFlow ("Satu atau beberapa asset sedang diproses pada laporan kerusakan."). AssetReturKaryawan_m::store kini juga memanggilnya ("Satu atau beberapa asset sedang diproses pada laporan kerusakan."). Pengajuan pengembalian peminjaman tidak memerlukannya karena asset dipinjam tidak bisa dilaporkan rusak (BR-001).
Masalah: Sebelumnya asset yang sedang dalam laporan kerusakan masih bisa diretur; kini ditolak saat ajukan retur.
Recommendation: Tidak ada; risiko ditutup (terverifikasi 12 Okt 2026).
RISK-002 — Unit pengganti "mengambang" antara serah terima dan penyelesaian (SEDANG)
Setelah karyawan menerima pengganti dengan checklist rusak (menunggu_review_checklist; alur lama juga menunggu_checklist), asset_data pengganti masih proses @gudang. Offboarding tidak akan menarik unit itu, dan transaksi lain tidak melihatnya sebagai milik karyawan.
RISK-003 — Tidak ada pembatalan / kedaluwarsa (SEDANG)
Laporan tidak bisa dibatalkan karyawan maupun admin setelah dikirim/disetujui; pengganti yang direservasi tetap proses.
RISK-004 — Serah terima hanya oleh karyawan (SEDANG)
Admin tidak punya aksi untuk mencatat serah terima; karyawan nonaktif menghentikan alur.
RISK-005 — Tanggal nol 0000-00-00 (SEDANG)
Header memakai tanggal nol untuk jadwal kosong. ⚠️ Asumsi: bermasalah pada MySQL strict mode.
RISK-006 — Notifikasi di luar transaksi (RENDAH)
Dikirim setelah commit; kegagalan tidak membatalkan transaksi.
RISK-007 — Kapasitas penomoran (RENDAH)
3 digit/bulan untuk header & item; setiap pengganti ulang memakai satu nomor item.
42Dependency
Asset terpakai milik karyawan (Onboarding / Penambahan / Retur pengganti / Upgrade)
↓ komponen dari asset_data_item
Laporan Kerusakan (review → serah terima + checklist ↺ pengganti ulang → selesai otomatis) ──► Notifikasi
↓
asset_data (rusak @gudang / tetap / pengganti terpakai) + asset_trx_log rusak_karyawan
Aturan silang:
- Kerusakan mengecek: kerusakan lain, Retur, Upgrade, Offboarding, Pemeliharaan PML01 (assetBlockMessage)
- Dicek oleh: Upgrade, Offboarding, Pemeliharaan PML01, Retur (hasActiveRusakAsset)
- Summary admin: kerusakan_perlu_proses / kerusakan_pending; Asset Saya: kerusakan[]
43Source Code Reference
| File | Layer | Function |
|---|---|---|
API/routes/modules/asset/RouteAsset.php (baris 44–50, 88–93) |
Route | 13 endpoint |
API/app/Http/Controllers/Asset/Admin/AssetAdminRusak_c.php |
Controller | Admin kerusakan, mutateAssetTrx, RUSAK_JADWAL_RULES |
API/app/Http/Controllers/Asset/Karyawan/AssetKaryawanRusak_c.php |
Controller | Karyawan kerusakan, mutateTrxSaya |
API/app/Models/Asset/AssetRusakKaryawan_m.php |
Model | Seluruh logika |
API/app/Models/Asset/Asset_m.php |
Model | komponenAssets, parseJadwalValue, insertAssetLog, getLockedAssets, konstanta status |
API/app/Models/Asset/AssetUpgradeKaryawan_m.php, AssetOffboardingKaryawan_m.php, AssetPemeliharaanKaryawan_m.php |
Model | Pemakai hasActiveRusakAsset |
API/app/Models/Asset/AssetKaryawan_m.php, AssetAdmin_m.php |
Model | Pending karyawan & summary |
API/app/Support/Asset/AssetNotification.php |
Support | kerusakan.* |
API/database/migrations/2026_09_25_000001_add_workflow_fields_to_asset_rusak_karyawan.php |
Migration | Kolom workflow, index, enum log |
API/tests/Asset/AssetRusakKaryawanTest.php |
Test | 15 test |
MOBILE/lib/Repository/Service/assetKerusakanApi.dart |
Api | – |
MOBILE/lib/Repository/Model/Asset/mAssetKerusakan.dart |
Model | – |
MOBILE/lib/Bloc/Asset/AssetKerusakanBloc.dart, AssetKerusakanAdminBloc.dart |
Bloc | – |
MOBILE/lib/UI/Modul/Asset/AssetSaya/Kerusakan/*, AssetAdmin/AssetAdminKaryawan/Kerusakan/*, UI/Modul/Asset/Shared/Widgets/AssetKerusakanWidgets.dart |
UI | – |
44Developer Notes
- Satu laporan = satu asset;
id_asset_datasama untuk semua item laporan (urutan 0). - Komponen berasal dari
asset_data_item.json_value(flag_spesifikasi1/2); asset tanpa unit utama mendapat baris sintetisid_item = id_asset_data. kelengkapan_itemberfungsi ganda: snapshot komponen (item laporan) dan hasil checklist (baris pengganti).- Rantai pengganti:
urutan_penggantiannaik 1 tiap penggantian,parent_idmenunjuk baris sebelumnya. - Objek
aksidi detail adalah sumber kebenaran tombol di mobile. - Satu jadwal dipakai untuk pengambilan item rusak dan kedatangan pengganti.
45End-to-End Traceability
Karyawan: Laptop → Unit Utama → "Ada garis pada layar" → Kirim Laporan
→ AssetKerusakanRequest(idAssetData, items[{idItem, ketRusak}])
→ POST /asset/karyawan/rusak → store() → header KRY06-… (1, pengajuan) + item urutan 0
Admin: Setujui + Diganti + unit LPT-0020 + jadwal 30 Sep 10:00 → Simpan Review
→ review() → item disetujui/diganti, item pengganti urutan 1 (belum_dicek), LPT-0020 = proses, header 3/menunggu_pengambilan
Karyawan: Serah Terima & Kirim Checklist (semua Normal) → pelepasan(items)
→ LPT-0012 rusak @gudang + log; pengganti tgl_serah_terima; status_checklist normal
→ LPT-0020 terpakai @karyawan + log; header selesai (otomatis)
Admin: hanya menerima notifikasi kerusakan.selesai_otomatis
→ Mobile: badge "Selesai", Histori Unit Pengganti "Pengganti ke-1"
45.4 Walkthrough Lengkap dengan Contoh Data
Bagian ini mengikuti satu laporan kerusakan sampai unit pengganti diterima, langkah demi langkah: apa yang dilakukan pengguna di mobile, apa yang dikirim, apa yang diproses API, dan apa yang tersimpan di database. Data bersifat sintetis, tetapi format ID, nama kolom, urutan proses, label status, dan pesan diambil dari kode (AssetRusakKaryawan_m, AssetKaryawanRusak_c, AssetAdminRusak_c, AssetNotification).
Skenario: Sari melaporkan unit utama laptopnya rusak. Admin menyetujui dan memilih laptop pengganti. Saat serah terima, Sari mengecek unit pengganti pertama dan menemukan charger rusak, sehingga admin memilih pengganti kedua. Unit pengganti kedua dinyatakan normal dan laporan selesai otomatis.
| Langkah | Pelaku | Aksi | Endpoint |
|---|---|---|---|
| 0 | Karyawan | Memuat asset dan komponen yang bisa dilaporkan | API-008 GET /asset/karyawan/rusak/options |
| 1 | Karyawan | Kirim Laporan | API-010 POST /asset/karyawan/rusak |
| 2 | Admin | Memuat opsi unit pengganti | API-003 GET /asset/rusak-karyawan/{id}/options |
| 3 | Admin | Setujui, Diganti, pilih pengganti, jadwal, Simpan Review | API-004 POST /asset/rusak-karyawan/{id}/review |
| 4 | Karyawan | Serah Terima & Kirim Checklist (checklist rusak) | API-012 POST /asset/karyawan/rusak/{id}/pelepasan |
| 5 | Admin | Pilih Pengganti Lain + jadwal baru | API-007 POST /asset/rusak-karyawan/{id}/ganti-pengganti |
| 6 | Karyawan | Serah Terima & Kirim Checklist (checklist normal) | API-012 |
Data awal
Company CMP001. Laporan dibuat 22 Oktober 2026, periode ID 202610. Belum ada laporan, log, atau notifikasi pada periode ini.
data_karyawan
| id_karyawan | nik | nama_lengkap | Peran |
|---|---|---|---|
| KRY0009 | EMP-009 | Sari Contoh | Pelapor, pemegang asset |
| KRY0099 | ADM-001 | Siti Admin | Admin Asset (aktor) |
| KRY0100 | ADM-002 | Rudi Admin | Admin Asset lain (ikut menerima notifikasi) |
asset_data (semua kategori Laptop, kondisi_awal = normal)
| Kode | id_asset_data | status_asset | pemegang_asset | id_pemegang_asset | Komponen (asset_data_item) |
|---|---|---|---|---|---|
| A12 | CMP00120260100012 (LPT-0012) | terpakai | karyawan | KRY0009 | CMP001ITEM0101 Laptop 14 inch (aset_utama), CMP001ITEM0102 Charger (kelengkapan) |
| A20 | CMP00120260100020 (LPT-0020) | tersedia | gudang | '' |
CMP001ITEM0201 Laptop 14 inch (aset_utama), CMP001ITEM0202 Charger (kelengkapan) |
| A21 | CMP00120260100021 (LPT-0021) | tersedia | gudang | '' |
CMP001ITEM0301 Laptop 14 inch (aset_utama), CMP001ITEM0302 Charger (kelengkapan) |
Komponen dibaca dari asset_data_item.json_value (flag_spesifikasi 1 = unit utama, 2 = kelengkapan).
Penomoran: header dan item id_company + YYYYMM + 3 digit, no_trx = KRY06-YYYYMMNNN; log dan notifikasi 5 digit. Satu laporan menyimpan item laporan (urutan_penggantian = 0) dan histori unit pengganti (urutan_penggantian ≥ 1) di tabel item yang sama.
Langkah 0 — Karyawan membuka form
Mobile: Asset Saya → Kerusakan → + → form Lapor Kerusakan Asset → AssetKerusakanApi.getOptions().
Dikirim
GET /asset/karyawan/rusak/options
Authorization: Bearer <access_token_sari>
Diproses API (AssetRusakKaryawan_m::getOptions): asset yang dipegang karyawan, berstatus terpakai (asset pinjaman tidak termasuk), tidak diblokir flow lain (laporan kerusakan lain, retur, upgrade, offboarding, pemeliharaan), beserta komponennya (komponenAssets).
Database: hanya SELECT.
Diterima mobile (ringkas)
{ "code": "SUCCESS", "message": "Opsi laporan kerusakan berhasil ditemukan.",
"data": { "assets": [ {
"id_asset_data": "CMP00120260100012", "kode_asset": "LPT-0012", "nama_asset": "Laptop 14 inch",
"kategori_asset": "Laptop", "status_asset": "terpakai",
"items": [
{ "id_item": "CMP001ITEM0101", "nama_item": "Laptop 14 inch", "jenis": "aset_utama", "detail": "RAM: 16 GB, SSD: 512 GB" },
{ "id_item": "CMP001ITEM0102", "nama_item": "Charger", "jenis": "kelengkapan", "detail": "Daya: 65 W" }
] } ] } }
Langkah 1 — Sari mengirim laporan
Mobile: Sari memilih laptop, memilih Unit Utama, mencentang "Laptop 14 inch", mengisi keterangan "Ada garis pada layar", lalu Kirim Laporan → AssetKerusakanApi.store. (Mobile membatasi satu jenis komponen per laporan; API menerima campuran.)
Dikirim
POST /asset/karyawan/rusak
{
"id_asset_data": "CMP00120260100012",
"keterangan": "Terjadi setelah update sistem",
"items": [ { "id_item": "CMP001ITEM0101", "ket_rusak": "Ada garis pada layar" } ]
}
Diproses API (AssetKaryawanRusak_c::storeRusakSaya → AssetRusakKaryawan_m::store, satu DB::transaction)
1. Validasi: id_asset_data wajib; items minimal 1; id_item unik; ket_rusak wajib (maks 255); keterangan maks 1000.
2. lockCompany; findActiveKaryawan("KRY0009").
3. Asset diambil FOR UPDATE: dipegang Sari dan berstatus terpakai; assetBlockMessage memastikan tidak ada flow lain yang aktif.
4. komponenAssets + normalizeReportItems: setiap id_item harus komponen asset itu.
5. Generate ID: header urutan 1 → CMP001202610001, no_trx = KRY06-202610001; item mulai urutan 1.
6. INSERT header (status_approval = 1, status_transaksi = pengajuan, jadwal nol) dan INSERT item laporan (urutan_penggantian = 0, snapshot komponen di kelengkapan_item dalam JSON).
7. asset_data tidak berubah. Notifikasi kerusakan.diajukan ke admin.
Hasil database
asset_trx_rusak_karyawan
| Kolom | Nilai |
|---|---|
| id_asset_trx_rusak_karyawan | CMP001202610001 |
| no_trx | KRY06-202610001 |
| keterangan | Terjadi setelah update sistem |
| id_karyawan / nik_karyawan / nama_karyawan | KRY0009 / EMP-009 / Sari Contoh |
| tgl_pengajuan | 2026-10-22 |
| flag_jadwalkan / tgl_serah_terima / jam_serah_terima | 0 / 0000-00-00 / 00:00:00 |
| status_approval / status_transaksi | 1 (proses) / pengajuan |
| tgl_pelepasan / user_pelepasan | NULL / '' |
| user_approval / tgl_approval | '' / NULL |
| tgl_input / user_input | 2026-10-22 09:00:00 / EMP-009 - Sari Contoh |
asset_trx_rusak_karyawan_item
| Kolom | Nilai |
|---|---|
| id_asset_trx_rusak_item | CMP001202610001 |
| parent_id / urutan_penggantian | NULL / 0 |
| id_asset_trx_rusak / id_asset_data | CMP001202610001 / A12 |
| nama_asset / kategori_asset | Laptop 14 inch / Laptop |
| status_approval / status_diganti | NULL / 0 |
| ket_rusak | Ada garis pada layar |
| flag_jenis_komponen | 0 (unit utama) |
| kelengkapan_item | {"id_item":"CMP001ITEM0101","nama_item":"Laptop 14 inch","jenis":"aset_utama","detail":"RAM: 16 GB, SSD: 512 GB"} |
notif_data (2 baris, satu per admin)
| id_notif | id_karyawan | id_ref | rute | ket_notif_id |
|---|---|---|---|---|
| CMP00120261000001 | KRY0099 | CMP001202610001 | asset_admin_detail_kerusakan | Sari Contoh melaporkan kerusakan asset KRY06-202610001. |
| CMP00120261000002 | KRY0100 | CMP001202610001 | asset_admin_detail_kerusakan | Sari Contoh melaporkan kerusakan asset KRY06-202610001. |
Diterima mobile (HTTP 201)
{ "code": "CREATED", "message": "Laporan kerusakan asset berhasil dikirim.",
"data": { "id": "CMP001202610001", "no_trx": "KRY06-202610001", "status_approval": 1,
"status_transaksi": "pengajuan", "status_label": "Menunggu Review", "tab": "pengajuan" } }
Langkah 2 — Admin membuka detail dan memuat opsi pengganti
Mobile: notifikasi membuka detail admin (GET /asset/rusak-karyawan/CMP001202610001, aksi.review = true) lalu GET /asset/rusak-karyawan/CMP001202610001/options.
Diproses API (getPenggantiOptions): asset tersedia di gudang dengan kategori sama dengan asset yang dilaporkan dan belum pernah dipakai di laporan ini (A20 dan A21 untuk kategori Laptop). Database: hanya SELECT.
Langkah 3 — Admin mereview dan memilih pengganti
Mobile: admin menekan Setujui pada item, memilih Diganti, memilih LPT-0020 sebagai Unit Pengganti, mengisi jadwal 23 Okt 2026 pukul 10:00, lalu Simpan Review → AssetKerusakanAdminApi.review.
Dikirim
POST /asset/rusak-karyawan/CMP001202610001/review
{
"items": [ { "id_item": "CMP001202610001", "status_item": "disetujui", "ket_tolak": "", "status_diganti": "1" } ],
"id_asset_pengganti": "CMP00120260100020",
"tgl_serah_terima": "2026-10-23",
"jam_serah_terima": "10:00",
"keterangan_serah_terima": "Ambil di ruang IT"
}
Diproses API (AssetAdminRusak_c::reviewRusakKaryawan → review)
1. Validasi items (id unik, status_item ∈ disetujui/ditolak, ket_tolak wajib bila ditolak, status_diganti 0/1 wajib bila disetujui); format tanggal Y-m-d dan jam H:i. Cek admin, lockCompany.
2. Header harus status_approval = 1 ("Laporan kerusakan sudah direview."); seluruh item laporan harus diputuskan.
3. Asset yang dilaporkan harus masih dipegang Sari ("Asset sudah tidak dipegang oleh karyawan.").
4. Ada item disetujui → jadwal wajib, tanggal tidak boleh sebelum tgl_pengajuan.
5. Unit utama diganti → lockReplacementCandidate: pengganti wajib dipilih, belum dipakai di laporan ini, tersedia @gudang, kategori sama (kategori pengganti dibandingkan dengan asset_data.id_asset_kategori_m asset rusak). Memilih pengganti padahal unit utama tidak diganti ditolak.
6. UPDATE item (status_approval, status_diganti); insertReplacement (urutan 1, parent_id = item laporan, status_approval = disetujui, status_checklist = belum_dicek) dan UPDATE asset_data A20 → proses.
7. UPDATE header: status_approval = 3, status_transaksi = menunggu_pengambilan, jadwal, flag_jadwalkan, approval.
8. Notifikasi kerusakan.disetujui ke karyawan.
Hasil database
| Tabel | Perubahan |
|---|---|
item laporan …001 |
status_approval NULL → disetujui; status_diganti 0 → 1 |
| item baru (pengganti 1) | CMP001202610002: parent_id CMP001202610001, urutan_penggantian 1, id_asset_data A20, nama_asset Laptop 14 inch, status_approval disetujui, status_diganti 0, status_checklist belum_dicek, flag_jenis_komponen 0, kelengkapan_item '', tgl_serah_terima NULL, user_input = ADM-001 - Siti Admin |
| asset_data A20 | status_asset tersedia → proses; user_update = ADM-001 - Siti Admin |
| header | status_approval 1 → 3; status_transaksi pengajuan → menunggu_pengambilan; flag_jadwalkan 1; tgl_serah_terima 2026-10-23; jam_serah_terima 10:00:00; keterangan_serah_terima = Ambil di ruang IT; user_approval = ADM-001 - Siti Admin; tgl_approval = 2026-10-22 11:00:00 |
| asset_data A12 | Tidak berubah (masih terpakai @Sari) |
| notif_data | + CMP00120261000003: KRY0009, id_ref CMP001202610001, rute asset_detail_kerusakan, "Laporan kerusakan KRY06-202610001 disetujui. Cek jadwal pengambilan." |
Diterima mobile (HTTP 200)
{ "code": "UPDATED", "message": "Review laporan kerusakan berhasil disimpan.",
"data": { "id": "CMP001202610001", "no_trx": "KRY06-202610001", "status_approval": 3,
"status_transaksi": "menunggu_pengambilan", "status_label": "Menunggu Serah Terima", "tab": "proses",
"jumlah_disetujui": 1, "jumlah_ditolak": 0, "perlu_pengganti": true } }
Admin masih bisa Ubah Jadwal (API-005, PUT …/jadwal) selama status menunggu_pengambilan; notifikasi kerusakan.dijadwalkan ke karyawan.
Langkah 4 — Sari menyerahkan laptop rusak dan mengecek pengganti pertama
Mobile: banner Serah Terima Asset Rusak → detail. Karena aksi.pelepasan_checklist = true, tombol Serah Terima & Kirim Checklist menampilkan checklist komponen unit pengganti. Sari menandai Laptop Normal dan Charger Rusak ("Kabel charger terkelupas") → AssetKerusakanApi.pelepasan(id, items).
Dikirim
POST /asset/karyawan/rusak/CMP001202610001/pelepasan
{
"items": [
{ "id_item": "CMP001ITEM0201", "kondisi": "normal", "ket_rusak": "" },
{ "id_item": "CMP001ITEM0202", "kondisi": "rusak", "ket_rusak": "Kabel charger terkelupas" }
]
}
Diproses API (AssetKaryawanRusak_c::pelepasanRusakSaya → pelepasan)
1. lockCompany; karyawan aktif; header milik Sari, status harus menunggu_pengambilan ("Laporan kerusakan belum siap diserahterimakan.").
2. Pengganti terbaru yang belum diterima = …002.
3. Karena tgl_pelepasan masih kosong → releaseOriginalAsset: asset dilaporkan harus masih dipegang Sari. Unit utama disetujui → A12 menjadi rusak, gudang, id_pemegang_asset = ''; ket_rusak = ringkasan "nama: keterangan" item disetujui (maks 255); INSERT asset_trx_log. (Bila hanya kelengkapan yang disetujui, asset tetap dipegang karyawan dan hanya ket_rusak yang terisi.)
4. UPDATE tgl_serah_terima pengganti …002 = sekarang.
5. applyChecklist: semua komponen pengganti wajib dicek (jumlah dan ID harus sama), kondisi ∈ normal/rusak, rusak wajib keterangan. Hasil disimpan sebagai JSON di kelengkapan_item; status_checklist = rusak karena ada satu komponen rusak; ket_rusak = ringkasan komponen rusak; tgl_checklist.
6. settleChecklist: checklist rusak → header menunggu_review_checklist (pengganti tidak diserahkan ke Sari). Checklist normal akan langsung menyelesaikan laporan (lihat langkah 6).
7. UPDATE header: tgl_pelepasan dan user_pelepasan (hanya sekali), status_transaksi.
8. Notifikasi kerusakan.checklist ke admin. Checklist tidak lengkap membatalkan seluruh transaksi, termasuk pelepasan asset lama.
Hasil database
| Tabel | Perubahan |
|---|---|
| asset_data A12 (laptop lama) | status_asset terpakai → rusak; pemegang_asset karyawan → gudang; id_pemegang_asset KRY0009 → ''; ket_rusak = Laptop 14 inch: Ada garis pada layar; user_update = EMP-009 - Sari Contoh |
item pengganti …002 |
tgl_serah_terima = 2026-10-23 10:15:00; status_checklist belum_dicek → rusak; ket_rusak = Charger: Kabel charger terkelupas; tgl_checklist sama; kelengkapan_item = [{"id_item":"CMP001ITEM0201","nama_item":"Laptop 14 inch","jenis":"aset_utama","kondisi":"normal","ket_rusak":""},{"id_item":"CMP001ITEM0202","nama_item":"Charger","jenis":"kelengkapan","kondisi":"rusak","ket_rusak":"Kabel charger terkelupas"}] |
| header | status_transaksi menunggu_pengambilan → menunggu_review_checklist; tgl_pelepasan = 2026-10-23 10:15:00; user_pelepasan = EMP-009 - Sari Contoh |
| asset_data A20 | Tidak berubah (masih proses @gudang) |
asset_trx_log (1 baris)
| Kolom | Nilai |
|---|---|
| id_asset_trx_log | CMP00120261000001 |
| id_asset_data / jenis_log | A12 / rusak_karyawan |
| id_transaksi / nama_tabel_transaksi | CMP001202610001 / asset_trx_rusak_karyawan |
| kondisi_awal / kondisi_akhir | normal / rusak |
| posisi_awal / posisi_akhir | karyawan / gudang |
| pemegang_asset / id_pemegang / nama_pemegang | gudang / '' / '' |
| user_input | EMP-009 - Sari Contoh |
notif_data (2 baris ke admin): CMP00120261000004 (KRY0099) dan CMP00120261000005 (KRY0100), rute asset_admin_detail_kerusakan, "Sari Contoh telah mengirim checklist unit pengganti KRY06-202610001."
Diterima mobile (HTTP 200): status_transaksi = menunggu_review_checklist, status_label = "Menunggu Review Checklist", status_checklist = "rusak", message "Serah terima asset rusak berhasil dikonfirmasi.".
Langkah 5 — Admin memilih pengganti lain
Mobile: detail admin menampilkan aksi.ganti_pengganti = true. Admin memilih Pilih Pengganti Lain → LPT-0021, jadwal 24 Okt 2026 pukul 09:00 → AssetKerusakanAdminApi.gantiPengganti.
Dikirim
POST /asset/rusak-karyawan/CMP001202610001/ganti-pengganti
{ "id_asset_pengganti": "CMP00120260100021", "tgl_serah_terima": "2026-10-24",
"jam_serah_terima": "09:00", "keterangan_serah_terima": "" }
Diproses API (gantiPengganti)
1. Cek admin; header harus menunggu_review_checklist dan pengganti terbaru harus punya checklist rusak ("Seluruh item unit pengganti normal. Selesaikan laporan." bila normal).
2. Pengganti lama (A20) harus masih proses @gudang ("Status asset pengganti sudah berubah.").
3. Jadwal wajib; pengganti baru dipilih dengan lockReplacementCandidate: belum dipakai di laporan ini (A12 dan A20 dikecualikan), tersedia @gudang, kategori sama.
4. UPDATE A20 → rusak, gudang, ket_rusak = ringkasan checklist; INSERT asset_trx_log (gudang → gudang).
5. INSERT item pengganti baru (urutan_penggantian = 2, parent_id = pengganti sebelumnya) dan UPDATE A21 → proses.
6. UPDATE header → menunggu_pengambilan dengan jadwal baru.
7. Notifikasi kerusakan.pengganti_ulang ke karyawan.
Hasil database
| Tabel | Perubahan |
|---|---|
| asset_data A20 (pengganti 1) | status_asset proses → rusak; pemegang_asset gudang; ket_rusak = Charger: Kabel charger terkelupas |
| asset_data A21 | status_asset tersedia → proses |
| item baru (pengganti 2) | CMP001202610003: parent_id CMP001202610002, urutan_penggantian 2, id_asset_data A21, status_approval disetujui, status_checklist belum_dicek, user_input = ADM-001 - Siti Admin |
| header | status_transaksi menunggu_review_checklist → menunggu_pengambilan; tgl_serah_terima 2026-10-24; jam_serah_terima 09:00:00; tgl_update 2026-10-23 14:00:00; user_update = ADM-001 - Siti Admin |
asset_trx_log (1 baris baru): CMP00120261000002, A20, rusak_karyawan, kondisi normal → rusak, posisi gudang → gudang, user_input = ADM-001 - Siti Admin.
notif_data: CMP00120261000006 ke KRY0009, rute asset_detail_kerusakan, "Unit pengganti baru untuk KRY06-202610001 telah dijadwalkan."
Diterima mobile (HTTP 200): status_transaksi = menunggu_pengambilan, urutan_penggantian = 2, message "Unit pengganti baru berhasil dipilih.".
Langkah 6 — Sari menerima pengganti kedua dan laporan selesai
Mobile: banner Serah Terima Asset Rusak muncul lagi. Sari mengecek komponen unit pengganti kedua; semuanya Normal → Serah Terima & Kirim Checklist.
Dikirim
POST /asset/karyawan/rusak/CMP001202610001/pelepasan
{
"items": [
{ "id_item": "CMP001ITEM0301", "kondisi": "normal", "ket_rusak": "" },
{ "id_item": "CMP001ITEM0302", "kondisi": "normal", "ket_rusak": "" }
]
}
Diproses API (pelepasan, panggilan kedua)
1. Status menunggu_pengambilan; tgl_pelepasan sudah terisi, sehingga tidak ada pelepasan asset lama lagi; yang diproses hanya pengganti terbaru (…003). Bila tidak ada pengganti yang menunggu, 422 "Tidak ada unit pengganti yang perlu diserahterimakan.".
2. UPDATE tgl_serah_terima pengganti …003; applyChecklist → status_checklist = normal.
3. settleChecklist → completeReplacement: lockReservedReplacement (A21 harus masih proses @gudang), UPDATE A21 → terpakai, karyawan, id_pemegang_asset = KRY0009, id_asset_lokasi_m = NULL; INSERT asset_trx_log; header → selesai.
4. tgl_pelepasan dan user_pelepasan tidak ditimpa (hanya pertama kali).
5. Notifikasi kerusakan.selesai_otomatis ke admin (admin hanya diberi tahu; tidak ada langkah Selesaikan).
Hasil database
| Tabel | Perubahan |
|---|---|
item pengganti …003 |
tgl_serah_terima dan tgl_checklist = 2026-10-24 09:20:00; status_checklist belum_dicek → normal; ket_rusak ''; kelengkapan_item = hasil checklist (kondisi normal) |
| asset_data A21 | status_asset proses → terpakai; pemegang_asset gudang → karyawan; id_pemegang_asset '' → KRY0009; id_asset_lokasi_m → NULL |
| header | status_transaksi menunggu_pengambilan → selesai; tgl_update = 2026-10-24 09:20:00; user_update = EMP-009 - Sari Contoh |
asset_trx_log (1 baris baru): CMP00120261000003, A21, rusak_karyawan, kondisi_awal → normal, posisi gudang → karyawan, id_pemegang KRY0009, nama_pemegang Sari Contoh, user_input = EMP-009 - Sari Contoh.
notif_data: CMP00120261000007 (KRY0099) dan CMP00120261000008 (KRY0100), rute asset_admin_detail_kerusakan, "Unit pengganti KRY06-202610001 normal dan telah diterima Sari Contoh. Laporan selesai."
Diterima mobile (HTTP 200): status_approval = 3, status_transaksi = selesai, status_label = "Selesai", tab = "selesai", status_checklist = "normal". Laptop pengganti kini ada di Asset Saya Sari.
Kondisi akhir data
asset_trx_rusak_karyawan: CMP001202610001 / KRY06-202610001, status_approval = 3, status_transaksi = selesai, tgl_pelepasan = 2026-10-23 10:15:00.
asset_trx_rusak_karyawan_item
| id | parent_id | urutan | asset | status_checklist | Catatan |
|---|---|---|---|---|---|
| CMP001202610001 | NULL | 0 | A12 laptop lama | – | Item laporan, disetujui dan diganti |
| CMP001202610002 | CMP001202610001 | 1 | A20 | rusak | Charger rusak, dikembalikan sebagai rusak |
| CMP001202610003 | CMP001202610002 | 2 | A21 | normal | Pengganti final |
asset_data: A12 → rusak @gudang; A20 → rusak @gudang (ket_rusak = Charger: Kabel charger terkelupas); A21 → terpakai @KRY0009. asset_trx_log: 3 baris. notif_data: 8 baris. Histori seluruh percobaan penggantian tetap tersimpan sebagai item urutan ≥ 1.
Variasi
Semua item ditolak. Pada langkah 3, bila semua item ditolak (alasan wajib per item): status_approval = 2, status_transaksi = selesai, tanpa pengganti, jadwal tidak diminta, asset_data tidak berubah, notifikasi kerusakan.ditolak.
Tanpa pengganti. Bila item disetujui dengan status_diganti = 0, atau yang disetujui hanya kelengkapan: tidak ada pengganti. Pada serah terima pertama laporan langsung selesai (items checklist ditolak karena tidak ada unit pengganti: "Tidak ada unit pengganti yang perlu dicek."). Untuk unit utama, asset menjadi rusak @gudang; untuk kelengkapan saja, asset tetap dipegang karyawan dan hanya ket_rusak yang diisi (log: kondisi rusak, posisi karyawan → karyawan).
Checklist normal pada percobaan pertama. Pada langkah 4, bila semua komponen normal: pengganti pertama langsung terpakai @karyawan dan laporan selesai otomatis; langkah 5–6 tidak terjadi.
Alur lama (checklist terpisah). pelepasan tanpa items menghasilkan menunggu_checklist; karyawan lalu memanggil API-013 POST /asset/karyawan/rusak/{id}/checklist dengan format items yang sama. Untuk laporan lama yang menunggu review dengan checklist normal, admin memakai API-006 POST …/selesai.
Kasus gagal yang umum
| Situasi | Langkah | HTTP | Pesan | Perubahan database |
|---|---|---|---|---|
| Asset bukan milik karyawan / tidak ditemukan | 1 | 422 | Asset bukan milik karyawan atau tidak ditemukan. | Tidak ada |
Asset bukan terpakai (mis. pinjaman) |
1 | 422 | Hanya asset berstatus terpakai yang dapat dilaporkan rusak. | Tidak ada |
| Asset di flow lain | 1 | 422 | Asset sedang diproses pada laporan kerusakan lain. / …retur. / …upgrade. / …offboarding. / …pemeliharaan. | Tidak ada |
| Item bukan komponen asset | 1 | 422 | Item rusak harus berupa unit utama atau kelengkapan asset. | Tidak ada |
| Keterangan item kosong | 1 | 422 | Keterangan kerusakan setiap item wajib diisi. | Tidak ada |
| Review dua kali | 3 | 422 | Laporan kerusakan sudah direview. | Tidak ada |
| Item belum diputuskan | 3 | 422 | Seluruh item kerusakan wajib direview. | Tidak ada |
| Asset sudah tidak dipegang | 3, 4 | 422 | Asset sudah tidak dipegang oleh karyawan. | Tidak ada |
| Pengganti pada item yang tidak diganti | 3 | 422 | Asset pengganti hanya dipilih jika unit utama diganti. | Tidak ada |
| Pengganti belum dipilih | 3, 5 | 422 | Asset pengganti wajib dipilih. | Tidak ada |
| Pengganti tidak tersedia | 3, 5 | 422 | Aset sudah tidak tersedia. Silakan pilih unit lain. | Tidak ada |
| Pengganti beda kategori | 3, 5 | 422 | Kategori asset pengganti harus sama dengan asset yang rusak. | Tidak ada |
| Pengganti sudah pernah dipakai di laporan ini | 5 | 422 | Asset pengganti sudah pernah dipakai pada laporan ini. | Tidak ada |
| Jadwal kosong atau sebelum tanggal pengajuan | 3, 5 | 422 | Tanggal dan jam serah terima wajib diisi. / Tanggal serah terima tidak boleh sebelum tanggal pengajuan. | Tidak ada |
| Ubah jadwal setelah serah terima | – | 422 | Jadwal hanya dapat diubah sebelum serah terima dilakukan. | Tidak ada |
| Serah terima sebelum siap | 4, 6 | 422 | Laporan kerusakan belum siap diserahterimakan. | Tidak ada |
| Tidak ada pengganti yang menunggu | 6 | 422 | Tidak ada unit pengganti yang perlu diserahterimakan. | Tidak ada |
| Checklist tidak lengkap | 4, 6 | 422 | Seluruh item unit pengganti wajib dicek. (seluruh serah terima dibatalkan) | Tidak ada |
| Rusak tanpa keterangan | 4, 6 | 422 | Keterangan kerusakan wajib diisi. | Tidak ada |
| Tombol salah (checklist normal / rusak) | 5 | 422 | Seluruh item unit pengganti normal. Selesaikan laporan. / Unit pengganti masih memiliki item rusak. Pilih unit pengganti lain. | Tidak ada |
| Pengganti sudah berubah status | 5, 6 | 422 | Status asset pengganti sudah berubah. | Tidak ada |
| Pengguna bukan admin asset | 2, 3, 5 | 403 / 422 | Pengguna tidak memiliki akses admin asset. / Pengguna tidak terdaftar sebagai admin asset. | Tidak ada |
| Token kedaluwarsa | semua | 401 | Token telah expired. Mobile me-refresh token sekali lalu mengulang request. | Tidak ada |
Semua pelanggaran aturan dilempar sebagai InvalidArgumentException di dalam DB::transaction, sehingga seluruh perubahan request itu dibatalkan. Pesan tersedia dalam bahasa Indonesia dan Inggris mengikuti header locale.
Ringkasan siapa mengerjakan apa
| Tahap | Mobile | API | Database |
|---|---|---|---|
| Lapor | Pilih asset, jenis komponen, item, keterangan | Validasi komponen, cek flow lain, insert header dan item laporan | header, item (urutan 0), notif_data (asset tidak berubah) |
| Review | Setujui/tolak, Diganti, pilih pengganti, jadwal | Aturan pengganti sekategori, reservasi pengganti, tentukan status | item, item pengganti, asset_data (pengganti → proses), header, notif_data |
| Serah terima + checklist | Checklist komponen unit pengganti | Lepas asset lama, simpan checklist JSON, selesai otomatis bila normal | asset_data, item, header, asset_trx_log, notif_data |
| Pilih pengganti lain | Pilih unit baru + jadwal | Tarik pengganti rusak ke gudang, tambah item urutan + 1 | asset_data, item, header, asset_trx_log, notif_data |
| Tampilan | JSON → model → widget; objek aksi menentukan tombol |
rusakStatusMetadata, aksi, histori pengganti[] |
SELECT saja |
46Ringkasan Database Impact
| Event | INSERT | UPDATE | DELETE |
|---|---|---|---|
| Kirim laporan | header, item, notif | – | – |
| Review (ditolak semua) | notif | item, header | – |
| Review (ada disetujui) | item pengganti (opsional), notif | item, header, asset pengganti → proses | – |
| Ubah jadwal | notif | header | – |
| Serah terima | asset_trx_log (pertama), notif | asset dilaporkan (pertama), item pengganti, header | – |
| Checklist | notif | item pengganti, header | – |
| Selesaikan | asset_trx_log, notif | asset pengganti, header | – |
| Pilih pengganti lain | item pengganti, asset_trx_log, notif | asset pengganti lama → rusak, asset pengganti baru → proses, header | – |
47Checklist Implementasi
Database
- Kolom workflow & index (migration)
- Enum
jenis_logrusak_karyawan - Selaraskan DBML
- Migration CREATE TABLE baseline
Backend
- Lapor per komponen, review, jadwal, serah terima, checklist, penggantian berulang
- Cek flow lain saat lapor
- Test otomatis (10)
- Cek laporan kerusakan aktif di Offboarding (v1.1)
- Cek laporan kerusakan aktif di Retur, Pengembalian Peminjaman
- Pembatalan / kedaluwarsa laporan
- Aksi admin untuk serah terima
- Pindahkan pemegang pengganti saat serah terima
Mobile
- List, form, detail, review, jadwal, checklist, pengganti ulang
- Banner Asset Saya & panel admin
- Selaraskan aturan satu jenis per laporan dengan backend
Documentation
- Business Flow, DB, API, Mobile, Mapping, Manual Book, Testing
- Screenshot
48Changelog
| Version | Date | Changes |
|---|---|---|
| 1.6 | 2026-10-22 | Menambah §45.4 Walkthrough Lengkap dengan Contoh Data (lapor, review dengan pengganti sekategori, serah terima dengan checklist rusak, pilih pengganti lain, checklist normal dan selesai otomatis; variasi tolak, tanpa pengganti, checklist normal pertama, alur lama; kasus gagal). Sinkronisasi kode: tabel log ternyata asset_trx_log (id_asset_trx_log), bukan asset_log. |
| 1.5 | 2026-10-20 | Mobile: kartu Data Karyawan di detail admin Kerusakan kini menampilkan Jabatan, Cabang, Departemen (label Divisi diganti Departemen); model AssetKerusakanKaryawan membaca jabatan/nama_jabatan. API: AssetRusakKaryawan_m::getDetail menambah karyawan.jabatan (join master_jabatan); tes AssetRusakKaryawanTest meng-assert Staff IT. |
| 1.4 | 2026-10-12 | Mobile: stepper alur status (AssetAlurStepper.kerusakan) dan kartu timeline vertikal AssetKerusakanTimelineCard di detail karyawan dan admin (§26.3-26.4); checklist unit pengganti memakai AssetKondisiChecklist dengan pilihan Normal/Rusak berwarna. Field tgl_pelepasan kini dibaca mobile. Teks langkah di grup JSON alur. Tidak ada perubahan API. |
| 1.3 | 2026-10-12 | Alur dipangkas: checklist unit pengganti dikirim bersama serah terima (pelepasan menerima items, flag aksi.pelepasan_checklist), dan checklist normal menyelesaikan laporan otomatis tanpa langkah admin (notifikasi kerusakan.selesai_otomatis). Checklist rusak tetap menunggu admin (Pilih Pengganti Lain). Endpoint checklist dan selesai dipertahankan untuk aplikasi lama dan laporan yang sudah menunggu review. 15 test API. |
| 1.2 | 2026-10-12 | RISK-001 ditutup: Retur kini menolak asset dalam laporan kerusakan aktif (TC-21, edge case). Sinkronisasi dengan kode 12 Okt 2026: path file mobile mengikuti struktur folder baru (UI/Modul/Asset/<Fitur>/ berhuruf kapital, model di Repository/Model/Asset/). AssetKerusakanWidgets kini di Shared/Widgets/. |
| 1.1 | 2026-09-28 | Offboarding kini menolak asset dalam laporan kerusakan aktif (RISK-001 sebagian selesai, turun ke SEDANG). BR-002 & error 422 menambah blokir Pemeliharaan (PML01). TC-04, TC-21, edge case, dependency, checklist disesuaikan |
| 1.0 | 2026-09-28 | Initial documentation — disusun dari source lokal API & MOBILE |