feat: make server own products

This commit is contained in:
2026-10-21 12:10:42 +02:00
parent 93acfe15a9
commit b15d94a805
21 changed files with 1717 additions and 106 deletions
+73
View File
@@ -0,0 +1,73 @@
import 'package:drift/drift.dart';
import '../models/remote_command.dart';
import 'app_database.dart';
/// The product catalog as the website manages it.
extension CatalogQueries on AppDatabase {
/// Makes the local products match [catalog]: new products are added,
/// changed ones updated, archived ones and products the server doesn't
/// know (such as the default products of a new tablet) are hidden. Hidden,
/// not deleted: open tabs and the history refer to them.
///
/// The stock is not touched here: the stock rebase that follows sets it, a
/// new product starts as untracked until then. Local images are kept.
Future<void> applyServerCatalog(List<ServerProduct> catalog) {
return transaction(() async {
final local = {
for (final row in await select(products).get()) row.id: row,
};
for (final product in catalog) {
final category = product.category ?? '';
final lowStockThreshold = product.lowStockThreshold ?? 0;
final existing = local.remove(product.id);
if (existing == null) {
await into(products).insert(
ProductsCompanion.insert(
id: product.id,
name: product.name,
category: category,
stockQuantity: 0,
lowStockThreshold: lowStockThreshold,
infiniteStock: const Value(true),
priceInCents: product.priceInCents,
active: Value(!product.archived),
),
);
continue;
}
if (existing.name == product.name &&
existing.category == category &&
existing.priceInCents == product.priceInCents &&
existing.lowStockThreshold == lowStockThreshold &&
existing.active == !product.archived) {
continue;
}
await (update(
products,
)..where((row) => row.id.equals(product.id))).write(
ProductsCompanion(
name: Value(product.name),
category: Value(category),
priceInCents: Value(product.priceInCents),
lowStockThreshold: Value(lowStockThreshold),
active: Value(!product.archived),
),
);
}
final unknown = [
for (final row in local.values)
if (row.active) row.id,
];
if (unknown.isNotEmpty) {
await (update(products)..where((row) => row.id.isIn(unknown))).write(
const ProductsCompanion(active: Value(false)),
);
}
});
}
}