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
This commit is contained in:
130
lib/models/settlement.dart
Normal file
130
lib/models/settlement.dart
Normal file
@@ -0,0 +1,130 @@
|
||||
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)';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user