feat: ajout de la gestion de la préparation d'un événement avec page permettant de le gérer
This commit is contained in:
@@ -24,8 +24,22 @@ class _EquipmentConflictDialogState extends State<EquipmentConflictDialog> {
|
||||
.where((entry) => !_removedEquipmentIds.contains(entry.key))
|
||||
.fold(0, (sum, entry) => sum + entry.value.length);
|
||||
|
||||
/// Retourne l'icône appropriée selon le type de conflit
|
||||
IconData _getIconForConflict(AvailabilityConflict conflict) {
|
||||
switch (conflict.type) {
|
||||
case ConflictType.containerFullyUsed:
|
||||
case ConflictType.containerPartiallyUsed:
|
||||
return Icons.inventory_2;
|
||||
case ConflictType.insufficientQuantity:
|
||||
return Icons.production_quantity_limits;
|
||||
case ConflictType.equipmentUnavailable:
|
||||
return Icons.block;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
final dateFormat = DateFormat('dd/MM/yyyy');
|
||||
|
||||
return Dialog(
|
||||
@@ -117,19 +131,37 @@ class _EquipmentConflictDialogState extends State<EquipmentConflictDialog> {
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.inventory_2,
|
||||
_getIconForConflict(firstConflict),
|
||||
color: isRemoved ? Colors.grey : AppColors.rouge,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
firstConflict.equipmentName,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
decoration: isRemoved ? TextDecoration.lineThrough : null,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
firstConflict.equipmentName,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
decoration: isRemoved ? TextDecoration.lineThrough : null,
|
||||
),
|
||||
),
|
||||
// Message de conflit spécifique
|
||||
if (firstConflict.conflictMessage.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: Text(
|
||||
firstConflict.conflictMessage,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.orange.shade700,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isRemoved)
|
||||
|
||||
@@ -213,28 +213,54 @@ class _EquipmentSelectionDialogState extends State<EquipmentSelectionDialog> {
|
||||
setState(() => _isLoadingConflicts = true);
|
||||
|
||||
try {
|
||||
print('[EquipmentSelectionDialog] Loading equipment conflicts...');
|
||||
final equipmentProvider = context.read<EquipmentProvider>();
|
||||
final equipment = await equipmentProvider.equipmentStream.first;
|
||||
|
||||
print('[EquipmentSelectionDialog] Checking conflicts for ${equipment.length} equipments');
|
||||
|
||||
for (var eq in equipment) {
|
||||
final conflicts = await _availabilityService.checkEquipmentAvailability(
|
||||
equipmentId: eq.id,
|
||||
equipmentName: eq.id,
|
||||
startDate: widget.startDate,
|
||||
endDate: widget.endDate,
|
||||
excludeEventId: widget.excludeEventId,
|
||||
);
|
||||
// Pour les consommables/câbles, vérifier avec gestion de quantité
|
||||
if (eq.hasQuantity) {
|
||||
// Récupérer la quantité disponible
|
||||
final availableQty = await _availabilityService.getAvailableQuantity(
|
||||
equipment: eq,
|
||||
startDate: widget.startDate,
|
||||
endDate: widget.endDate,
|
||||
excludeEventId: widget.excludeEventId,
|
||||
);
|
||||
|
||||
if (conflicts.isNotEmpty) {
|
||||
print('[EquipmentSelectionDialog] Found ${conflicts.length} conflict(s) for ${eq.id}');
|
||||
_equipmentConflicts[eq.id] = conflicts;
|
||||
// Vérifier si un item de cet équipement est déjà sélectionné
|
||||
final selectedItem = _selectedItems[eq.id];
|
||||
final requestedQty = selectedItem?.quantity ?? 1;
|
||||
|
||||
// ✅ Ne créer un conflit QUE si la quantité demandée dépasse la quantité disponible
|
||||
if (requestedQty > availableQty) {
|
||||
final conflicts = await _availabilityService.checkEquipmentAvailabilityWithQuantity(
|
||||
equipment: eq,
|
||||
requestedQuantity: requestedQty,
|
||||
startDate: widget.startDate,
|
||||
endDate: widget.endDate,
|
||||
excludeEventId: widget.excludeEventId,
|
||||
);
|
||||
|
||||
if (conflicts.isNotEmpty) {
|
||||
_equipmentConflicts[eq.id] = conflicts;
|
||||
}
|
||||
}
|
||||
// Sinon, pas de conflit à afficher dans la liste
|
||||
} else {
|
||||
// Pour les équipements non quantifiables, vérification classique
|
||||
final conflicts = await _availabilityService.checkEquipmentAvailability(
|
||||
equipmentId: eq.id,
|
||||
equipmentName: eq.id,
|
||||
startDate: widget.startDate,
|
||||
endDate: widget.endDate,
|
||||
excludeEventId: widget.excludeEventId,
|
||||
);
|
||||
|
||||
if (conflicts.isNotEmpty) {
|
||||
_equipmentConflicts[eq.id] = conflicts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print('[EquipmentSelectionDialog] Total equipments with conflicts: ${_equipmentConflicts.length}');
|
||||
} catch (e) {
|
||||
print('[EquipmentSelectionDialog] Error loading conflicts: $e');
|
||||
} finally {
|
||||
@@ -247,32 +273,76 @@ class _EquipmentSelectionDialogState extends State<EquipmentSelectionDialog> {
|
||||
try {
|
||||
print('[EquipmentSelectionDialog] Loading container conflicts...');
|
||||
final containerProvider = context.read<ContainerProvider>();
|
||||
final equipmentProvider = context.read<EquipmentProvider>();
|
||||
final containers = await containerProvider.containersStream.first;
|
||||
final allEquipment = await equipmentProvider.equipmentStream.first;
|
||||
|
||||
print('[EquipmentSelectionDialog] Checking conflicts for ${containers.length} containers');
|
||||
|
||||
for (var container in containers) {
|
||||
final conflictingChildren = <String>[];
|
||||
// Vérifier d'abord si la boîte complète est utilisée ailleurs
|
||||
final containerEquipment = allEquipment
|
||||
.where((eq) => container.equipmentIds.contains(eq.id))
|
||||
.toList();
|
||||
|
||||
// Vérifier chaque équipement enfant
|
||||
for (var equipmentId in container.equipmentIds) {
|
||||
if (_equipmentConflicts.containsKey(equipmentId)) {
|
||||
conflictingChildren.add(equipmentId);
|
||||
}
|
||||
}
|
||||
final containerConflicts = await _availabilityService.checkContainerAvailability(
|
||||
container: container,
|
||||
containerEquipment: containerEquipment,
|
||||
startDate: widget.startDate,
|
||||
endDate: widget.endDate,
|
||||
excludeEventId: widget.excludeEventId,
|
||||
);
|
||||
|
||||
if (conflictingChildren.isNotEmpty) {
|
||||
final status = conflictingChildren.length == container.equipmentIds.length
|
||||
? ContainerConflictStatus.complete
|
||||
: ContainerConflictStatus.partial;
|
||||
|
||||
_containerConflicts[container.id] = ContainerConflictInfo(
|
||||
status: status,
|
||||
conflictingEquipmentIds: conflictingChildren,
|
||||
totalChildren: container.equipmentIds.length,
|
||||
if (containerConflicts.isNotEmpty) {
|
||||
// Déterminer le statut en fonction du type de conflit
|
||||
final hasFullConflict = containerConflicts.any(
|
||||
(c) => c.type == ConflictType.containerFullyUsed,
|
||||
);
|
||||
|
||||
print('[EquipmentSelectionDialog] Container ${container.id}: ${status.name} conflict (${conflictingChildren.length}/${container.equipmentIds.length} children)');
|
||||
final conflictingChildren = containerConflicts
|
||||
.where((c) => c.type != ConflictType.containerFullyUsed &&
|
||||
c.type != ConflictType.containerPartiallyUsed)
|
||||
.map((c) => c.equipmentId)
|
||||
.toList();
|
||||
|
||||
final status = hasFullConflict
|
||||
? ContainerConflictStatus.complete
|
||||
: (conflictingChildren.isNotEmpty
|
||||
? ContainerConflictStatus.partial
|
||||
: ContainerConflictStatus.none);
|
||||
|
||||
if (status != ContainerConflictStatus.none) {
|
||||
_containerConflicts[container.id] = ContainerConflictInfo(
|
||||
status: status,
|
||||
conflictingEquipmentIds: conflictingChildren,
|
||||
totalChildren: container.equipmentIds.length,
|
||||
);
|
||||
|
||||
print('[EquipmentSelectionDialog] Container ${container.id}: ${status.name} conflict');
|
||||
}
|
||||
} else {
|
||||
// Vérifier chaque équipement enfant individuellement
|
||||
final conflictingChildren = <String>[];
|
||||
|
||||
for (var equipmentId in container.equipmentIds) {
|
||||
if (_equipmentConflicts.containsKey(equipmentId)) {
|
||||
conflictingChildren.add(equipmentId);
|
||||
}
|
||||
}
|
||||
|
||||
if (conflictingChildren.isNotEmpty) {
|
||||
final status = conflictingChildren.length == container.equipmentIds.length
|
||||
? ContainerConflictStatus.complete
|
||||
: ContainerConflictStatus.partial;
|
||||
|
||||
_containerConflicts[container.id] = ContainerConflictInfo(
|
||||
status: status,
|
||||
conflictingEquipmentIds: conflictingChildren,
|
||||
totalChildren: container.equipmentIds.length,
|
||||
);
|
||||
|
||||
print('[EquipmentSelectionDialog] Container ${container.id}: ${status.name} conflict (${conflictingChildren.length}/${container.equipmentIds.length} children)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user