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 applyServerCatalog(List 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)), ); } }); } }