300 lines
9.6 KiB
Dart
300 lines
9.6 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import '../models/trip.dart';
|
|
|
|
class TripService {
|
|
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
|
static const String _tripsCollection = 'trips';
|
|
|
|
// Charger tous les voyages
|
|
Future<List<Trip>> loadTrips() async {
|
|
try {
|
|
final QuerySnapshot querySnapshot = await _firestore
|
|
.collection(_tripsCollection)
|
|
.orderBy('createdAt', descending: true)
|
|
.get();
|
|
|
|
return querySnapshot.docs.map((doc) {
|
|
final data = doc.data() as Map<String, dynamic>;
|
|
return Trip.fromMap({...data, 'id': doc.id});
|
|
}).toList();
|
|
} catch (e) {
|
|
print('Erreur lors du chargement des voyages: $e');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Ajouter un nouveau voyage
|
|
Future<bool> addTrip(Trip trip) async {
|
|
try {
|
|
final tripData = trip.toMap();
|
|
// Retirer l'ID vide du map
|
|
tripData.remove('id');
|
|
|
|
// Les participants contiennent déjà uniquement des IDs
|
|
// Pas besoin d'ajouter le créateur car il est déjà inclus
|
|
|
|
// Convertir les dates en Timestamp pour Firestore
|
|
tripData['startDate'] = Timestamp.fromDate(trip.startDate);
|
|
tripData['endDate'] = Timestamp.fromDate(trip.endDate);
|
|
tripData['createdAt'] = FieldValue.serverTimestamp();
|
|
tripData['updatedAt'] = FieldValue.serverTimestamp();
|
|
|
|
await _firestore.collection(_tripsCollection).add(tripData);
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors de l\'ajout du voyage: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Stream pour écouter les voyages d'un utilisateur en temps réel
|
|
Stream<List<Trip>> getTripsStreamByUser(String userId, String userEmail) {
|
|
print('=== STREAM CRÉÉ ===');
|
|
print('UserId: $userId');
|
|
|
|
return _firestore
|
|
.collection(_tripsCollection)
|
|
.snapshots()
|
|
.map((snapshot) {
|
|
print('=== NOUVEAU SNAPSHOT ===');
|
|
print('Nombre de documents: ${snapshot.docs.length}');
|
|
|
|
final List<Trip> trips = [];
|
|
|
|
for (int i = 0; i < snapshot.docs.length; i++) {
|
|
var doc = snapshot.docs[i];
|
|
print('\n--- Document $i (${doc.id}) ---');
|
|
|
|
try {
|
|
final data = doc.data() as Map<String, dynamic>;
|
|
|
|
// Vérifier si l'utilisateur est impliqué dans ce voyage
|
|
final String createdBy = data['createdBy']?.toString() ?? '';
|
|
final List<dynamic> participants = data['participants'] ?? [];
|
|
|
|
print('CreatedBy: "$createdBy"');
|
|
print('UserId: "$userId"');
|
|
print('Participants: $participants');
|
|
|
|
bool userIsInvolved = false;
|
|
String reason = '';
|
|
|
|
// L'utilisateur est le créateur
|
|
if (createdBy == userId) {
|
|
userIsInvolved = true;
|
|
reason = 'Créateur du voyage';
|
|
}
|
|
|
|
// L'utilisateur est dans la liste des participants (par ID uniquement)
|
|
if (participants.contains(userId)) {
|
|
userIsInvolved = true;
|
|
reason = reason.isEmpty ? 'Participant par ID' : '$reason + Participant par ID';
|
|
}
|
|
|
|
print('Utilisateur impliqué: $userIsInvolved');
|
|
print('Raison: $reason');
|
|
|
|
if (userIsInvolved) {
|
|
print('Tentative de conversion du trip...');
|
|
final trip = _convertDocumentToTrip(doc.id, data);
|
|
if (trip != null) {
|
|
trips.add(trip);
|
|
print('Trip ajouté: ${trip.title}');
|
|
} else {
|
|
print('Échec de la conversion du trip');
|
|
}
|
|
} else {
|
|
print('Utilisateur non impliqué dans ce voyage');
|
|
}
|
|
} catch (e, stackTrace) {
|
|
print('Erreur lors du traitement du document ${doc.id}: $e');
|
|
print('StackTrace: $stackTrace');
|
|
}
|
|
}
|
|
|
|
print('\n=== RÉSUMÉ ===');
|
|
print('Trips trouvés: ${trips.length}');
|
|
if (trips.isNotEmpty) {
|
|
for (int i = 0; i < trips.length; i++) {
|
|
print(' ${i+1}. ${trips[i].title} (${trips[i].id})');
|
|
}
|
|
}
|
|
|
|
// Trier par date de création (les plus récents en premier)
|
|
trips.sort((a, b) {
|
|
try {
|
|
return b.createdAt.compareTo(a.createdAt);
|
|
} catch (e) {
|
|
print('Erreur lors du tri: $e');
|
|
return 0;
|
|
}
|
|
});
|
|
|
|
return trips;
|
|
}).handleError((error, stackTrace) {
|
|
print('Erreur dans le stream: $error');
|
|
print('StackTrace: $stackTrace');
|
|
return <Trip>[];
|
|
});
|
|
}
|
|
|
|
// Obtenir les voyages d'un utilisateur (version simplifiée)
|
|
Future<List<Trip>> getTripsByUser(String userId) async {
|
|
try {
|
|
print('Récupération des voyages pour userId: $userId');
|
|
|
|
// Récupérer d'abord les voyages créés par l'utilisateur
|
|
final QuerySnapshot createdTrips = await _firestore
|
|
.collection(_tripsCollection)
|
|
.where('createdBy', isEqualTo: userId)
|
|
.get();
|
|
|
|
final List<Trip> trips = [];
|
|
|
|
for (var doc in createdTrips.docs) {
|
|
try {
|
|
final data = doc.data() as Map<String, dynamic>;
|
|
final trip = _convertDocumentToTrip(doc.id, data);
|
|
if (trip != null) {
|
|
trips.add(trip);
|
|
}
|
|
} catch (e) {
|
|
print('Erreur lors de la conversion du voyage créé ${doc.id}: $e');
|
|
}
|
|
}
|
|
|
|
// Trier par date de création
|
|
trips.sort((a, b) {
|
|
try {
|
|
return b.createdAt.compareTo(a.createdAt);
|
|
} catch (e) {
|
|
return 0;
|
|
}
|
|
});
|
|
return trips;
|
|
} catch (e) {
|
|
print('Erreur lors de la récupération des voyages: $e');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Méthode helper pour convertir un document Firestore en Trip
|
|
Trip? _convertDocumentToTrip(String docId, Map<String, dynamic> data) {
|
|
print('\n=== CONVERSION TRIP $docId ===');
|
|
|
|
try {
|
|
// Créer une copie des données pour ne pas modifier l'original
|
|
Map<String, dynamic> processedData = Map<String, dynamic>.from(data);
|
|
|
|
// Convertir les Timestamps Firestore en String ISO
|
|
if (processedData['createdAt'] is Timestamp) {
|
|
processedData['createdAt'] = (processedData['createdAt'] as Timestamp).toDate().toIso8601String();
|
|
}
|
|
|
|
if (processedData['updatedAt'] is Timestamp) {
|
|
processedData['updatedAt'] = (processedData['updatedAt'] as Timestamp).toDate().toIso8601String();
|
|
}
|
|
|
|
if (processedData['startDate'] is Timestamp) {
|
|
processedData['startDate'] = (processedData['startDate'] as Timestamp).toDate().toIso8601String();
|
|
}
|
|
|
|
if (processedData['endDate'] is Timestamp) {
|
|
processedData['endDate'] = (processedData['endDate'] as Timestamp).toDate().toIso8601String();
|
|
}
|
|
|
|
// Assurer que tous les champs requis sont présents
|
|
processedData['id'] = docId;
|
|
processedData['participants'] = processedData['participants'] ?? [];
|
|
processedData['budget'] = (processedData['budget'] is num) ? (processedData['budget'] as num).toDouble() : 0.0;
|
|
processedData['description'] = processedData['description'] ?? '';
|
|
processedData['status'] = processedData['status'] ?? 'draft';
|
|
|
|
final trip = Trip.fromMap(processedData);
|
|
return trip;
|
|
|
|
} catch (e, stackTrace) {
|
|
print('❌ Erreur lors de la conversion du document $docId: $e');
|
|
print('StackTrace: $stackTrace');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Mettre à jour un voyage
|
|
Future<bool> updateTrip(Trip updatedTrip) async {
|
|
try {
|
|
final tripData = updatedTrip.toMap();
|
|
tripData['updatedAt'] = FieldValue.serverTimestamp();
|
|
tripData.remove('id'); // Retirer l'ID des données à mettre à jour
|
|
|
|
await _firestore
|
|
.collection(_tripsCollection)
|
|
.doc(updatedTrip.id)
|
|
.update(tripData);
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors de la mise à jour du voyage: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Supprimer un voyage
|
|
Future<bool> deleteTrip(String tripId) async {
|
|
try {
|
|
await _firestore.collection(_tripsCollection).doc(tripId).delete();
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors de la suppression du voyage: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Obtenir un voyage par son ID
|
|
Future<Trip?> getTripById(String tripId) async {
|
|
try {
|
|
final DocumentSnapshot doc = await _firestore
|
|
.collection(_tripsCollection)
|
|
.doc(tripId)
|
|
.get();
|
|
|
|
if (doc.exists) {
|
|
final data = doc.data() as Map<String, dynamic>;
|
|
return Trip.fromMap({...data, 'id': doc.id});
|
|
}
|
|
return null;
|
|
} catch (e) {
|
|
print('Erreur lors de la récupération du voyage: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Ajouter un participant à un voyage
|
|
Future<bool> addParticipant(String tripId, String userId) async {
|
|
try {
|
|
await _firestore.collection(_tripsCollection).doc(tripId).update({
|
|
'participants': FieldValue.arrayUnion([userId]),
|
|
'updatedAt': FieldValue.serverTimestamp(),
|
|
});
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors de l\'ajout du participant: $e');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Retirer un participant d'un voyage
|
|
Future<bool> removeParticipant(String tripId, String userId) async {
|
|
try {
|
|
await _firestore.collection(_tripsCollection).doc(tripId).update({
|
|
'participants': FieldValue.arrayRemove([userId]),
|
|
'updatedAt': FieldValue.serverTimestamp(),
|
|
});
|
|
return true;
|
|
} catch (e) {
|
|
print('Erreur lors du retrait du participant: $e');
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|