UnionInternationalCheminsdeFer / OSDM

Projects related to an open sales & distribution API for public transportation.
https://osdm.io
Apache License 2.0
53 stars 21 forks source link

I‐94 Capability to handle split seat reservations on a leg #356

Closed Linus-Turnit closed 6 months ago

Linus-Turnit commented 11 months ago

There is a need to make it possible to give the passenger place reservations on different parts of a leg.

Use case is: The train is fully booked between leg (A - C). But there is seats available between A-B and B-C. The passenger is OK with the need of changing place at stop B.

To present this in reservation we need a change. Suggested solution could be (TBD).

image

CGantert345 commented 10 months ago

Would it be an option to provide multiple reservation offers to handle this case. This would not require any changes in the messages and the handling would follow the standard flow. It would make the split also transparent for the customer at offer level so he could select another trip or offer.

Linus-Turnit commented 10 months ago

Good thinking! That could work. Two reservations has tripCoverage with different coveredSections for the same startLegId and endLegId @.***

//Linus

Linus-Turnit commented 10 months ago

After more thinking. It might not be that good.

To have two reservations will give problems with the pricing. You are not supposed to pay for two places at splitting the reservation. With the fist suggested solution that problem is out of scope when the reservation part is in one record.

//Linus

jspetrak commented 10 months ago
CGantert345 commented 10 months ago

Hello Linus,

the pricing for reservations is not on the individual reservation but is modelled as a fee linked to one or more reservations. So pricing is not a problem (e.g. at DB all reservations of a trip are linked to one fee).

Best regards Clemens

Linus-Turnit commented 10 months ago

Hello, For TLT tickets we use the price in the reservation booking part object to set the price of the reservation itself. Especially if it is an optional reservation. We are not using any fees. The only fee-object we have so far is the booking fee. The price for the reservation is related to the carrier not the distributor as it is in DB.

//Linus

CGantert345 commented 10 months ago

There is a need to make it possible to give the passenger place reservations on different parts of a leg.

Use case is: The train is fully booked between leg (A - C). But there is seats available between A-B and B-C. The passenger is OK with the need of changing place at stop B.

To present this in reservation we need a change. Suggested solution could be (TBD).

image

--> additional element in the offer search required: acceptedSpecialFeatures with value SPLIT_RESERVATION image

Linus-Turnit commented 10 months ago

Turnit doesn't think it is feasible to manage split-reservations by having several reservations covering different sections of a leg.

The reservation-object describes a logical and physical reservation with product descriptions, after sales rules, price, places and so on. It is only the placeAllocation that describes the physical part, all other parts are logical related.

There is already a possibility to have a list of placeAllocations for a reservation, in specification described to handle bicycle reservation together with the seat. Another use-case is to present a product where next seat is free (actually already a case in Sweden). In that case you get one reservations with two placeAllocations.

For split-reservations there will be two placeAllocations as well with different splitSection's covering different parts of a leg.

Our opinion is that this is a small, non required, addon to the placeAllocation object. It is only IMS's with this functionality that will return splitSection:s and it is only returned if the productTag "SPLIT_RESERVATION" is provided in offer search from the customer. With good comments in the API it can be clear for the consumers when to handle this.

The need for split reservations can be discussed, but the seat reservation algorithm is active at booking time and optimize the reservations at that time. Closer to departure, cancellations will change the situation and suddenly a split-reservation booking is possible. With seat-maps, the algorithm is more out of control as well, even if not all free places are shown as selectable.

For Turnit one new carrier (not in Europe) has split-booking as a requirement and since we aim to be OSDM-compliant in all our API's this is very important for us. Alternative for us is to do a special version of OSDM, since there is no interoperability needs for that content., but it is not the perfect way to go we think..

CGantert345 commented 10 months ago

Decision:

Linus-Turnit commented 9 months ago

In POST /offers image

    OfferSearchCriteria:
      type: object
      additionalProperties: false
      properties:
        requestedOfferParts:
          type: array
          items:
            $ref: '#/components/schemas/OfferPartType'
        productTags:
          type: array
          items:
            $ref: '#/components/schemas/ProductTag'
          nullable: true
        flexibilities:
          description: |
            Defines the flexibility levels desired of the fares returned.
            This refers to the after sales flexibility levels as defined in IRS-90918-10
          type: array
          items:
            $ref: '#/components/schemas/Flexibility'
        travelClasses:
          description: |
            The classes returned might be different from the requested classes.
          type: array
          items:
            $ref: '#/components/schemas/TravelClass'
        serviceClassTypes:
          description: |
            The classes returned might be different from the requested classes.
          type: array
          items:
            $ref: '#/components/schemas/ServiceClassType'
          maxItems: 4
        offerMode:
          $ref: '#/components/schemas/OfferMode'
        currency:
          $ref: '#/components/schemas/Currency'

    ProductTag:
      description: |
        Known values:
        - SPLITED_RESERVATION
          Indicate for the provider that the distributor is prepared to get splitted reservations in the response
      type: string
      x-extensible-enum:
        - SPLITED_RESEVATION

GET /booking/{bookingId}

image

    ReservedPlace:
      type: object
      additionalProperties: false
      description: |
        In distributor mode placeProperties are mandatory to be returned.
      required:
        - id
        - passengerIds
        - vehicleNumber
        - coachNumber
      properties:
        id:
          type: string
          nullable: false
        passengerIds:
          description: |
            Id of the passenger
          type: array
          items:
            type: string
          minItems: 1
          nullable: false
        vehicleNumber:
          description: |
            vehicle number (e.g. train number)
          type: string
          nullable: false
        coachNumber:
          type: string
          nullable: false
        placeDescription:
          description: |
            description of the places (e.g. 11-35,51)
          type: string
          nullable: true
        placeNumbers:
          description: |
            list of individual place numbers
          type: array
          items:
            type: string
          nullable: true
        placeProperties:
          description: |
            place properties to be indicated to the customer
          type: array
          items:
            $ref: '#/components/schemas/PlaceProperty'
        splitSection:
          $ref: '#/components/schemas/SplitSection'

    SplitSection:
      type: object
      description: |
       Provider can return this object if
       distributor asked with PorductTag,
       SPLITED_RESERVATION      
      required:
      - startStop
      - endStop
      properties:
        startStop:
          $ref: '#/components/schemas/ShortStopPlace'
        endStop:
          $ref: '#/components/schemas/ShortStopPlace'

    ShortStopPlace:
      type: object
      required:
        - stopPlaceRef
        - stopPlaceName
      properties:
        stopPlaceRef:
              type: string
              nullable: false
              example: urn:uic:stn:8503000
        stopPlaceName:
          type: string
          nullable: false
          example: Luzern