feat: Refactor event equipment management with advanced selection and conflict detection

This commit introduces a complete overhaul of how equipment is assigned to events, focusing on an enhanced user experience, advanced selection capabilities, and robust conflict detection.

**Key Features & Enhancements:**

-   **Advanced Equipment Selection UI (`EquipmentSelectionDialog`):**
    -   New full-screen dialog to select equipment and containers ("boîtes") for an event.
    -   Hierarchical view showing containers and a flat list of all individual equipment.
    -   Real-time search and filtering by equipment category.
    -   Side panel summarizing the current selection and providing recommendations for containers based on selected equipment.
    -   Supports quantity selection for consumables and cables.

-   **Conflict Detection & Management (`EventAvailabilityService`):**
    -   A new service (`EventAvailabilityService`) checks for equipment availability against other events based on the selected date range.
    -   The selection dialog visually highlights equipment and containers with scheduling conflicts (e.g., already used, partially unavailable).
    -   A dedicated conflict resolution dialog (`EquipmentConflictDialog`) appears if conflicting items are selected, allowing the user to either remove them or force the assignment.

-   **Integrated Event Form (`EventAssignedEquipmentSection`):**
    -   The event creation/editing form now includes a new section for managing assigned equipment.
    -   It clearly displays assigned containers and standalone equipment, showing the composition of each container.
    -   Integrates the new selection dialog, ensuring all assignments are checked for conflicts before being saved.

-   **Event Preparation & Return Workflow (`EventPreparationPage`):**
    -   New page (`EventPreparationPage`) for managing the check-out (preparation) and check-in (return) of equipment for an event.
    -   Provides a checklist of all assigned equipment.
    -   Users can validate each item, with options to "validate all" or finalize with missing items.
    -   Includes a dialog (`MissingEquipmentDialog`) to handle discrepancies.
    -   Supports tracking returned quantities for consumables.

**Data Model and Other Changes:**

-   The `EventModel` now includes `assignedContainers` to explicitly link containers to an event.
-   `EquipmentAssociatedEventsSection` on the equipment detail page is now functional, displaying current, upcoming, and past events for that item.
-   Added deployment and versioning scripts (`scripts/deploy.js`, `scripts/increment_version.js`, `scripts/toggle_env.js`) to automate the release process.
-   Introduced an application version display in the main drawer (`AppVersion`).
This commit is contained in:
ElPoyo
2025-11-30 20:33:03 +01:00
parent e59e3e6316
commit 08f046c89c
31 changed files with 4955 additions and 46 deletions

View File

@@ -174,6 +174,7 @@ class EventModel {
// Nouveaux champs pour la gestion du matériel
final List<EventEquipment> assignedEquipment;
final List<String> assignedContainers; // IDs des conteneurs assignés
final PreparationStatus? preparationStatus;
final ReturnStatus? returnStatus;
@@ -197,6 +198,7 @@ class EventModel {
this.options = const [],
this.status = EventStatus.waitingForApproval,
this.assignedEquipment = const [],
this.assignedContainers = const [],
this.preparationStatus,
this.returnStatus,
});
@@ -295,6 +297,18 @@ class EventModel {
}
}
// Gestion des conteneurs assignés
final assignedContainersRaw = map['assignedContainers'] ?? [];
final List<String> assignedContainers = [];
if (assignedContainersRaw is List) {
for (var e in assignedContainersRaw) {
if (e is String) {
assignedContainers.add(e);
}
}
}
return EventModel(
id: id,
name: (map['Name'] ?? '').toString().trim(),
@@ -303,6 +317,7 @@ class EventModel {
endDateTime: endDate,
basePrice: _parseDouble(map['BasePrice'] ?? map['Price'] ?? 0.0),
installationTime: _parseInt(map['InstallationTime'] ?? 0),
assignedContainers: assignedContainers,
disassemblyTime: _parseInt(map['DisassemblyTime'] ?? 0),
eventTypeId: eventTypeId,
eventTypeRef: eventTypeRef,
@@ -370,6 +385,7 @@ class EventModel {
'options': options,
'status': eventStatusToString(status),
'assignedEquipment': assignedEquipment.map((e) => e.toMap()).toList(),
'assignedContainers': assignedContainers,
'preparationStatus': preparationStatus != null ? preparationStatusToString(preparationStatus!) : null,
'returnStatus': returnStatus != null ? returnStatusToString(returnStatus!) : null,
};