feat: création branche singletons - début refactorisation
- Sauvegarde des fichiers critiques - Préparation transformation ApiService en singleton - Préparation création CurrentUserService et CurrentAmicaleService - Objectif: renommer Box users -> user
This commit is contained in:
@@ -37,6 +37,9 @@ class MembreModel extends HiveObject {
|
||||
@HiveField(10)
|
||||
final String email;
|
||||
|
||||
@HiveField(11)
|
||||
final int fkEntite;
|
||||
|
||||
MembreModel({
|
||||
required this.id,
|
||||
required this.fkRole,
|
||||
@@ -49,6 +52,7 @@ class MembreModel extends HiveObject {
|
||||
required this.name,
|
||||
required this.username,
|
||||
required this.email,
|
||||
required this.fkEntite,
|
||||
});
|
||||
|
||||
// Factory pour convertir depuis JSON (API)
|
||||
@@ -63,13 +67,15 @@ class MembreModel extends HiveObject {
|
||||
|
||||
// Convertir le titre en int, qu'il soit déjà int ou string
|
||||
final dynamic rawTitre = json['fk_titre'];
|
||||
final int fkTitre =
|
||||
rawTitre is String ? int.parse(rawTitre) : rawTitre as int;
|
||||
final int fkTitre = rawTitre is String ? int.parse(rawTitre) : rawTitre as int;
|
||||
|
||||
// Convertir le chkActive en int, qu'il soit déjà int ou string
|
||||
final dynamic rawActive = json['chk_active'];
|
||||
final int chkActive =
|
||||
rawActive is String ? int.parse(rawActive) : rawActive as int;
|
||||
final int chkActive = rawActive is String ? int.parse(rawActive) : rawActive as int;
|
||||
|
||||
// Convertir le fkEntite en int, qu'il soit déjà int ou string
|
||||
final dynamic rawEntite = json['fk_entite'];
|
||||
final int fkEntite = rawEntite is String ? int.parse(rawEntite) : rawEntite as int;
|
||||
|
||||
return MembreModel(
|
||||
id: id,
|
||||
@@ -77,16 +83,13 @@ class MembreModel extends HiveObject {
|
||||
fkTitre: fkTitre,
|
||||
firstName: json['first_name'] ?? '',
|
||||
sectName: json['sect_name'],
|
||||
dateNaissance: json['date_naissance'] != null
|
||||
? DateTime.parse(json['date_naissance'])
|
||||
: null,
|
||||
dateEmbauche: json['date_embauche'] != null
|
||||
? DateTime.parse(json['date_embauche'])
|
||||
: null,
|
||||
dateNaissance: json['date_naissance'] != null ? DateTime.parse(json['date_naissance']) : null,
|
||||
dateEmbauche: json['date_embauche'] != null ? DateTime.parse(json['date_embauche']) : null,
|
||||
chkActive: chkActive,
|
||||
name: json['name'] ?? '',
|
||||
username: json['username'] ?? '',
|
||||
email: json['email'] ?? '',
|
||||
fkEntite: fkEntite,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,6 +107,7 @@ class MembreModel extends HiveObject {
|
||||
'name': name,
|
||||
'username': username,
|
||||
'email': email,
|
||||
'fk_entite': fkEntite,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -119,9 +123,10 @@ class MembreModel extends HiveObject {
|
||||
String? name,
|
||||
String? username,
|
||||
String? email,
|
||||
int? fkEntite,
|
||||
}) {
|
||||
return MembreModel(
|
||||
id: this.id,
|
||||
id: id,
|
||||
fkRole: fkRole ?? this.fkRole,
|
||||
fkTitre: fkTitre ?? this.fkTitre,
|
||||
firstName: firstName ?? this.firstName,
|
||||
@@ -132,6 +137,7 @@ class MembreModel extends HiveObject {
|
||||
name: name ?? this.name,
|
||||
username: username ?? this.username,
|
||||
email: email ?? this.email,
|
||||
fkEntite: fkEntite ?? this.fkEntite,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,14 @@ class MembreModelAdapter extends TypeAdapter<MembreModel> {
|
||||
name: fields[8] as String,
|
||||
username: fields[9] as String,
|
||||
email: fields[10] as String,
|
||||
fkEntite: fields[11] as int,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, MembreModel obj) {
|
||||
writer
|
||||
..writeByte(11)
|
||||
..writeByte(12)
|
||||
..writeByte(0)
|
||||
..write(obj.id)
|
||||
..writeByte(1)
|
||||
@@ -56,7 +57,9 @@ class MembreModelAdapter extends TypeAdapter<MembreModel> {
|
||||
..writeByte(9)
|
||||
..write(obj.username)
|
||||
..writeByte(10)
|
||||
..write(obj.email);
|
||||
..write(obj.email)
|
||||
..writeByte(11)
|
||||
..write(obj.fkEntite);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -7,8 +7,7 @@ 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);
|
||||
Box<AmicaleModel> get _amicaleBox => Hive.box<AmicaleModel>(AppKeys.amicaleBoxName);
|
||||
|
||||
final ApiService _apiService;
|
||||
bool _isLoading = false;
|
||||
@@ -18,6 +17,19 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
// 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 {
|
||||
@@ -59,8 +71,7 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
_ensureBoxIsOpen();
|
||||
return _amicaleBox.get(fkEntite);
|
||||
} catch (e) {
|
||||
debugPrint(
|
||||
'Erreur lors de la récupération de l\'amicale de l\'utilisateur: $e');
|
||||
debugPrint('Erreur lors de la récupération de l\'amicale de l\'utilisateur: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -146,8 +157,7 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
final amicale = AmicaleModel.fromJson(amicaleMap);
|
||||
await _amicaleBox.put(amicale.id, amicale);
|
||||
count++;
|
||||
debugPrint(
|
||||
'Amicale unique traitée: ${amicale.name} (ID: ${amicale.id})');
|
||||
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');
|
||||
@@ -177,8 +187,7 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
await processAmicalesData(amicalesData);
|
||||
return getAllAmicales();
|
||||
} else {
|
||||
debugPrint(
|
||||
'Erreur lors de la récupération des amicales: ${response.statusCode}');
|
||||
debugPrint('Erreur lors de la récupération des amicales: ${response.statusCode}');
|
||||
return [];
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -204,8 +213,7 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
await saveAmicale(amicale);
|
||||
return amicale;
|
||||
} else {
|
||||
debugPrint(
|
||||
'Erreur lors de la récupération de l\'amicale: ${response.statusCode}');
|
||||
debugPrint('Erreur lors de la récupération de l\'amicale: ${response.statusCode}');
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -234,8 +242,7 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
await saveAmicale(updatedAmicale);
|
||||
return updatedAmicale;
|
||||
} else {
|
||||
debugPrint(
|
||||
'Erreur lors de la mise à jour de l\'amicale: ${response.statusCode}');
|
||||
debugPrint('Erreur lors de la mise à jour de l\'amicale: ${response.statusCode}');
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -254,23 +261,17 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
}
|
||||
|
||||
final lowercaseQuery = query.toLowerCase();
|
||||
return _amicaleBox.values
|
||||
.where((amicale) => amicale.name.toLowerCase().contains(lowercaseQuery))
|
||||
.toList();
|
||||
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();
|
||||
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();
|
||||
return _amicaleBox.values.where((amicale) => amicale.fkRegion == regionId).toList();
|
||||
}
|
||||
|
||||
// Filtrer les amicales actives
|
||||
@@ -280,16 +281,12 @@ class AmicaleRepository extends ChangeNotifier {
|
||||
|
||||
// Filtrer les amicales par code postal
|
||||
List<AmicaleModel> getAmicalesByPostalCode(String postalCode) {
|
||||
return _amicaleBox.values
|
||||
.where((amicale) => amicale.codePostal == postalCode)
|
||||
.toList();
|
||||
return _amicaleBox.values.where((amicale) => amicale.codePostal == postalCode).toList();
|
||||
}
|
||||
|
||||
// Filtrer les amicales par ville
|
||||
List<AmicaleModel> getAmicalesByCity(String city) {
|
||||
final lowercaseCity = city.toLowerCase();
|
||||
return _amicaleBox.values
|
||||
.where((amicale) => amicale.ville.toLowerCase().contains(lowercaseCity))
|
||||
.toList();
|
||||
return _amicaleBox.values.where((amicale) => amicale.ville.toLowerCase().contains(lowercaseCity)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import 'package:geosector_app/core/data/models/membre_model.dart';
|
||||
|
||||
class MembreRepository extends ChangeNotifier {
|
||||
// Utilisation de getters lazy pour n'accéder à la boîte que lorsque nécessaire
|
||||
Box<MembreModel> get _membreBox =>
|
||||
Hive.box<MembreModel>(AppKeys.membresBoxName);
|
||||
Box<MembreModel> get _membreBox => Hive.box<MembreModel>(AppKeys.membresBoxName);
|
||||
|
||||
final ApiService _apiService;
|
||||
bool _isLoading = false;
|
||||
@@ -20,6 +19,19 @@ class MembreRepository extends ChangeNotifier {
|
||||
bool get isLoading => _isLoading;
|
||||
List<MembreModel> get membres => getAllMembres();
|
||||
|
||||
// Méthode pour exposer la Box Hive (nécessaire pour ValueListenableBuilder)
|
||||
Box<MembreModel> getMembresBox() {
|
||||
try {
|
||||
if (!Hive.isBoxOpen(AppKeys.membresBoxName)) {
|
||||
throw Exception('La boîte membres n\'est pas ouverte');
|
||||
}
|
||||
return Hive.box<MembreModel>(AppKeys.membresBoxName);
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de l\'accès à la boîte membres: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
// Méthode pour vérifier si une boîte est ouverte et l'ouvrir si nécessaire
|
||||
Future<void> _ensureBoxIsOpen() async {
|
||||
try {
|
||||
@@ -29,10 +41,37 @@ class MembreRepository extends ChangeNotifier {
|
||||
debugPrint('Boîte ${AppKeys.membresBoxName} ouverte avec succès');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint(
|
||||
'Erreur lors de l\'ouverture de la boîte ${AppKeys.membresBoxName}: $e');
|
||||
throw Exception(
|
||||
'Impossible d\'ouvrir la boîte ${AppKeys.membresBoxName}: $e');
|
||||
debugPrint('Erreur lors de l\'ouverture de la boîte ${AppKeys.membresBoxName}: $e');
|
||||
throw Exception('Impossible d\'ouvrir la boîte ${AppKeys.membresBoxName}: $e');
|
||||
}
|
||||
}
|
||||
|
||||
List<MembreModel> getMembresByAmicale(int fkEntite) {
|
||||
try {
|
||||
return _membreBox.values.where((membre) => membre.fkEntite == fkEntite).toList();
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération des membres par amicale: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération des membres actifs par amicale: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Compter les membres par amicale
|
||||
int countMembresByAmicale(int fkEntite) {
|
||||
try {
|
||||
return _membreBox.values.where((membre) => membre.fkEntite == fkEntite).length;
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors du comptage des membres par amicale: $e');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,8 +118,7 @@ class MembreRepository extends ChangeNotifier {
|
||||
try {
|
||||
final hasConnection = await _apiService.hasInternetConnection();
|
||||
if (!hasConnection) {
|
||||
debugPrint(
|
||||
'Pas de connexion Internet, utilisation des données locales');
|
||||
debugPrint('Pas de connexion Internet, utilisation des données locales');
|
||||
return getAllMembres();
|
||||
}
|
||||
|
||||
@@ -107,8 +145,7 @@ class MembreRepository extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
return membres;
|
||||
} catch (e) {
|
||||
debugPrint(
|
||||
'Erreur lors de la récupération des membres depuis l\'API: $e');
|
||||
debugPrint('Erreur lors de la récupération des membres depuis l\'API: $e');
|
||||
return getAllMembres();
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
@@ -129,8 +166,7 @@ class MembreRepository extends ChangeNotifier {
|
||||
}
|
||||
|
||||
// Endpoint à adapter selon votre API
|
||||
final response =
|
||||
await _apiService.post('/membres', data: membre.toJson());
|
||||
final response = await _apiService.post('/membres', data: membre.toJson());
|
||||
final membreData = response.data['membre'];
|
||||
|
||||
final newMembre = MembreModel.fromJson(membreData);
|
||||
@@ -154,14 +190,12 @@ class MembreRepository extends ChangeNotifier {
|
||||
try {
|
||||
final hasConnection = await _apiService.hasInternetConnection();
|
||||
if (!hasConnection) {
|
||||
debugPrint(
|
||||
'Pas de connexion Internet, impossible de mettre à jour le membre');
|
||||
debugPrint('Pas de connexion Internet, impossible de mettre à jour le membre');
|
||||
return null;
|
||||
}
|
||||
|
||||
// Endpoint à adapter selon votre API
|
||||
final response =
|
||||
await _apiService.put('/membres/${membre.id}', data: membre.toJson());
|
||||
final response = await _apiService.put('/membres/${membre.id}', data: membre.toJson());
|
||||
final membreData = response.data['membre'];
|
||||
|
||||
final updatedMembre = MembreModel.fromJson(membreData);
|
||||
@@ -185,8 +219,7 @@ class MembreRepository extends ChangeNotifier {
|
||||
try {
|
||||
final hasConnection = await _apiService.hasInternetConnection();
|
||||
if (!hasConnection) {
|
||||
debugPrint(
|
||||
'Pas de connexion Internet, impossible de supprimer le membre');
|
||||
debugPrint('Pas de connexion Internet, impossible de supprimer le membre');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,16 +13,16 @@ class ApiService {
|
||||
late final String _baseUrl;
|
||||
late final String _appIdentifier;
|
||||
String? _sessionId;
|
||||
|
||||
|
||||
// Détermine l'environnement actuel (DEV, REC, PROD) en fonction de l'URL
|
||||
String _determineEnvironment() {
|
||||
if (!kIsWeb) {
|
||||
// En mode non-web, utiliser l'environnement de développement par défaut
|
||||
return 'DEV';
|
||||
}
|
||||
|
||||
|
||||
final currentUrl = html.window.location.href.toLowerCase();
|
||||
|
||||
|
||||
if (currentUrl.contains('dapp.geosector.fr')) {
|
||||
return 'DEV';
|
||||
} else if (currentUrl.contains('rapp.geosector.fr')) {
|
||||
@@ -31,11 +31,11 @@ class ApiService {
|
||||
return 'PROD';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Configure l'URL de base API et l'identifiant d'application selon l'environnement
|
||||
void _configureEnvironment() {
|
||||
final env = _determineEnvironment();
|
||||
|
||||
|
||||
switch (env) {
|
||||
case 'DEV':
|
||||
_baseUrl = AppKeys.baseApiUrlDev;
|
||||
@@ -49,23 +49,23 @@ class ApiService {
|
||||
_baseUrl = AppKeys.baseApiUrlProd;
|
||||
_appIdentifier = AppKeys.appIdentifierProd;
|
||||
}
|
||||
|
||||
|
||||
debugPrint('GEOSECTOR 🔗 Environnement: $env, API: $_baseUrl');
|
||||
}
|
||||
|
||||
ApiService() {
|
||||
// Configurer l'environnement
|
||||
_configureEnvironment();
|
||||
|
||||
|
||||
// Configurer Dio
|
||||
_dio.options.baseUrl = _baseUrl;
|
||||
_dio.options.connectTimeout = AppKeys.connectionTimeout;
|
||||
_dio.options.receiveTimeout = AppKeys.receiveTimeout;
|
||||
|
||||
|
||||
// Ajouter les en-têtes par défaut avec l'identifiant d'application adapté à l'environnement
|
||||
final headers = Map<String, String>.from(AppKeys.defaultHeaders);
|
||||
headers['X-App-Identifier'] = _appIdentifier;
|
||||
|
||||
|
||||
_dio.options.headers.addAll(headers);
|
||||
|
||||
// Ajouter des intercepteurs pour l'authentification par session
|
||||
@@ -89,17 +89,17 @@ class ApiService {
|
||||
void setSessionId(String? sessionId) {
|
||||
_sessionId = sessionId;
|
||||
}
|
||||
|
||||
|
||||
// Obtenir l'environnement actuel (utile pour le débogage)
|
||||
String getCurrentEnvironment() {
|
||||
return _determineEnvironment();
|
||||
}
|
||||
|
||||
|
||||
// Obtenir l'URL API actuelle (utile pour le débogage)
|
||||
String getCurrentApiUrl() {
|
||||
return _baseUrl;
|
||||
}
|
||||
|
||||
|
||||
// Obtenir l'identifiant d'application actuel (utile pour le débogage)
|
||||
String getCurrentAppIdentifier() {
|
||||
return _appIdentifier;
|
||||
@@ -119,7 +119,7 @@ class ApiService {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Méthode GET générique
|
||||
Future<Response> get(String path, {Map<String, dynamic>? queryParameters}) async {
|
||||
try {
|
||||
@@ -128,7 +128,7 @@ class ApiService {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Méthode PUT générique
|
||||
Future<Response> put(String path, {dynamic data}) async {
|
||||
try {
|
||||
@@ -137,7 +137,7 @@ class ApiService {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Méthode DELETE générique
|
||||
Future<Response> delete(String path) async {
|
||||
try {
|
||||
@@ -159,7 +159,7 @@ class ApiService {
|
||||
// Vérifier la structure de la réponse
|
||||
final data = response.data as Map<String, dynamic>;
|
||||
final status = data['status'] as String?;
|
||||
|
||||
|
||||
// Afficher le message en cas d'erreur
|
||||
if (status != 'success') {
|
||||
final message = data['message'] as String?;
|
||||
@@ -203,9 +203,7 @@ class ApiService {
|
||||
retryIf: (e) => e is SocketException || e is TimeoutException,
|
||||
);
|
||||
|
||||
return (response.data as List)
|
||||
.map((json) => UserModel.fromJson(json))
|
||||
.toList();
|
||||
return (response.data as List).map((json) => UserModel.fromJson(json)).toList();
|
||||
} catch (e) {
|
||||
// Gérer les erreurs
|
||||
rethrow;
|
||||
|
||||
Reference in New Issue
Block a user