// lib/providers/receipt_state.dart import 'package:cashumit/models/receipt_group.dart'; class ReceiptState { List groups; DateTime transactionDate; List> accounts; String? destinationAccountId; String? destinationAccountName; String? fireflyUrl; String? accessToken; double paymentAmount; String? tipSourceAccountId; String? tipSourceAccountName; List tags; List availableTags; ReceiptState({ List? groups, DateTime? transactionDate, List>? accounts, this.destinationAccountId, this.destinationAccountName, this.fireflyUrl, this.accessToken, this.paymentAmount = 0.0, this.tipSourceAccountId, this.tipSourceAccountName, List? tags, List? availableTags, }) : groups = groups ?? [], transactionDate = transactionDate ?? DateTime.now(), accounts = accounts ?? [], tags = tags ?? [], availableTags = availableTags ?? []; static const _unset = Object(); ReceiptState copyWith({ List? groups, DateTime? transactionDate, List>? accounts, Object? destinationAccountId = _unset, Object? destinationAccountName = _unset, Object? fireflyUrl = _unset, Object? accessToken = _unset, double? paymentAmount, Object? tipSourceAccountId = _unset, Object? tipSourceAccountName = _unset, List? tags, List? availableTags, }) { return ReceiptState( groups: groups ?? this.groups, transactionDate: transactionDate ?? this.transactionDate, accounts: accounts ?? this.accounts, destinationAccountId: identical(destinationAccountId, _unset) ? this.destinationAccountId : destinationAccountId as String?, destinationAccountName: identical(destinationAccountName, _unset) ? this.destinationAccountName : destinationAccountName as String?, fireflyUrl: identical(fireflyUrl, _unset) ? this.fireflyUrl : fireflyUrl as String?, accessToken: identical(accessToken, _unset) ? this.accessToken : accessToken as String?, paymentAmount: paymentAmount ?? this.paymentAmount, tipSourceAccountId: identical(tipSourceAccountId, _unset) ? this.tipSourceAccountId : tipSourceAccountId as String?, tipSourceAccountName: identical(tipSourceAccountName, _unset) ? this.tipSourceAccountName : tipSourceAccountName as String?, tags: tags ?? this.tags, availableTags: availableTags ?? this.availableTags, ); } // Total gabungan semua grup double get total => groups.fold(0.0, (sum, group) => sum + group.total); // Kembalian double get changeAmount => paymentAmount - total; // Apakah ada tip aktif (akun sumber tip dipilih dan ada kembalian) bool get hasTip => tipSourceAccountId != null && paymentAmount > total; // Nominal tip = kembalian jika tip aktif double get tipAmount => hasTip ? (paymentAmount - total) : 0.0; // Helper validasi bool get hasItems => groups.any((g) => g.items.isNotEmpty); bool get allGroupsHaveSource => groups.isEmpty || groups.every((g) => g.hasSource || g.items.isEmpty); @override String toString() { return 'ReceiptState(groups: $groups, transactionDate: $transactionDate, accounts: $accounts, destinationAccountId: $destinationAccountId, destinationAccountName: $destinationAccountName, fireflyUrl: $fireflyUrl, accessToken: $accessToken, paymentAmount: $paymentAmount, tipSourceAccountId: $tipSourceAccountId, tipSourceAccountName: $tipSourceAccountName)'; } }