Files
app-grosir/PRD.md
2026-07-23 22:12:32 +07:00

26 KiB
Raw Blame History

PRD - Dutra Store

Changelog

v1.0.1 — 2026-07-22

  • Perbaikan UI/UX form produk: auto-scroll keyboard pada Tambah Produk dan Edit Produk.
  • reorganisasi metode pembayaran: kelompok atas 3 (Tunai, Bank, QRIS), kelompok bawah 2 (Bayar Nanti, Split).
  • Validasi harga reseller: harga reseller tidak boleh lebih tinggi dari harga umum.
  • Fix sinttas produk_screen.dart dan kasir_screen.dart (flutter analyze clean dari error).
  • Deploy release APK ke device: TECNO KM4 (Android 15).

v1.0.0 — 2026-07-20 (Resmikan)

  • Fitur lengkap: Auth, Kasir, Produk, Riwayat, Pembayaran, Struk, Printer Bluetooth, Export PDF.
  • Release APK pertama untuk distribusi.

1. Ringkasan Produk

Dutra Store adalah aplikasi kasir digital berbasis Flutter untuk toko grosir. Aplikasi ini menghubungkan multi-device melalui sinkronisasi realtime Supabase, sehingga data produk dan transaksi dapat diakses dari berbagai perangkat secara bersamaan.

2. Tujuan Bisnis

  • Mempercepat transaksi penjualan di toko grosir.
  • Menjamin harga konsisten untuk pelanggan umum dan reseller.
  • Menyediakan laporan penjualan yang realtime.
  • Mengurangi risiko inkonsistensi data antar perangkat kasir.
  • Memisahkan wewenang antara admin (pemilik) dan kasir (karyawan).

3. Target Pengguna

  • Admin (pemilik toko): mengelola produk, melihat laporan, mengubah setting toko.
  • Kasir (karyawan): melakukan transaksi penjualan, tidak bisa mengubah data master.
  • Pelanggan reseller yang mendapatkan harga khusus.

4. Lingkung Aplikasi

  • Platform: Android (emulator & perangkat fisik).
  • State management: Provider.
  • Backend: Supabase (PostgreSQL).
  • Autentikasi: Supabase Auth (email + password) + tabel profiles untuk role.
  • Sinkronisasi: Realtime stream untuk products dan sales pada paid tier; pada free tier menggunakan periodic polling 1 menit saat app aktif sebagai fallback, ditambah pull-to-refresh manual.
  • Penyimpanan lokal: shared_preferences untuk cache JSON + session auth dikelola oleh Supabase.
  • Startup flow: AuthGate mengecek session/login state → LoginScreen atau HomePage.

5. Role & Permission

5.1 Admin

  • Login ke aplikasi.
  • CRUD produk (tambah, edit, hapus, atur stok & harga).
  • Melihat riwayat transaksi & laporan.
  • Mengelola akun kasir (tambah / nonaktifkan).
  • Mengubah pengaturan toko (nama toko, mata uang, printer default).

5.2 Kasir

  • Login ke aplikasi.
  • Melakukan transaksi penjualan (tab Kasir).
  • Tidak dapat mengedit atau menghapus produk.
  • Tidak dapat melihat laporan lengkap / riwayat lama.
  • Tidak dapat mengubah pengaturan toko.

5.3 Guest (tanpa login)

  • Tidak diizinkan. Semua perangkat harus login terlebih dahulu.

6. Fitur Utama

6.1 Autentikasi

  • Screen login (email + password) menggunakan Supabase Auth.
  • Logout.
  • Role ditentukan dari kolom role di tabel profiles Supabase.
  • Session disimpan lokal; startup otomatis login jika session masih valid.

6.2 Manajemen Produk (Admin only)

  • CRUD produk: nama, barcode/no. produk, harga umum, harga reseller, stok.
  • Pencarian produk berdasarkan nama atau barcode.
  • Indikator stok habis (label "Habis" + opacity reduced).
  • Input harga menggunakan format Rupiah otomatis (RupiahInputFormatter): pengguna mengetik angka mentah, field otomatis menampilkan Rp XX.XXX.
  • Scan barcode produk: tombol scan di form "Tambah Produk" menggunakan kamera HP. Setelah barcode discan, hasil scan otomatis diisi ke field "Barcode / No. Produk" (bukan nama). Admin tetap mengisi nama produk, harga, dan stok secara manual.
  • Di list produk, barcode ditampilkan di bawah nama produk untuk memudahkan identifikasi.
  • Seed data otomatis jika tabel produk kosong.

6.3 Transaksi Kasir (Admin & Kasir)

  • Toggle tipe pembeli: Umum / Reseller (global per transaksi).
  • Fitur harga reseller dapat dinonaktifkan dari Pengaturan Toko → Mode Reseller Aktif. Jika dimatikan: toggle Pembeli (Umum/Reseller) dan badge per-item (Reseller/Umum) disembunyikan, semua harga otomatis Umum.
  • Tambah produk ke keranjang dengan 1 tap.
  • Override harga per line: setiap item di keranjang dapat di-toggle antara Umum / Reseller.
  • Qty per item, dengan batas stok.
  • Diskon transaksi (Rp).
  • Perhitungan otomatis: subtotal, diskon, total, bayar, kembalian.

6.4 Keranjang (Cart)

  • Bottom bar ringkas menampilkan jumlah item & total.
  • Draggable bottom sheet untuk detail keranjang.
  • Tombol "Kosongkan" keranjang.
  • Input diskon dengan format Rupiah otomatis.
  • Tombol "Bayar" mengarah ke dialog pembayaran.

6.5 Pembayaran

  • Dialog pembayaran scrollable (mengantisipasi keyboard).
  • Input "Uang Dibayar" dengan format Rupiah otomatis dan kalkulasi kembalian realtime.
  • Pemilihan metode pembayaran: Tunai, Bank, QRIS, Split.
  • Chip cepat untuk Tunai: Uang Pas, +5rb, +10rb, +20rb, +50rb, +100rb.
  • Bank/QRIS: tampilkan informasi petunjuk + input jumlah + status Lunas/Kurang.
  • Split Payment: input pembayaran gabungan (Tunai + Bank + QRIS) dengan total split real-time.
  • Validasi minimal pembayaran >= total untuk Tunai.
  • Tombol "Selesai & Cetak" menyelesaikan transaksi. Saat diproses, tombol menampilkan indikator loading (spinner + teks "Memproses...") dan terkunci agar tidak bisa diklik dua kali.
  • Jika offline, transaksi disimpan ke queue lokal dan disinkronkan otomatis saat koneksi kembali.

6.6 Struk / Nota

  • Dialog struk setelah pembayaran berhasil.
  • Menampilkan: daftar item, diskon, total, bayar, kembali, tanggal, ID transaksi.
  • Tombol "Tutup".

6.7 Riwayat Transaksi

  • Urutan: transaksi terbaru tampil di paling atas (baik untuk kasir maupun admin).
  • Kasir: menampilkan transaksi hanya hari ini (tanggal berjalan).
  • Admin: menampilkan transaksi bulan berjalan secara default, dengan opsi filter rentang tanggal menggunakan date range picker untuk melihat data periode lain.
  • Export: Admin dapat export laporan transaksi dalam format PDF. Export CSV/Excel ditunda untuk pengembangan berikutnya.
  • Summary cards dalam bentuk horizontal slider/carousel dengan dot indicator:
    • Pendapatan Hari Ini vs Kemarin (persentase perubahan).
    • Pendapatan Bulan Ini vs Bulan Lalu.
    • Laba Kotor Bulan Ini vs Bulan Lalu.
    • Transaksi Bulan Ini vs Bulan Lalu.
    • Swipe kiri/kanan untuk berpindah antar card.
    • Dot indicator di bawah slider menandakan card aktif.
    • Card aktif menampilkan detail lengkap, card non-aktif menampilkan ringkas.
  • List transaksi menampilkan: total, tanggal & waktu, jumlah item, ID transaksi.
  • Tap pada item transaksi membuka dialog detail struk (daftar item, diskon, total, bayar, kembali, tanggal, ID transaksi).
  • Setiap item di dialog detail menampilkan badge "Reseller" atau "Umum" sesuai tipe harganya.
  • Dialog detail riwayat menampilkan Metode Pembayaran (Tunai/Bank/QRIS/Split Payment).
  • Jika Split Payment, menampilkan breakdown per metode beserta jumlahnya.
  • Dialog detail riwayat memiliki tombol "Cetak Struk" yang mengirim struk ke thermal printer Bluetooth (ESC/POS) — mirip dengan cetak dari dialog pembayaran kasir.

6.9 Retur / Pembatalan Transaksi (Admin only)

  • Admin dapat membatalkan transaksi dari dialog detail riwayat.
  • Saat dibatalkan, stok produk secara otomatis dikembalikan ke jumlah semula.
  • Transaksi yang dibatalkan ditandai dengan label "DIBATALKAN" dan tidak masuk hitungan pendapatan.
  • Tombol "Batalkan Transaksi" hanya muncul untuk admin dan hanya pada transaksi yang belum dibatalkan.
  • Konfirmasi dialog sebelum pembatalan: "Stok akan dikembalikan secara otomatis. Tindakan ini tidak dapat dibatalkan."

6.10 Stok Minimum & Notifikasi

  • Setiap produk memiliki field Stok Minimum (default: 5) yang dapat diatur saat tambah/edit produk.
  • Di list produk, stok yang di bawah minimum akan menampilkan badge peringatan berwarna oranye: "⚠ Stok rendah (X/Y)".
  • Stok habis tetap menampilkan badge merah "Stok habis".
  • Field stok minimum ditambahkan di form tambah produk dan form edit produk.

6.11 Laba / Rugi

  • Setiap produk memiliki field Harga Pokok (modal) yang dapat diatur saat tambah/edit produk.
  • Di Riwayat, menampilkan Laba Kotor per transaksi: Pendapatan - Harga Pokok.
  • Kasir: melihat Laba Hari Ini.
  • Admin: melihat Laba Kotor Total (semua transaksi) dan Laba Kotor per periode filter.
  • Laba kotor dihitung otomatis saat checkout berdasarkan harga pokok yang tersimpan di produk.
  • Transaksi yang dibatalkan tidak masuk hitungan laba/rugi.

6.12 Pengaturan Toko (Admin only)

  • Nama toko.
  • Mata uang default (default: IDR).
  • Toggle mode reseller (aktif/nonaktif).

7. Screen / Menu Structure

7.1 Login Screen

  • Email + password.
  • Tombol "Masuk".
  • Loading indicator selama inisialisasi AppState.
  • Error handling (invalid credentials).
  • Layout: SafeArea + SingleChildScrollView dengan padding dinamis untuk keyboard.

7.2 AuthGate (main.dart)

  • StreamBuilder + Selector<AppState> untuk mengecek:
    1. state.loading → tampilkan CircularProgressIndicator.
    2. state.isLoggedIn → tampilkan HomePage.
    3. Selain itu → tampilkan LoginScreen.
  • Listener onAuthStateChange di AppState untuk update userId dan userRole otomatis.

7.3 HomePage (bottom nav)

  • AppBar: judul "Dutra Store" + icon logout.
  • Body: IndexedStack dengan screens sesuai role.
  • BottomNavigationBar:
    • Kasir: 2 tab (Kasir, Riwayat).
    • Admin: 5 tab (Kasir, Produk, Riwayat, Akun, Pengaturan).
  • Navigasi menggunakan _index yang direset ke 0 jika role berubah.

7.4 Kasir Screen

  • Search bar + segmented button tipe pembeli (Umum/Reseller).
  • Grid produk 2 kolom.
  • Bottom bar: jumlah item + total + icon expand.
  • Draggable bottom sheet keranjang.
  • Dialog pembayaran + struk.

7.5 Produk Screen

  • Search bar + form tambah/edit produk.
  • Grid daftar produk.
  • Hanya admin yang melihat tab ini.

7.6 Riwayat Screen

  • Admin: date range picker untuk filter transaksi berdasarkan tanggal.
  • Summary cards:
    • Kasir: Transaksi Hari Ini, Pendapatan Hari Ini.
    • Admin: Semua Transaksi, Total Pendapatan, Jumlah Semua Transaksi.
  • List transaksi:
    • Kasir: hanya transaksi hari ini.
    • Admin: semua transaksi atau sesuai filter tanggal.
  • Setiap item: total, tanggal & waktu, jumlah item, ID transaksi.

7.7 Kelola Akun Kasir (Admin only)

  • Screen untuk mengelola akun kasir.
  • Form tambah akun kasir: email, password, nama lengkap.
  • List akun kasir yang ada dengan opsi hapus.
  • Setiap akun memiliki role kasir di tabel profiles.

7.8 Pengaturan Toko (Admin only)

  • Screen untuk mengubah pengaturan toko.
  • Field: nama toko, mata uang (default: IDR), alamat printer Bluetooth.
  • Toggle mode reseller (aktif/nonaktif).
  • Pengaturan disimpan di shared_preferences.

7.9 Login/Logout Flow

  • Login: LoginScreen → AppState.login() → update userId + userRole → AuthGate otomatis navigate ke HomePage.
  • Logout: icon logout di AppBar → AppState.logout() → clear cart + discount → AuthGate otomatis navigate ke LoginScreen.

8. Model Data

Product

Field Tipe Keterangan
id text (PK) UUID unik
name text Nama produk
barcode text Barcode / No. Produk (opsional)
price number Harga umum
price_reseller number Harga reseller
stock integer Stok tersedia
min_stock integer Batas stok minimum untuk peringatan (default: 5)
harga_pokok number Harga modal per unit (untuk hitung laba kotor)

Sale

Field Tipe Keterangan
id text (PK) UUID unik
created_at timestamp Waktu transaksi
items jsonb Array of {name, price, qty, isReseller}
subtotal number Total sebelum diskon
discount number Diskon transaksi
total number subtotal - discount
paid number Jumlah dibayar
change number paid - total
user_id text (FK) ID user yang melakukan transaksi (opsional)
is_cancelled boolean true jika transaksi dibatalkan (default: false)
total_cost number Total harga pokok dari item yang terjual (untuk laba kotor)
payment_method text Metode pembayaran: 'tunai' (default), 'bank', 'qris', 'split'
split_payment jsonb Object pembayaran gabungan: {"tunai": 50000, "bank": 100000, "qris": 50000} (opsional)

CartLine (lokal)

Field Tipe Keterangan
product Product Referensi produk
qty int Jumlah
isReseller bool true = harga reseller dipakai

Profile (Supabase)

Field Tipe Keterangan
id uuid (FK auth.users) Referensi user
role text 'admin' atau 'kasir'
full_name text Nama lengkap (opsional)

8.1 Utilitas Format Rupiah

  • RupiahInputFormatter: TextInputFormatter untuk field harga/uang.
  • Saat pengguna mengetik angka, field otomatis menampilkan format Rp XX.XXX (contoh: 50000 → Rp 50.000).
  • RupiahInputFormatter.getRawValue(String): mengembalikan nilai int? dari string yang diformat, untuk kebutuhan perhitungan.
  • Digunakan pada:
    • Form tambah/edit produk: Harga Umum, Harga Reseller.
    • Dialog pembayaran: Uang Dibayar.
    • Keranjang: Diskon.

9. Alur Transaksi

  1. User login → role ditentukan → navigasi sesuai role.
  2. Kasir:
    • Pilih tipe pembeli (Umum / Reseller).
    • Tambah produk ke keranjang.
    • Sesuaikan qty & tipe harga per item.
    • Isi diskon (opsional).
    • Tekan "Bayar" → dialog pembayaran muncul.
    • Input uang dibayar / pilih chip cepat.
    • Validasi, lalu checkout → simpan ke Supabase, kurangi stok.
    • Tampilkan dialog struk.
    • Tutup struk → kembali ke tab Kasir dengan keranjang kosong.
  3. Admin:
    • Dapat melakukan transaksi seperti kasir.
    • Dapat menambah/edit/hapus produk.
    • Dapat melihat riwayat & laporan.
    • Dapat mengelola akun kasir & pengaturan toko.

10. UI / UX Requirements

  • Tema gelap dengan aksen amber.
  • Kartu produk dengan sudut rounded, shadow, avatar inisial nama.
  • Bottom sheet keranjang dengan handle drag.
  • Semua dialog yang berpotensi overflow harus menggunakan scroll view.
  • Label dan mata uang dalam Bahasa Indonesia (Rupiah).
  • UI menyesuaikan role: tombol/fitur yang tidak diizinkan disembunyikan (tidak hanya di-disable).

10.1 Design System

  • Tema utama: Dark theme. Warna aksen: amber.
  • Radius: 18 (kartu), 12 (input/dialog), 8 (chip/tag).
  • Spacing: padding screen/list EdgeInsets.all(12), padding form/dialog EdgeInsets.all(16), gap field SizedBox(height: 10), gap section SizedBox(height: 14).
  • Kartu: padding minimal 12, jangan hardcode tinggi. Jika 3+ field, prioritaskan wrap/scroll.
  • Input: label jelas, helper text untuk opsional. Jika form panjang, bungkus SingleChildScrollView + padding bottom MediaQuery.of(context).viewInsets.bottom agar tidak tertutup keyboard.
  • Tombol: primary = FilledButton (aksi utama: Bayar, Tambah, Simpan), destructive = merah (kDanger), secondary = TextButton/OutlinedButton.

10.2 Responsif & Overflow

  • Grid Kasir: 2 kolom di HP, 3–4 kolom di tablet (lebar > 600dp). Hindari childAspectRatio tetap; pakai AspectRatio(1.1) atau biarkan grid menentukan tinggi.
  • Bottom Sheet: keranjang harus berupa bottom sheet (bukan panel tetap), bisa di-drag, konten selalu scrollable (SingleChildScrollView tanpa Expanded).
  • Dialog: input panjang harus scrollable. Jangan pakai Expanded di dalam dialog yang bisa overflow.
  • Produk: form + list dalam satu halaman scroll (SingleChildScrollView + ListView.shrinkWrap).
  • Teks: jangan hardcode font size. Batasi nama produk max 2 baris (maxLines: 2, overflow: TextOverflow.ellipsis).

10.3 UX Kasir (Critical Path)

  • Target: transaksi selesai dalam 3 tap (pilih → bayar → selesai).
  • Tampilkan total, diskon, kembalian real-time.
  • Tipe pembeli pakai segmented button (Umum/Reseller), bukan dropdown.
  • Setiap item keranjang bisa ubah qty atau tipe harga dalam 1 tap.
  • Stok habis: tampil badge merah "Habis" + matikan visual/tap.
  • Stok menipis: badge peringatan oranye sebelum habis.

10.4 Aksesibilitas & Feedback

  • Minimal tap target: 44x44dp.
  • Kontras teks minimal 4.5:1.
  • Jangan andal warna saja (tambah ikon/label). Contoh: stok habis = badge merah + teks "Habis".
  • Setiap aksi ada SnackBar feedback: sukses hijau, error merah, info biru/abu.
  • Loading state untuk operasi > 500ms (CircularProgressIndicator(color: kAccent)).

10.5 Role-Based Visibility

  • Fitur tidak diizinkan untuk role tertentu harus disembunyikan sepenuhnya, bukan cuma di-disable.
  • Admin: lihat semua transaksi + filter tanggal + aksi batalkan.
  • Kasir: lihat transaksi hari ini, tidak ada aksi batalkan/filter.

10.6 Reusability & Konsistensi

  • Buat widget reuseable untuk komponen berulang: _Tag, _ReportCard, _Avatar, _Stepper.
  • Taruh konstanta warna/spacing di lib/utils/colors.dart.
  • Konsisten pakai formatRupiah() untuk semua angka mata uang.

10.7 Checklist Sebelum Submit Perubahan UI/UX

  • flutter analyze → No issues found (tanpa error).
  • Coba di layar kecil (HP 5") dan besar (tablet).
  • Coba dengan keyboard muncul (input uang/diskon).
  • Pastikan tidak ada hardcoded height yang bikin overflow.
  • Semua teks dalam Bahasa Indonesia.
  • Konsisten pakai formatRupiah() untuk angka mata uang.

11. Non-Fitur (Out of Scope untuk versi ini)

  • Printer thermal Bluetooth (direncanakan Sprint 4). ✅ Sudah diimplementasikan (Sprint 4).
  • Laporan bulanan / export PDF/Excel. ✅ Sudah diimplementasikan (export PDF & CSV di Sprint 3/4).
  • Barcode scanner. ✅ Sudah diimplementasikan (Sprint 2, mobile_scanner).
  • Multi-cabang / multi-toko.

12. Kebutuhan Non-Fungsional

  • Sinkronisasi realtime < 2 detik antar perangkat.
  • Offline mode: data terbaru tetap tampil meskipun koneksi terputus (cache lokal).
  • Build APK debug untuk emulator Android 13+.
  • Session auth harus aman (token disimpan aman, auto-logout setelah inactivity opsional).

13. Risiko & Mitigasi

Risiko Mitigasi
Stok menjadi negatif Validasi di addToCart & changeQty dibatasi oleh stok produk.
Data inkonsistenan saat并发 Supabase realtime + operasi atomic di sisi backend.
Keyboard menutupi input di dialog Semua dialog input menggunakan SingleChildScrollView.
Akses tidak sah Role-based UI + validasi di Supabase (RLS policies).
Koneksi putus saat checkout Simpan transaksi ke queue lokal, kirim saat koneksi kembali (opsional).

14. Sprint Breakdown

Sprint 0 — Foundation (Selesai)

  • Setup Flutter + Provider + Supabase.
  • Struktur dasar: screens, models, state, utils.
  • CRUD Produk + Realtime stream.
  • Dual pricing (Umum / Reseller).
  • UI redesign (dark theme, amber accent).

Sprint 1 — Transaksi Kasir (Selesai)

  • Tab Kasir: grid produk + search + tipe pembeli.
  • Cart: bottom bar + bottom sheet + qty control.
  • Diskon transaksi.
  • Dialog pembayaran + kalkulasi kembalian.
  • Dialog struk.
  • Fix overflow (Produk tab, Kasir dialog, Cart sheet).

Sprint 2 — Auth & Role-Based Access (Selesai)

  • Setup Supabase Auth (email + password).
  • Tabel profiles dengan kolom role.
  • Screen login + loading state + error handling.
  • Logout icon di AppBar.
  • Integrasi role ke AppState (userId, userRole, isAdmin, isKasir, isLoggedIn).
  • Auth state listener (onAuthStateChange) untuk update otomatis saat login/logout.
  • UI adaptif sesuai role:
    • Bottom nav: Kasir (2 tab), Admin (3 tab).
    • Riwayat: Kasir lihat hari ini, Admin lihat semua.
    • Produk: hanya admin.
  • Seed admin default via _seedAdminIfEmpty().
  • Audit trail: tambah user_id pada model Sale dan simpan saat checkout.
  • Fix bottom nav assertion error untuk role kasir (nav disembunyikan jika < 2 item).
  • Fix login screen stuck/overflow dengan SafeArea + SingleChildScrollView + padding dinamis.
  • Optimasi AuthGate dengan Selector agar tidak rebuild berlebihan.
  • Rupiah input formatter untuk field harga/uang di Produk, Pembayaran, dan Diskon.
  • Scan barcode produk di form Produk menggunakan mobile_scanner + permission kamera.

Sprint 3 — Admin Features

  • Riwayat transaksi dengan filter role-based (kasir: hari ini, admin: semua).
  • Summary cards adaptif sesuai role.
  • Filter date range untuk admin di riwayat menggunakan date range picker.
  • Manajemen akun kasir (tambah/hapus akun kasir dari dalam app).
  • Edit akun kasir (ubah nama/email/password via dialog edit, password pakai auth.admin.updateUserById).
  • Pengaturan toko (nama toko, mata uang, toggle reseller).
  • Export laporan ke PDF dan CSV (Excel) menggunakan pdf, csv, path_provider, dan share_plus.

Sprint 4 — Polish & Integration

  • Export laporan ke PDF dan CSV (Excel) menggunakan pdf, csv, path_provider, dan share_plus.
  • Offline mode improvements (queue transaksi menggunakan OfflineQueueService + connectivity_plus).
  • Thermal printer Bluetooth (package print_bluetooth_thermal + esc_pos_utils_plus, ganti dari blue_thermal_printer yang gagal build).
  • Cetak struk langsung dari dialog pembayaran kasir.
  • Retur / Pembatalan transaksi (admin dapat batalkan transaksi dari riwayat, stok otomatis dipulihkan).
  • Stok minimum & notifikasi (field min_stock di produk, badge warning di list produk).
  • Laba / Rugi (harga pokok per produk, laporan laba kotor di riwayat).
  • Build release APK untuk distribusi.
  • Testing & bug fixing menyeluruh.

15. Status Implementasi Saat Ini

Fitur yang Sudah Berjalan

  • ✅ Login/logout dengan Supabase Auth
  • ✅ Role-based access: Admin (3 tab: Kasir, Produk, Riwayat, Pengaturan) dan Kasir (2 tab) — Akun Kasir & Printer digabung ke dalam tab Pengaturan
  • ✅ CRUD Produk dengan barcode scanner
  • ✅ Transaksi kasir dengan dual pricing (Umum/Reseller)
  • ✅ Mode Reseller dapat dinyalakan/matikan dari Pengaturan Toko (saat mati, toggle harga reseller di kasir disembunyikan)
  • ✅ Cart bottom sheet + diskon + pembayaran + struk
  • ✅ Pembayaran: tombol "Selesai & Cetak" pakai loading guard (spinner + "Memproses...") agar tidak dobel klik
  • ✅ Riwayat transaksi: terurut terbaru di atas, filter role-based, date range
  • ✅ Detail riwayat: badge per-item "Reseller"/"Umum" + tombol "Cetak Struk"
  • ✅ Manajemen akun kasir (tambah/hapus/edit)
  • ✅ Pengaturan toko (nama, mata uang, toggle reseller) — nama app "Dutra Store"
  • ✅ Export laporan PDF
  • ⏸️ Export laporan CSV/Excel (ditunda untuk pengembangan berikutnya)
  • ✅ Offline mode queue untuk transaksi
  • ✅ Thermal printer Bluetooth (scan, connect, auto-reconnect, cetak struk ESC/POS)
  • ✅ Cetak struk dari riwayat (tap transaksi → dialog detail → tombol "Cetak Struk")
  • ✅ Rupiah input formatter
  • ✅ Overflow fixes pada semua screen
  • ✅ Retur/Pembatalan transaksi (admin dapat batalkan dari dialog detail riwayat, stok otomatis dipulihkan)
  • ✅ Stok minimum & notifikasi (badge warning stok rendah di list produk)
  • ✅ Laba/Rugi (harga pokok per produk, laporan laba kotor di riwayat: Laba Hari Ini untuk kasir, LABA KOTOR untuk admin)
  • ✅ Tab Riwayat: summary cards compact (tap untuk expand), list transaksi ditampilkan di bawah summary, detail transaksi menggunakan bottom sheet
  • ✅ Tab Riwayat: ringkasan bulanan dengan perbandingan MoM (Pendapatan, Laba Kotor, Transaksi) untuk admin
  • ✅ Tab Riwayat: admin melihat transaksi bulan berjalan secara default (bukan semua transaksi)
  • ✅ Tab Riwayat: summary cards dalam bentuk horizontal slider/carousel dengan dot indicator, swipe kiri/kanan untuk pindah card, card aktif menampilkan detail lengkap
  • ✅ Tab Produk: form tambah produk dipindah ke bottom sheet (FAB + Tambah Produk), list produk tetap terlihat
  • ✅ Tab Kasir: animasi pulse di cart bar saat produk ditambahkan
  • ✅ Dialog pembayaran: loading overlay + disable input saat proses checkout + minimum 300ms visibility
  • ✅ Dialog pembayaran: pilihan metode pembayaran (Tunai, Bank, QRIS, Split) dengan chip selector
  • ✅ Dialog pembayaran: chip cepat untuk Tunai (Uang Pas, +5rb, +10rb, +20rb, +50rb, +100rb)
  • ✅ Dialog pembayaran: split payment support dengan total split real-time
  • ✅ Receipt & detail riwayat: menampilkan metode pembayaran dan breakdown split payment
  • ✅ Sale model: field payment_method + split_payment untuk dokumentasi transaksi
  • ✅ Release APK (app-release.apk 66.9MB)

Fitur yang Didefer / Belum

  • ✅ Ganti password akun kasir via Supabase admin API (auth.admin.updateUserById tersedia di gotrue 2.26.0).
  • ✅ Testing & bug fixing menyeluruh (analyzer No issues found!, 0 error/warning).
  • ⏳ Testing & bug fixing menyeluruh (belum dilakukan comprehensive testing).
  • ✅ Build release APK untuk distribusi (app-release.apk 66.9MB).

Catatan Teknis

  • Nama aplikasi: Dutra Store (launcher label, AppBar, judul login, export).
  • Admin tab dikurangi: Akun Kasir & Printer digabung ke dalam tab Pengaturan (admin sekarang 3 tab: Produk, Riwayat, Pengaturan).
  • Printer auto-connect saat app start (MAC tersimpan di shared_preferences).
  • flutter analyze sekarang No issues found! (semua withOpacity diganti withValues(alpha:), use_build_context_synchronously di-handle, dead code dihapus).
  • App sudah di-deploy ke device: TECNO KM4 (Android 15) dan RMX2061 (Android 11 API 30), keduanya berjalan normal.
  • Database migration:
    1. Jalankan SQL di supabase/migrations/20240101_add_cancel_and_min_stock.sql untuk kolom is_cancelled (sales) dan min_stock (products).
    2. Jalankan SQL di supabase/migrations/20240102_add_harga_pokok_and_profit.sql untuk kolom harga_pokok (products) dan total_cost (sales).
    3. Jalankan SQL di supabase/migrations/20240103_add_payment_method.sql untuk kolom payment_method dan split_payment (sales) — sudah dijalankan.
  • UI/UX skill tersimpan di .kilo/agent/uiux-pos-grosir.md dan bagian PRD 10.1-10.7.
  • Color scheme: brand amber dominant di Kasir & Produk, hijau untuk harga umum, merah untuk error/habis, abu untuk muted.