Files
EM2_ERP/em2rp/lib/services/maintenance_service.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;
}
}
}