/// A confirmed shopping trip saved from a receipt. library; class Shop { const Shop({ required this.id, required this.supermarket, required this.shoppedAt, required this.total, required this.itemCount, this.name, this.receiptImagePath, this.tags = const [], }); final int id; final String supermarket; final String? name; final DateTime shoppedAt; final double total; final int itemCount; final String? receiptImagePath; final List tags; String get displayName { final tripName = name?.trim(); if (tripName != null && tripName.isNotEmpty) return tripName; return supermarket; } Shop copyWith({String? name, bool clearName = false, List? tags}) { return Shop( id: id, supermarket: supermarket, shoppedAt: shoppedAt, total: total, itemCount: itemCount, receiptImagePath: receiptImagePath, name: clearName ? null : (name ?? this.name), tags: tags ?? this.tags, ); } factory Shop.fromMap(Map map) { final rawName = (map['name'] as String?)?.trim(); return Shop( id: map['id']! as int, supermarket: map['supermarket']! as String, name: (rawName == null || rawName.isEmpty) ? null : rawName, shoppedAt: DateTime.parse(map['shopped_at']! as String), total: (map['total'] as num).toDouble(), itemCount: (map['item_count'] as num?)?.toInt() ?? 0, receiptImagePath: map['receipt_image_path'] as String?, ); } } class ShopItem { const ShopItem({ required this.id, required this.shopId, this.productId, required this.name, required this.price, this.quantity, this.unitPrice, }); final int id; final int shopId; final int? productId; final String name; final double price; final int? quantity; final double? unitPrice; factory ShopItem.fromMap(Map map) { return ShopItem( id: map['id']! as int, shopId: map['shop_id']! as int, productId: map['product_id'] as int?, name: map['name']! as String, price: (map['price'] as num).toDouble(), quantity: map['quantity'] as int?, unitPrice: (map['unit_price'] as num?)?.toDouble(), ); } }