Mise en place suppression membre
This commit is contained in:
@@ -127,18 +127,44 @@ class MembreRepository extends ChangeNotifier {
|
||||
// Appeler l'API users
|
||||
final response = await ApiService.instance.post('/users', data: data);
|
||||
|
||||
if (response.statusCode == 201 || response.statusCode == 200) {
|
||||
// Créer le membre avec les données retournées par l'API
|
||||
final createdMember = MembreModel.fromJson(response.data);
|
||||
if (response.statusCode == 201) {
|
||||
// Extraire l'ID de la réponse API
|
||||
final responseData = response.data;
|
||||
debugPrint('🎉 Réponse API création utilisateur: $responseData');
|
||||
|
||||
// Sauvegarder localement
|
||||
// L'API retourne {"status":"success","message":"Utilisateur créé avec succès","id":"10027748"}
|
||||
final userId = responseData['id'] is String ? int.parse(responseData['id']) : responseData['id'] as int;
|
||||
|
||||
// Créer le nouveau membre avec l'ID retourné par l'API
|
||||
final createdMember = MembreModel(
|
||||
id: userId,
|
||||
fkEntite: membre.fkEntite,
|
||||
role: membre.role,
|
||||
fkTitre: membre.fkTitre,
|
||||
name: membre.name,
|
||||
firstName: membre.firstName,
|
||||
username: membre.username,
|
||||
sectName: membre.sectName,
|
||||
email: membre.email,
|
||||
phone: membre.phone,
|
||||
mobile: membre.mobile,
|
||||
dateNaissance: membre.dateNaissance,
|
||||
dateEmbauche: membre.dateEmbauche,
|
||||
createdAt: DateTime.now(),
|
||||
isActive: membre.isActive,
|
||||
);
|
||||
|
||||
// Sauvegarder localement dans Hive
|
||||
await saveMembreBox(createdMember);
|
||||
|
||||
return createdMember; // Retourner le membre créé
|
||||
debugPrint('✅ Membre créé avec l\'ID: $userId et sauvegardé localement');
|
||||
return createdMember;
|
||||
}
|
||||
|
||||
debugPrint('❌ Échec création membre - Code: ${response.statusCode}');
|
||||
return null;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la création du membre: $e');
|
||||
debugPrint('❌ Erreur lors de la création du membre: $e');
|
||||
rethrow; // Propager l'exception pour la gestion d'erreurs
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
@@ -174,25 +200,45 @@ class MembreRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Supprimer un membre via l'API
|
||||
Future<bool> deleteMembre(int id) async {
|
||||
// Supprimer un membre via l'API avec transfert optionnel
|
||||
Future<bool> deleteMembre(int membreId, [int? transferToUserId, int? operationId]) async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
// Appeler l'API users au lieu de membres (correction ici)
|
||||
final response = await ApiService.instance.delete('/users/$id');
|
||||
String endpoint = '/users/$membreId';
|
||||
|
||||
// Construire les paramètres query SEULEMENT si on a des passages à transférer
|
||||
List<String> queryParams = [];
|
||||
|
||||
if (transferToUserId != null && transferToUserId > 0) {
|
||||
queryParams.add('transfer_to=$transferToUserId');
|
||||
|
||||
// Ajouter operation_id SEULEMENT s'il y a un transfert
|
||||
if (operationId != null && operationId > 0) {
|
||||
queryParams.add('operation_id=$operationId');
|
||||
}
|
||||
}
|
||||
|
||||
// Ajouter les paramètres à l'endpoint
|
||||
if (queryParams.isNotEmpty) {
|
||||
endpoint += '?${queryParams.join('&')}';
|
||||
}
|
||||
|
||||
debugPrint('🔗 DELETE endpoint: $endpoint');
|
||||
|
||||
final response = await ApiService.instance.delete(endpoint);
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 204) {
|
||||
// Supprimer le membre localement
|
||||
await deleteMembreBox(id);
|
||||
await deleteMembreBox(membreId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la suppression du membre: $e');
|
||||
return false;
|
||||
rethrow;
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
|
||||
@@ -41,6 +41,44 @@ class OperationRepository extends ChangeNotifier {
|
||||
return _operationBox.get(id);
|
||||
}
|
||||
|
||||
OperationModel? getCurrentOperation() {
|
||||
try {
|
||||
// Récupérer toutes les opérations actives
|
||||
final activeOperations = _operationBox.values.where((operation) => operation.isActive == true).toList();
|
||||
|
||||
if (activeOperations.isEmpty) {
|
||||
debugPrint('⚠️ Aucune opération active trouvée');
|
||||
return null;
|
||||
}
|
||||
|
||||
// Trier par ID décroissant et prendre la première (ID le plus élevé)
|
||||
activeOperations.sort((a, b) => b.id.compareTo(a.id));
|
||||
final currentOperation = activeOperations.first;
|
||||
|
||||
debugPrint('🎯 Opération courante: ${currentOperation.id} - ${currentOperation.name}');
|
||||
return currentOperation;
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur lors de la récupération de l\'opération courante: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Méthode helper pour récupérer seulement l'ID de l'opération courante
|
||||
int? getCurrentOperationId() {
|
||||
final currentOperation = getCurrentOperation();
|
||||
return currentOperation?.id;
|
||||
}
|
||||
|
||||
// Méthode pour récupérer toutes les opérations actives (utile pour debug/admin)
|
||||
List<OperationModel> getActiveOperations() {
|
||||
try {
|
||||
return _operationBox.values.where((operation) => operation.isActive == true).toList()..sort((a, b) => b.id.compareTo(a.id)); // Tri par ID décroissant
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur lors de la récupération des opérations actives: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Sauvegarder une opération
|
||||
Future<void> saveOperation(OperationModel operation) async {
|
||||
await _operationBox.put(operation.id, operation);
|
||||
|
||||
@@ -9,6 +9,9 @@ class PassageRepository extends ChangeNotifier {
|
||||
// Constructeur sans paramètres - utilise ApiService.instance
|
||||
PassageRepository();
|
||||
|
||||
// Cache pour les statistiques
|
||||
Map<String, dynamic>? _cachedStats;
|
||||
|
||||
// Utiliser un getter lazy pour n'accéder à la boîte que lorsque nécessaire
|
||||
// et vérifier qu'elle est ouverte avant accès
|
||||
Box<PassageModel> get _passageBox {
|
||||
@@ -16,6 +19,19 @@ class PassageRepository extends ChangeNotifier {
|
||||
return Hive.box<PassageModel>(AppKeys.passagesBoxName);
|
||||
}
|
||||
|
||||
// Méthode pour exposer la Box Hive (nécessaire pour ValueListenableBuilder)
|
||||
Box<PassageModel> getPassagesBox() {
|
||||
try {
|
||||
if (!Hive.isBoxOpen(AppKeys.passagesBoxName)) {
|
||||
throw Exception('La boîte passages n\'est pas ouverte');
|
||||
}
|
||||
return Hive.box<PassageModel>(AppKeys.passagesBoxName);
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de l\'accès à la boîte passages: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// Stream pour notifier des changements de passages
|
||||
StreamController<List<PassageModel>>? _passageStreamController;
|
||||
|
||||
@@ -73,6 +89,16 @@ class PassageRepository extends ChangeNotifier {
|
||||
return _passageBox.values.where((passage) => passage.fkOperation == operationId).toList();
|
||||
}
|
||||
|
||||
// Récupérer les passages par utilisateur
|
||||
List<PassageModel> getPassagesByUser(int userId) {
|
||||
try {
|
||||
return _passageBox.values.where((passage) => passage.fkUser == userId).toList();
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération des passages par utilisateur: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer les passages par date
|
||||
List<PassageModel> getPassagesByDate(DateTime date) {
|
||||
return _passageBox.values.where((passage) {
|
||||
@@ -263,11 +289,14 @@ class PassageRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Statistiques
|
||||
Map<String, int> getPassageStatistics() {
|
||||
// Recalculer les statistiques (appelée par le ValueListenableBuilder)
|
||||
Map<String, dynamic> calculatePassageStatistics() {
|
||||
final allPassages = getAllPassages();
|
||||
|
||||
return {
|
||||
debugPrint('📊 Calcul des statistiques: ${allPassages.length} passages');
|
||||
|
||||
// Statistiques globales
|
||||
final globalStats = {
|
||||
'total': allPassages.length,
|
||||
'effectues': allPassages.where((p) => p.fkType == 1).length,
|
||||
'a_finaliser': allPassages.where((p) => p.fkType == 2).length,
|
||||
@@ -276,6 +305,57 @@ class PassageRepository extends ChangeNotifier {
|
||||
'lots': allPassages.where((p) => p.fkType == 5).length,
|
||||
'maisons_vides': allPassages.where((p) => p.fkType == 6).length,
|
||||
};
|
||||
|
||||
// Statistiques par utilisateur
|
||||
final Map<int, Map<String, int>> statsByUser = {};
|
||||
|
||||
// Grouper les passages par utilisateur
|
||||
final passagesByUser = <int, List<PassageModel>>{};
|
||||
for (final passage in allPassages) {
|
||||
passagesByUser.putIfAbsent(passage.fkUser, () => []).add(passage);
|
||||
}
|
||||
|
||||
// Calculer les statistiques pour chaque utilisateur
|
||||
for (final entry in passagesByUser.entries) {
|
||||
final userId = entry.key;
|
||||
final userPassages = entry.value;
|
||||
|
||||
statsByUser[userId] = {
|
||||
'total': userPassages.length,
|
||||
'effectues': userPassages.where((p) => p.fkType == 1).length,
|
||||
'a_finaliser': userPassages.where((p) => p.fkType == 2).length,
|
||||
'refuses': userPassages.where((p) => p.fkType == 3).length,
|
||||
'dons': userPassages.where((p) => p.fkType == 4).length,
|
||||
'lots': userPassages.where((p) => p.fkType == 5).length,
|
||||
'maisons_vides': userPassages.where((p) => p.fkType == 6).length,
|
||||
};
|
||||
}
|
||||
|
||||
// Statistiques par type
|
||||
final statsByType = {
|
||||
1: allPassages.where((p) => p.fkType == 1).length,
|
||||
2: allPassages.where((p) => p.fkType == 2).length,
|
||||
3: allPassages.where((p) => p.fkType == 3).length,
|
||||
4: allPassages.where((p) => p.fkType == 4).length,
|
||||
5: allPassages.where((p) => p.fkType == 5).length,
|
||||
6: allPassages.where((p) => p.fkType == 6).length,
|
||||
};
|
||||
|
||||
// Mettre en cache et retourner
|
||||
_cachedStats = {
|
||||
'global': globalStats,
|
||||
'by_user': statsByUser,
|
||||
'by_type': statsByType,
|
||||
'user_count': statsByUser.length,
|
||||
'calculated_at': DateTime.now().toIso8601String(),
|
||||
};
|
||||
|
||||
return _cachedStats!;
|
||||
}
|
||||
|
||||
// Getter simple pour les statistiques (optionnel, pour usage sans ValueListenableBuilder)
|
||||
Map<String, dynamic> getPassageStatistics() {
|
||||
return _cachedStats ?? calculatePassageStatistics();
|
||||
}
|
||||
|
||||
// Vider tous les passages
|
||||
|
||||
Reference in New Issue
Block a user