282 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			282 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:cloud_firestore/cloud_firestore.dart';
 | |
| import 'package:em2rp/models/maintenance_model.dart';
 | |
| import 'package:em2rp/models/alert_model.dart';
 | |
| import 'package:em2rp/models/equipment_model.dart';
 | |
| import 'package:em2rp/services/equipment_service.dart';
 | |
| 
 | |
| class MaintenanceService {
 | |
|   final FirebaseFirestore _firestore = FirebaseFirestore.instance;
 | |
|   final EquipmentService _equipmentService = EquipmentService();
 | |
| 
 | |
|   // Collection references
 | |
|   CollectionReference get _maintenancesCollection => _firestore.collection('maintenances');
 | |
|   CollectionReference get _equipmentCollection => _firestore.collection('equipment');
 | |
|   CollectionReference get _alertsCollection => _firestore.collection('alerts');
 | |
| 
 | |
|   // CRUD Operations
 | |
| 
 | |
|   /// Créer une nouvelle maintenance
 | |
|   Future<void> createMaintenance(MaintenanceModel maintenance) async {
 | |
|     try {
 | |
|       await _maintenancesCollection.doc(maintenance.id).set(maintenance.toMap());
 | |
| 
 | |
|       // Mettre à jour les équipements concernés
 | |
|       for (String equipmentId in maintenance.equipmentIds) {
 | |
|         await _updateEquipmentMaintenanceList(equipmentId, maintenance.id);
 | |
| 
 | |
|         // Si la maintenance est planifiée dans les 7 prochains jours, créer une alerte
 | |
|         if (maintenance.scheduledDate.isBefore(DateTime.now().add(const Duration(days: 7)))) {
 | |
|           await _createMaintenanceAlert(equipmentId, maintenance);
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error creating maintenance: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Mettre à jour une maintenance
 | |
|   Future<void> updateMaintenance(String id, Map<String, dynamic> data) async {
 | |
|     try {
 | |
|       data['updatedAt'] = Timestamp.fromDate(DateTime.now());
 | |
|       await _maintenancesCollection.doc(id).update(data);
 | |
|     } catch (e) {
 | |
|       print('Error updating maintenance: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Supprimer une maintenance
 | |
|   Future<void> deleteMaintenance(String id) async {
 | |
|     try {
 | |
|       // Récupérer la maintenance pour connaître les équipements
 | |
|       final doc = await _maintenancesCollection.doc(id).get();
 | |
|       if (doc.exists) {
 | |
|         final maintenance = MaintenanceModel.fromMap(
 | |
|           doc.data() as Map<String, dynamic>,
 | |
|           doc.id,
 | |
|         );
 | |
| 
 | |
|         // Retirer la maintenance des équipements
 | |
|         for (String equipmentId in maintenance.equipmentIds) {
 | |
|           await _removeMaintenanceFromEquipment(equipmentId, id);
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       await _maintenancesCollection.doc(id).delete();
 | |
|     } catch (e) {
 | |
|       print('Error deleting maintenance: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Récupérer une maintenance par ID
 | |
|   Future<MaintenanceModel?> getMaintenanceById(String id) async {
 | |
|     try {
 | |
|       final doc = await _maintenancesCollection.doc(id).get();
 | |
|       if (doc.exists) {
 | |
|         return MaintenanceModel.fromMap(doc.data() as Map<String, dynamic>, doc.id);
 | |
|       }
 | |
|       return null;
 | |
|     } catch (e) {
 | |
|       print('Error getting maintenance: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Récupérer l'historique des maintenances pour un équipement
 | |
|   Stream<List<MaintenanceModel>> getMaintenances(String equipmentId) {
 | |
|     try {
 | |
|       return _maintenancesCollection
 | |
|           .where('equipmentIds', arrayContains: equipmentId)
 | |
|           .orderBy('scheduledDate', descending: true)
 | |
|           .snapshots()
 | |
|           .map((snapshot) {
 | |
|         return snapshot.docs
 | |
|             .map((doc) => MaintenanceModel.fromMap(
 | |
|                   doc.data() as Map<String, dynamic>,
 | |
|                   doc.id,
 | |
|                 ))
 | |
|             .toList();
 | |
|       });
 | |
|     } catch (e) {
 | |
|       print('Error streaming maintenances: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Récupérer toutes les maintenances
 | |
|   Stream<List<MaintenanceModel>> getAllMaintenances() {
 | |
|     try {
 | |
|       return _maintenancesCollection
 | |
|           .orderBy('scheduledDate', descending: true)
 | |
|           .snapshots()
 | |
|           .map((snapshot) {
 | |
|         return snapshot.docs
 | |
|             .map((doc) => MaintenanceModel.fromMap(
 | |
|                   doc.data() as Map<String, dynamic>,
 | |
|                   doc.id,
 | |
|                 ))
 | |
|             .toList();
 | |
|       });
 | |
|     } catch (e) {
 | |
|       print('Error streaming all maintenances: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Marquer une maintenance comme complétée
 | |
|   Future<void> completeMaintenance(String id, {String? performedBy, double? cost}) async {
 | |
|     try {
 | |
|       final updateData = <String, dynamic>{
 | |
|         'completedDate': Timestamp.fromDate(DateTime.now()),
 | |
|         'updatedAt': Timestamp.fromDate(DateTime.now()),
 | |
|       };
 | |
| 
 | |
|       if (performedBy != null) {
 | |
|         updateData['performedBy'] = performedBy;
 | |
|       }
 | |
| 
 | |
|       if (cost != null) {
 | |
|         updateData['cost'] = cost;
 | |
|       }
 | |
| 
 | |
|       await updateMaintenance(id, updateData);
 | |
| 
 | |
|       // Mettre à jour la date de dernière maintenance des équipements
 | |
|       final maintenance = await getMaintenanceById(id);
 | |
|       if (maintenance != null) {
 | |
|         for (String equipmentId in maintenance.equipmentIds) {
 | |
|           await _equipmentCollection.doc(equipmentId).update({
 | |
|             'lastMaintenanceDate': Timestamp.fromDate(DateTime.now()),
 | |
|           });
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error completing maintenance: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Vérifier les maintenances à venir et créer des alertes
 | |
|   Future<void> checkUpcomingMaintenances() async {
 | |
|     try {
 | |
|       final sevenDaysFromNow = DateTime.now().add(const Duration(days: 7));
 | |
| 
 | |
|       // Récupérer les maintenances planifiées dans les 7 prochains jours
 | |
|       final maintenancesQuery = await _maintenancesCollection
 | |
|           .where('scheduledDate', isLessThanOrEqualTo: Timestamp.fromDate(sevenDaysFromNow))
 | |
|           .where('completedDate', isNull: true)
 | |
|           .get();
 | |
| 
 | |
|       for (var doc in maintenancesQuery.docs) {
 | |
|         final maintenance = MaintenanceModel.fromMap(
 | |
|           doc.data() as Map<String, dynamic>,
 | |
|           doc.id,
 | |
|         );
 | |
| 
 | |
|         for (String equipmentId in maintenance.equipmentIds) {
 | |
|           await _createMaintenanceAlert(equipmentId, maintenance);
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error checking upcoming maintenances: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Créer une alerte de maintenance à venir
 | |
|   Future<void> _createMaintenanceAlert(String equipmentId, MaintenanceModel maintenance) async {
 | |
|     try {
 | |
|       // Vérifier si une alerte existe déjà
 | |
|       final existingAlerts = await _alertsCollection
 | |
|           .where('equipmentId', isEqualTo: equipmentId)
 | |
|           .where('type', isEqualTo: alertTypeToString(AlertType.maintenanceDue))
 | |
|           .where('isRead', isEqualTo: false)
 | |
|           .get();
 | |
| 
 | |
|       // Vérifier si l'alerte concerne la même maintenance
 | |
|       bool alertExists = false;
 | |
|       for (var alertDoc in existingAlerts.docs) {
 | |
|         final alertData = alertDoc.data() as Map<String, dynamic>;
 | |
|         if (alertData['message']?.contains(maintenance.name) ?? false) {
 | |
|           alertExists = true;
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       if (!alertExists) {
 | |
|         // Récupérer l'équipement pour le nom
 | |
|         final equipmentDoc = await _equipmentCollection.doc(equipmentId).get();
 | |
|         String equipmentName = equipmentId;
 | |
|         if (equipmentDoc.exists) {
 | |
|           final equipmentData = equipmentDoc.data() as Map<String, dynamic>;
 | |
|           equipmentName = equipmentData['name'] ?? equipmentId;
 | |
|         }
 | |
| 
 | |
|         final daysUntil = maintenance.scheduledDate.difference(DateTime.now()).inDays;
 | |
|         final alert = AlertModel(
 | |
|           id: _alertsCollection.doc().id,
 | |
|           type: AlertType.maintenanceDue,
 | |
|           message: 'Maintenance "${maintenance.name}" prévue dans $daysUntil jour(s) pour $equipmentName',
 | |
|           equipmentId: equipmentId,
 | |
|           createdAt: DateTime.now(),
 | |
|         );
 | |
| 
 | |
|         await _alertsCollection.doc(alert.id).set(alert.toMap());
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error creating maintenance alert: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Mettre à jour la liste des maintenances d'un équipement
 | |
|   Future<void> _updateEquipmentMaintenanceList(String equipmentId, String maintenanceId) async {
 | |
|     try {
 | |
|       final equipmentDoc = await _equipmentCollection.doc(equipmentId).get();
 | |
|       if (equipmentDoc.exists) {
 | |
|         final equipment = EquipmentModel.fromMap(
 | |
|           equipmentDoc.data() as Map<String, dynamic>,
 | |
|           equipmentDoc.id,
 | |
|         );
 | |
| 
 | |
|         final updatedMaintenanceIds = List<String>.from(equipment.maintenanceIds);
 | |
|         if (!updatedMaintenanceIds.contains(maintenanceId)) {
 | |
|           updatedMaintenanceIds.add(maintenanceId);
 | |
| 
 | |
|           await _equipmentCollection.doc(equipmentId).update({
 | |
|             'maintenanceIds': updatedMaintenanceIds,
 | |
|           });
 | |
|         }
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error updating equipment maintenance list: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// Retirer une maintenance de la liste d'un équipement
 | |
|   Future<void> _removeMaintenanceFromEquipment(String equipmentId, String maintenanceId) async {
 | |
|     try {
 | |
|       final equipmentDoc = await _equipmentCollection.doc(equipmentId).get();
 | |
|       if (equipmentDoc.exists) {
 | |
|         final equipment = EquipmentModel.fromMap(
 | |
|           equipmentDoc.data() as Map<String, dynamic>,
 | |
|           equipmentDoc.id,
 | |
|         );
 | |
| 
 | |
|         final updatedMaintenanceIds = List<String>.from(equipment.maintenanceIds);
 | |
|         updatedMaintenanceIds.remove(maintenanceId);
 | |
| 
 | |
|         await _equipmentCollection.doc(equipmentId).update({
 | |
|           'maintenanceIds': updatedMaintenanceIds,
 | |
|         });
 | |
|       }
 | |
|     } catch (e) {
 | |
|       print('Error removing maintenance from equipment: $e');
 | |
|       rethrow;
 | |
|     }
 | |
|   }
 | |
| }
 | 
