Add equipment management features (and qr generation support)
This commit is contained in:
89
em2rp/lib/models/alert_model.dart
Normal file
89
em2rp/lib/models/alert_model.dart
Normal file
@@ -0,0 +1,89 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
enum AlertType {
|
||||
lowStock, // Stock faible
|
||||
maintenanceDue, // Maintenance à venir
|
||||
conflict // Conflit disponibilité
|
||||
}
|
||||
|
||||
String alertTypeToString(AlertType type) {
|
||||
switch (type) {
|
||||
case AlertType.lowStock:
|
||||
return 'LOW_STOCK';
|
||||
case AlertType.maintenanceDue:
|
||||
return 'MAINTENANCE_DUE';
|
||||
case AlertType.conflict:
|
||||
return 'CONFLICT';
|
||||
}
|
||||
}
|
||||
|
||||
AlertType alertTypeFromString(String? type) {
|
||||
switch (type) {
|
||||
case 'LOW_STOCK':
|
||||
return AlertType.lowStock;
|
||||
case 'MAINTENANCE_DUE':
|
||||
return AlertType.maintenanceDue;
|
||||
case 'CONFLICT':
|
||||
return AlertType.conflict;
|
||||
default:
|
||||
return AlertType.conflict;
|
||||
}
|
||||
}
|
||||
|
||||
class AlertModel {
|
||||
final String id; // ID généré automatiquement
|
||||
final AlertType type; // Type d'alerte
|
||||
final String message; // Message de l'alerte
|
||||
final String? equipmentId; // ID de l'équipement concerné (optionnel)
|
||||
final DateTime createdAt; // Date de création
|
||||
final bool isRead; // Statut lu/non lu
|
||||
|
||||
AlertModel({
|
||||
required this.id,
|
||||
required this.type,
|
||||
required this.message,
|
||||
this.equipmentId,
|
||||
required this.createdAt,
|
||||
this.isRead = false,
|
||||
});
|
||||
|
||||
factory AlertModel.fromMap(Map<String, dynamic> map, String id) {
|
||||
return AlertModel(
|
||||
id: id,
|
||||
type: alertTypeFromString(map['type']),
|
||||
message: map['message'] ?? '',
|
||||
equipmentId: map['equipmentId'],
|
||||
createdAt: (map['createdAt'] as Timestamp?)?.toDate() ?? DateTime.now(),
|
||||
isRead: map['isRead'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'type': alertTypeToString(type),
|
||||
'message': message,
|
||||
'equipmentId': equipmentId,
|
||||
'createdAt': Timestamp.fromDate(createdAt),
|
||||
'isRead': isRead,
|
||||
};
|
||||
}
|
||||
|
||||
AlertModel copyWith({
|
||||
String? id,
|
||||
AlertType? type,
|
||||
String? message,
|
||||
String? equipmentId,
|
||||
DateTime? createdAt,
|
||||
bool? isRead,
|
||||
}) {
|
||||
return AlertModel(
|
||||
id: id ?? this.id,
|
||||
type: type ?? this.type,
|
||||
message: message ?? this.message,
|
||||
equipmentId: equipmentId ?? this.equipmentId,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
isRead: isRead ?? this.isRead,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
279
em2rp/lib/models/equipment_model.dart
Normal file
279
em2rp/lib/models/equipment_model.dart
Normal file
@@ -0,0 +1,279 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
enum EquipmentStatus {
|
||||
available, // Disponible
|
||||
inUse, // En prestation
|
||||
rented, // Loué
|
||||
lost, // Perdu
|
||||
outOfService, // HS
|
||||
maintenance, // En maintenance
|
||||
}
|
||||
|
||||
String equipmentStatusToString(EquipmentStatus status) {
|
||||
switch (status) {
|
||||
case EquipmentStatus.available:
|
||||
return 'AVAILABLE';
|
||||
case EquipmentStatus.inUse:
|
||||
return 'IN_USE';
|
||||
case EquipmentStatus.rented:
|
||||
return 'RENTED';
|
||||
case EquipmentStatus.lost:
|
||||
return 'LOST';
|
||||
case EquipmentStatus.outOfService:
|
||||
return 'OUT_OF_SERVICE';
|
||||
case EquipmentStatus.maintenance:
|
||||
return 'MAINTENANCE';
|
||||
}
|
||||
}
|
||||
|
||||
EquipmentStatus equipmentStatusFromString(String? status) {
|
||||
switch (status) {
|
||||
case 'AVAILABLE':
|
||||
return EquipmentStatus.available;
|
||||
case 'IN_USE':
|
||||
return EquipmentStatus.inUse;
|
||||
case 'RENTED':
|
||||
return EquipmentStatus.rented;
|
||||
case 'LOST':
|
||||
return EquipmentStatus.lost;
|
||||
case 'OUT_OF_SERVICE':
|
||||
return EquipmentStatus.outOfService;
|
||||
case 'MAINTENANCE':
|
||||
return EquipmentStatus.maintenance;
|
||||
default:
|
||||
return EquipmentStatus.available;
|
||||
}
|
||||
}
|
||||
|
||||
enum EquipmentCategory {
|
||||
lighting, // Lumière
|
||||
sound, // Son
|
||||
video, // Vidéo
|
||||
effect, // Effets spéciaux
|
||||
structure, // Structure
|
||||
consumable, // Consommable
|
||||
cable, // Câble
|
||||
other // Autre
|
||||
}
|
||||
|
||||
String equipmentCategoryToString(EquipmentCategory category) {
|
||||
switch (category) {
|
||||
case EquipmentCategory.lighting:
|
||||
return 'LIGHTING';
|
||||
case EquipmentCategory.sound:
|
||||
return 'SOUND';
|
||||
case EquipmentCategory.video:
|
||||
return 'VIDEO';
|
||||
case EquipmentCategory.structure:
|
||||
return 'STRUCTURE';
|
||||
case EquipmentCategory.consumable:
|
||||
return 'CONSUMABLE';
|
||||
case EquipmentCategory.cable:
|
||||
return 'CABLE';
|
||||
case EquipmentCategory.other:
|
||||
return 'OTHER';
|
||||
case EquipmentCategory.effect:
|
||||
return 'EFFECT';
|
||||
}
|
||||
}
|
||||
|
||||
EquipmentCategory equipmentCategoryFromString(String? category) {
|
||||
switch (category) {
|
||||
case 'LIGHTING':
|
||||
return EquipmentCategory.lighting;
|
||||
case 'SOUND':
|
||||
return EquipmentCategory.sound;
|
||||
case 'VIDEO':
|
||||
return EquipmentCategory.video;
|
||||
case 'STRUCTURE':
|
||||
return EquipmentCategory.structure;
|
||||
case 'CONSUMABLE':
|
||||
return EquipmentCategory.consumable;
|
||||
case 'CABLE':
|
||||
return EquipmentCategory.cable;
|
||||
case 'EFFECT':
|
||||
return EquipmentCategory.effect;
|
||||
case 'OTHER':
|
||||
default:
|
||||
return EquipmentCategory.other;
|
||||
}
|
||||
}
|
||||
|
||||
class EquipmentModel {
|
||||
final String id; // Identifiant unique (clé)
|
||||
final String name; // Nom de l'équipement
|
||||
final String? brand; // Marque (indexé)
|
||||
final String? model; // Modèle (indexé)
|
||||
final EquipmentCategory category; // Catégorie
|
||||
final EquipmentStatus status; // Statut actuel
|
||||
|
||||
// Prix (visible uniquement avec manage_equipment)
|
||||
final double? purchasePrice; // Prix d'achat
|
||||
final double? rentalPrice; // Prix de location
|
||||
|
||||
// Quantité (pour consommables/câbles)
|
||||
final int? totalQuantity; // Quantité totale
|
||||
final int? availableQuantity; // Quantité disponible
|
||||
final int? criticalThreshold; // Seuil critique pour alerte
|
||||
|
||||
// Boîtes parentes (plusieurs possibles)
|
||||
final List<String> parentBoxIds; // IDs des boîtes contenant cet équipement
|
||||
|
||||
// Dates & maintenance
|
||||
final DateTime? purchaseDate; // Date d'achat
|
||||
final DateTime? lastMaintenanceDate; // Dernière maintenance
|
||||
final DateTime? nextMaintenanceDate; // Prochaine maintenance prévue
|
||||
|
||||
// Maintenances (références)
|
||||
final List<String> maintenanceIds; // IDs des opérations de maintenance
|
||||
|
||||
// Image
|
||||
final String? imageUrl; // URL de l'image (Storage /materiel)
|
||||
|
||||
// Métadonnées
|
||||
final String? notes; // Notes additionnelles
|
||||
final DateTime createdAt; // Date de création
|
||||
final DateTime updatedAt; // Date de mise à jour
|
||||
|
||||
EquipmentModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
this.brand,
|
||||
this.model,
|
||||
required this.category,
|
||||
this.status = EquipmentStatus.available,
|
||||
this.purchasePrice,
|
||||
this.rentalPrice,
|
||||
this.totalQuantity,
|
||||
this.availableQuantity,
|
||||
this.criticalThreshold,
|
||||
this.parentBoxIds = const [],
|
||||
this.purchaseDate,
|
||||
this.lastMaintenanceDate,
|
||||
this.nextMaintenanceDate,
|
||||
this.maintenanceIds = const [],
|
||||
this.imageUrl,
|
||||
this.notes,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
factory EquipmentModel.fromMap(Map<String, dynamic> map, String id) {
|
||||
// Gestion des listes
|
||||
final List<dynamic> parentBoxIdsRaw = map['parentBoxIds'] ?? [];
|
||||
final List<String> parentBoxIds = parentBoxIdsRaw.map((e) => e.toString()).toList();
|
||||
|
||||
final List<dynamic> maintenanceIdsRaw = map['maintenanceIds'] ?? [];
|
||||
final List<String> maintenanceIds = maintenanceIdsRaw.map((e) => e.toString()).toList();
|
||||
|
||||
return EquipmentModel(
|
||||
id: id,
|
||||
name: map['name'] ?? '',
|
||||
brand: map['brand'],
|
||||
model: map['model'],
|
||||
category: equipmentCategoryFromString(map['category']),
|
||||
status: equipmentStatusFromString(map['status']),
|
||||
purchasePrice: map['purchasePrice']?.toDouble(),
|
||||
rentalPrice: map['rentalPrice']?.toDouble(),
|
||||
totalQuantity: map['totalQuantity']?.toInt(),
|
||||
availableQuantity: map['availableQuantity']?.toInt(),
|
||||
criticalThreshold: map['criticalThreshold']?.toInt(),
|
||||
parentBoxIds: parentBoxIds,
|
||||
purchaseDate: (map['purchaseDate'] as Timestamp?)?.toDate(),
|
||||
nextMaintenanceDate: (map['nextMaintenanceDate'] as Timestamp?)?.toDate(),
|
||||
maintenanceIds: maintenanceIds,
|
||||
imageUrl: map['imageUrl'],
|
||||
notes: map['notes'],
|
||||
createdAt: (map['createdAt'] as Timestamp?)?.toDate() ?? DateTime.now(),
|
||||
updatedAt: (map['updatedAt'] as Timestamp?)?.toDate() ?? DateTime.now(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'name': name,
|
||||
'brand': brand,
|
||||
'model': model,
|
||||
'category': equipmentCategoryToString(category),
|
||||
'status': equipmentStatusToString(status),
|
||||
'purchasePrice': purchasePrice,
|
||||
'rentalPrice': rentalPrice,
|
||||
'totalQuantity': totalQuantity,
|
||||
'availableQuantity': availableQuantity,
|
||||
'criticalThreshold': criticalThreshold,
|
||||
'parentBoxIds': parentBoxIds,
|
||||
'lastMaintenanceDate': lastMaintenanceDate != null ? Timestamp.fromDate(lastMaintenanceDate!) : null,
|
||||
'purchaseDate': purchaseDate != null ? Timestamp.fromDate(purchaseDate!) : null,
|
||||
'nextMaintenanceDate': nextMaintenanceDate != null ? Timestamp.fromDate(nextMaintenanceDate!) : null,
|
||||
'maintenanceIds': maintenanceIds,
|
||||
'imageUrl': imageUrl,
|
||||
'notes': notes,
|
||||
'createdAt': Timestamp.fromDate(createdAt),
|
||||
'updatedAt': Timestamp.fromDate(updatedAt),
|
||||
};
|
||||
}
|
||||
|
||||
EquipmentModel copyWith({
|
||||
String? id,
|
||||
String? brand,
|
||||
String? name,
|
||||
String? model,
|
||||
EquipmentCategory? category,
|
||||
EquipmentStatus? status,
|
||||
double? purchasePrice,
|
||||
double? rentalPrice,
|
||||
int? totalQuantity,
|
||||
int? availableQuantity,
|
||||
int? criticalThreshold,
|
||||
List<String>? parentBoxIds,
|
||||
DateTime? purchaseDate,
|
||||
DateTime? lastMaintenanceDate,
|
||||
DateTime? nextMaintenanceDate,
|
||||
List<String>? maintenanceIds,
|
||||
String? imageUrl,
|
||||
String? notes,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return EquipmentModel(
|
||||
id: id ?? this.id,
|
||||
brand: brand ?? this.brand,
|
||||
name: name ?? this.name,
|
||||
model: model ?? this.model,
|
||||
category: category ?? this.category,
|
||||
status: status ?? this.status,
|
||||
purchasePrice: purchasePrice ?? this.purchasePrice,
|
||||
rentalPrice: rentalPrice ?? this.rentalPrice,
|
||||
totalQuantity: totalQuantity ?? this.totalQuantity,
|
||||
availableQuantity: availableQuantity ?? this.availableQuantity,
|
||||
criticalThreshold: criticalThreshold ?? this.criticalThreshold,
|
||||
parentBoxIds: parentBoxIds ?? this.parentBoxIds,
|
||||
lastMaintenanceDate: lastMaintenanceDate ?? this.lastMaintenanceDate,
|
||||
purchaseDate: purchaseDate ?? this.purchaseDate,
|
||||
nextMaintenanceDate: nextMaintenanceDate ?? this.nextMaintenanceDate,
|
||||
maintenanceIds: maintenanceIds ?? this.maintenanceIds,
|
||||
imageUrl: imageUrl ?? this.imageUrl,
|
||||
notes: notes ?? this.notes,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
);
|
||||
}
|
||||
|
||||
// Helper pour vérifier si c'est un consommable/câble avec quantité
|
||||
bool get hasQuantity => category == EquipmentCategory.consumable || category == EquipmentCategory.cable;
|
||||
|
||||
// Helper pour vérifier si le stock est critique
|
||||
bool get isCriticalStock {
|
||||
if (!hasQuantity || criticalThreshold == null || availableQuantity == null) {
|
||||
return false;
|
||||
}
|
||||
return availableQuantity! <= criticalThreshold!;
|
||||
}
|
||||
|
||||
// Helper pour vérifier si la maintenance est à venir
|
||||
bool get isMaintenanceDue {
|
||||
if (nextMaintenanceDate == null) return false;
|
||||
return nextMaintenanceDate!.isBefore(DateTime.now().add(const Duration(days: 7)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,128 @@ EventStatus eventStatusFromString(String? status) {
|
||||
}
|
||||
}
|
||||
|
||||
enum PreparationStatus {
|
||||
notStarted,
|
||||
inProgress,
|
||||
completed,
|
||||
completedWithMissing
|
||||
}
|
||||
|
||||
String preparationStatusToString(PreparationStatus status) {
|
||||
switch (status) {
|
||||
case PreparationStatus.notStarted:
|
||||
return 'NOT_STARTED';
|
||||
case PreparationStatus.inProgress:
|
||||
return 'IN_PROGRESS';
|
||||
case PreparationStatus.completed:
|
||||
return 'COMPLETED';
|
||||
case PreparationStatus.completedWithMissing:
|
||||
return 'COMPLETED_WITH_MISSING';
|
||||
}
|
||||
}
|
||||
|
||||
PreparationStatus preparationStatusFromString(String? status) {
|
||||
switch (status) {
|
||||
case 'NOT_STARTED':
|
||||
return PreparationStatus.notStarted;
|
||||
case 'IN_PROGRESS':
|
||||
return PreparationStatus.inProgress;
|
||||
case 'COMPLETED':
|
||||
return PreparationStatus.completed;
|
||||
case 'COMPLETED_WITH_MISSING':
|
||||
return PreparationStatus.completedWithMissing;
|
||||
default:
|
||||
return PreparationStatus.notStarted;
|
||||
}
|
||||
}
|
||||
|
||||
enum ReturnStatus {
|
||||
notStarted,
|
||||
inProgress,
|
||||
completed,
|
||||
completedWithMissing
|
||||
}
|
||||
|
||||
String returnStatusToString(ReturnStatus status) {
|
||||
switch (status) {
|
||||
case ReturnStatus.notStarted:
|
||||
return 'NOT_STARTED';
|
||||
case ReturnStatus.inProgress:
|
||||
return 'IN_PROGRESS';
|
||||
case ReturnStatus.completed:
|
||||
return 'COMPLETED';
|
||||
case ReturnStatus.completedWithMissing:
|
||||
return 'COMPLETED_WITH_MISSING';
|
||||
}
|
||||
}
|
||||
|
||||
ReturnStatus returnStatusFromString(String? status) {
|
||||
switch (status) {
|
||||
case 'NOT_STARTED':
|
||||
return ReturnStatus.notStarted;
|
||||
case 'IN_PROGRESS':
|
||||
return ReturnStatus.inProgress;
|
||||
case 'COMPLETED':
|
||||
return ReturnStatus.completed;
|
||||
case 'COMPLETED_WITH_MISSING':
|
||||
return ReturnStatus.completedWithMissing;
|
||||
default:
|
||||
return ReturnStatus.notStarted;
|
||||
}
|
||||
}
|
||||
|
||||
class EventEquipment {
|
||||
final String equipmentId; // ID de l'équipement
|
||||
final int quantity; // Quantité (pour consommables)
|
||||
final bool isPrepared; // Validé en préparation
|
||||
final bool isReturned; // Validé au retour
|
||||
final int? returnedQuantity; // Quantité retournée (pour consommables)
|
||||
|
||||
EventEquipment({
|
||||
required this.equipmentId,
|
||||
this.quantity = 1,
|
||||
this.isPrepared = false,
|
||||
this.isReturned = false,
|
||||
this.returnedQuantity,
|
||||
});
|
||||
|
||||
factory EventEquipment.fromMap(Map<String, dynamic> map) {
|
||||
return EventEquipment(
|
||||
equipmentId: map['equipmentId'] ?? '',
|
||||
quantity: map['quantity'] ?? 1,
|
||||
isPrepared: map['isPrepared'] ?? false,
|
||||
isReturned: map['isReturned'] ?? false,
|
||||
returnedQuantity: map['returnedQuantity'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'equipmentId': equipmentId,
|
||||
'quantity': quantity,
|
||||
'isPrepared': isPrepared,
|
||||
'isReturned': isReturned,
|
||||
'returnedQuantity': returnedQuantity,
|
||||
};
|
||||
}
|
||||
|
||||
EventEquipment copyWith({
|
||||
String? equipmentId,
|
||||
int? quantity,
|
||||
bool? isPrepared,
|
||||
bool? isReturned,
|
||||
int? returnedQuantity,
|
||||
}) {
|
||||
return EventEquipment(
|
||||
equipmentId: equipmentId ?? this.equipmentId,
|
||||
quantity: quantity ?? this.quantity,
|
||||
isPrepared: isPrepared ?? this.isPrepared,
|
||||
isReturned: isReturned ?? this.isReturned,
|
||||
returnedQuantity: returnedQuantity ?? this.returnedQuantity,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EventModel {
|
||||
final String id;
|
||||
final String name;
|
||||
@@ -50,6 +172,11 @@ class EventModel {
|
||||
final List<Map<String, dynamic>> options;
|
||||
final EventStatus status;
|
||||
|
||||
// Nouveaux champs pour la gestion du matériel
|
||||
final List<EventEquipment> assignedEquipment;
|
||||
final PreparationStatus? preparationStatus;
|
||||
final ReturnStatus? returnStatus;
|
||||
|
||||
EventModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
@@ -69,6 +196,9 @@ class EventModel {
|
||||
required this.documents,
|
||||
this.options = const [],
|
||||
this.status = EventStatus.waitingForApproval,
|
||||
this.assignedEquipment = const [],
|
||||
this.preparationStatus,
|
||||
this.returnStatus,
|
||||
});
|
||||
|
||||
factory EventModel.fromMap(Map<String, dynamic> map, String id) {
|
||||
@@ -149,6 +279,22 @@ class EventModel {
|
||||
customerId = map['customer'] as String;
|
||||
}
|
||||
|
||||
// Gestion des équipements assignés
|
||||
final assignedEquipmentRaw = map['assignedEquipment'] ?? [];
|
||||
final List<EventEquipment> assignedEquipment = [];
|
||||
|
||||
if (assignedEquipmentRaw is List) {
|
||||
for (var e in assignedEquipmentRaw) {
|
||||
try {
|
||||
if (e is Map) {
|
||||
assignedEquipment.add(EventEquipment.fromMap(Map<String, dynamic>.from(e)));
|
||||
}
|
||||
} catch (equipmentError) {
|
||||
print('Warning: Failed to parse equipment in event $id: $equipmentError');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EventModel(
|
||||
id: id,
|
||||
name: (map['Name'] ?? '').toString().trim(),
|
||||
@@ -168,6 +314,9 @@ class EventModel {
|
||||
documents: docs,
|
||||
options: options,
|
||||
status: eventStatusFromString(map['status'] as String?),
|
||||
assignedEquipment: assignedEquipment,
|
||||
preparationStatus: preparationStatusFromString(map['preparationStatus'] as String?),
|
||||
returnStatus: returnStatusFromString(map['returnStatus'] as String?),
|
||||
);
|
||||
} catch (e) {
|
||||
print('Error parsing event $id: $e');
|
||||
@@ -220,6 +369,9 @@ class EventModel {
|
||||
'documents': documents,
|
||||
'options': options,
|
||||
'status': eventStatusToString(status),
|
||||
'assignedEquipment': assignedEquipment.map((e) => e.toMap()).toList(),
|
||||
'preparationStatus': preparationStatus != null ? preparationStatusToString(preparationStatus!) : null,
|
||||
'returnStatus': returnStatus != null ? returnStatusToString(returnStatus!) : null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
138
em2rp/lib/models/maintenance_model.dart
Normal file
138
em2rp/lib/models/maintenance_model.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
enum MaintenanceType {
|
||||
preventive, // Préventive
|
||||
corrective, // Corrective
|
||||
inspection // Inspection
|
||||
}
|
||||
|
||||
String maintenanceTypeToString(MaintenanceType type) {
|
||||
switch (type) {
|
||||
case MaintenanceType.preventive:
|
||||
return 'PREVENTIVE';
|
||||
case MaintenanceType.corrective:
|
||||
return 'CORRECTIVE';
|
||||
case MaintenanceType.inspection:
|
||||
return 'INSPECTION';
|
||||
}
|
||||
}
|
||||
|
||||
MaintenanceType maintenanceTypeFromString(String? type) {
|
||||
switch (type) {
|
||||
case 'PREVENTIVE':
|
||||
return MaintenanceType.preventive;
|
||||
case 'CORRECTIVE':
|
||||
return MaintenanceType.corrective;
|
||||
case 'INSPECTION':
|
||||
return MaintenanceType.inspection;
|
||||
default:
|
||||
return MaintenanceType.preventive;
|
||||
}
|
||||
}
|
||||
|
||||
class MaintenanceModel {
|
||||
final String id; // ID aléatoire
|
||||
final List<String> equipmentIds; // IDs des équipements concernés (peut être multiple)
|
||||
final MaintenanceType type; // Type de maintenance
|
||||
final DateTime scheduledDate; // Date planifiée
|
||||
final DateTime? completedDate; // Date de réalisation (null si pas encore effectuée)
|
||||
final String name; // Nom de l'opération
|
||||
final String description; // Description détaillée
|
||||
final String? performedBy; // ID de l'utilisateur qui a effectué la maintenance
|
||||
final double? cost; // Coût de la maintenance
|
||||
final String? notes; // Notes additionnelles
|
||||
final DateTime createdAt; // Date de création
|
||||
final DateTime updatedAt; // Date de mise à jour
|
||||
|
||||
MaintenanceModel({
|
||||
required this.id,
|
||||
required this.equipmentIds,
|
||||
required this.type,
|
||||
required this.scheduledDate,
|
||||
this.completedDate,
|
||||
required this.name,
|
||||
required this.description,
|
||||
this.performedBy,
|
||||
this.cost,
|
||||
this.notes,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
factory MaintenanceModel.fromMap(Map<String, dynamic> map, String id) {
|
||||
// Gestion de la liste des équipements
|
||||
final List<dynamic> equipmentIdsRaw = map['equipmentIds'] ?? [];
|
||||
final List<String> equipmentIds = equipmentIdsRaw.map((e) => e.toString()).toList();
|
||||
|
||||
return MaintenanceModel(
|
||||
id: id,
|
||||
equipmentIds: equipmentIds,
|
||||
type: maintenanceTypeFromString(map['type']),
|
||||
scheduledDate: (map['scheduledDate'] as Timestamp?)?.toDate() ?? DateTime.now(),
|
||||
completedDate: (map['completedDate'] as Timestamp?)?.toDate(),
|
||||
name: map['name'] ?? '',
|
||||
description: map['description'] ?? '',
|
||||
performedBy: map['performedBy'],
|
||||
cost: map['cost']?.toDouble(),
|
||||
notes: map['notes'],
|
||||
createdAt: (map['createdAt'] as Timestamp?)?.toDate() ?? DateTime.now(),
|
||||
updatedAt: (map['updatedAt'] as Timestamp?)?.toDate() ?? DateTime.now(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'equipmentIds': equipmentIds,
|
||||
'type': maintenanceTypeToString(type),
|
||||
'scheduledDate': Timestamp.fromDate(scheduledDate),
|
||||
'completedDate': completedDate != null ? Timestamp.fromDate(completedDate!) : null,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'performedBy': performedBy,
|
||||
'cost': cost,
|
||||
'notes': notes,
|
||||
'createdAt': Timestamp.fromDate(createdAt),
|
||||
'updatedAt': Timestamp.fromDate(updatedAt),
|
||||
};
|
||||
}
|
||||
|
||||
MaintenanceModel copyWith({
|
||||
String? id,
|
||||
List<String>? equipmentIds,
|
||||
MaintenanceType? type,
|
||||
DateTime? scheduledDate,
|
||||
DateTime? completedDate,
|
||||
String? name,
|
||||
String? description,
|
||||
String? performedBy,
|
||||
double? cost,
|
||||
String? notes,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return MaintenanceModel(
|
||||
id: id ?? this.id,
|
||||
equipmentIds: equipmentIds ?? this.equipmentIds,
|
||||
type: type ?? this.type,
|
||||
scheduledDate: scheduledDate ?? this.scheduledDate,
|
||||
completedDate: completedDate ?? this.completedDate,
|
||||
name: name ?? this.name,
|
||||
description: description ?? this.description,
|
||||
performedBy: performedBy ?? this.performedBy,
|
||||
cost: cost ?? this.cost,
|
||||
notes: notes ?? this.notes,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
);
|
||||
}
|
||||
|
||||
// Helper pour vérifier si la maintenance est complétée
|
||||
bool get isCompleted => completedDate != null;
|
||||
|
||||
// Helper pour vérifier si la maintenance est en retard
|
||||
bool get isOverdue {
|
||||
if (isCompleted) return false;
|
||||
return scheduledDate.isBefore(DateTime.now());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user