feat: make server own products
This commit is contained in:
@@ -245,6 +245,355 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
// The website changes prices: drinks already on a tab keep theirs, the
|
||||
// next one is charged the new price
|
||||
group('addProductToTab after a price or name change', () {
|
||||
test(
|
||||
'a new price starts a new line; earlier drinks keep theirs',
|
||||
() async {
|
||||
final tab = await service.createTab(customerName: 'John');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(priceInCents: 450),
|
||||
);
|
||||
|
||||
final items = (await service.getTabById(tab.id))!.items;
|
||||
expect([
|
||||
for (final item in items) (item.unitPriceInCents, item.quantity),
|
||||
], unorderedEquals([(400, 2), (450, 1)]));
|
||||
expect((await service.getTabById(tab.id))!.totalInCents, 1250);
|
||||
},
|
||||
);
|
||||
|
||||
test('more drinks at the new price go on the new line', () async {
|
||||
final tab = await service.createTab(customerName: 'John');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(priceInCents: 450),
|
||||
);
|
||||
}
|
||||
|
||||
final items = (await service.getTabById(tab.id))!.items;
|
||||
expect(items, hasLength(2));
|
||||
expect(
|
||||
items.firstWhere((item) => item.unitPriceInCents == 450).quantity,
|
||||
3,
|
||||
);
|
||||
});
|
||||
|
||||
test('a price going back joins the line at that price again', () async {
|
||||
final tab = await service.createTab(customerName: 'John');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(priceInCents: 300),
|
||||
);
|
||||
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
|
||||
final items = (await service.getTabById(tab.id))!.items;
|
||||
expect([
|
||||
for (final item in items) (item.unitPriceInCents, item.quantity),
|
||||
], unorderedEquals([(400, 2), (300, 1)]));
|
||||
});
|
||||
|
||||
test('a renamed product starts a new line under its new name', () async {
|
||||
final tab = await service.createTab(customerName: 'John');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(name: 'Pils'),
|
||||
);
|
||||
|
||||
final items = (await service.getTabById(tab.id))!.items;
|
||||
expect([
|
||||
for (final item in items) item.productName,
|
||||
], unorderedEquals(['Test Beer', 'Pils']));
|
||||
});
|
||||
|
||||
test('both lines count down the stock of the one product', () async {
|
||||
final tab = await service.createTab(customerName: 'John');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(priceInCents: 450),
|
||||
);
|
||||
|
||||
final stored = await (database.select(
|
||||
database.products,
|
||||
)..where((row) => row.id.equals('prod-1'))).getSingle();
|
||||
expect(stored.stockQuantity, 98);
|
||||
});
|
||||
|
||||
test('settling charges each line at its own price', () async {
|
||||
final tab = await service.createTab(customerName: 'John');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(priceInCents: 450),
|
||||
);
|
||||
|
||||
await service.closeTab(tab.id);
|
||||
|
||||
final closed = (await service.getClosedTabs()).single;
|
||||
expect(closed.totalInCents, 850);
|
||||
expect([
|
||||
for (final item in closed.items) item.unitPriceInCents,
|
||||
], unorderedEquals([400, 450]));
|
||||
});
|
||||
});
|
||||
|
||||
// Foo has 2 at the old price; the website changes the price; staff tap +
|
||||
// on Foo's line. The 2 stay at the old price, every new one is charged
|
||||
// the new price.
|
||||
group('+ on a line after a price change', () {
|
||||
Future<void> setPrice(int priceInCents, {String? name}) async {
|
||||
await (database.update(
|
||||
database.products,
|
||||
)..where((row) => row.id.equals('prod-1'))).write(
|
||||
ProductsCompanion(
|
||||
priceInCents: Value(priceInCents),
|
||||
name: name == null ? const Value.absent() : Value(name),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> fooWithTwoAtOldPrice() async {
|
||||
final tab = await service.createTab(customerName: 'Foo');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await setPrice(450);
|
||||
return tab.id;
|
||||
}
|
||||
|
||||
Future<List<(int, int)>> lines(String tabId) async {
|
||||
return [
|
||||
for (final item in (await service.getTabById(tabId))!.items)
|
||||
(item.unitPriceInCents, item.quantity),
|
||||
];
|
||||
}
|
||||
|
||||
Future<String> lineAt(String tabId, int priceInCents) async {
|
||||
return (await service.getTabById(tabId))!.items
|
||||
.firstWhere((item) => item.unitPriceInCents == priceInCents)
|
||||
.id;
|
||||
}
|
||||
|
||||
test(
|
||||
'the old drinks keep their price, the new one gets the new price',
|
||||
() async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
|
||||
final added = await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
expect(added, 1);
|
||||
expect(await lines(tabId), unorderedEquals([(400, 2), (450, 1)]));
|
||||
expect((await service.getTabById(tabId))!.totalInCents, 1250);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'tapping + on the old line again keeps adding at the new price',
|
||||
() async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
final oldLine = await lineAt(tabId, 400);
|
||||
|
||||
await service.adjustTabItemQuantity(tabItemId: oldLine, delta: 1);
|
||||
await service.adjustTabItemQuantity(tabItemId: oldLine, delta: 1);
|
||||
|
||||
expect(await lines(tabId), unorderedEquals([(400, 2), (450, 2)]));
|
||||
},
|
||||
);
|
||||
|
||||
test('+ on the line at the new price adds there', () async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 450),
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
expect(await lines(tabId), unorderedEquals([(400, 2), (450, 2)]));
|
||||
});
|
||||
|
||||
test('the tile and + end up on the same new line', () async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
|
||||
await service.addProductToTab(
|
||||
tabId: tabId,
|
||||
product: createTestProduct(priceInCents: 450),
|
||||
);
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
expect(await lines(tabId), unorderedEquals([(400, 2), (450, 2)]));
|
||||
});
|
||||
|
||||
test('+ several at once adds them all at the new price', () async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
|
||||
final added = await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 3,
|
||||
);
|
||||
|
||||
expect(added, 3);
|
||||
expect(await lines(tabId), unorderedEquals([(400, 2), (450, 3)]));
|
||||
});
|
||||
|
||||
test('− on the old line takes off a drink at the old price', () async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: -1,
|
||||
);
|
||||
|
||||
expect(await lines(tabId), unorderedEquals([(400, 1), (450, 1)]));
|
||||
});
|
||||
|
||||
test('a price going back makes + add to the old line again', () async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
await setPrice(400);
|
||||
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
expect(await lines(tabId), [(400, 3)]);
|
||||
});
|
||||
|
||||
test('a renamed product gets a new line under its new name', () async {
|
||||
final tab = await service.createTab(customerName: 'Foo');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await setPrice(400, name: 'Pils');
|
||||
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: (await service.getTabById(tab.id))!.items.single.id,
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
final names = [
|
||||
for (final item in (await service.getTabById(tab.id))!.items)
|
||||
(item.productName, item.quantity),
|
||||
];
|
||||
expect(names, unorderedEquals([('Test Beer', 1), ('Pils', 1)]));
|
||||
});
|
||||
|
||||
test(
|
||||
'a hidden (archived) product is still charged its latest price',
|
||||
() async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
await (database.update(database.products)
|
||||
..where((row) => row.id.equals('prod-1')))
|
||||
.write(const ProductsCompanion(active: Value(false)));
|
||||
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
expect(await lines(tabId), unorderedEquals([(400, 2), (450, 1)]));
|
||||
},
|
||||
);
|
||||
|
||||
test('a line whose product is gone keeps its own price', () async {
|
||||
final tab = await service.createTab(customerName: 'Foo');
|
||||
await service.addProductToTab(
|
||||
tabId: tab.id,
|
||||
product: createTestProduct(),
|
||||
);
|
||||
await database.delete(database.products).go();
|
||||
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: (await service.getTabById(tab.id))!.items.single.id,
|
||||
delta: 1,
|
||||
);
|
||||
|
||||
expect(await lines(tab.id), [(400, 2)]);
|
||||
});
|
||||
|
||||
test('another tab without the product gets the new price', () async {
|
||||
await fooWithTwoAtOldPrice();
|
||||
final bar = await service.createTab(customerName: 'Bar');
|
||||
|
||||
await service.addProductToTab(
|
||||
tabId: bar.id,
|
||||
product: createTestProduct(priceInCents: 450),
|
||||
);
|
||||
|
||||
expect(await lines(bar.id), [(450, 1)]);
|
||||
});
|
||||
|
||||
test('every drink counts down the stock of the one product', () async {
|
||||
final tabId = await fooWithTwoAtOldPrice();
|
||||
|
||||
await service.adjustTabItemQuantity(
|
||||
tabItemId: await lineAt(tabId, 400),
|
||||
delta: 2,
|
||||
);
|
||||
|
||||
final stored = await (database.select(
|
||||
database.products,
|
||||
)..where((row) => row.id.equals('prod-1'))).getSingle();
|
||||
expect(stored.stockQuantity, 96);
|
||||
});
|
||||
});
|
||||
|
||||
group('adjustTabItemQuantity', () {
|
||||
test('updates item quantity', () async {
|
||||
final tab = await service.createTab(customerName: 'John');
|
||||
|
||||
Reference in New Issue
Block a user