Add equipment management features (and qr generation support)
This commit is contained in:
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)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user