Fix: Hive sync et update entité via API REST
- Correction mapping JSON membres (fk_role, chk_active) - Ajout traitement amicale au login - Fix callback onSubmit pour sync Hive après update API
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:geosector_app/core/data/models/amicale_model.dart';
|
||||
import 'package:geosector_app/core/services/api_service.dart';
|
||||
@@ -34,6 +31,19 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Méthode pour exposer la Box Hive (nécessaire pour ValueListenableBuilder)
|
||||
Box<AmicaleModel> getAmicalesBox() {
|
||||
try {
|
||||
if (!Hive.isBoxOpen(AppKeys.amicaleBoxName)) {
|
||||
throw Exception('La boîte amicales n\'est pas ouverte');
|
||||
}
|
||||
return _amicaleBox;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de l\'accès à la boîte amicales: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer toutes les amicales
|
||||
List<AmicaleModel> getAllAmicales() {
|
||||
return _amicaleBox.values.toList();
|
||||
@@ -54,6 +64,16 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
return getAmicalesByType(1);
|
||||
}
|
||||
|
||||
// Récupérer l'amicale de l'utilisateur connecté (basé sur fkEntite)
|
||||
AmicaleModel? getAmicaleByUserId(int userId, int fkEntite) {
|
||||
try {
|
||||
return _amicaleBox.get(fkEntite);
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération de l\'amicale de l\'utilisateur: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Sauvegarder une amicale
|
||||
Future<void> saveAmicale(AmicaleModel amicale) async {
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
@@ -66,6 +86,12 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// Vider la boîte des amicales
|
||||
Future<void> clearAmicales() async {
|
||||
await _amicaleBox.clear();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// Créer une amicale via l'API
|
||||
Future<bool> createAmicale(AmicaleModel amicale) async {
|
||||
_isLoading = true;
|
||||
@@ -82,14 +108,33 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
// Récupérer l'ID de la nouvelle amicale
|
||||
final amicaleId = response.data['id'] is String ? int.parse(response.data['id']) : response.data['id'] as int;
|
||||
|
||||
// Créer l'amicale localement avec l'ID retourné par l'API
|
||||
final newAmicale = amicale.copyWith(
|
||||
// Créer l'amicale localement avec l'ID retourné par l'API et updatedAt
|
||||
final amicaleWithNewId = AmicaleModel(
|
||||
id: amicaleId,
|
||||
lastSyncedAt: DateTime.now(),
|
||||
isSynced: true,
|
||||
name: amicale.name,
|
||||
adresse1: amicale.adresse1,
|
||||
adresse2: amicale.adresse2,
|
||||
codePostal: amicale.codePostal,
|
||||
ville: amicale.ville,
|
||||
fkRegion: amicale.fkRegion,
|
||||
libRegion: amicale.libRegion,
|
||||
fkType: amicale.fkType,
|
||||
phone: amicale.phone,
|
||||
mobile: amicale.mobile,
|
||||
email: amicale.email,
|
||||
gpsLat: amicale.gpsLat,
|
||||
gpsLng: amicale.gpsLng,
|
||||
stripeId: amicale.stripeId,
|
||||
chkDemo: amicale.chkDemo,
|
||||
chkCopieMailRecu: amicale.chkCopieMailRecu,
|
||||
chkAcceptSms: amicale.chkAcceptSms,
|
||||
chkActive: amicale.chkActive,
|
||||
chkStripe: amicale.chkStripe,
|
||||
createdAt: amicale.createdAt ?? DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
await saveAmicale(newAmicale);
|
||||
await saveAmicale(amicaleWithNewId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -116,10 +161,9 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
final response = await ApiService.instance.put('/amicales/${amicale.id}', data: data);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Mettre à jour l'amicale localement
|
||||
// Mettre à jour l'amicale localement avec updatedAt
|
||||
final updatedAmicale = amicale.copyWith(
|
||||
lastSyncedAt: DateTime.now(),
|
||||
isSynced: true,
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
await saveAmicale(updatedAmicale);
|
||||
@@ -136,6 +180,35 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Mettre à jour une amicale via l'API (version alternative avec retour d'objet)
|
||||
Future<AmicaleModel?> updateAmicaleViaApi(AmicaleModel amicale) async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final response = await ApiService.instance.put(
|
||||
'/amicales/${amicale.id}',
|
||||
data: amicale.toJson(),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final updatedAmicaleData = response.data;
|
||||
final updatedAmicale = AmicaleModel.fromJson(updatedAmicaleData);
|
||||
await saveAmicale(updatedAmicale);
|
||||
return updatedAmicale;
|
||||
} else {
|
||||
debugPrint('Erreur lors de la mise à jour de l\'amicale: ${response.statusCode}');
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la mise à jour de l\'amicale: $e');
|
||||
return null;
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// Supprimer une amicale via l'API
|
||||
Future<bool> deleteAmicaleViaApi(int id) async {
|
||||
_isLoading = true;
|
||||
@@ -161,228 +234,55 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Traitement des données d'amicales depuis l'API
|
||||
Future<void> processAmicalesData(dynamic amicalesData) async {
|
||||
// Traitement des données d'amicale depuis l'API (amicale unique)
|
||||
Future<void> processAmicalesData(dynamic amicaleData) async {
|
||||
try {
|
||||
debugPrint('Traitement des données des amicales...');
|
||||
debugPrint('Traitement de l\'amicale utilisateur...');
|
||||
|
||||
// Vérifier que les données sont au bon format
|
||||
if (amicalesData == null) {
|
||||
if (amicaleData == null) {
|
||||
debugPrint('Aucune donnée d\'amicale à traiter');
|
||||
return;
|
||||
}
|
||||
|
||||
List<dynamic> amicalesList;
|
||||
if (amicalesData is List) {
|
||||
amicalesList = amicalesData;
|
||||
} else if (amicalesData is Map && amicalesData.containsKey('data')) {
|
||||
amicalesList = amicalesData['data'] as List<dynamic>;
|
||||
} else {
|
||||
debugPrint('Format de données d\'amicales non reconnu');
|
||||
return;
|
||||
}
|
||||
|
||||
// Vider la boîte avant d'ajouter les nouvelles données
|
||||
// Vider la boîte avant d'ajouter la nouvelle amicale
|
||||
await _amicaleBox.clear();
|
||||
|
||||
// Traiter chaque amicale
|
||||
int count = 0;
|
||||
for (final amicaleData in amicalesList) {
|
||||
try {
|
||||
final amicale = AmicaleModel.fromJson(amicaleData);
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
count++;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du traitement d\'une amicale: $e');
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint('$count amicales traitées et stockées');
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du traitement des amicales: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
import 'package:geosector_app/core/services/api_service.dart';
|
||||
import 'package:geosector_app/core/data/models/amicale_model.dart';
|
||||
|
||||
class AmicaleRepository extends ChangeNotifier {
|
||||
// Utilisation de getters lazy pour n'accéder à la boîte que lorsque nécessaire
|
||||
Box<AmicaleModel> get _amicaleBox => Hive.box<AmicaleModel>(AppKeys.amicaleBoxName);
|
||||
|
||||
final ApiService _apiService;
|
||||
bool _isLoading = false;
|
||||
|
||||
AmicaleRepository(this._apiService);
|
||||
|
||||
// Getters
|
||||
bool get isLoading => _isLoading;
|
||||
|
||||
// Méthode pour exposer la Box Hive (nécessaire pour ValueListenableBuilder)
|
||||
Box<AmicaleModel> getAmicalesBox() {
|
||||
try {
|
||||
if (!Hive.isBoxOpen(AppKeys.amicaleBoxName)) {
|
||||
throw Exception('La boîte amicales n\'est pas ouverte');
|
||||
}
|
||||
return _amicaleBox;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de l\'accès à la boîte amicales: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// Méthode pour vérifier si une boîte est ouverte et l'ouvrir si nécessaire
|
||||
Future<void> _ensureBoxIsOpen() async {
|
||||
try {
|
||||
if (!Hive.isBoxOpen(AppKeys.amicaleBoxName)) {
|
||||
debugPrint('Ouverture de la boîte amicale...');
|
||||
await Hive.openBox<AmicaleModel>(AppKeys.amicaleBoxName);
|
||||
try {
|
||||
// Les données sont un objet amicale unique
|
||||
final Map<String, dynamic> amicaleMap = Map<String, dynamic>.from(amicaleData as Map);
|
||||
final amicale = AmicaleModel.fromJson(amicaleMap);
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
debugPrint('✅ Amicale utilisateur traitée: ${amicale.name} (ID: ${amicale.id})');
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur lors du traitement de l\'amicale: $e');
|
||||
debugPrint('Données reçues: $amicaleData');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de l\'ouverture de la boîte amicale: $e');
|
||||
throw Exception('Impossible d\'ouvrir la boîte amicale: $e');
|
||||
debugPrint('❌ Erreur lors du traitement de l\'amicale: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer toutes les amicales
|
||||
List<AmicaleModel> getAllAmicales() {
|
||||
// Méthode spécifique pour récupérer l'amicale de l'utilisateur connecté
|
||||
AmicaleModel? getUserAmicale(int fkEntite) {
|
||||
try {
|
||||
_ensureBoxIsOpen();
|
||||
return _amicaleBox.values.toList();
|
||||
final amicale = _amicaleBox.get(fkEntite);
|
||||
debugPrint('🔍 Recherche amicale ID $fkEntite: ${amicale?.name ?? 'non trouvée'}');
|
||||
return amicale;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération des amicales: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer une amicale par son ID
|
||||
AmicaleModel? getAmicaleById(int id) {
|
||||
try {
|
||||
_ensureBoxIsOpen();
|
||||
return _amicaleBox.get(id);
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération de l\'amicale: $e');
|
||||
debugPrint('❌ Erreur lors de la récupération de l\'amicale utilisateur: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer l'amicale de l'utilisateur connecté (basé sur fkEntite)
|
||||
AmicaleModel? getAmicaleByUserId(int userId, int fkEntite) {
|
||||
try {
|
||||
_ensureBoxIsOpen();
|
||||
return _amicaleBox.get(fkEntite);
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération de l\'amicale de l\'utilisateur: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Créer ou mettre à jour une amicale localement
|
||||
Future<AmicaleModel> saveAmicale(AmicaleModel amicale) async {
|
||||
await _ensureBoxIsOpen();
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
notifyListeners(); // Notifier les changements pour mettre à jour l'UI
|
||||
return amicale;
|
||||
}
|
||||
|
||||
// Supprimer une amicale localement
|
||||
Future<void> deleteAmicale(int id) async {
|
||||
await _ensureBoxIsOpen();
|
||||
await _amicaleBox.delete(id);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// Vider la boîte des amicales
|
||||
Future<void> clearAmicales() async {
|
||||
await _ensureBoxIsOpen();
|
||||
await _amicaleBox.clear();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// Traiter les données des amicales reçues de l'API
|
||||
Future<void> processAmicalesData(dynamic amicalesData) async {
|
||||
try {
|
||||
debugPrint('Traitement des données des amicales...');
|
||||
debugPrint('Détails amicale: $amicalesData');
|
||||
|
||||
// Vérifier que les données sont au bon format
|
||||
if (amicalesData == null) {
|
||||
debugPrint('Aucune donnée d\'amicale à traiter');
|
||||
return;
|
||||
}
|
||||
|
||||
// Vider la boîte avant d'ajouter les nouvelles données
|
||||
await _ensureBoxIsOpen();
|
||||
await _amicaleBox.clear();
|
||||
|
||||
int count = 0;
|
||||
|
||||
// Cas 1: Les données sont une liste d'amicales
|
||||
if (amicalesData is List) {
|
||||
for (final amicaleData in amicalesData) {
|
||||
try {
|
||||
final amicale = AmicaleModel.fromJson(amicaleData);
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
count++;
|
||||
debugPrint('Amicale traitée: ${amicale.name} (ID: ${amicale.id})');
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du traitement d\'une amicale: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cas 2: Les données sont un objet avec une clé 'data' contenant une liste
|
||||
else if (amicalesData is Map && amicalesData.containsKey('data')) {
|
||||
final amicalesList = amicalesData['data'] as List<dynamic>;
|
||||
for (final amicaleData in amicalesList) {
|
||||
try {
|
||||
final amicale = AmicaleModel.fromJson(amicaleData);
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
count++;
|
||||
debugPrint('Amicale traitée: ${amicale.name} (ID: ${amicale.id})');
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du traitement d\'une amicale: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cas 3: Les données sont un objet amicale unique (pas une liste)
|
||||
else if (amicalesData is Map) {
|
||||
try {
|
||||
// Convertir Map<dynamic, dynamic> en Map<String, dynamic>
|
||||
final Map<String, dynamic> amicaleMap = {};
|
||||
amicalesData.forEach((key, value) {
|
||||
if (key is String) {
|
||||
amicaleMap[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
final amicale = AmicaleModel.fromJson(amicaleMap);
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
count++;
|
||||
debugPrint('Amicale unique traitée: ${amicale.name} (ID: ${amicale.id})');
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du traitement de l\'amicale unique: $e');
|
||||
debugPrint('Exception détaillée: $e');
|
||||
}
|
||||
} else {
|
||||
debugPrint('Format de données d\'amicale non reconnu');
|
||||
return;
|
||||
}
|
||||
|
||||
debugPrint('$count amicales traitées et stockées');
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du traitement des amicales: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer les amicales depuis l'API
|
||||
Future<List<AmicaleModel>> fetchAmicalesFromApi() async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final response = await _apiService.get('/amicales');
|
||||
final response = await ApiService.instance.get('/amicales');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final amicalesData = response.data;
|
||||
@@ -407,7 +307,7 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final response = await _apiService.get('/amicales/$id');
|
||||
final response = await ApiService.instance.get('/amicales/$id');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final amicaleData = response.data;
|
||||
@@ -427,34 +327,7 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// Mettre à jour une amicale via l'API
|
||||
Future<AmicaleModel?> updateAmicaleViaApi(AmicaleModel amicale) async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final response = await _apiService.put(
|
||||
'/amicales/${amicale.id}',
|
||||
data: amicale.toJson(),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final updatedAmicaleData = response.data;
|
||||
final updatedAmicale = AmicaleModel.fromJson(updatedAmicaleData);
|
||||
await saveAmicale(updatedAmicale);
|
||||
return updatedAmicale;
|
||||
} else {
|
||||
debugPrint('Erreur lors de la mise à jour de l\'amicale: ${response.statusCode}');
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la mise à jour de l\'amicale: $e');
|
||||
return null;
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
// === MÉTHODES DE FILTRAGE ET RECHERCHE ===
|
||||
|
||||
// Filtrer les amicales par nom
|
||||
List<AmicaleModel> searchAmicalesByName(String query) {
|
||||
@@ -466,11 +339,6 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
return _amicaleBox.values.where((amicale) => amicale.name.toLowerCase().contains(lowercaseQuery)).toList();
|
||||
}
|
||||
|
||||
// Filtrer les amicales par type
|
||||
List<AmicaleModel> getAmicalesByType(int type) {
|
||||
return _amicaleBox.values.where((amicale) => amicale.fkType == type).toList();
|
||||
}
|
||||
|
||||
// Filtrer les amicales par région
|
||||
List<AmicaleModel> getAmicalesByRegion(int regionId) {
|
||||
return _amicaleBox.values.where((amicale) => amicale.fkRegion == regionId).toList();
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
class ClientRepository extends ChangeNotifier {
|
||||
// Constructeur sans paramètres - utilise ApiService.instance
|
||||
ClientRepository();
|
||||
|
||||
// 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<ClientModel> get _clientBox {
|
||||
@@ -58,8 +59,11 @@ class ClientRepository extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
// Préparer les données pour l'API
|
||||
// Préparer les données pour l'API - exclure l'id pour la création
|
||||
final data = client.toJson();
|
||||
data.remove('id'); // L'API génère l'ID
|
||||
data.remove('created_at'); // L'API génère created_at
|
||||
data.remove('updated_at'); // L'API génère updated_at
|
||||
|
||||
// Appeler l'API pour créer le client
|
||||
final response = await ApiService.instance.post('/clients', data: data);
|
||||
@@ -70,11 +74,13 @@ class ClientRepository extends ChangeNotifier {
|
||||
|
||||
// Créer le client localement avec l'ID retourné par l'API
|
||||
final newClient = client.copyWith(
|
||||
id: clientId,
|
||||
lastSyncedAt: DateTime.now(),
|
||||
isSynced: true,
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
await saveClient(newClient);
|
||||
|
||||
// Sauvegarder avec le nouvel ID
|
||||
await _clientBox.put(clientId, newClient);
|
||||
notifyListeners();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -95,17 +101,14 @@ class ClientRepository extends ChangeNotifier {
|
||||
try {
|
||||
// Préparer les données pour l'API
|
||||
final data = client.toJson();
|
||||
|
||||
// Appeler l'API pour mettre à jour le client
|
||||
final response = await ApiService.instance.put('/clients/${client.id}', data: data);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Mettre à jour le client localement
|
||||
// Mettre à jour le client localement avec updatedAt
|
||||
final updatedClient = client.copyWith(
|
||||
lastSyncedAt: DateTime.now(),
|
||||
isSynced: true,
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
|
||||
await saveClient(updatedClient);
|
||||
return true;
|
||||
}
|
||||
@@ -190,7 +193,6 @@ class ClientRepository extends ChangeNotifier {
|
||||
|
||||
// Vider la boîte des clients
|
||||
Future<void> clearClients() async {
|
||||
await _ensureBoxIsOpen();
|
||||
await _clientBox.clear();
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -220,6 +222,7 @@ class ClientRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// === MÉTHODES DE FILTRAGE ET RECHERCHE ===
|
||||
// Filtrer les clients par nom
|
||||
List<ClientModel> searchClientsByName(String query) {
|
||||
if (query.isEmpty) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
class MembreRepository extends ChangeNotifier {
|
||||
// Constructeur sans paramètres - utilise ApiService.instance
|
||||
MembreRepository();
|
||||
|
||||
// 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<MembreModel> get _membreBox {
|
||||
@@ -43,6 +44,9 @@ class MembreRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// === MÉTHODES SPÉCIFIQUES AUX MEMBRES ===
|
||||
|
||||
// Récupérer les membres par amicale
|
||||
List<MembreModel> getMembresByAmicale(int fkEntite) {
|
||||
try {
|
||||
return _membreBox.values.where((membre) => membre.fkEntite == fkEntite).toList();
|
||||
@@ -55,7 +59,7 @@ class MembreRepository extends ChangeNotifier {
|
||||
// Récupérer les membres actifs par amicale
|
||||
List<MembreModel> getActiveMembresByAmicale(int fkEntite) {
|
||||
try {
|
||||
return _membreBox.values.where((membre) => membre.fkEntite == fkEntite && membre.chkActive == 1).toList();
|
||||
return _membreBox.values.where((membre) => membre.fkEntite == fkEntite && membre.isActive == true).toList();
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération des membres actifs par amicale: $e');
|
||||
return [];
|
||||
@@ -72,6 +76,8 @@ class MembreRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// === MÉTHODES CRUD DE BASE ===
|
||||
|
||||
// Récupérer tous les membres
|
||||
List<MembreModel> getAllMembres() {
|
||||
try {
|
||||
@@ -94,27 +100,28 @@ class MembreRepository extends ChangeNotifier {
|
||||
|
||||
// Sauvegarder un membre
|
||||
Future<void> saveMembre(MembreModel membre) async {
|
||||
await _ensureBoxIsOpen();
|
||||
await _membreBox.put(membre.id, membre);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// Supprimer un membre
|
||||
Future<void> deleteMembre(int id) async {
|
||||
await _ensureBoxIsOpen();
|
||||
await _membreBox.delete(id);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// === MÉTHODES API ===
|
||||
|
||||
// Créer un membre via l'API
|
||||
Future<bool> createMembre(MembreModel membre) async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
// Préparer les données pour l'API
|
||||
// Préparer les données pour l'API - exclure l'id pour la création
|
||||
final data = membre.toJson();
|
||||
|
||||
data.remove('id'); // L'API génère l'ID
|
||||
data.remove('created_at'); // L'API génère created_at
|
||||
// Appeler l'API pour créer le membre
|
||||
final response = await ApiService.instance.post('/membres', data: data);
|
||||
|
||||
@@ -123,11 +130,24 @@ class MembreRepository extends ChangeNotifier {
|
||||
final membreId = response.data['id'] is String ? int.parse(response.data['id']) : response.data['id'] as int;
|
||||
|
||||
// Créer le membre localement avec l'ID retourné par l'API
|
||||
final newMembre = membre.copyWith(
|
||||
final newMembre = MembreModel(
|
||||
id: membreId,
|
||||
lastSyncedAt: DateTime.now(),
|
||||
isSynced: true,
|
||||
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,
|
||||
);
|
||||
|
||||
await saveMembre(newMembre);
|
||||
return true;
|
||||
}
|
||||
@@ -154,13 +174,8 @@ class MembreRepository extends ChangeNotifier {
|
||||
final response = await ApiService.instance.put('/membres/${membre.id}', data: data);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Mettre à jour le membre localement
|
||||
final updatedMembre = membre.copyWith(
|
||||
lastSyncedAt: DateTime.now(),
|
||||
isSynced: true,
|
||||
);
|
||||
|
||||
await saveMembre(updatedMembre);
|
||||
// Sauvegarder le membre mis à jour localement
|
||||
await saveMembre(membre);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -199,6 +214,8 @@ class MembreRepository extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
// === TRAITEMENT DES DONNÉES ===
|
||||
|
||||
// Traitement des données de membres depuis l'API
|
||||
Future<void> processMembresData(dynamic membresData) async {
|
||||
try {
|
||||
@@ -221,9 +238,7 @@ class MembreRepository extends ChangeNotifier {
|
||||
}
|
||||
|
||||
// Vider la boîte avant d'ajouter les nouvelles données
|
||||
await _ensureBoxIsOpen();
|
||||
await _membreBox.clear();
|
||||
|
||||
// Traiter chaque membre
|
||||
int count = 0;
|
||||
for (final membreData in membresList) {
|
||||
@@ -242,4 +257,55 @@ class MembreRepository extends ChangeNotifier {
|
||||
debugPrint('Erreur lors du traitement des membres: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer les membres depuis l'API
|
||||
Future<List<MembreModel>> fetchMembresFromApi() async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final response = await ApiService.instance.get('/membres');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final membresData = response.data;
|
||||
await processMembresData(membresData);
|
||||
return getAllMembres();
|
||||
} else {
|
||||
debugPrint('Erreur lors de la récupération des membres: ${response.statusCode}');
|
||||
return [];
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération des membres: $e');
|
||||
return [];
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// === MÉTHODES DE FILTRAGE ET RECHERCHE ===
|
||||
|
||||
// Filtrer les membres par nom
|
||||
List<MembreModel> searchMembresByName(String query) {
|
||||
if (query.isEmpty) {
|
||||
return getAllMembres();
|
||||
}
|
||||
|
||||
final lowercaseQuery = query.toLowerCase();
|
||||
return _membreBox.values
|
||||
.where(
|
||||
(membre) => (membre.name?.toLowerCase().contains(lowercaseQuery) ?? false) || (membre.firstName?.toLowerCase().contains(lowercaseQuery) ?? false))
|
||||
.toList();
|
||||
}
|
||||
|
||||
// Filtrer les membres actifs
|
||||
List<MembreModel> getActiveMembres() {
|
||||
return _membreBox.values.where((membre) => membre.isActive == true).toList();
|
||||
}
|
||||
|
||||
// Vider la boîte des membres
|
||||
Future<void> clearMembres() async {
|
||||
await _membreBox.clear();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,11 @@ class PassageRepository extends ChangeNotifier {
|
||||
return _passageBox.values.where((passage) => passage.fkType == type).toList();
|
||||
}
|
||||
|
||||
// Récupérer les passages par opération
|
||||
List<PassageModel> getPassagesByOperation(int operationId) {
|
||||
return _passageBox.values.where((passage) => passage.fkOperation == operationId).toList();
|
||||
}
|
||||
|
||||
// Récupérer les passages par date
|
||||
List<PassageModel> getPassagesByDate(DateTime date) {
|
||||
return _passageBox.values.where((passage) {
|
||||
|
||||
@@ -226,9 +226,6 @@ class UserRepository extends ChangeNotifier {
|
||||
try {
|
||||
debugPrint('🔐 Tentative de connexion: $username');
|
||||
|
||||
// Étape 1: Nettoyage des données via DataLoadingService
|
||||
await DataLoadingService.instance.cleanDataBeforeLogin();
|
||||
|
||||
// Étape 2: Connexion à l'API (25%)
|
||||
final apiResult = await loginAPI(username, password, type: type);
|
||||
|
||||
@@ -264,7 +261,13 @@ class UserRepository extends ChangeNotifier {
|
||||
}
|
||||
|
||||
// Étape 5: Traitement de toutes les autres données via DataLoadingService
|
||||
await DataLoadingService.instance.processLoginData(apiResult);
|
||||
try {
|
||||
await DataLoadingService.instance.processLoginData(apiResult);
|
||||
} catch (processingError) {
|
||||
debugPrint('❌ Erreur lors du traitement des données: $processingError');
|
||||
// On continue quand même car l'utilisateur est connecté
|
||||
debugPrint('⚠️ Connexion réussie mais avec des données partielles');
|
||||
}
|
||||
|
||||
debugPrint('✅ Connexion réussie');
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user