364 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			364 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:cloud_firestore/cloud_firestore.dart';
 | |
| import 'package:em2rp/models/event_model.dart';
 | |
| import 'package:em2rp/models/equipment_model.dart';
 | |
| import 'package:em2rp/services/equipment_service.dart';
 | |
| 
 | |
| class EventPreparationService {
 | |
|   final FirebaseFirestore _firestore = FirebaseFirestore.instance;
 | |
|   final EquipmentService _equipmentService = EquipmentService();
 | |
| 
 | |
|   // Collection references
 | |
|   CollectionReference get _eventsCollection => _firestore.collection('events');
 | |
|   CollectionReference get _equipmentCollection => _firestore.collection('equipment');
 | |
| 
 | |
|   // === PRÉPARATION ===
 | |
| 
 | |
|    /// Valider un équipement individuel en préparation
 | |
|   Future<void> validateEquipmentPreparation(String eventId, String equipmentId) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       // Mettre à jour le statut de l'équipement dans la liste
 | |
|       final updatedEquipment = event.assignedEquipment.map((eq) {
 | |
|         if (eq.equipmentId == equipmentId) {
 | |
|           return eq.copyWith(isPrepared: true);
 | |
|         }
 | |
|         return eq;
 | |
|       }).toList();
 | |
| 
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'assignedEquipment': updatedEquipment.map((e) => e.toMap()).toList(),
 | |
|       });
 | |
|     } catch (e) {
 | |
|       print('Error validating equipment preparation: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Valider tous les équipements en préparation
 | |
|   Future<void> validateAllPreparation(String eventId) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       // Marquer tous les équipements comme préparés
 | |
|       final updatedEquipment = event.assignedEquipment.map((eq) {
 | |
|         return eq.copyWith(isPrepared: true);
 | |
|       }).toList();
 | |
| 
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'assignedEquipment': updatedEquipment.map((e) => e.toMap()).toList(),
 | |
|         'preparationStatus': preparationStatusToString(PreparationStatus.completed),
 | |
|       });
 | |
| 
 | |
|       // Mettre à jour le statut des équipements à "inUse"
 | |
|       for (var equipment in event.assignedEquipment) {
 | |
|         await updateEquipmentStatus(equipment.equipmentId, EquipmentStatus.inUse);
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error validating all preparation: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Finaliser la préparation avec des équipements manquants
 | |
|   Future<void> completePreparationWithMissing(
 | |
|     String eventId,
 | |
|     List<String> missingEquipmentIds,
 | |
|   ) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       // Marquer comme complété avec manquants
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'preparationStatus': preparationStatusToString(PreparationStatus.completedWithMissing),
 | |
|       });
 | |
| 
 | |
|       // Mettre à jour le statut des équipements préparés à "inUse"
 | |
|       for (var equipment in event.assignedEquipment) {
 | |
|         if (equipment.isPrepared && !missingEquipmentIds.contains(equipment.equipmentId)) {
 | |
|           await updateEquipmentStatus(equipment.equipmentId, EquipmentStatus.inUse);
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error completing preparation with missing: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // === RETOUR ===
 | |
| 
 | |
| 
 | |
|     /// Valider le retour d'un équipement individuel
 | |
|   Future<void> validateEquipmentReturn(
 | |
|     String eventId,
 | |
|     String equipmentId, {
 | |
|     int? returnedQuantity,
 | |
|   }) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       // Mettre à jour le statut de l'équipement dans la liste
 | |
|       final updatedEquipment = event.assignedEquipment.map((eq) {
 | |
|         if (eq.equipmentId == equipmentId) {
 | |
|           return eq.copyWith(
 | |
|             isReturned: true,
 | |
|             returnedQuantity: returnedQuantity,
 | |
|           );
 | |
|         }
 | |
|         return eq;
 | |
|       }).toList();
 | |
| 
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'assignedEquipment': updatedEquipment.map((e) => e.toMap()).toList(),
 | |
|       });
 | |
| 
 | |
|       // Mettre à jour le stock si c'est un consommable
 | |
|       if (returnedQuantity != null) {
 | |
|         final equipmentDoc = await _equipmentCollection.doc(equipmentId).get();
 | |
|         if (equipmentDoc.exists) {
 | |
|           final equipment = EquipmentModel.fromMap(
 | |
|             equipmentDoc.data() as Map<String, dynamic>,
 | |
|             equipmentDoc.id,
 | |
|           );
 | |
| 
 | |
|           if (equipment.hasQuantity) {
 | |
|             final currentAvailable = equipment.availableQuantity ?? 0;
 | |
|             await _equipmentCollection.doc(equipmentId).update({
 | |
|               'availableQuantity': currentAvailable + returnedQuantity,
 | |
|             });
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error validating equipment return: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Valider tous les retours
 | |
|   Future<void> validateAllReturn(String eventId) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       // Marquer tous les équipements comme retournés
 | |
|       final updatedEquipment = event.assignedEquipment.map((eq) {
 | |
|         return eq.copyWith(
 | |
|           isReturned: true,
 | |
|           returnedQuantity: eq.returnedQuantity ?? eq.quantity,
 | |
|         );
 | |
|       }).toList();
 | |
| 
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'assignedEquipment': updatedEquipment.map((e) => e.toMap()).toList(),
 | |
|         'returnStatus': returnStatusToString(ReturnStatus.completed),
 | |
|       });
 | |
| 
 | |
|       // Mettre à jour le statut des équipements à "available" et gérer les stocks
 | |
|       for (var equipment in updatedEquipment) {
 | |
|         await updateEquipmentStatus(equipment.equipmentId, EquipmentStatus.available);
 | |
| 
 | |
|         // Restaurer le stock pour les consommables
 | |
|         final equipmentDoc = await _equipmentCollection.doc(equipment.equipmentId).get();
 | |
|         if (equipmentDoc.exists) {
 | |
|           final equipmentData = EquipmentModel.fromMap(
 | |
|             equipmentDoc.data() as Map<String, dynamic>,
 | |
|             equipmentDoc.id,
 | |
|           );
 | |
| 
 | |
|           if (equipmentData.hasQuantity && equipment.returnedQuantity != null) {
 | |
|             final currentAvailable = equipmentData.availableQuantity ?? 0;
 | |
|             await _equipmentCollection.doc(equipment.equipmentId).update({
 | |
|               'availableQuantity': currentAvailable + equipment.returnedQuantity!,
 | |
|             });
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error validating all return: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Finaliser le retour avec des équipements manquants
 | |
|   Future<void> completeReturnWithMissing(
 | |
|     String eventId,
 | |
|     List<String> missingEquipmentIds,
 | |
|   ) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       // Marquer comme complété avec manquants
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'returnStatus': returnStatusToString(ReturnStatus.completedWithMissing),
 | |
|       });
 | |
| 
 | |
|       // Mettre à jour le statut des équipements retournés à "available"
 | |
|       for (var equipment in event.assignedEquipment) {
 | |
|         if (equipment.isReturned && !missingEquipmentIds.contains(equipment.equipmentId)) {
 | |
|           await updateEquipmentStatus(equipment.equipmentId, EquipmentStatus.available);
 | |
| 
 | |
|           // Restaurer le stock pour les consommables
 | |
|           final equipmentDoc = await _equipmentCollection.doc(equipment.equipmentId).get();
 | |
|           if (equipmentDoc.exists) {
 | |
|             final equipmentData = EquipmentModel.fromMap(
 | |
|               equipmentDoc.data() as Map<String, dynamic>,
 | |
|               equipmentDoc.id,
 | |
|             );
 | |
| 
 | |
|             if (equipmentData.hasQuantity && equipment.returnedQuantity != null) {
 | |
|               final currentAvailable = equipmentData.availableQuantity ?? 0;
 | |
|               await _equipmentCollection.doc(equipment.equipmentId).update({
 | |
|                 'availableQuantity': currentAvailable + equipment.returnedQuantity!,
 | |
|               });
 | |
|             }
 | |
|           }
 | |
|         } else if (missingEquipmentIds.contains(equipment.equipmentId)) {
 | |
|           // Marquer comme perdu
 | |
|           await updateEquipmentStatus(equipment.equipmentId, EquipmentStatus.lost);
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error completing return with missing: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // === HELPERS ===
 | |
| 
 | |
|   /// Mettre à jour le statut d'un équipement
 | |
|   Future<void> updateEquipmentStatus(String equipmentId, EquipmentStatus status) async {
 | |
|     try {
 | |
|       await _equipmentCollection.doc(equipmentId).update({
 | |
|         'status': equipmentStatusToString(status),
 | |
|         'updatedAt': Timestamp.fromDate(DateTime.now()),
 | |
|       });
 | |
|     } catch (e) {
 | |
|       print('Error updating equipment status: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Récupérer un événement
 | |
|   Future<EventModel?> _getEvent(String eventId) async {
 | |
|     try {
 | |
|       final doc = await _eventsCollection.doc(eventId).get();
 | |
|       if (doc.exists) {
 | |
|         return EventModel.fromMap(doc.data() as Map<String, dynamic>, doc.id);
 | |
|       }
 | |
|       return null;
 | |
|     } catch (e) {
 | |
|       print('Error getting event: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Ajouter un équipement à un événement
 | |
|   Future<void> addEquipmentToEvent(
 | |
|     String eventId,
 | |
|     String equipmentId, {
 | |
|     int quantity = 1,
 | |
|   }) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       // Vérifier que l'équipement n'est pas déjà ajouté
 | |
|       final alreadyAdded = event.assignedEquipment.any((eq) => eq.equipmentId == equipmentId);
 | |
|       if (alreadyAdded) {
 | |
|         throw Exception('Equipment already added to event');
 | |
|       }
 | |
| 
 | |
|       final newEquipment = EventEquipment(
 | |
|         equipmentId: equipmentId,
 | |
|         quantity: quantity,
 | |
|       );
 | |
| 
 | |
|       final updatedEquipment = [...event.assignedEquipment, newEquipment];
 | |
| 
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'assignedEquipment': updatedEquipment.map((e) => e.toMap()).toList(),
 | |
|       });
 | |
| 
 | |
|       // Décrémenter le stock pour les consommables
 | |
|       final equipmentDoc = await _equipmentCollection.doc(equipmentId).get();
 | |
|       if (equipmentDoc.exists) {
 | |
|         final equipmentData = EquipmentModel.fromMap(
 | |
|           equipmentDoc.data() as Map<String, dynamic>,
 | |
|           equipmentDoc.id,
 | |
|         );
 | |
| 
 | |
|         if (equipmentData.hasQuantity) {
 | |
|           final currentAvailable = equipmentData.availableQuantity ?? 0;
 | |
|           await _equipmentCollection.doc(equipmentId).update({
 | |
|             'availableQuantity': currentAvailable - quantity,
 | |
|           });
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error adding equipment to event: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Retirer un équipement d'un événement
 | |
|   Future<void> removeEquipmentFromEvent(String eventId, String equipmentId) async {
 | |
|     try {
 | |
|       final event = await _getEvent(eventId);
 | |
|       if (event == null) {
 | |
|         throw Exception('Event not found');
 | |
|       }
 | |
| 
 | |
|       final equipmentToRemove = event.assignedEquipment.firstWhere(
 | |
|         (eq) => eq.equipmentId == equipmentId,
 | |
|       );
 | |
| 
 | |
|       final updatedEquipment = event.assignedEquipment
 | |
|           .where((eq) => eq.equipmentId != equipmentId)
 | |
|           .toList();
 | |
| 
 | |
|       await _eventsCollection.doc(eventId).update({
 | |
|         'assignedEquipment': updatedEquipment.map((e) => e.toMap()).toList(),
 | |
|       });
 | |
| 
 | |
|       // Restaurer le stock pour les consommables
 | |
|       final equipmentDoc = await _equipmentCollection.doc(equipmentId).get();
 | |
|       if (equipmentDoc.exists) {
 | |
|         final equipmentData = EquipmentModel.fromMap(
 | |
|           equipmentDoc.data() as Map<String, dynamic>,
 | |
|           equipmentDoc.id,
 | |
|         );
 | |
| 
 | |
|         if (equipmentData.hasQuantity) {
 | |
|           final currentAvailable = equipmentData.availableQuantity ?? 0;
 | |
|           await _equipmentCollection.doc(equipmentId).update({
 | |
|             'availableQuantity': currentAvailable + equipmentToRemove.quantity,
 | |
|           });
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error removing equipment from event: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| }
 | 
