112 lines
3.4 KiB
Dart
112 lines
3.4 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:equatable/equatable.dart';
|
|
import 'user_balance.dart';
|
|
import 'settlement.dart';
|
|
|
|
class GroupBalance extends Equatable {
|
|
final String groupId;
|
|
final List<UserBalance> userBalances;
|
|
final List<Settlement> settlements;
|
|
final double totalExpenses;
|
|
final DateTime calculatedAt;
|
|
|
|
const GroupBalance({
|
|
required this.groupId,
|
|
required this.userBalances,
|
|
required this.settlements,
|
|
required this.totalExpenses,
|
|
required this.calculatedAt,
|
|
});
|
|
|
|
// Constructeur factory pour créer depuis une Map
|
|
factory GroupBalance.fromMap(Map<String, dynamic> map) {
|
|
return GroupBalance(
|
|
groupId: map['groupId'] ?? '',
|
|
userBalances:
|
|
(map['userBalances'] as List?)
|
|
?.map(
|
|
(userBalance) =>
|
|
UserBalance.fromMap(userBalance as Map<String, dynamic>),
|
|
)
|
|
.toList() ??
|
|
[],
|
|
settlements:
|
|
(map['settlements'] as List?)
|
|
?.map(
|
|
(settlement) =>
|
|
Settlement.fromMap(settlement as Map<String, dynamic>),
|
|
)
|
|
.toList() ??
|
|
[],
|
|
totalExpenses: (map['totalExpenses'] as num?)?.toDouble() ?? 0.0,
|
|
calculatedAt: _parseDateTime(map['calculatedAt']),
|
|
);
|
|
}
|
|
|
|
// Convertir en Map pour Firestore
|
|
Map<String, dynamic> toMap() {
|
|
return {
|
|
'groupId': groupId,
|
|
'userBalances': userBalances
|
|
.map((userBalance) => userBalance.toMap())
|
|
.toList(),
|
|
'settlements': settlements
|
|
.map((settlement) => settlement.toMap())
|
|
.toList(),
|
|
'totalExpenses': totalExpenses,
|
|
'calculatedAt': Timestamp.fromDate(calculatedAt),
|
|
};
|
|
}
|
|
|
|
// Méthode copyWith pour créer une copie modifiée
|
|
GroupBalance copyWith({
|
|
String? groupId,
|
|
List<UserBalance>? userBalances,
|
|
List<Settlement>? settlements,
|
|
double? totalExpenses,
|
|
DateTime? calculatedAt,
|
|
}) {
|
|
return GroupBalance(
|
|
groupId: groupId ?? this.groupId,
|
|
userBalances: userBalances ?? this.userBalances,
|
|
settlements: settlements ?? this.settlements,
|
|
totalExpenses: totalExpenses ?? this.totalExpenses,
|
|
calculatedAt: calculatedAt ?? this.calculatedAt,
|
|
);
|
|
}
|
|
|
|
// Helper pour parser les dates de différents formats
|
|
static DateTime _parseDateTime(dynamic value) {
|
|
if (value is Timestamp) return value.toDate();
|
|
if (value is String) return DateTime.parse(value);
|
|
if (value is DateTime) return value;
|
|
if (value is int) return DateTime.fromMillisecondsSinceEpoch(value);
|
|
return DateTime.now();
|
|
}
|
|
|
|
// Méthodes utilitaires pour la logique métier
|
|
bool get hasUnbalancedUsers =>
|
|
userBalances.any((balance) => !balance.isBalanced);
|
|
|
|
bool get hasSettlements => settlements.isNotEmpty;
|
|
|
|
double get totalSettlementAmount =>
|
|
settlements.fold(0.0, (total, settlement) => total + settlement.amount);
|
|
|
|
List<UserBalance> get creditors =>
|
|
userBalances.where((b) => b.shouldReceive).toList();
|
|
|
|
List<UserBalance> get debtors =>
|
|
userBalances.where((b) => b.shouldPay).toList();
|
|
|
|
int get participantCount => userBalances.length;
|
|
|
|
@override
|
|
List<Object?> get props => [groupId, calculatedAt];
|
|
|
|
@override
|
|
String toString() {
|
|
return 'GroupBalance(groupId: $groupId, totalExpenses: $totalExpenses, participantCount: $participantCount, calculatedAt: $calculatedAt)';
|
|
}
|
|
}
|