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
130 lines
3.8 KiB
Dart
130 lines
3.8 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:equatable/equatable.dart';
|
|
|
|
class Settlement extends Equatable {
|
|
final String fromUserId;
|
|
final String fromUserName;
|
|
final String toUserId;
|
|
final String toUserName;
|
|
final double amount;
|
|
final bool isCompleted;
|
|
final DateTime? completedAt;
|
|
|
|
const Settlement({
|
|
required this.fromUserId,
|
|
required this.fromUserName,
|
|
required this.toUserId,
|
|
required this.toUserName,
|
|
required this.amount,
|
|
this.isCompleted = false,
|
|
this.completedAt,
|
|
});
|
|
|
|
// Constructeur factory pour créer depuis une Map
|
|
factory Settlement.fromMap(Map<String, dynamic> map) {
|
|
return Settlement(
|
|
fromUserId: map['fromUserId'] ?? '',
|
|
fromUserName: map['fromUserName'] ?? '',
|
|
toUserId: map['toUserId'] ?? '',
|
|
toUserName: map['toUserName'] ?? '',
|
|
amount: (map['amount'] as num?)?.toDouble() ?? 0.0,
|
|
isCompleted: map['isCompleted'] ?? false,
|
|
completedAt: map['completedAt'] != null
|
|
? _parseDateTime(map['completedAt'])
|
|
: null,
|
|
);
|
|
}
|
|
|
|
// Convertir en Map pour la sérialisation
|
|
Map<String, dynamic> toMap() {
|
|
return {
|
|
'fromUserId': fromUserId,
|
|
'fromUserName': fromUserName,
|
|
'toUserId': toUserId,
|
|
'toUserName': toUserName,
|
|
'amount': amount,
|
|
'isCompleted': isCompleted,
|
|
'completedAt': completedAt != null
|
|
? Timestamp.fromDate(completedAt!)
|
|
: null,
|
|
};
|
|
}
|
|
|
|
// Méthode copyWith étendue pour créer une copie modifiée
|
|
Settlement copyWith({
|
|
String? fromUserId,
|
|
String? fromUserName,
|
|
String? toUserId,
|
|
String? toUserName,
|
|
double? amount,
|
|
bool? isCompleted,
|
|
DateTime? completedAt,
|
|
}) {
|
|
return Settlement(
|
|
fromUserId: fromUserId ?? this.fromUserId,
|
|
fromUserName: fromUserName ?? this.fromUserName,
|
|
toUserId: toUserId ?? this.toUserId,
|
|
toUserName: toUserName ?? this.toUserName,
|
|
amount: amount ?? this.amount,
|
|
isCompleted: isCompleted ?? this.isCompleted,
|
|
completedAt: completedAt ?? this.completedAt,
|
|
);
|
|
}
|
|
|
|
// Constructeur factory pour marquer comme complété
|
|
factory Settlement.completed(Settlement settlement) {
|
|
return settlement.copyWith(
|
|
isCompleted: true,
|
|
completedAt: DateTime.now(),
|
|
);
|
|
}
|
|
|
|
// 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();
|
|
}
|
|
|
|
// Getters utilitaires pour la logique métier
|
|
bool get isPending => !isCompleted;
|
|
|
|
String get formattedAmount => '${amount.toStringAsFixed(2)} €';
|
|
|
|
String get description => '$fromUserName doit ${formattedAmount} à $toUserName';
|
|
|
|
String get shortDescription => '$fromUserName → $toUserName';
|
|
|
|
String get status => isCompleted ? 'Payé' : 'En attente';
|
|
|
|
// Durée depuis la completion (si applicable)
|
|
Duration? get timeSinceCompletion {
|
|
if (completedAt == null) return null;
|
|
return DateTime.now().difference(completedAt!);
|
|
}
|
|
|
|
// Formatage de la date de completion
|
|
String get formattedCompletedAt {
|
|
if (completedAt == null) return 'Non payé';
|
|
return 'Payé le ${completedAt!.day}/${completedAt!.month}/${completedAt!.year}';
|
|
}
|
|
|
|
// Méthodes de validation
|
|
bool get isValid =>
|
|
fromUserId.isNotEmpty &&
|
|
toUserId.isNotEmpty &&
|
|
fromUserId != toUserId &&
|
|
amount > 0;
|
|
|
|
bool get isSelfSettlement => fromUserId == toUserId;
|
|
|
|
@override
|
|
List<Object?> get props => [fromUserId, toUserId, amount, isCompleted];
|
|
|
|
@override
|
|
String toString() {
|
|
return 'Settlement(${shortDescription}: ${formattedAmount}, status: $status)';
|
|
}
|
|
} |