Files
TravelMate/lib/models/group_balance.dart
Dayron 4edbd1cf34 feat: Add User and UserBalance models with serialization methods
feat: Implement BalanceRepository for group balance calculations

feat: Create ExpenseRepository for managing expenses

feat: Add services for handling expenses and storage operations

fix: Update import paths for models in repositories and services

refactor: Rename CountContent to AccountContent in HomePage

chore: Add StorageService for image upload and management
2025-10-21 16:02:58 +02:00

93 lines
3.2 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, (sum, settlement) => sum + 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)';
}
}