Produk kini punya cara jual `unit` (cacah) atau `weight` (timbangan),
mengikuti kontrak backend di docs/integration-weight-based-products.md.
- tipe SellBy, domain/infrastructure unit baru, dan endpoint /api/v1/units
- dialog input berat saat produk timbangan ditambahkan ke keranjang
- tiap penimbangan jadi baris keranjang sendiri; total baris dihitung
berat x harga satuan, sedangkan produk cacah tetap digabung
- request ke backend mengirim quantity 1 dan membawa berat
- migrasi DB v3: kolom sell_by, unit_id, unit_name, unit_abbreviation
di tabel products supaya satuan tetap tampil saat offline
- tampilan keranjang, struk, split bill, void, dan refund memakai berat
- test/weight_based_products_test.dart menutup perilaku di atas (9 test)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PrinterFormBloc dan PrinterLoaderBloc di-provide sekali secara global, sementara lima tab pengaturan printer hidup bersamaan di dalam TabBarView dan semuanya membaca-menulis state yang sama.
Karena created dan updated membangun entitas Printer sepenuhnya dari state itu (type, address, code, name, paper), tab yang terakhir menulis state akan menang, lalu tombol Simpan di tab mana pun menyimpan milik tab lain. Nilai awal state kebetulan type 'Bluetooth' — itu sebabnya printer kitchen tersimpan dengan alamat IP yang benar tapi tipe Bluetooth, dan cetakannya dikirim ke radio Bluetooth untuk mencari perangkat yang tidak pernah ada.
Provider global dihapus karena tidak ada tempat lain yang memakainya. Catatan: ini mencegah kerusakan baru, tidak memulihkan baris yang sudah terlanjur salah di SQLite — konfigurasi kelima tab perlu disimpan ulang.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
printStruckOrder berhenti di kegagalan pertama, jadi satu station gagal membuat semua station sesudahnya tidak pernah dicoba. Karena checker (Bluetooth) berada sebelum kitchen dan bar (Network) dalam rantai, satu kegagalan koneksi Bluetooth menghilangkan tiga tiket sekaligus, dua di antaranya di jaringan yang sehat.
Jalur printer Network juga mengembalikan right(false) saat gagal, yang lolos sebagai sukses ke pemanggil, sehingga kasir melihat 'berhasil dicetak' padahal tidak ada kertas keluar.
Perubahan: repository kini mengembalikan Stream<List<PrintStationResult>> dan tetap mencoba semua station; kegagalan Network jadi left; station Network berjalan paralel dengan rantai Bluetooth; station Bluetooth dikelompokkan per alamat agar perpindahan koneksi seminimal mungkin; CapabilityProfile di-cache.
Bluetooth: retry connect dengan backoff dan disconnect di tiap percobaan ulang (socket RFCOMM setengah terbuka membuat connect berulang gagal identik), jeda settle dikembalikan setelah dipangkas ke 300ms, satu lock untuk seluruh radio (bukan per MAC), izin runtime dipastikan di jalur cetak, dan repository jadi LazySingleton agar state koneksi benar-benar dibagi.
UI: dialog progres per-station menggantikan toast tunggal, lengkap dengan durasi tiap station dan tombol cetak ulang khusus yang gagal. Enam listener duplikat di halaman diganti satu listener terpusat di AppWidget. Menu Print di detail transaksi dapat item Print All.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>