# Manual Checklist Pembatalan Transaksi

edited by glg

## Tujuan
Checklist ini dipakai untuk validasi manual operator kasir pada fitur pembatalan transaksi, terutama guard:

1. Transaksi yang sudah settle tidak bisa dibatalkan.
2. Human error input/seleksi tidak menyebabkan data salah.
3. Pesan UI konsisten dan tidak membingungkan operator.

## Prasyarat Uji
1. Gunakan build aplikasi terbaru (setelah patch validasi pembatalan).
2. Siapkan minimal 3 transaksi invoice:
   1. `INV-A`: invoice hari ini, belum settle (`settlement_id=1`).
   2. `INV-B`: invoice hari ini, sudah settle (`settlement_id=0`).
   3. `INV-C`: invoice di luar range hari pembatalan.
3. Pastikan user kasir bisa membuka menu Pembatalan Transaksi.
4. Siapkan akun admin yang punya hak verifikasi settlement.
5. Aktifkan logging aplikasi (`logs/`) selama pengujian.

## Skenario Uji Utama

### Skenario 1 - Klik batal tanpa memilih transaksi
1. Buka menu `Pembatalan Transaksi`.
2. Jangan pilih baris transaksi.
3. Klik tombol `Batalkan Transaksi`.

Hasil yang diharapkan:
1. Muncul warning: `Pilih transaksi yang akan dibatalkan.`
2. Tidak ada perubahan data di tabel transaksi.
3. Tidak ada data baru di history pembatalan.

### Skenario 2 - Transaksi sudah settle harus ditolak
1. Pilih transaksi `INV-B` (sudah settle).
2. Klik `Batalkan Transaksi`.
3. Klik `Yes` pada dialog konfirmasi.
4. Lakukan verifikasi admin yang valid.

Hasil yang diharapkan:
1. Muncul warning: `Transaksi sudah disettle dan tidak dapat dibatalkan.`
2. `trash` transaksi tetap `0`.
3. `cancel_dtime` tidak terisi.
4. Tidak ada insert ke `pembatalan_transaksi_history`.

### Skenario 3 - Transaksi valid (belum settle) berhasil dibatalkan
1. Pilih transaksi `INV-A` (belum settle).
2. Klik `Batalkan Transaksi`.
3. Klik `Yes` pada dialog konfirmasi.
4. Lakukan verifikasi admin yang valid.

Hasil yang diharapkan:
1. Muncul informasi: `Transaksi berhasil dibatalkan.`
2. Data transaksi berubah:
   1. `transaksi.trash = 1`
   2. `transaksi.cancel_dtime` terisi waktu proses.
3. Semua detail item transaksi ikut ditandai:
   1. `transaksi_data.trash = 1` untuk `transaksi_id` terkait.
4. Ada 1 record baru di `pembatalan_transaksi_history`.
5. Daftar transaksi di view melakukan refresh.

### Skenario 4 - Coba batalkan transaksi yang sama untuk kedua kali
1. Ambil transaksi yang sudah dibatalkan dari Skenario 3.
2. Coba lakukan pembatalan lagi.

Hasil yang diharapkan:
1. Ditolak dengan pesan: `Transaksi sudah dibatalkan.`
2. Tidak ada duplikasi history pembatalan untuk percobaan kedua.

### Skenario 5 - Guard periode pembatalan
1. Pilih `INV-C` (di luar periode pembatalan yang diizinkan).
2. Klik `Batalkan Transaksi`.
3. Lanjutkan konfirmasi dan verifikasi admin.

Hasil yang diharapkan:
1. Ditolak dengan pesan: `Transaksi di luar periode pembatalan yang diizinkan.`
2. Data transaksi dan detail tidak berubah.
3. Tidak ada insert history pembatalan.

## Skenario Human Error Tambahan
1. Salah password admin saat verifikasi:
   1. Harus gagal verifikasi, proses batal tidak lanjut.
2. User menekan `No` pada dialog konfirmasi:
   1. Proses batal dibatalkan sepenuhnya.
3. User menutup dialog verifikasi admin:
   1. Proses batal dihentikan tanpa perubahan data.
4. User pindah tab/menu saat dialog belum selesai:
   1. Aplikasi tetap responsif, tidak freeze/crash.

## Bukti Uji yang Wajib Dikumpulkan
1. Screenshot setiap hasil popup (warning/info) dari tiap skenario.
2. Cuplikan tabel:
   1. `transaksi` (kolom `id, nomer, settlement_id, trash, cancel_dtime`)
   2. `transaksi_data` (`transaksi_id, trash`)
   3. `pembatalan_transaksi_history`
3. Cuplikan log aplikasi di waktu pengujian (folder `logs`).

## Query Verifikasi Cepat (SQLite)
```sql
-- 1) Cek status transaksi
SELECT id, nomer, settlement_id, trash, cancel_dtime
FROM transaksi
WHERE nomer IN ('INV-A', 'INV-B', 'INV-C');

-- 2) Cek detail item ikut terbatal
SELECT transaksi_id, COUNT(*) AS total_item, SUM(CASE WHEN COALESCE(trash,0)=1 THEN 1 ELSE 0 END) AS item_trash
FROM transaksi_data
WHERE transaksi_id IN (
  SELECT CAST(id AS TEXT) FROM transaksi WHERE nomer IN ('INV-A', 'INV-B', 'INV-C')
)
GROUP BY transaksi_id;

-- 3) Cek history pembatalan
SELECT transaksi_id, nomer, admin_verifikasi, dibatalkan_oleh_nama, cancel_dtime
FROM pembatalan_transaksi_history
WHERE nomer IN ('INV-A', 'INV-B', 'INV-C')
ORDER BY id DESC;
```

## Kriteria Lulus
1. Semua skenario utama (1-5) sesuai hasil yang diharapkan.
2. Tidak ada crash/freeze saat interaksi dialog.
3. Tidak ada inkonsistensi data antara popup UI, tabel transaksi, dan history pembatalan.
