feat: make server own products
This commit is contained in:
@@ -461,68 +461,87 @@ class DriftBarTabService implements BarTabService {
|
||||
final tabRow = await _getTabRow(tabId);
|
||||
if (tabRow == null) throw TabNotFoundException(tabId);
|
||||
|
||||
// A merge on the server can leave two lines of one product at
|
||||
// different prices; new drinks go on the oldest
|
||||
final existingItem =
|
||||
await (database.select(database.tabItems)
|
||||
..where(
|
||||
(item) =>
|
||||
item.tabId.equals(tabId) &
|
||||
item.productId.equals(product.id),
|
||||
)
|
||||
..orderBy([(item) => OrderingTerm.asc(item.createdAt)])
|
||||
..limit(1))
|
||||
.getSingleOrNull();
|
||||
|
||||
if (existingItem != null) {
|
||||
await (database.update(
|
||||
database.tabItems,
|
||||
)..where((item) => item.id.equals(existingItem.id))).write(
|
||||
TabItemsCompanion(quantity: Value(existingItem.quantity + 1)),
|
||||
);
|
||||
await _recordPurchase(existingItem.id);
|
||||
// The line keeps the price it was first added at
|
||||
await _recordLineChange(
|
||||
tabId: tabId,
|
||||
customerName: tabRow.customerName,
|
||||
lineId: existingItem.id,
|
||||
productId: existingItem.productId,
|
||||
productName: existingItem.productName,
|
||||
unitPriceInCents: existingItem.unitPriceInCents,
|
||||
delta: 1,
|
||||
);
|
||||
} else {
|
||||
final tabItemId = _uuid.v4();
|
||||
|
||||
await database
|
||||
.into(database.tabItems)
|
||||
.insert(
|
||||
TabItemsCompanion.insert(
|
||||
id: tabItemId,
|
||||
tabId: tabId,
|
||||
productId: product.id,
|
||||
productName: product.name,
|
||||
quantity: 1,
|
||||
unitPriceInCents: product.priceInCents,
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
);
|
||||
await _recordPurchase(tabItemId);
|
||||
await _recordLineChange(
|
||||
tabId: tabId,
|
||||
customerName: tabRow.customerName,
|
||||
lineId: tabItemId,
|
||||
productId: product.id,
|
||||
productName: product.name,
|
||||
unitPriceInCents: product.priceInCents,
|
||||
delta: 1,
|
||||
);
|
||||
}
|
||||
|
||||
await _addDrinks(
|
||||
tabRow,
|
||||
productId: product.id,
|
||||
productName: product.name,
|
||||
unitPriceInCents: product.priceInCents,
|
||||
quantity: 1,
|
||||
);
|
||||
await _incrementTabVersion(tabId);
|
||||
});
|
||||
}
|
||||
|
||||
/// Puts [quantity] drinks on the tab, charged [unitPriceInCents]: on the
|
||||
/// line of that product, name and price, or a new line when there is none.
|
||||
/// Every new drink goes through here, so it is always charged the current
|
||||
/// price: after a price or name change on the website the drinks already
|
||||
/// on the tab keep what they were rung up at, and new ones start a new
|
||||
/// line. Of several matching lines (a merge on the server) the oldest gets
|
||||
/// them.
|
||||
Future<void> _addDrinks(
|
||||
BarTabRow tabRow, {
|
||||
required String productId,
|
||||
required String productName,
|
||||
required int unitPriceInCents,
|
||||
required int quantity,
|
||||
}) async {
|
||||
final existingItem =
|
||||
await (database.select(database.tabItems)
|
||||
..where(
|
||||
(item) =>
|
||||
item.tabId.equals(tabRow.id) &
|
||||
item.productId.equals(productId) &
|
||||
item.unitPriceInCents.equals(unitPriceInCents) &
|
||||
item.productName.equals(productName),
|
||||
)
|
||||
..orderBy([(item) => OrderingTerm.asc(item.createdAt)])
|
||||
..limit(1))
|
||||
.getSingleOrNull();
|
||||
|
||||
final String lineId;
|
||||
if (existingItem != null) {
|
||||
lineId = existingItem.id;
|
||||
await (database.update(
|
||||
database.tabItems,
|
||||
)..where((item) => item.id.equals(lineId))).write(
|
||||
TabItemsCompanion(quantity: Value(existingItem.quantity + quantity)),
|
||||
);
|
||||
} else {
|
||||
lineId = _uuid.v4();
|
||||
await database
|
||||
.into(database.tabItems)
|
||||
.insert(
|
||||
TabItemsCompanion.insert(
|
||||
id: lineId,
|
||||
tabId: tabRow.id,
|
||||
productId: productId,
|
||||
productName: productName,
|
||||
quantity: quantity,
|
||||
unitPriceInCents: unitPriceInCents,
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
for (var index = 0; index < quantity; index++) {
|
||||
await _recordPurchase(lineId);
|
||||
}
|
||||
await _recordLineChange(
|
||||
tabId: tabRow.id,
|
||||
customerName: tabRow.customerName,
|
||||
lineId: lineId,
|
||||
productId: productId,
|
||||
productName: productName,
|
||||
unitPriceInCents: unitPriceInCents,
|
||||
delta: quantity,
|
||||
);
|
||||
}
|
||||
|
||||
/// Taking drinks off changes [tabItemId] itself. Adding is ringing up new
|
||||
/// drinks of its product, at the current price: on this line while its
|
||||
/// price and name are still current, else on the line at the current price
|
||||
/// (see [_addDrinks]). Returns how many were added (positive) or taken off.
|
||||
@override
|
||||
Future<int> adjustTabItemQuantity({
|
||||
required String tabItemId,
|
||||
@@ -537,19 +556,31 @@ class DriftBarTabService implements BarTabService {
|
||||
|
||||
if (item == null) return 0;
|
||||
|
||||
if (delta > 0) {
|
||||
final tabRow = await _getTabRow(item.tabId);
|
||||
if (tabRow == null) return 0;
|
||||
|
||||
// Hidden products still count: the drink is on the tab already
|
||||
final product = await (database.select(
|
||||
database.products,
|
||||
)..where((row) => row.id.equals(item.productId))).getSingleOrNull();
|
||||
await _addDrinks(
|
||||
tabRow,
|
||||
productId: item.productId,
|
||||
productName: product?.name ?? item.productName,
|
||||
unitPriceInCents: product?.priceInCents ?? item.unitPriceInCents,
|
||||
quantity: delta,
|
||||
);
|
||||
await _incrementTabVersion(item.tabId);
|
||||
return delta;
|
||||
}
|
||||
|
||||
final newQuantity = max(item.quantity + delta, 0);
|
||||
final actualDelta = newQuantity - item.quantity;
|
||||
|
||||
if (actualDelta == 0) return 0;
|
||||
|
||||
if (actualDelta > 0) {
|
||||
for (var index = 0; index < actualDelta; index++) {
|
||||
await _recordPurchase(item.id);
|
||||
}
|
||||
} else {
|
||||
await _removeLatestPurchases(item.id, -actualDelta);
|
||||
}
|
||||
|
||||
await _removeLatestPurchases(item.id, -actualDelta);
|
||||
await (database.update(database.tabItems)
|
||||
..where((row) => row.id.equals(tabItemId)))
|
||||
.write(TabItemsCompanion(quantity: Value(newQuantity)));
|
||||
|
||||
Reference in New Issue
Block a user