POS Grosir Dutra Store: update kasir/produk/riwayat/pengaturan + offline queue

This commit is contained in:
onie
2026-10-17 06:38:50 +07:00
parent bec02d196c
commit 0121eca8bb
15 changed files with 1202 additions and 524 deletions

View File

@@ -33,6 +33,8 @@ class AppState extends ChangeNotifier {
static const Duration _timeout = Duration(seconds: 30);
static const String _currentStoreId = '00000000-0000-0000-0000-000000000000';
Future<T> _withTimeout<T>(Future<T> future, [String? operation]) async {
try {
return await future.timeout(
@@ -451,7 +453,7 @@ class AppState extends ChangeNotifier {
Future<void> _loadProducts() async {
final rows = await _withTimeout(
_supabase.from('products').select().order('name'),
_supabase.from('products').select().eq('store_id', _currentStoreId).order('name'),
'Load products',
);
products = rows.map((e) => Product.fromJson(e)).toList();
@@ -463,6 +465,7 @@ class AppState extends ChangeNotifier {
_supabase
.from('sales')
.select()
.eq('store_id', _currentStoreId)
.order('created_at', ascending: false),
'Load sales',
);
@@ -480,7 +483,7 @@ class AppState extends ChangeNotifier {
Product(id: uid(), name: 'Indomie Dus', price: 95000, priceReseller: 90000, stock: 25),
];
await _withTimeout(
_supabase.from('products').insert(seeds.map((e) => e.toJson()).toList()),
_supabase.from('products').insert(seeds.map((e) => e.toJson()..['store_id'] = _currentStoreId).toList()),
'Seed products',
);
products = seeds;
@@ -517,7 +520,7 @@ class AppState extends ChangeNotifier {
hargaPokok: hargaPokok,
);
await _withTimeout(
_supabase.from('products').insert(product.toJson()),
_supabase.from('products').insert(product.toJson()..['store_id'] = _currentStoreId),
'Add product',
);
} catch (e) {
@@ -547,6 +550,7 @@ class AppState extends ChangeNotifier {
'stock': stock,
'min_stock': minStock,
'harga_pokok': hargaPokok,
'store_id': _currentStoreId,
}).eq('id', id),
'Update product',
);
@@ -564,7 +568,7 @@ class AppState extends ChangeNotifier {
try {
cart.removeWhere((c) => c.product.id == id);
await _withTimeout(
_supabase.from('products').delete().eq('id', id),
_supabase.from('products').delete().eq('id', id).eq('store_id', _currentStoreId),
'Delete product',
);
} catch (e) {
@@ -641,7 +645,7 @@ class AppState extends ChangeNotifier {
discount: _discount,
total: total,
paid: paid,
change: paid - total,
change: paymentStatus == 'paid' ? (paid - total).clamp(0, double.infinity) : 0,
totalCost: totalCost,
paymentMethod: paymentMethod,
paymentStatus: paymentStatus,
@@ -652,11 +656,12 @@ class AppState extends ChangeNotifier {
try {
await _withTimeout(
_supabase.from('sales').insert(sale.toJson()),
_supabase.from('sales').insert(sale.toJson()..['store_id'] = _currentStoreId),
'Create sale',
);
for (final line in cart) {
if (line.product.id.startsWith('manual-')) continue;
try {
final current =
products.firstWhere((p) => p.id == line.product.id);
@@ -664,7 +669,8 @@ class AppState extends ChangeNotifier {
_supabase
.from('products')
.update({'stock': current.stock - line.qty})
.eq('id', line.product.id),
.eq('id', line.product.id)
.eq('store_id', _currentStoreId),
'Update stock',
);
} catch (_) {}
@@ -703,7 +709,7 @@ class AppState extends ChangeNotifier {
final sale = sales.firstWhere((s) => s.id == saleId);
await _withTimeout(
_supabase.from('sales').update({'is_cancelled': true}).eq('id', saleId),
_supabase.from('sales').update({'is_cancelled': true}).eq('id', saleId).eq('store_id', _currentStoreId),
'Cancel sale',
);
@@ -717,7 +723,8 @@ class AppState extends ChangeNotifier {
_supabase
.from('products')
.update({'stock': product.stock + item.qty})
.eq('id', product.id),
.eq('id', product.id)
.eq('store_id', _currentStoreId),
'Restore stock',
);
}
@@ -745,7 +752,8 @@ class AppState extends ChangeNotifier {
'paid': newPaid,
'due_amount': newDue,
'payment_status': newStatus,
}).eq('id', saleId),
'change': (newPaid - sale.total).clamp(0, double.infinity),
}).eq('id', saleId).eq('store_id', _currentStoreId),
'Record payment',
);
await _loadSales();