import 'format.dart'; class AppUser { const AppUser({ required this.id, required this.username, required this.isAdmin, required this.active, required this.shopIds, this.phone, this.sendResults = false, }); final int id; final String username; final String? phone; final bool isAdmin; final bool active; final List shopIds; final bool sendResults; bool get getsResults => sendResults && active && phone != null; } class Shop { const Shop({ required this.id, required this.code, required this.name, this.active = true, }); final int id; final String code; final String name; final bool active; Shop copyWith({String? name, bool? active}) => Shop( id: id, code: code, name: name ?? this.name, active: active ?? this.active, ); } class DrawInfo { const DrawInfo({ required this.date, required this.published, this.scheme, this.code, this.hasWin = false, }); final DateTime date; final String? scheme; final String? code; final bool published; final bool hasWin; String get label => published ? '$scheme ยท $code' : 'No result yet'; } class PrizeHit { const PrizeHit({required this.tier, required this.amount}); final int tier; final int amount; } class EndingQty { const EndingQty({ required this.ending, required this.qty, this.hits = const [], }); final String ending; final int qty; final List hits; bool get wins => hits.isNotEmpty; int get perTicket => hits.fold(0, (a, h) => a + h.amount); int get prize => qty * perTicket; String get tierText => tiersLabel([for (final h in hits) h.tier]); } class Order { const Order({ required this.id, required this.shop, required this.drawDate, required this.time, required this.isPhoto, required this.edited, required this.lines, this.rawText, }); final int id; final Shop shop; final DateTime drawDate; final DateTime time; final bool isPhoto; final bool edited; final String? rawText; final List lines; int get tickets => lines.fold(0, (a, l) => a + l.qty); int get prize => lines.fold(0, (a, l) => a + l.prize); int get winTickets => lines.where((l) => l.wins).fold(0, (a, l) => a + l.qty); } class ShopResult { const ShopResult({ required this.shop, required this.tickets, required this.orders, required this.winTickets, required this.prize, }); final Shop shop; final int tickets; final int orders; final int winTickets; final int prize; } class DrawResults { const DrawResults({required this.draw, required this.shops}); final DrawInfo draw; final List shops; int get totalPrize => shops.fold(0, (a, s) => a + s.prize); int get winningTickets => shops.fold(0, (a, s) => a + s.winTickets); int get totalTickets => shops.fold(0, (a, s) => a + s.tickets); int get orders => shops.fold(0, (a, s) => a + s.orders); int get winningShops => shops.where((s) => s.prize > 0).length; ShopResult? get topShop => shops.isNotEmpty && shops.first.prize > 0 ? shops.first : null; } class ShopDay { const ShopDay({ required this.shop, required this.tickets, required this.orders, required this.endings, }); final Shop shop; final int tickets; final int orders; final int endings; } class ShopDetail { const ShopDetail({ required this.shop, required this.draw, required this.endings, required this.orders, }); final Shop shop; final DrawInfo draw; final List endings; final List orders; int get tickets => endings.fold(0, (a, e) => a + e.qty); List get wins => endings.where((e) => e.wins).toList(); int get winTickets => wins.fold(0, (a, e) => a + e.qty); int get prize => wins.fold(0, (a, e) => a + e.prize); }