← Semua dokumen

Asset Management · Dokumentasi Teknis & Manual Book

Disposal Asset (PML04)

Aset gudang yang rusak dan tidak layak dipertahankan dihapus dari daftar aktif oleh admin: keputusan dengan riwayat aset, pencatatan pelaksanaan menurut metode (lelang/jual, donasi, pemusnahan) dengan bukti wajib, lalu penyelesaian. Data tetap diarsipkan. Seluruh isi diturunkan dari source code API (Lumen) dan MOBILE (Flutter).

Kode
PML04
Modul
Pemeliharaan Aset
Versi
1.2 · 22 Okt 2026
Stack
Lumen 10 · Flutter
API
6 endpoint
PML04-YYYYMMNNN
Daftar isi

Ringkasan dalam 1 menit: tiga langkah disposal

Admin/HR saja, tanpa approval. Satu transaksi = satu aset.

Keputusan

Alasan, metode, nilai sisa, catatan setelah meninjau usia, harga perolehan, dan jumlah perbaikan/klaim. Aset → menunggu_disposal.

Pelaksanaan

Fisik di luar sistem. Catat pembeli+harga, penerima donasi, atau cara pemusnahan, plus tanggal dan bukti wajib.

Penyelesaian

Selesaikan Disposal → aset disposed, keluar dari daftar aktif; data tetap diarsipkan.

Siklus disposal

Status transaksi dan dampaknya ke asset.

Menunggu DisposalAdmin: Submit Keputusan

Aset rusak di gudang dipilih beserta metode.

asset → menunggu_disposal
Siap DiselesaikanAdmin: Catat Pelaksanaan

Field per metode, tanggal, bukti; dapat diperbarui.

tgl_pelaksanaan terisi
Dihapus (Disposed)Admin: Selesaikan Disposal

Dengan dialog konfirmasi; tidak dapat dibatalkan.

asset → disposed · asset_trx_log · notifikasi

Mulai dari sini sesuai peran

Lompat langsung ke bagian yang paling relevan.

Business Analyst / PM

Aturan bisnis, status, perbedaan dengan dokumen bisnis.

Backend Developer

Logika, dampak ke asset_data, kontrak API.

Mobile Developer

Bloc, route, layar, objek aksi.

QA / Tester

7 test API, 13 test mobile, skenario, edge case, risiko.

Technical Support

Pesan error, audit trail, notifikasi.

User / Admin Asset

Langkah operasional dan kondisi tombol.

Perlu perhatian

Temuan terpenting. Detail di §39 dan §41.

  • TINGGISQL manual belum dijalankan; jalankan setelah SQL PML01 gudang, PML03, PML02. RISK-001
  • SEDANGPML01/02/03 hanya mencatat nama tabel disposal; disposal tidak dibuat otomatis. INC-04
  • SEDANGTidak ada pembatalan disposal. INC-05
Gambaran & Bisnis

01Informasi Dokumen

Informasi Nilai
Nama Fitur Disposal Asset (penghapusan aset dari registri aktif)
Kode Fitur PML04 (nomor transaksi PML04-YYYYMMNNN)
Modul Asset Management — Pemeliharaan Aset
Backend Laravel Lumen ^10.0, PHP ^8.1, JWT, Query Builder
Database API/diagram-asset.dbml (tanda [REVISI PML04] / [NEW PML04]) + SQL manual Claude outputs/sql-pml04-disposal.sql. ⚠️ SQL harus dijalankan manual (belum dijalankan saat dokumen ditulis)
Mobile Flutter (professional_flutter_3_35), flutter_bloc, dio, image_picker
Web ⚠️ Belum ditemukan: tidak ada source web di workspace
Test otomatis API tests/Asset/AssetDisposalTest.php (7 test) · Mobile test/asset/asset_disposal_test.dart (13 test)
Versi dokumen 1.2 — 22 Oktober 2026
Dokumen terkait Perbaikan (PML02), Klaim Garansi (PML03), Pemeliharaan (PML01)

03Quick Overview

Aset gudang yang rusak dan tidak layak dipertahankan dihapus dari daftar aset aktif lewat tiga langkah. Fase 1: admin meninjau riwayat aset (usia, harga perolehan, jumlah perbaikan dan klaim garansi) lalu menyubmit keputusan: alasan, metode (lelang/jual, donasi, pemusnahan), nilai sisa, catatan; aset menjadi menunggu_disposal. Fase 2: disposal fisik terjadi di luar sistem; admin mencatat hasilnya (pembeli dan harga, penerima donasi, atau cara pemusnahan) beserta bukti wajib. Fase 3: admin menekan Selesaikan Disposal; aset menjadi disposed dan tidak muncul lagi di daftar aktif, sementara datanya tetap tersimpan sebagai arsip audit.

Aspek Ringkasan
Aktor Admin/HR saja (tanpa approval)
Status transaksi proses (menunggu disposal) → selesai (dihapus/disposed)
Status asset rusak → menunggu_disposal → disposed
Metode lelang_jual, donasi, pemusnahan
Endpoint 6 (semua admin)
Notifikasi 1 event (disposal.selesai) ke admin

04Ringkasan Fitur

No Fitur Aktor
1 Pilih aset gudang rusak dengan riwayatnya Admin
2 Submit keputusan disposal Admin
3 Catat pelaksanaan sesuai metode + bukti (dapat diperbarui) Admin
4 Selesaikan disposal (dengan konfirmasi) Admin
5 Daftar (Menunggu/Selesai) dan detail Admin
6 Kartu "perlu diproses" di beranda admin Admin

05Tujuan Fitur

5.1 Tujuan Bisnis (dari dokumen bisnis dan kode)

  • Penghapusan aset punya keputusan, alasan, dan bukti yang dapat diaudit.
  • Status perantara menunggu_disposal mencegah penghapusan tanpa bukti pelaksanaan.
  • Data historis aset tidak dihapus, hanya dikeluarkan dari daftar aktif.

5.2 Tujuan Sistem

  • Menjaga aset yang sedang di-disposal tidak bisa dipakai alur lain.
  • Memvalidasi field wajib per metode dan bukti.
  • Mencatat pelaksana, waktu, asset_trx_log, dan notifikasi penyelesaian.

06Aktor

Aktor Peran
Admin/HR (admin asset) Memutuskan, memilih metode, mencatat pelaksanaan, menyelesaikan
Sistem Mengunci status aset, memvalidasi, menulis log dan notifikasi

07Hak Akses

Seluruh endpoint hanya untuk admin asset (Asset_m::isAdmin). Non-admin menerima 403. Tidak ada endpoint karyawan/PIC.

08Terminologi

Istilah Arti
Disposal Penghapusan aset dari registri aktif
MENUNGGU DISPOSAL Keputusan sudah disubmit, penyelesaian belum dilakukan (status = proses, aset menunggu_disposal)
DIHAPUS (DISPOSED) Disposal selesai (status = selesai, aset disposed)
Nilai sisa Book value aset (opsional)
Bukti Satu foto/scan kwitansi, berita acara, atau foto pemusnahan

09Business Rules

BR-001 — Aset yang boleh di-disposal

Hanya pemegang_asset = gudang dan status_asset = rusak. Karena proses lain mengubah status (dalam_perbaikan, dalam_proses_klaim, menunggu serah terima), syarat "tidak ada proses aktif" terpenuhi otomatis. Tidak boleh masih dalam onboarding aktif. Pesan: "Hanya asset rusak di gudang yang dapat di-disposal."

BR-002 — Keputusan

alasan_disposal wajib; metode_disposal ∈ tiga nilai; nilai_sisa opsional dan tidak negatif; catatan opsional.

BR-003 — Status perantara

Setelah keputusan, aset menjadi menunggu_disposal dan keluar dari daftar pilihan aset gudang rusak (tidak bisa diajukan dua kali).

BR-004 — Pelaksanaan menurut metode

Metode Field wajib
lelang_jual pembeli, harga_jual, tgl_pelaksanaan, bukti
donasi penerima_donasi, tgl_pelaksanaan, bukti
pemusnahan metode_pemusnahan, tgl_pelaksanaan, bukti

Tanggal pelaksanaan tidak boleh setelah hari ini. Field milik metode lain dikosongkan.

BR-005 — Bukti wajib

Semua metode wajib bukti. Pembaruan tanpa bukti baru mempertahankan bukti lama; bila belum pernah ada bukti, ditolak.

BR-006 — Pelaksanaan dapat diperbarui

Selama status = proses, admin boleh memperbarui data pelaksanaan. Setelah selesai, tidak dapat diubah.

BR-007 — Penyelesaian

Hanya bila pelaksanaan sudah dicatat (tgl_pelaksanaan terisi) dan data masih lengkap sesuai metode. Aset harus masih di gudang dengan status menunggu_disposal. Hasil: aset disposed, transaksi selesai, asset_trx_log disposal_gudang.

BR-008 — Arsip, bukan hapus

Baris transaksi dan baris asset_data (status disposed) tetap ada. Daftar aset admin dan total ringkasan mengecualikan disposed bila filter status kosong; filter status disposed eksplisit tetap menampilkannya.

BR-009 — Penomoran

id = id_company + YYYYMM + 3 digit; no_trx = PML04-YYYYMMNNN; maksimum 999 per bulan per perusahaan.

BR-010 — Skema harus sudah diterapkan

skemaSiap() menjaga dashboard tetap berjalan sebelum SQL diterapkan.

10Business Flow

  1. Admin membuka Disposal → + → memilih satu aset gudang rusak dan meninjau riwayatnya.
  2. Admin mengisi alasan, metode, nilai sisa, catatan → Submit Keputusan. Aset menunggu_disposal.
  3. Disposal fisik dilakukan di luar sistem.
  4. Admin membuka detail → Catat Pelaksanaan (field sesuai metode + tanggal + bukti).
  5. Admin menekan Selesaikan Disposal dan mengonfirmasi.
  6. Aset disposed; notifikasi ringkasan dikirim ke admin.

11Flow Berdasarkan Role

11.1 Admin/HR

Seluruh alur di atas.

11.2 System

Validasi, kunci status, log, notifikasi, penyaringan daftar aktif.

12Flow Diagram

flowchart TD
    A[Aset gudang rusak] --> B[Admin tinjau riwayat]
    B --> C[Submit keputusan<br/>alasan, metode, nilai sisa]
    C --> D[status proses<br/>asset menunggu_disposal]
    D --> E[Disposal fisik di luar sistem]
    E --> F{Metode}
    F -- lelang_jual --> G[Pembeli, harga, tanggal, bukti]
    F -- donasi --> H[Penerima, tanggal, bukti]
    F -- pemusnahan --> I[Cara, tanggal, bukti]
    G --> J[Pelaksanaan tercatat]
    H --> J
    I --> J
    J --> K[Selesaikan Disposal]
    K --> L[status selesai<br/>asset disposed, data diarsipkan]

13Sequence Diagram

sequenceDiagram
    actor Admin
    participant App as Mobile
    participant API
    participant DB
    Admin->>App: Pilih aset + isi keputusan
    App->>API: POST asset/disposal
    API->>DB: insert trx (proses), asset menunggu_disposal
    Admin->>App: Catat pelaksanaan + foto bukti
    App->>API: POST asset/disposal/{id}/pelaksanaan
    API->>DB: simpan pelaksanaan + file_bukti
    Admin->>App: Selesaikan Disposal (konfirmasi)
    App->>API: POST asset/disposal/{id}/selesai
    API->>DB: trx selesai, asset disposed, asset_trx_log
    API-->>Admin: Notifikasi disposal.selesai

14Status Transaksi

status Kondisi Label di aplikasi Tab
proses tgl_pelaksanaan kosong Menunggu Disposal Menunggu
proses tgl_pelaksanaan terisi Siap Diselesaikan Menunggu
selesai — Dihapus (Disposed) Selesai

Tidak ada kolom fase terpisah; tahap pelaksanaan ditandai terisinya tgl_pelaksanaan.

15State Transition

stateDiagram-v2
    [*] --> MenungguDisposal: Submit keputusan
    MenungguDisposal --> SiapDiselesaikan: Catat pelaksanaan
    SiapDiselesaikan --> SiapDiselesaikan: Perbarui pelaksanaan
    SiapDiselesaikan --> Dihapus: Selesaikan Disposal
    Dihapus --> [*]
Database

16Struktur Database

Tabel Fungsi
asset_trx_disposal Satu baris per disposal (keputusan, pelaksanaan, penyelesaian)
asset_data Status aset (menunggu_disposal, disposed)
asset_trx_log Jejak disposal_gudang

Tabel lama asset_trx_disposal_item dan kolom approval dihapus (struktur lama berbasis approval, belum dipakai API).

17Relasi Database

erDiagram
    asset_trx_disposal }o--|| asset_data : "asset"
    asset_trx_disposal }o--o| asset_lokasi_m : "gudang asal"
    asset_data ||--o{ asset_trx_log : "jejak"

18Data Dictionary

18.1 asset_trx_disposal

Kolom Tipe Keterangan
id_asset_trx_disposal varchar(50) PK id_company+YYYYMM+3 digit
no_trx varchar(50) PML04-YYYYMMNNN
id_asset_data varchar(50) FK Aset
nama_asset, deskripsi_asset, kategori_asset varchar Snapshot saat keputusan
id_asset_lokasi_m_asal varchar(50) FK null Gudang asal
alasan_disposal varchar(255) Wajib
metode_disposal enum lelang_jual, donasi, pemusnahan
nilai_sisa decimal(18,2) null Book value, opsional
catatan text null Opsional
tgl_pelaksanaan date null NULL = pelaksanaan belum dicatat
pembeli, harga_jual varchar, decimal(18,2) Metode lelang/jual
penerima_donasi varchar(255) Metode donasi
metode_pemusnahan varchar(255) Metode pemusnahan
file_bukti varchar(255) Key object bukti (wajib semua metode)
tgl_selesai, user_selesai timestamp, varchar Klik Selesaikan Disposal
status enum proses/selesai Status transaksi
id_company, tgl_input, user_input, tgl_update, user_update Audit; tgl_input/user_input = keputusan

18.2 asset_trx_log (jenis_log = disposal_gudang)

Ditulis saat penyelesaian: posisi gudang → gudang, kondisi_awal/kondisi_akhir = kondisi aset, user_input = pelaksana.

19Database Index

Index Kolom Fungsi
atd_company_status_idx id_company, status, tgl_input, id Daftar per tab
atd_company_asset_status_idx id_company, id_asset_data, status Cek disposal aktif dan riwayat per aset
FK id_asset_data, id_asset_lokasi_m_asal Integritas
Backend & API

20Backend Architecture

Lapisan File
Route RouteAsset.php (disposal/*)
Controller Asset/Admin/AssetAdminDisposal_c.php
Model Models/Asset/AssetDisposal_m.php
Notifikasi Support/Asset/AssetNotification.php (disposal.selesai, placeholder {aset}, {metode})
Pendukung Asset_c::mutateAssetTrx (event null = tanpa notifikasi), Asset_c::uploadAssetImage + AssetImageStorage (object storage)
Dashboard AssetAdmin_m (disposal_perlu_proses, disposal_pending; pengecualian disposed)

21Backend Business Logic

21.1 Keputusan — store

Kunci perusahaan; validasi alasan, metode, nilai sisa; kunci aset (lockForUpdate), cek BR-001; nomor urut; insert transaksi (snapshot aset dan gudang asal); aset → menunggu_disposal.

21.2 Pelaksanaan — pelaksanaan

Hanya status = proses. pelaksanaanFields memvalidasi tanggal, bukti, dan field sesuai metode; kolom metode lain dikosongkan; harga_jual dinormalisasi.

21.3 Penyelesaian — selesai

Validasi ulang kelengkapan pelaksanaan, cek aset masih menunggu_disposal di gudang; aset → disposed; asset_trx_log; transaksi selesai dengan tgl_selesai/user_selesai.

21.4 Query baca

getPage (tab proses|selesai, paginasi limit+1), getDetail (aset + riwayat, keputusan, pelaksanaan, penyelesaian, aksi), getAdminOptions (aset gudang rusak + metode), getPendingForAdmin, countPendingForAdmin.

21.5 Riwayat aset

riwayat() menghitung usia (bulan) dari tgl_perolehan, harga_perolehan, serta jumlah baris di asset_trx_perbaikan_item dan asset_trx_garansi_item untuk aset tersebut (0 bila tabel belum ada). Biaya perbaikan tidak dicatat sistem.

22Dampak terhadap asset_data

Kejadian status_asset Kolom lain
Keputusan disubmit rusak → menunggu_disposal —
Disposal selesai → disposed tgl_update, user_update

Aset disposed tidak muncul di daftar aset admin bawaan dan tidak dihitung pada total_asset.

23API Documentation

Kode Method Path Fungsi
API-001 GET asset/disposal/options Aset gudang rusak + metode
API-002 GET asset/disposal Daftar
API-003 POST asset/disposal Submit keputusan
API-004 POST asset/disposal/{id}/pelaksanaan Catat/perbarui pelaksanaan
API-005 POST asset/disposal/{id}/selesai Selesaikan disposal
API-006 GET asset/disposal/{id} Detail

24Detail Setiap API

API-001 — Opsi

{"asset": [{"id_asset_data": "LP-1", "kode_asset": "KD-LP-1", "nama_asset": "Laptop Lama",
  "kategori_asset": "Laptop", "merek": "", "keterangan_rusak": "Mati total", "lokasi_gudang": "Gudang Utama",
  "riwayat": {"tgl_perolehan": "2019-10-01", "usia_bulan": 85, "harga_perolehan": 15000000,
              "jumlah_perbaikan": 2, "jumlah_klaim_garansi": 1}}],
 "metode": [{"value": "lelang_jual", "label": "Lelang / Jual"}]}

API-002 — Daftar

Query tab (proses|selesai), limit (1–50, default 20), offset. Respons {filters, records[], pagination}; record: id, no_trx, status, status_label, tab, id_asset_data, nama_asset, kategori_asset, metode_disposal, metode_label, alasan_disposal, pelaksanaan_tercatat, tgl_input.

API-003 — Keputusan

{"id_asset_data": "LP-1", "alasan_disposal": "Motherboard rusak total",
 "metode_disposal": "donasi", "nilai_sisa": 250000, "catatan": "Data sudah dihapus"}

Respons CREATED {id, no_trx, status, status_label, tab}.

API-004 — Pelaksanaan

{"tgl_pelaksanaan": "2026-10-09", "pembeli": "PT Pembeli", "harga_jual": 1500000,
 "penerima_donasi": "", "metode_pemusnahan": "", "file_bukti": "<base64 atau file multipart>"}

Hanya field milik metode transaksi yang dipakai. file_bukti kosong = bukti lama dipertahankan. Bukti disimpan di object storage dengan key <company>/asset/disposal/<id_karyawan>/<hex>.<ext>; kolom file_bukti menyimpan key tersebut.

API-005 — Selesai

Tanpa body. Respons {id, no_trx, status: "selesai", status_label: "Dihapus (Disposed)"}.

API-006 — Detail

Grup asset (dengan riwayat), keputusan, pelaksanaan (tercatat, file_bukti_url), penyelesaian, dan aksi: {pelaksanaan, selesai}.

Mobile

25Mobile Architecture

Lapisan File
Model lib/Repository/Model/Asset/mAssetDisposal.dart
API client lib/Repository/Service/assetDisposalApi.dart
Bloc lib/Bloc/Asset/AssetDisposalBloc.dart
UI lib/UI/Modul/Asset/Pemeliharaan/Disposal/* (termasuk AssetDisposalProsesWidgets; pratinjau foto layar penuh memakai Pemeliharaan/AssetFotoPreview.dart)
Teks grup disposal di assets/{id,en}/asset.json (81 kunci)
Navigasi NavigatorBloc (NavigateToAssetAdminDisposal, …DetailDisposal, …BuatDisposal), router.dart

26Mobile Screen

26.1 Daftar — HalamanAssetDisposal

Tab Menunggu/Selesai, AssetDisposalRecordCard, tombol +.

26.2 Buat — HalamanBuatDisposal

Pilih satu aset (radio); aset terpilih menampilkan kartu riwayat; Lanjut membuka sheet keputusan (alasan, metode chip, nilai sisa, catatan).

26.3 Detail — HalamanDetailAssetDisposal

Kartu status, petunjuk langkah berikutnya, aset + riwayat, keputusan, pelaksanaan (dengan foto bukti), penyelesaian. Tombol bawah: Catat/Ubah Data Pelaksanaan dan Selesaikan Disposal (dialog konfirmasi).

26.4 Sheet pelaksanaan

Field mengikuti metode, picker tanggal (tidak boleh melewati hari ini), foto bukti dari kamera/galeri.

26.5 Entry point

Beranda admin: menu Disposal dan kartu "perlu diproses" (langkah berikutnya: Catat pelaksanaan / Selesaikan disposal). Notifikasi membuka asset_admin_detail_disposal.

27Mobile → API

Aksi UI Method Endpoint
Muat daftar GET asset/disposal?tab=
Muat opsi GET asset/disposal/options
Muat detail GET asset/disposal/{id}
Submit keputusan POST asset/disposal
Simpan pelaksanaan POST asset/disposal/{id}/pelaksanaan
Selesaikan POST asset/disposal/{id}/selesai

28API → Mobile

Respons dipetakan ke AssetDisposalRecord, Page, Options. Daftar mengirim data datar, detail mengirim grup; model menangani keduanya. 422 tampil snackbar warning, lainnya error; sukses menutup halaman dengan pesan dan memuat ulang daftar/ringkasan.

29Mapping Mobile → API → Database

Field UI Field API Kolom DB
Aset terpilih id_asset_data id_asset_data
Alasan alasan_disposal alasan_disposal
Metode metode_disposal metode_disposal
Nilai sisa nilai_sisa nilai_sisa
Tanggal pelaksanaan tgl_pelaksanaan tgl_pelaksanaan
Pembeli / Harga jual pembeli / harga_jual pembeli / harga_jual
Penerima donasi penerima_donasi penerima_donasi
Cara pemusnahan metode_pemusnahan metode_pemusnahan
Foto bukti file_bukti file_bukti (key object)

30Mapping Database → API → Mobile

Kolom DB Field API Tampil di
status, tgl_pelaksanaan status, pelaksanaan_tercatat Badge fase
file_bukti pelaksanaan.file_bukti_url Gambar bukti di detail
user_selesai, tgl_selesai penyelesaian.* Bagian penyelesaian
harga_perolehan, tgl_perolehan asset.riwayat.* Kartu riwayat
Validasi, Error & Keamanan

31Validation

31.1 Mobile

Alasan dan metode wajib; nilai sisa angka tidak negatif; pada pelaksanaan: field metode, tanggal, dan bukti wajib.

31.2 Backend

Aturan Laravel: id_asset_data wajib, alasan_disposal wajib ≤255, metode_disposal ∈ tiga nilai, nilai_sisa numerik ≥ 0, tgl_pelaksanaan Y-m-d, harga_jual numerik ≥ 0. Aturan bisnis di model (§9).

31.3 Database

Enum metode_disposal, status; FK aset dan gudang.

32Error Handling

Kondisi Kode Contoh pesan
Validasi request 422 "Alasan disposal wajib diisi."
Aturan bisnis 422 BUSINESS_RULE_VIOLATION "Data pelaksanaan disposal belum dicatat."
Bukan admin 403 "Pengguna tidak memiliki akses admin asset."
Tidak ditemukan 404 "Disposal tidak ditemukan."
Sistem 500 SYSTEM_ERROR Pesan umum

33Audit Trail

user_input/tgl_input = keputusan, user_update/tgl_update = pelaksanaan terakhir, user_selesai/tgl_selesai = penyelesaian (format nik - nama). asset_trx_log disposal_gudang saat selesai.

34Notification

Event Penerima Isi Rute mobile
disposal.selesai Seluruh admin asset "Disposal {no_trx} selesai: {aset} ({metode}) telah dihapus dari daftar asset aktif." asset_admin_detail_disposal

Pencatatan pelaksanaan tidak mengirim notifikasi. Notifikasi dikirim setelah transaksi commit.

35Security

JWT; semua endpoint admin-only; filter id_company; transaksi + lockForUpdate; bukti diunggah ke bucket MinIO privat lewat Asset_c::uploadAssetImage (AssetImageStorage): hanya JPEG/PNG/WebP valid, maks 5 MB dan 25 megapiksel; key memuat id_company dan id_karyawan dari JWT; URL bukti berupa presigned URL berumur singkat (lihat dokumentasi-minio-object-storage.md).

Manual Book

36Manual Book User/Admin

A. Membuat keputusan disposal

  1. Beranda Asset → Disposal → tombol +.
  2. Pilih aset; tinjau usia, harga perolehan, jumlah perbaikan dan klaim.
  3. Lanjut → isi alasan, pilih metode, (opsional) nilai sisa dan catatan → Submit Keputusan.

B. Mencatat pelaksanaan

  1. Setelah disposal fisik selesai, buka transaksi di tab Menunggu.
  2. Catat Pelaksanaan: isi field sesuai metode, tanggal, dan foto bukti → Simpan.
  3. Data dapat diubah lagi lewat Ubah Data Pelaksanaan sebelum diselesaikan.

C. Menyelesaikan disposal

Selesaikan Disposal → baca konfirmasi → konfirmasi. Aset berstatus DIHAPUS dan hilang dari daftar aktif.

37Kondisi Button

Tombol Syarat
Catat / Ubah Data Pelaksanaan status = proses (aksi.pelaksanaan)
Selesaikan Disposal status = proses dan pelaksanaan tercatat (aksi.selesai)
Lanjut (halaman buat) Satu aset dipilih
QA & Risiko

38Testing Scenario

No Skenario Hasil
T-01 Aset karyawan / tersedia / tidak ada Ditolak
T-02 Alasan kosong, metode salah, nilai sisa negatif Ditolak
T-03 Keputusan valid PML04-…, aset menunggu_disposal, hilang dari opsi
T-04 Pelaksanaan tanpa pembeli/harga/penerima/cara/bukti/tanggal Ditolak sesuai metode
T-05 Tanggal pelaksanaan besok Ditolak
T-06 Perbarui tanpa bukti baru Bukti lama dipertahankan
T-07 Field metode lain ikut dikirim Dikosongkan
T-08 Selesai sebelum pelaksanaan Ditolak
T-09 Selesai valid Aset disposed, asset_trx_log, transaksi selesai
T-10 Ubah/selesai ulang setelah selesai Ditolak
T-11 Status aset berubah di luar alur Ditolak
T-12 Alur penuh via route; non-admin 200; 403

Cakupan otomatis: API 7 test, mobile 13 test (teks id/en, parsing, payload, bloc, detail 320/400 px, konfirmasi selesai, validasi sheet, alur buat).

39Temuan Ketidaksesuaian

ID Temuan
INC-01 Dokumen bisnis tidak menyebut batasan "hanya aset gudang"; implementasi menegakkannya
INC-02 Dokumen bisnis menyebut tahap pelaksanaan per metode sebagai langkah; implementasi memakai satu tabel dengan kolom per metode dan penanda tgl_pelaksanaan
INC-03 Dokumen menyebut "memindahkan data ke arsip"; implementasi mengarsipkan lewat status disposed (tanpa tabel arsip terpisah)
INC-04 PML01 (hasil 5), PML02 (tidak bisa diperbaiki/unit lama diganti), dan PML03 (ditolak) hanya mencatat nama tabel asset_trx_disposal; transaksi disposal tidak dibuat otomatis
INC-05 Tidak ada pembatalan disposal dari menunggu_disposal
INC-06 Bukti hanya gambar; dokumen PDF belum didukung

40Edge Case

  • Dua admin memilih aset yang sama: yang kedua gagal karena aset sudah menunggu_disposal.
  • Status aset berubah antara keputusan dan penyelesaian: penyelesaian ditolak.
  • Harga jual berformat koma (1500,50): dinormalisasi di mobile sebelum dikirim.
  • Tabel PML02/PML03 belum ada: riwayat menampilkan 0 tanpa error.

41Potential Bug / Technical Risk

RISK-001 — Skema dari SQL manual (TINGGI)

Endpoint gagal bila sql-pml04-disposal.sql belum dijalankan. Jalankan setelah SQL PML01 gudang, PML03, dan PML02 (blok enum menulis ulang daftar penuh).

RISK-002 — Tidak ada pembatalan (SEDANG)

Keputusan yang salah mengunci aset di menunggu_disposal; perbaikan membutuhkan intervensi manual di database.

RISK-003 — Penyelesaian tidak dapat dibatalkan (SEDANG)

Dialog konfirmasi memitigasi di UI; di API tidak ada rollback.

RISK-004 — Bukti lama di disk lokal (RENDAH)

Bukti baru disimpan di object storage. Bukti lama di UPLOAD_DIR tetap terbaca lewat fallback URL lokal. Object lama tidak dihapus saat bukti diganti; object baru yang yatim dibersihkan otomatis bila transaksi gagal.

RISK-005 — Kapasitas penomoran 999/bulan (RENDAH)

Batas 999 transaksi per bulan per perusahaan.

Referensi Developer

42Dependency

Asset_m/Asset_c, AssetImageStorage, AssetNotification, AssetPemeliharaanKaryawan_m (format tanggal), tabel asset_data, asset_kategori_m, asset_lokasi_m, asset_trx_log; asset_trx_perbaikan_item dan asset_trx_garansi_item (riwayat, opsional).

43Source Code Reference

Area Lokasi
Model API/app/Models/Asset/AssetDisposal_m.php
Controller API/app/Http/Controllers/Asset/Admin/AssetAdminDisposal_c.php
Route API/routes/modules/asset/RouteAsset.php
SQL Claude outputs/sql-pml04-disposal.sql
Test API API/tests/Asset/AssetDisposalTest.php
Mobile UI MOBILE/lib/UI/Modul/Asset/Pemeliharaan/Disposal/
Test mobile MOBILE/test/asset/asset_disposal_test.dart

44Developer Notes

  • Desain disederhanakan dari struktur header+item: satu aset per transaksi, satu tabel.
  • mutateAssetTrx menerima event null untuk langkah tanpa notifikasi.
  • pelaksanaanFields dipakai ulang oleh selesai untuk memastikan data tetap lengkap.
  • Teks UI memakai AssetDisposalText.t(key); kunci dinamis: fase_*, hint_*, metode_*, bukti_*, tgl_pelaksanaan_*, aksi_*.

45End-to-End Traceability

Kebutuhan Rule API Mobile DB
Hanya aset rusak di gudang BR-001 API-003 Halaman buat asset_data.status_asset, pemegang_asset
Bukti wajib BR-005 API-004 Sheet pelaksanaan file_bukti
Status perantara BR-003 API-003 Badge Menunggu asset_data.status_asset = menunggu_disposal
Arsip bukan hapus BR-008 API-005 Tab Selesai status = selesai, disposed

45.4 Walkthrough Lengkap dengan Contoh Data

Bagian ini mengikuti satu disposal dari keputusan sampai asset dihapus dari daftar aktif, langkah demi langkah: apa yang dilakukan admin 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 (AssetDisposal_m, AssetAdminDisposal_c, AssetNotification). Disposal hanya dilakukan admin (tanpa approval) dan tidak ada PIC.

Skenario: Laptop lama di gudang rusak total dan tidak layak dipertahankan. Admin meninjau riwayatnya lalu memutuskan disposal dengan metode Lelang / Jual. Setelah laptop terjual, admin mencatat pelaksanaan (pembeli, harga, tanggal, bukti), memperbaruinya satu kali karena harga terkoreksi, lalu menyelesaikan disposal.

Langkah Pelaku Aksi Endpoint
0 Admin Memuat asset gudang rusak beserta riwayat API-001 GET /asset/disposal/options
1 Admin Submit Keputusan API-003 POST /asset/disposal
2 Admin Catat Pelaksanaan + bukti API-004 POST /asset/disposal/{id}/pelaksanaan
3 Admin Perbarui Pelaksanaan API-004
4 Admin Selesaikan Disposal API-005 POST /asset/disposal/{id}/selesai

Data awal

Company CMP001. Keputusan diambil 22 Oktober 2026, periode ID 202610. Belum ada transaksi disposal, log, atau notifikasi pada periode ini.

asset_data A70: CMP00120260100070 (LPT-0070), Laptop Lama, kategori Laptop, pemegang_asset = gudang, status_asset = rusak, kondisi_awal = rusak, ket_rusak = Mati total, id_asset_lokasi_m = CMP001202601001 (Gudang Pusat), tgl_perolehan = 2019-10-01, harga_perolehan = 15000000. Asset ini pernah 2 kali masuk Perbaikan dan 1 kali Klaim Garansi.

Admin: KRY0099 (ADM-001, Siti Admin) sebagai pelaksana, KRY0100 (ADM-002, Rudi Admin).

Penomoran: id_company + YYYYMM + 3 digit, no_trx = PML04-YYYYMMNNN; log dan notifikasi 5 digit. Satu transaksi = satu asset; tidak ada tabel item terpisah dan tidak ada kolom fase: tahap pelaksanaan ditandai terisinya tgl_pelaksanaan.


Langkah 0 — Admin memuat opsi dan riwayat

Mobile: Pemeliharaan (admin) → Disposal → buat → AssetDisposalApi memuat opsi.

Dikirim

HTTP
GET /asset/disposal/options
Authorization: Bearer <access_token_admin>

Diproses API (AssetDisposal_m::getAdminOptions): asset gudang berstatus rusak (asset yang sudah menunggu_disposal tidak muncul lagi), masing-masing dengan riwayat: usia dalam bulan dari tgl_perolehan, harga_perolehan, jumlah baris di asset_trx_perbaikan_item, dan jumlah baris di asset_trx_garansi_item (0 bila tabel belum ada). Biaya perbaikan tidak dicatat sistem. Ditambah daftar metode.

Database: hanya SELECT.

Diterima mobile (ringkas)

JSON
{ "asset": [ { "id_asset_data": "CMP00120260100070", "kode_asset": "LPT-0070", "nama_asset": "Laptop Lama",
    "kategori_asset": "Laptop", "keterangan_rusak": "Mati total", "lokasi_gudang": "Gudang Pusat",
    "riwayat": { "tgl_perolehan": "2019-10-01", "usia_bulan": 84, "harga_perolehan": 15000000,
                 "jumlah_perbaikan": 2, "jumlah_klaim_garansi": 1 } } ],
  "metode": [ { "value": "lelang_jual", "label": "Lelang / Jual" }, { "value": "donasi", "label": "Donasi" },
              { "value": "pemusnahan", "label": "Pemusnahan" } ] }

Langkah 1 — Admin menyubmit keputusan

Mobile: admin memilih laptop, meninjau riwayat, mengisi alasan, memilih metode, nilai sisa, dan catatan → Submit → AssetDisposalApi.store.

Dikirim

HTTP
POST /asset/disposal
JSON
{ "id_asset_data": "CMP00120260100070", "alasan_disposal": "Motherboard rusak total",
  "metode_disposal": "lelang_jual", "nilai_sisa": 250000, "catatan": "Data sudah dihapus" }

Diproses API (AssetAdminDisposal_c::storeDisposal → store, satu DB::transaction) 1. Validasi: alasan_disposal wajib, metode_disposal ∈ lelang_jual/donasi/pemusnahan; nilai_sisa opsional dan tidak negatif ("Nilai sisa harus berupa angka tidak negatif."). 2. lockCompany; cek admin; asset dikunci FOR UPDATE dan harus tepat satu ("Asset tidak ditemukan."). 3. Asset harus gudang dan rusak ("Hanya asset rusak di gudang yang dapat di-disposal."); tidak ada di onboarding aktif. Karena proses lain mengubah status (dalam_perbaikan, dalam_proses_klaim, menunggu serah terima), syarat "tidak ada proses aktif" terpenuhi otomatis. 4. Generate ID: CMP001202610001, no_trx = PML04-202610001. 5. INSERT transaksi (snapshot asset dan gudang asal, status = proses, tgl_pelaksanaan NULL) dan UPDATE asset_data → menunggu_disposal. 6. Tidak ada notifikasi pada tahap ini (event null).

Hasil database

asset_trx_disposal

Kolom Nilai
id_asset_trx_disposal / no_trx CMP001202610001 / PML04-202610001
id_asset_data / nama_asset / deskripsi_asset / kategori_asset A70 / Laptop Lama / '' / Laptop
id_asset_lokasi_m_asal CMP001202601001
alasan_disposal Motherboard rusak total
metode_disposal lelang_jual
nilai_sisa 250000.00
catatan Data sudah dihapus
tgl_pelaksanaan / pembeli / harga_jual / penerima_donasi / metode_pemusnahan / file_bukti NULL / '' / NULL / '' / '' / ''
status proses
tgl_selesai / user_selesai NULL / ''
tgl_input / user_input 2026-10-22 09:00:00 / ADM-001 - Siti Admin

asset_data A70: status_asset rusak → menunggu_disposal, tgl_update = 09:00:00, user_update = ADM-001 - Siti Admin.

Diterima mobile (HTTP 201)

JSON
{ "code": "CREATED", "message": "…",
  "data": { "id": "CMP001202610001", "no_trx": "PML04-202610001", "status": "proses",
            "status_label": "Menunggu Disposal", "tab": "proses" } }

Asset kini hilang dari opsi sehingga tidak dapat diajukan dua kali.

Langkah 2 — Admin mencatat pelaksanaan

Mobile: detail disposal (aksi.pelaksanaan = true) → form pelaksanaan sesuai metode Lelang / Jual: tanggal, pembeli, harga jual, dan foto bukti (kamera atau galeri) → Simpan.

Dikirim (multipart karena ada file)

HTTP
POST /asset/disposal/CMP001202610001/pelaksanaan
JSON
{ "tgl_pelaksanaan": "2026-10-23", "pembeli": "PT Pembeli Sejahtera", "harga_jual": 1500000,
  "penerima_donasi": "", "metode_pemusnahan": "", "file_bukti": "<file multipart atau base64>" }

Diproses API (buktiPath lalu pelaksanaan) 1. Validasi controller: tgl_pelaksanaan wajib Y-m-d; harga_jual numerik ≥ 0. 2. prepareImageUpload memastikan transaksi masih proses sebelum file diunggah ("Disposal sudah selesai dan tidak dapat diubah."). File diunggah dengan key CMP001/asset/disposal/<id_karyawan>/<hex>.<ext>; hanya key yang disimpan. File tidak valid → "File bukti tidak valid.". 3. pelaksanaanFields menerapkan aturan menurut metode transaksi (bukan menurut input): tanggal wajib dan tidak boleh setelah hari ini; bukti wajib (bila tidak mengunggah baru, bukti lama dipertahankan; bila belum pernah ada, ditolak). Untuk lelang_jual: pembeli dan harga_jual wajib. Field milik metode lain dikosongkan. 4. UPDATE transaksi dengan kolom pelaksanaan, tgl_update, user_update. asset_data belum berubah. Tidak ada notifikasi.

Hasil database

Kolom (asset_trx_disposal) Sebelum Sesudah
tgl_pelaksanaan NULL 2026-10-23
pembeli '' PT Pembeli Sejahtera
harga_jual NULL 1500000.00
penerima_donasi / metode_pemusnahan '' / '' '' / ''
file_bukti '' CMP001/asset/disposal/KRY0099/9f3a1c2e.jpg
status proses proses
tgl_update / user_update NULL / '' 2026-10-23 10:00:00 / ADM-001 - Siti Admin

Diterima mobile (HTTP 200): status = proses, status_label = "Siap Diselesaikan" (karena tgl_pelaksanaan sudah terisi), tab = "proses", message "Data pelaksanaan disposal berhasil disimpan.". Detail menampilkan pelaksanaan.tercatat = true dan file_bukti_url.

Langkah 3 — Admin memperbarui pelaksanaan

Pelaksanaan boleh diperbarui selama status = proses. Admin mengoreksi harga jual.

Dikirim: POST /asset/disposal/CMP001202610001/pelaksanaan dengan harga_jual = 1750000, tanpa file_bukti baru dan tanpa mengulang field lain.

Diproses API: pelaksanaanFields memakai nilai lama untuk field yang tidak dikirim (pakai(key, nilai lama)), sehingga pembeli dan tanggal tetap; bukti lama dipertahankan karena file_bukti kosong. Hasil database: harga_jual 1500000.00 → 1750000.00, tgl_update = 2026-10-23 10:30:00; kolom lain tetap.

Langkah 4 — Admin menyelesaikan disposal

Mobile: Selesaikan Disposal (dialog konfirmasi) → AssetDisposalApi.selesai.

Dikirim

HTTP
POST /asset/disposal/CMP001202610001/selesai

Tanpa body.

Diproses API (selesai) 1. Transaksi harus proses ("Disposal sudah selesai."). 2. tgl_pelaksanaan harus terisi ("Data pelaksanaan disposal belum dicatat."); pelaksanaanFields dijalankan ulang untuk memastikan data masih lengkap menurut metode. 3. Asset dikunci dan harus masih gudang dengan status menunggu_disposal ("Status asset sudah berubah atau tidak lagi berada di gudang."). 4. UPDATE asset_data → disposed; INSERT asset_trx_log (jenis_log = disposal_gudang, posisi gudang → gudang, kondisi tidak berubah). 5. UPDATE transaksi: status = selesai, tgl_selesai, user_selesai, tgl_update, user_update. 6. Notifikasi disposal.selesai ke seluruh admin.

Hasil database

Tabel Perubahan
asset_data A70 status_asset menunggu_disposal → disposed; user_update = ADM-001 - Siti Admin
asset_trx_disposal status proses → selesai; tgl_selesai = 2026-10-23 11:00:00; user_selesai = ADM-001 - Siti Admin

asset_trx_log (1 baris)

Kolom Nilai
id_asset_trx_log CMP00120261000001
id_asset_data / jenis_log A70 / disposal_gudang
id_transaksi / nama_tabel_transaksi CMP001202610001 / asset_trx_disposal
kondisi_awal / kondisi_akhir rusak / rusak
posisi_awal / posisi_akhir gudang / gudang
id_pemegang / nama_pemegang '' / ''
user_input ADM-001 - Siti Admin

notif_data (2 baris, satu per admin)

id_notif id_karyawan id_ref rute ket_notif_id
CMP00120261000001 KRY0099 CMP001202610001 asset_admin_detail_disposal Disposal PML04-202610001 selesai: Laptop Lama (Lelang / Jual) telah dihapus dari daftar asset aktif.
CMP00120261000002 KRY0100 CMP001202610001 asset_admin_detail_disposal Disposal PML04-202610001 selesai: Laptop Lama (Lelang / Jual) telah dihapus dari daftar asset aktif.

Diterima mobile (HTTP 200)

JSON
{ "code": "UPDATED", "message": "Disposal berhasil diselesaikan.",
  "data": { "id": "CMP001202610001", "no_trx": "PML04-202610001", "status": "selesai",
            "status_label": "Dihapus (Disposed)", "tab": "selesai" } }

Kondisi akhir data

asset_trx_disposal: CMP001202610001 / PML04-202610001, status = selesai, metode_disposal = lelang_jual, harga_jual = 1750000.00, tgl_pelaksanaan = 2026-10-23, bukti tersimpan sebagai key object storage.

asset_data A70: status_asset = disposed. Baris asset tidak dihapus (arsip): daftar asset admin dan total ringkasan mengecualikan disposed bila filter status kosong, tetapi filter status disposed eksplisit tetap menampilkannya. asset_trx_log: 1 baris. notif_data: 2 baris.


Variasi

Donasi. metode_disposal = donasi: pelaksanaan wajib penerima_donasi ("Penerima donasi wajib diisi."), tanggal, dan bukti; pembeli, harga_jual, dan metode_pemusnahan dikosongkan. Notifikasi menyebut "(Donasi)".

Pemusnahan. metode_disposal = pemusnahan: pelaksanaan wajib metode_pemusnahan ("Metode pemusnahan wajib diisi."), tanggal, dan bukti; field metode lain dikosongkan. Notifikasi menyebut "(Pemusnahan)".

Disposal sebagai tindak lanjut modul lain. Asset rusak di gudang yang berasal dari Pemeliharaan (hasil 4–5), Perbaikan ("diganti unit baru" atau "tidak bisa diperbaiki"), atau Klaim Garansi (ditolak dengan tindak lanjut disposal) hanya ditandai nama_tabel_tindak_lanjut = asset_trx_disposal; transaksi Disposal tetap harus dibuat manual lewat langkah 1.


Kasus gagal yang umum

Situasi Langkah HTTP Pesan Perubahan database
Asset belum dipilih / tidak ditemukan 1 422 Asset wajib dipilih. / Asset tidak ditemukan. Tidak ada
Alasan kosong 1 422 Alasan disposal wajib diisi. Tidak ada
Metode kosong atau tidak dikenal 1 422 Metode disposal wajib dipilih. / Metode disposal tidak valid. Tidak ada
Nilai sisa negatif atau bukan angka 1 422 Nilai sisa harus berupa angka tidak negatif. Tidak ada
Asset bukan rusak di gudang (mis. sudah menunggu_disposal) 1 422 Hanya asset rusak di gudang yang dapat di-disposal. Tidak ada
Asset di onboarding aktif 1 422 Asset sedang diproses pada onboarding. Tidak ada
Tanggal pelaksanaan kosong 2 422 Tanggal pelaksanaan wajib diisi. Tidak ada
Tanggal pelaksanaan setelah hari ini 2 422 Tanggal pelaksanaan tidak boleh setelah hari ini. Tidak ada
Bukti belum pernah diunggah 2 422 Bukti pelaksanaan wajib diunggah. Tidak ada
File bukti tidak valid 2 422 File bukti tidak valid. Tidak ada (file tidak tersimpan)
Pembeli atau harga jual kosong (lelang/jual) 2 422 Nama pembeli wajib diisi. / Harga jual wajib diisi. Tidak ada
Penerima donasi kosong (donasi) 2 422 Penerima donasi wajib diisi. Tidak ada
Metode pemusnahan kosong (pemusnahan) 2 422 Metode pemusnahan wajib diisi. Tidak ada
Mengubah pelaksanaan setelah selesai 2, 3 422 Disposal sudah selesai dan tidak dapat diubah. Tidak ada
Selesaikan sebelum pelaksanaan dicatat 4 422 Data pelaksanaan disposal belum dicatat. Tidak ada
Selesaikan dua kali 4 422 Disposal sudah selesai. Tidak ada
Asset sudah berubah status 4 422 Status asset sudah berubah atau tidak lagi berada di gudang. Tidak ada
Disposal tidak ditemukan 2–4 422 Disposal tidak ditemukan. Tidak ada
Pengguna bukan admin asset semua 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
Opsi Daftar asset gudang rusak dengan riwayat Hitung usia, jumlah perbaikan dan klaim SELECT saja
Keputusan Alasan, metode, nilai sisa, catatan Validasi asset gudang rusak, snapshot, kunci status asset_trx_disposal, asset_data → menunggu_disposal
Pelaksanaan Form sesuai metode dan foto bukti Validasi menurut metode, unggah bukti setelah validasi asset_trx_disposal (kolom pelaksanaan)
Selesai Dialog konfirmasi Validasi ulang, asset → disposed, log, notifikasi asset_data, asset_trx_disposal, asset_trx_log, notif_data
Tampilan JSON → model → widget; objek aksi statusMeta (Menunggu Disposal, Siap Diselesaikan, Dihapus) SELECT saja

46Ringkasan Database Impact

Tabel asset_trx_disposal dibuat ulang (tabel lama asset_trx_disposal dan _item di-drop bila kosong). asset_data.status_asset +menunggu_disposal; asset_trx_log.jenis_log +disposal_gudang.

47Checklist Implementasi

Database

  • DBML diperbarui
  • SQL manual + guard + rollback
  • SQL dijalankan di setiap environment

Backend

  • Model, controller, route, notifikasi, pengecualian aset disposed
  • Test otomatis

Mobile

  • Daftar, buat, detail, sheet keputusan dan pelaksanaan
  • Kartu beranda admin, rute notifikasi, teks id/en
  • Test otomatis

Documentation

  • Dokumen ini

48Changelog

Versi Tanggal Perubahan
1.0 8 Okt 2026 Dokumen awal PML04
1.1 12 Okt 2026 Sinkronisasi dengan kode: bukti kini disimpan di object storage MinIO (RISK-004 diturunkan ke RENDAH); path UI/model mobile mengikuti struktur folder baru; berkas AssetDisposalProsesWidgets dan AssetFotoPreview dicatat. Perbaikan 422 vs 500 pada controller Asset (import InvalidArgumentException/Throwable) tidak mengubah kontrak API
1.2 22 Okt 2026 Menambah §45.4 Walkthrough Lengkap dengan Contoh Data (keputusan dengan riwayat asset, pelaksanaan lelang/jual dengan bukti, pembaruan pelaksanaan, penyelesaian dan notifikasi; variasi donasi, pemusnahan, disposal sebagai tindak lanjut modul lain; kasus gagal). Sinkronisasi kode: tabel log ternyata asset_trx_log (id_asset_trx_log), bukan asset_log.