Rezervační systém
Struktura sedadel
Každý spoj tvoří jeden až n vozů. Vozy obsahují contingenty, což je abstraktní blok sedadel nebo jiných prvků. Typ contingentu určuje, jestli se jedná o povinně místenkový oddíl nebo kapacitu. Kapacita se používá pro limitované zdroje, jako jsou zvířata, jízdní kola apod., kterých lze do vozu prodat pouze omezené množství, ale které nemají konkrétní místo.
Vůz je pak značen pořadím v soupravě a popisem.
Spoje jezdí po trase, která je určena typem, číslem spoje (LineNumber) a v případě autobusů suffixem. Např. R 1322 je vlak na trase Liberec - Ústí nad Labem. Na této trase jezdí vlak několikrát denně, každý spoj v rámci dne má vlastní LineNumber (a může jet po jiné trase). Kombinace linky a datumu určuje unikátní jízdu spoje.
Rezervace místenky
Získání vstupních dat
Pro úspěšnou rezervaci místa je třeba znát linku, stanice z a do a datum jízdy.
Pro stanice využijeme číselník, který poskytuje volání /v1/Constants/GetAllPlaces
. Seznam stanic je obsáhlý a je třeba si ho uložit lokálně, opakované volání by příliš vytěžovalo komunikaci.
Dle číselníku přiřadíme stanicím z a do konkrétní identifikátory. Nyní se volá /v1/Route/ExtSearch
, čímž se získá číslo linky; v případě přestupů více linek.
Řekněme, že chceme jet 31.1.2024 v 6 hodin z Liberce do České Lípy. Liberec má ID=1453, Česká Lípa má ID=2187. Vyhledávání vrátí linku "R 1322". Pokud vyhledáme autobusové spojení, dostaneme např. pro trasu Olomouc - Brno "Bus 950157 1", kde 950157 je číslo linky a 1 je suffix. Tyto údaje použijeme v následujícím volání.
Zjištění volné kapacity
V této chvíli je třeba zjistit, jestli dotyčný spoj má volnou kapacitu. K tomu je třeba zavolat /v1/Reservation/ExtGetFreeSeatsCount
s následujícími parametry (line je struktura odvozená z výsledku hledání):
{ "source": { "type": "sr70", "number": 542126 }, "target": { "type": "sr70", "number": 562090 }, "line": { "prefix": "R", "number": 1322, "suffix": "" }, "date": "2024-01-31T06:00:00.000Z" }
Pro autobusový spoj bude struktura následující (suffix je číslo spoje a je povinný):
{ "source": { "type": "idosbus", "number": 27878 }, "target": { "type": "idosbus", "number": 19053 }, "line": { "prefix": "Bus", "number": 950157, "suffix": "1" }, "date": "2024-01-31T06:00:00.000Z" }
Pro vlakové spoje se používá číselník SR70, pro autobusové spoje IDOSBUS.
Výsledek bude přibližně tento:
[ { "contingentTypeId": 1, "capacityResult": { "capacity": 63, "available": 54 } } , { "contingentTypeId": 3, "capacityResult": { "capacity": 10, "available": 8 } }, { "contingentTypeId": 4, "capacityResult": { "capacity": 20, "available": 17 } } ]
Znamená to, že tento spoj má jeden contingent typu 1, což odpovídá povinně místenkovému vozu. Jeho celková kapacita je 63 míst a zbývá 54 míst. Dále je možné prodat celkem 10 jízdenek pro jízdní kolo (TypeId=3), přičemž k dispozici je ještě 8 a 20 jízdenek pro psa (TypeId=4), kde je k dispozici 17 míst.
Seznam typů contingentu
Id | ContingentType |
---|---|
1 | Reservation |
2 | Allocation |
3 | Bicycle |
4 | Dog / Animal |
5 | DisabledPerson |
Seznam číselníků stanic
Type | Číselník |
---|---|
arriva | Arriva |
uic | UIC |
sr70 | SR70 |
idosbus | idosbus |
Rezervace místenky
Řekněme, že potřebujeme jednu místenku, zavoláme tedy /v1/Reservation/ExtMakeReservations
s parametry:
{ "source": { "type": "sr70", "number": 542126 }, "target": { "type": "sr70", "number": 568097 }, "line": { "prefix": "R", "number": 1322, "suffix": "" }, "date": "2023-12-05T00:00:00.000Z", "count": 1 }
a dostaneme odpověď (vrací se pole pro případ, že bychom zadali víc než jednu místenku):
[ { "externalId": "e99d2d0a-4e40-42ea-bd95-33ccdf48e3eb", "traceFromName": "Liberec", "traceFromSequence": 1, "traceToName": "Česká Lípa hl.n.", "traceToSequence": 4, "expiresAt": "2025-02-18T10:03:11.2063966+01:00", "date": "2025-02-20T00:00:00", "lineNumber": "R 1322", "line": { "prefix": "R", "number": 1322, "suffix": "" }, "routeName": "R14B", "reservationStatus": "Temporary", "vehicleOrder": 1, "reservationType": "Reservation", "seat": { "isAvailable": false, "seatAttributes": [ "Window", "Forward", "V230" ], "isEnabled": false, "description": "41", "orientation": "Forward", "coordX": 0, "coordY": 12, "floor": 1, "vehicle": { "model": "845.P", "sequence": 1, "description": "A", "vehicleAttributes": [ "WiFi", "Silent", "V230" ], "vehicleType": 1, "seatMap": [], "contingents": [], "externalId": "af8f32f7-6d02-4288-8ff6-4816d260c70e", "shiftingExternalId": "791791cb-1ec5-4c13-aaf8-aaa057c8c154" } } } ]
Popis nejdůležitějších hodnot:
seat popisuje vybrané sedadlo, a to jeho pozici ve voze (coordX, coordY), jeho vlastnosti (seatAttributes), isAvailable - je sedadlo k dispozici? isEnabled - pro interní účely
vehicle informace o vozu. Model je typ vozu. Důležité parametry jsou sequence (na jaké pozici je vůz řazen) a description, to je označení vozu pro cestující. Pokud se změní řazení vozu v soupravě, např. mezi dva vozy se zařadí další, změní se hodnota sequence, ale nesmí se změnit description, protože pak by cestující ztratili orientační bod.
shiftingId je identifikátor řazení vozu. Jak funguje řazení? V systému máme omezený počet vozů, je to vlastně šablona, popisující jak vůz vypadá, kde má které sedadlo apod. Pokud ho chci zařadit do soupravy, vytvořím záznam o řazení (shifting), který propojuje šablonu vozu s konkrétní jízdou (lineInstance) a pozicí v soupravě (sequence).
externalId je hodnota, pomocí které je místenka identifikována pro budoucí operace. Následují informace o trase (traceFromId, traceFromName...), date určuje den jízdy a lineNumber číslo linky.
reservationStatus Temporary určuje, že se jedná o dočasnou rezervaci, která má nastavenou automatickou expiraci (expiresAt). Po tomto čase přestane místenka existovat, pokud není potvrzena.
Uvolnění dočasné rezervace
V případě, že se nákup ruší bez potvrzení, volá se místo potvrzení /v1/Reservation/ExtReleaseReservations
s parametrem:
{ "reservationsExternalIds": [ "193d04af-9dc8-4767-ad6f-9115886a85e6" ] }
která vrací pouze true/false. Tím se rezervovaná místenka uvolní pro ostatní zájemce a není třeba čekat na vypršení expirace.
Zkrácení trasy
Zkrácení trasy u platné rezervace: /v1/Reservation/ShortenReservationRoute
. Používá se v případě, kdy se generuje rezervace do zásoby pro zrychlení odbavení. Určeno především pro autobusy. Nová cílová stanice musí být na trase před původní stanicí. Rezervace se modifikuje, na rozdíl od změny sedadla se negeneruje nová.
"reservationExternalId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"newStationToId": 0
}
Změna sedadla
Pokud nevyhovuje automaticky přidělené sedadlo, je možné jej změnit. Nejprve se zavolá /v1/Reservation/ExtGetVehicles
s parametrem:
{ "source": { "type": "sr70", "number": 542126 }, "target": { "type": "sr70", "number": 568097 }, "line": { "prefix": "R", "number": 1322, "suffix": "" }, "date": "2025-03-05T00:00:00.000Z" }
Jako odpověď dostaneme seznam řazených vozů, pasivních prvků (item) a sedadel (seat)
[ { "model": "845.P", "sequence": 1, "description": "A", "vehicleAttributes": [], "seatMap": [ { "description": "Východ", "orientation": "Backward", "externalId": "8be67ae9-0d6e-45c9-ad12-2ba24e7433e9", "coordX": 0, "coordY": 0, "floor": 1, "availability": "Unknown", "itemType": "Exit", "seatAttributes": [] }, { "description": "Prázdný prostor", "orientation": "Backward", "externalId": "5fc6c8ab-edca-4b9f-9e68-a0f947b3050e", "coordX": 1, "coordY": 0, "floor": 1, "availability": "Unknown", "itemType": "Empty", "seatAttributes": [] }, /* .... */ { "description": "11", "orientation": "Backward", "externalId": "2bb66e74-d0de-429a-9d78-7ad01108992b", "coordX": 0, "coordY": 4, "floor": 1, "availability": "Sold", "itemType": "Seat", "seatAttributes": [] }, { "description": "13", "orientation": "Backward", "externalId": "70123deb-4e70-4ab3-a4ab-6f50da18c780", "coordX": 1, "coordY": 4, "floor": 1, "availability": "Available", "itemType": "Seat", "seatAttributes": [] }, { "description": "Ulička", "orientation": "Backward", "externalId": "2acf9a37-0e3e-43f7-a82f-6d9718931aa5", "coordX": 2, "coordY": 4, "floor": 1, "availability": "Unknown", "itemType": "Corridor", "seatAttributes": [] }, { "description": "17", "orientation": "Backward", "externalId": "394c4cfa-7de5-4edc-b890-94b9dc64428e", "coordX": 3, "coordY": 4, "floor": 1, "availability": "Available", "itemType": "Seat", "seatAttributes": [] }, { "description": "15", "orientation": "Backward", "externalId": "766cc612-0185-4ca5-9613-031d74d13fe0", "coordX": 4, "coordY": 4, "floor": 1, "availability": "Available", "itemType": "Seat", "seatAttributes": [] }, /* .... */ ], "contingents": [ { "capacity": 39, "available": 38, "contingentType": "Reservation" }, { "capacity": 24, "available": 24, "contingentType": "Reservation" }, { "capacity": 10, "available": 10, "contingentType": "Bicycle" }, { "capacity": 0, "available": 0, "contingentType": "Disabled" } ], "shiftingId": "29160129-c223-4022-b186-fba25b085377" } ]
Data jsou zkrácena. Důležité informace jsou v sekci contingens, které popisují, jaké typy rezervací vůz nabízí (místenka, zvíře, kolo, invalidé...).
Ve struktuře seatMap je popsán vůz včetně souřadnic jednotlivých pasivních prvků (stolek, ulička...) a především sedadel. Zde je důležitá vlastnost availability, která popisuje, je-li možné sedadlo obsadit. Availability může obsahovat hodnotu z výčtu: Unknown, Unavailable, Available, Sold a Blocked. Kterákoliv možnost kromě Available znamená, že sedadlo nelze prodat. (Blocked je určen pro zákaz prodeje správcem systému).
Voláním /v1/Reservation/ChangeReservation
s parametry
{ "reservationExternalId": "193d04af-9dc8-4767-ad6f-9115886a85e6", "seatExternalId": "766cc612-0185-4ca5-9613-031d74d13fe0", "shiftingExternalId": "29160129-c223-4022-b186-fba25b085377" }
kde reservationExternalId je Id rezervace, seatExternalId je Id požadovaného sedadla a shiftingExternalId je identifikátor vozu a jeho řazení, lze změnit místo přiřazené rezervaci. Lze měnit místa pouze u rezervací ve stavu Temporary, po potvrzení je již rezervace neměnná.
Funkce vrací novou rezervaci. Původní rezervace je automaticky uvolněna, ale je odpovědnosti klienta, aby identifikátor rezervace na své straně změnil na nově vrácený identifikátor a dále pracoval s novým identifikátorem.
[ { "seat": { "isAvailable": false, "seatAttributes": [], "isEnabled": false, "description": "15", "orientation": "Backward", "coordX": 4, "coordY": 4, "floor": 1, "vehicle": { "model": "845.P", "sequence": 1, "description": "1", "vehicleAttributes": [], "seatMap": [], "contingents": [], "shiftingId": "29160129-c223-4022-b186-fba25b085377" } }, "externalId": "e3e7abb2-15b1-4b75-bd9e-215eb8d49350", "traceFromId": 1453, "traceFromName": "Liberec", "traceToId": 2187, "traceFromSequence": 1, "traceToName": "Česká Lípa hl.n.", "traceToSequence": 4, "expiresAt": "2024-01-10T21:00:00", "date": "2023-12-05T00:00:00", "lineNumber": "R1322", "routeName": "R14B", "reservationStatus": "Temporary", "vehicleOrder": 1, "reservationType": "Reservation" } ]
Alokace místa bez místenky
Používá se v případě, kdy potřebujeme alokovat omezený zdroj, pro který ale není rezervováno konkrétní místo. Může se jednat o zvíře (v jednom voze může cestovat omezený počet zvířat, případně může být přeprava zvířat zakázána), jízdní kolo (ve voze je např. 10 háků na jízdní kola, nelze tedy prodat víc jízdenek na jízdní kolo, ale cestující nemá přiřazen konkrétní hák) apod. Kromě toho se používá pro spoje bez místenek.
Tento scénář lze použít, vrátí*-li nám funkce GetFreeSeatsCount continget jiného typu než 1. V takovém případě budeme pro alokace volat funkci /v1/Reservation/ExtMakeAllocations
s parametry:
{ "contingentTypeId": 3, "source": { "type": "sr70", "number": 335356 }, "target": { "type": "sr70", "number": 336529 }, "line": { "prefix": "Os", "number": 23234, "suffix": "" }, "date": "2025-12-01T00:00:00.000Z", "count": 2 }
Vrácená data jsou podobná jako v případě vytvoření rezervace, chybí ale popis konkrétního místa.
[ { "contingentType": "Bicycle", "externalId": "0f717220-a32c-4b64-9932-1cff0444e88a", "traceFromId": 1453, "traceFromName": "Liberec", "traceToId": 2187, "traceFromSequence": 1, "traceToName": "Česká Lípa hl.n.", "traceToSequence": 4, "expiresAt": "2024-01-11T21:23:24.0744351+01:00", "date": "2023-12-05T00:00:00", "lineNumber": "R1322", "routeName": "R14B", "reservationStatus": "Temporary", "vehicleOrder": -1, "reservationType": "Allocation" } ]
Následná práce s výsledkem je prakticky stejná, jako u rezervací. Rozdíl je v tom, že alokace nemají přiřazené konkrétní sedadlo, ale jinak je možné je uvolnit a hlavně nutné potvrdit stejně jako plnohodnotnou místenku.
Načtení existující rezervace
Pro načtení existující rezervace můžeme použít metodu /v1/Reservation/ExtGetReservation
. Lze tak ověřit uložené informace nebo stav rezervace,
např. došlo-li k úspěšnému zrušení. Pozor, pokud dojde pouze k uvolnění dočasné rezervace, není ji možné již načíst, stejně tak po expirování doby, po kterou byla rezervace rezervována.