Ajout de la gestion des containers (création, édition, suppression, affichage des détails).
Introduction d'un système de génération de QR codes unifié et d'un mode de sélection multiple.
**Features:**
- **Gestion des Containers :**
- Nouvelle page de gestion des containers (`container_management_page.dart`) avec recherche et filtres.
- Formulaire de création/édition de containers (`container_form_page.dart`) avec génération d'ID automatique.
- Page de détails d'un container (`container_detail_page.dart`) affichant son contenu et ses caractéristiques.
- Ajout des routes et du provider (`ContainerProvider`) nécessaires.
- **Modèle de Données :**
- Ajout du `ContainerModel` pour représenter les boîtes, flight cases, etc.
- Le modèle `EquipmentModel` a été enrichi avec des caractéristiques physiques (poids, dimensions).
- **QR Codes :**
- Nouveau service unifié (`UnifiedPDFGeneratorService`) pour générer des PDFs de QR codes pour n'importe quelle entité.
- Services `PDFGeneratorService` et `ContainerPDFGeneratorService` transformés en wrappers pour maintenir la compatibilité.
- Amélioration de la performance de la génération de QR codes en masse.
- **Interface Utilisateur (UI/UX) :**
- Nouvelle page de détails pour le matériel (`equipment_detail_page.dart`).
- Ajout d'un `SelectionModeMixin` pour gérer la sélection multiple dans les pages de gestion.
- Dialogues réutilisables pour l'affichage de QR codes (`QRCodeDialog`) et la sélection de format d'impression (`QRCodeFormatSelectorDialog`).
- Ajout d'un bouton "Gérer les boîtes" sur la page de gestion du matériel.
**Refactorisation :**
- L' `IdGenerator` a été déplacé dans le répertoire `utils` et étendu pour gérer les containers.
- Mise à jour de nombreuses dépendances `pubspec.yaml` vers des versions plus récentes.
- Séparation de la logique d'affichage des containers et du matériel dans des widgets dédiés (`ContainerHeaderCard`, `EquipmentParentContainers`, etc.).
156 lines
4.4 KiB
Dart
156 lines
4.4 KiB
Dart
import 'package:em2rp/models/container_model.dart';
|
|
import 'package:em2rp/services/equipment_service.dart';
|
|
|
|
/// Générateur d'identifiants unifié pour l'application
|
|
/// Gère les équipements, containers et autres entités
|
|
class IdGenerator {
|
|
// ============================================================================
|
|
// ÉQUIPEMENTS
|
|
// ============================================================================
|
|
|
|
/// Génère un ID pour un équipement
|
|
/// Format: {Marque4Chars}_{Modèle}_{#Numéro}
|
|
/// Exemple: BEAM_7R_#1
|
|
static String generateEquipmentId({
|
|
required String brand,
|
|
required String model,
|
|
int? number,
|
|
}) {
|
|
final brandTrim = brand.trim().replaceAll(' ', '_');
|
|
final modelTrim = model.trim().replaceAll(' ', '_');
|
|
|
|
if (brandTrim.isEmpty && modelTrim.isEmpty) {
|
|
return 'EQ-${DateTime.now().millisecondsSinceEpoch}${number != null ? '_$number' : ''}';
|
|
}
|
|
|
|
final brandPrefix = brandTrim.length >= 4
|
|
? brandTrim.substring(0, 4)
|
|
: brandTrim;
|
|
|
|
String baseId = modelTrim.isNotEmpty
|
|
? '${brandPrefix}_$modelTrim'
|
|
: (brandPrefix.isNotEmpty ? brandPrefix : 'EQ');
|
|
|
|
// Empêcher les ID commençant par BOX_ (réservé aux containers)
|
|
if (baseId.toUpperCase().startsWith('BOX_')) {
|
|
baseId = 'EQ_$baseId';
|
|
}
|
|
|
|
if (number != null) {
|
|
baseId += '_#$number';
|
|
}
|
|
|
|
return baseId.toUpperCase();
|
|
}
|
|
|
|
/// Garantit l'unicité d'un ID d'équipement
|
|
static Future<String> ensureUniqueEquipmentId(
|
|
String baseId,
|
|
EquipmentService service,
|
|
) async {
|
|
// Vérifier que l'ID ne commence pas par BOX_
|
|
if (baseId.toUpperCase().startsWith('BOX_')) {
|
|
baseId = 'EQ_$baseId';
|
|
}
|
|
|
|
if (await service.isIdUnique(baseId)) {
|
|
return baseId;
|
|
}
|
|
|
|
return '${baseId}_${DateTime.now().millisecondsSinceEpoch}';
|
|
}
|
|
|
|
// ============================================================================
|
|
// CONTAINERS
|
|
// ============================================================================
|
|
|
|
/// Génère un ID pour un container
|
|
/// Format: BOX_{Type}_{Nom}_{#Numéro}
|
|
/// Exemple: BOX_FLIGHT_CASE_BEAM_#1
|
|
static String generateContainerId({
|
|
required ContainerType type,
|
|
required String name,
|
|
int? number,
|
|
}) {
|
|
final typeStr = containerTypeToString(type);
|
|
final cleanName = _cleanId(name);
|
|
|
|
if (number != null) {
|
|
return 'BOX_${typeStr}_${cleanName}_#$number';
|
|
}
|
|
|
|
return 'BOX_${typeStr}_$cleanName';
|
|
}
|
|
|
|
/// Garantit l'unicité d'un ID de container
|
|
/// Note: La vérification d'unicité doit être faite par l'appelant
|
|
static String ensureUniqueContainerId(String baseId) {
|
|
// Retourne simplement l'ID de base
|
|
// L'unicité sera vérifiée au niveau du provider/form
|
|
return baseId;
|
|
}
|
|
|
|
/// Génère un ID unique avec un timestamp si nécessaire
|
|
static String generateUniqueContainerId(String baseId) {
|
|
return '${baseId}_${DateTime.now().millisecondsSinceEpoch}';
|
|
}
|
|
|
|
|
|
// ============================================================================
|
|
// UTILITAIRES
|
|
// ============================================================================
|
|
|
|
/// Nettoie une chaîne pour en faire un ID valide
|
|
/// - Supprime les espaces (remplacés par _)
|
|
/// - Supprime les caractères spéciaux
|
|
/// - Met en majuscules
|
|
static String _cleanId(String input) {
|
|
return input
|
|
.trim()
|
|
.toUpperCase()
|
|
.replaceAll(' ', '_')
|
|
.replaceAll(RegExp(r'[^A-Z0-9_-]'), '');
|
|
}
|
|
|
|
/// Valide qu'un ID d'équipement ne commence pas par un préfixe réservé
|
|
static String? validateEquipmentId(String id) {
|
|
if (id.isEmpty) {
|
|
return 'L\'identifiant ne peut pas être vide';
|
|
}
|
|
|
|
if (id.toUpperCase().startsWith('BOX_')) {
|
|
return 'Les ID commençant par BOX_ sont réservés aux containers';
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// Valide qu'un ID de container commence bien par BOX_
|
|
static String? validateContainerId(String id) {
|
|
if (id.isEmpty) {
|
|
return 'L\'identifiant ne peut pas être vide';
|
|
}
|
|
|
|
if (!id.toUpperCase().startsWith('BOX_')) {
|
|
return 'Les containers doivent avoir un ID commençant par BOX_';
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// Détermine le type d'entité à partir d'un ID
|
|
static EntityType getEntityType(String id) {
|
|
if (id.toUpperCase().startsWith('BOX_')) {
|
|
return EntityType.container;
|
|
}
|
|
return EntityType.equipment;
|
|
}
|
|
}
|
|
|
|
/// Type d'entité identifiable
|
|
enum EntityType {
|
|
equipment,
|
|
container,
|
|
}
|
|
|