280 lines
9.2 KiB
Dart
280 lines
9.2 KiB
Dart
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)));
|
|
}
|
|
}
|
|
|