added product import and billing integration
This commit is contained in:
@@ -239,6 +239,24 @@ class CatalogueDao {
|
||||
});
|
||||
}
|
||||
|
||||
/// Drops every product and forgets when the catalogue was last imported.
|
||||
///
|
||||
/// Used at sign-out. Leaves customers, staff, orders and every other table
|
||||
/// untouched — this is about the shelf, not the terminal's history — so the
|
||||
/// next session starts with nothing to sell until it pulls a fresh copy from
|
||||
/// the back office rather than carrying over whatever this session ended
|
||||
/// with.
|
||||
Future<void> clearCatalogue() async {
|
||||
await _db.transaction((txn) async {
|
||||
await txn.delete(Tables.products);
|
||||
await txn.delete(
|
||||
Tables.meta,
|
||||
where: 'key IN (?, ?)',
|
||||
whereArgs: [MetaKeys.lastImportAt, MetaKeys.catalogueRevision],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Applies stock movement after a sale, clamped at zero.
|
||||
Future<void> decrementStock(Map<String, double> quantities) async {
|
||||
if (quantities.isEmpty) return;
|
||||
|
||||
@@ -85,6 +85,46 @@ class OrderDao {
|
||||
});
|
||||
}
|
||||
|
||||
/// Reverses [commitSale]: deletes the order and its lines, adds the stock
|
||||
/// back, and restores an attached customer's row exactly as passed in
|
||||
/// (the caller supplies the pre-sale row — reconstructing it from deltas
|
||||
/// here would get `last_visit_at` wrong).
|
||||
Future<void> voidSale({
|
||||
required String orderId,
|
||||
required Map<String, double> stockMovements,
|
||||
Map<String, Object?>? customerRow,
|
||||
}) async {
|
||||
await _db.transaction((txn) async {
|
||||
await txn
|
||||
.delete(Tables.orderItems, where: 'order_id = ?', whereArgs: [orderId]);
|
||||
await txn.delete(Tables.orders, where: 'id = ?', whereArgs: [orderId]);
|
||||
|
||||
final batch = txn.batch();
|
||||
final now = DateTime.now().millisecondsSinceEpoch;
|
||||
stockMovements.forEach((id, qty) {
|
||||
batch.rawUpdate(
|
||||
'UPDATE ${Tables.products} SET stock = stock + ?, updated_at = ? '
|
||||
'WHERE id = ?',
|
||||
[qty, now, id],
|
||||
);
|
||||
});
|
||||
if (customerRow != null) {
|
||||
batch.update(
|
||||
Tables.customers,
|
||||
{
|
||||
'loyalty_points': customerRow['loyalty_points'],
|
||||
'lifetime_spend': customerRow['lifetime_spend'],
|
||||
'visit_count': customerRow['visit_count'],
|
||||
'last_visit_at': customerRow['last_visit_at'],
|
||||
},
|
||||
where: 'id = ?',
|
||||
whereArgs: [customerRow['id']],
|
||||
);
|
||||
}
|
||||
await batch.commit(noResult: true);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _insertOrder(DatabaseExecutor txn, SaleTransaction t) async {
|
||||
final cart = t.cart;
|
||||
|
||||
|
||||
@@ -53,7 +53,13 @@ class TerminalIdentityStore {
|
||||
///
|
||||
/// The mint is idempotent: an existing device id is never replaced, so a
|
||||
/// terminal cannot silently change identity and orphan its own history.
|
||||
Future<TerminalIdentity> load({String defaultStoreId = 'store-01'}) async {
|
||||
///
|
||||
/// [defaultStoreId] matches the store this build's default HTTP endpoint
|
||||
/// serves — see `syncConfigProvider` — so a fresh terminal's first import
|
||||
/// pulls that store's real catalogue without anyone visiting Settings
|
||||
/// first. Settings → Connectivity & sync → Configure changes it per
|
||||
/// terminal from there.
|
||||
Future<TerminalIdentity> load({String defaultStoreId = '1135'}) async {
|
||||
var deviceId = await _catalogue.meta(MetaKeys.deviceId);
|
||||
var code = await _catalogue.meta(MetaKeys.terminalCode);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user