cashumit/lib/providers/receipt_state.dart

106 lines
3.6 KiB
Dart

// lib/providers/receipt_state.dart
import 'package:cashumit/models/receipt_group.dart';
class ReceiptState {
List<ReceiptGroup> groups;
DateTime transactionDate;
List<Map<String, dynamic>> accounts;
String? destinationAccountId;
String? destinationAccountName;
String? fireflyUrl;
String? accessToken;
double paymentAmount;
String? tipSourceAccountId;
String? tipSourceAccountName;
List<String> tags;
List<String> availableTags;
ReceiptState({
List<ReceiptGroup>? groups,
DateTime? transactionDate,
List<Map<String, dynamic>>? accounts,
this.destinationAccountId,
this.destinationAccountName,
this.fireflyUrl,
this.accessToken,
this.paymentAmount = 0.0,
this.tipSourceAccountId,
this.tipSourceAccountName,
List<String>? tags,
List<String>? availableTags,
}) : groups = groups ?? [],
transactionDate = transactionDate ?? DateTime.now(),
accounts = accounts ?? [],
tags = tags ?? [],
availableTags = availableTags ?? [];
static const _unset = Object();
ReceiptState copyWith({
List<ReceiptGroup>? groups,
DateTime? transactionDate,
List<Map<String, dynamic>>? accounts,
Object? destinationAccountId = _unset,
Object? destinationAccountName = _unset,
Object? fireflyUrl = _unset,
Object? accessToken = _unset,
double? paymentAmount,
Object? tipSourceAccountId = _unset,
Object? tipSourceAccountName = _unset,
List<String>? tags,
List<String>? 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)';
}
}