Module occurrence-capacity (mobile)
Ce fichier doit rester synchronisé avec le code du module. À mettre à jour à chaque changement structurel.
Rôle : fournir au mobile les dates de départ concrètes d'un voyage et leur capacité résiduelle (chambres, sièges véhicule). Aligné sur occurrence-capacity backend Horizon.
Code
- Store :
stores/occurrence.ts(cache des occurrences chargées + occupation véhicule) - Components :
travel-booking/TBStepDepartureDate.vue— sélection de la datetravel-booking/TBStepSeatSelection.vue+TBSeatMap.vue— plan véhiculecards/UpcomingDeparturesCard.vue,TravelOccurrenceRow.vue— affichage
- API :
publicApi.occurrences.{getById,getUpcoming,getRoomTypeAvailability,getVehicleOccupancy}
Entités principales
OccurrenceSummary— type renvoyé aussi bien pargetUpcoming(liste/cards) que pargetById/fetchOccurrence(occurrence sélectionnée, peupleselectedTO) : il n'existe pas de type « Occurrence complète » distinct côté@spektrum/horizon-types. Portedrives,stops,vehicles(affectation datée, cf. « Points d'attention »),vehicleCapacity/vehicleOccupancy(agrégats),start,end,bookingState, etc. ⚠️ Le champvehiclesdeselectedTO(issu degetById, doncGET /occurrences/:id) est peuplé vide côté backend (bug confirmé) — ne pas s'y fier, voir « Points d'attention ». ⚠️vehicleCapacityReturn(mentionné en business rule pour Seaside aller/retour) n'existe pas dans@spektrum/horizon-types@1.9.0ni en extension locale (types/extensions.ts) — à vérifier sur le wire / à augmenter localement avant de s'y fier en code (même pattern queisFlatRatePerPerson).RoomTypeAvailability— disponibilité par type de chambre pour une occurrenceSeat(aliasapi_vehicle_Seat) — siège occupé/dispo dans le plan véhicule
Invariants & règles spécifiques
- Édition d'un booking existant :
getVehicleOccupancy(occurrenceId, currentBookingId)exclut les sièges du booking en cours d'édition de la carte d'occupation, sinon l'utilisateur ne pourrait pas resélectionner ses propres sièges. - Seaside — deux capacités séparées :
VehicleCapacity(aller) etVehicleCapacityReturn(retour). Un client Seaside peut partir à la date X et revenir à Y/Z (séjour 2 ou 3 semaines). bookingState: porté soit par l'occurrence sélectionnée, soit en fallback par le voyage lui-même (travel.bookingState). Gouverne si l'occurrence est réservable ou en liste d'attente.- Sélection d'une occurrence dans le wizard déclenche en parallèle :
fetchOccurrence(id)pour peuplerselectedTOfetchVehicleOccupancy(id)pour la map des sièges Et reset les rooms/passengers/seats précédents.
- Source du plan de sièges = catalog vs occurrence, selon le type de voyage :
bookingConstructor.vehicles(exposé paruseBCVehicle, consommé parTBSeatMap.vue) vaut l'affectation véhicule réelle de l'occurrence sélectionnée pour les voyages multi-day hors Seaside, et retombe surcatalog.vehicles(modèle générique) pour single-day et Seaside — même bascule questopOptions(isSeaside/isSingleDay/ sinon). Raison : la capacité et le plan de sièges peuvent différer par date, et l'occupation (vehicleOccupancy, matché parseat.id) est déjà par-occurrence — un mismatch d'id catalog/occurrence pouvait faire passer des sièges occupés pour libres. Seaside garde le catalog car son affectation datée vit sur un champ distinct (SeasideDate.Vehicles), pasOccurrence.vehicles. Pas lu depuisselectedTO.vehicles(bug backend,GET /occurrences/:idrenvoie une liste de véhicules vide) :useBCVehicleretrouve l'occurrence danstravel.value.occurrences(chargé viaGET /travel/slug, fiable) par id, et lit.vehiclesdessus — même contournement, pour la même raison, quesingleDayDrives/linesun peu plus haut dans le même composable (bug backend équivalent sur les quotas/occupancy desdrives). TBSeatMap.vuedoit re-synchroniserselectedDeckIdà chaque changement devehicles(watch(vehicleDeckSelection, ..., { immediate: true })), pas seulement au premier montage : pour les voyages multi-day, le véhicule/pont affiché dépend maintenant de l'occurrence sélectionnée, qui peut changer en cours de session (navigation par pastilles, wizard<KeepAlive>sur toute la session) sans remonter le composant.
Dépendances
- Dépend de :
travel-catalog(l'occurrence appartient à un Travel) - Consommé par :
booking(wizard),travel-catalog(affichage UpcomingDepartures)
Points d'attention
getByIdpeut renvoyer{}(objet vide) — code traite ça comme « pas trouvé » et reset leselectedTO. Conserver ce comportement.- Les sièges sont stockés par siège, pas par passager — le mapping passenger ↔ siège vit dans
bookingConstructorvia le composableuseBCVehicle. selectedTO.vehicles(getById) ne pas utiliser — vide côté backend. Toujours passer partravel.value.occurrences.find(occ => occ.id === selectedTO.value?.id)?.vehicles(voiroccurrenceVehiclesdansuseBCVehicle). Si ce bug backend est corrigé un jour, ce contournement (et celui, identique, desingleDayDrives/lines) pourra être simplifié — mais vérifier d'abord queGET /occurrences/:idrenvoie bien les véhicules avant de le faire.
Contributors
No contributors
Changelog
No recent changes

