Guides

Departures

Departures in the inventory is identified by originalDatedServiceJourneyIds. The inventory is made up by quotas and reservations which are both added to a dated service journey.

Dated Service Journeys

A dated service journey represents a departure on a specific date. It contains the following fields:

  • id, the originalDatedServiceJourneyId, e.g. ENT:DatedServiceJourney:905144.
  • invertedDirection, indicates which direction this journey travels, TRUE or FALSE.
  • lineId, the id of the line this journey travels on, e.g. VYG:Line:57 (Bergensbanen).

DatedServiceJourneyIds is defined by Entur's timetable service.

Lines

A line is a sequence of stop places that a dated service journey travels, it contains the following fields:

  • id, the id for the line, e.g. VYG:Line:57.
  • version, the version of this line, e.g. 1.
  • stops, the list of stop places that is traversed by the line, e.g. NSR:StopPlace:337, NSR:StopPlace:451, ...

Quotas

A quota describes the limit of a resource, e.g. discounted tickets on a specific dated service journey. The constrained resource is called a "product", this is not necessarily a product in the NetEx sense, it might e.g. be a FareQuotaFactor. The inventory does not attach any semantics to the "product", it only use an ID which can be counted and consumed/reserved. For instance we can have a quota of 5 "ENT:DiscountTicket:1" and if someone reserves 2 of that "product" we can calculate that there are 3 "ENT:DiscountTicket:1" left available.

A quota can restrict multiple products, i.e. the consumption of separate products can decrement the availability of the same quota. E.g. a quota might restrict that a maximum of 10 "product x" and "product y" can be consumed. If a reservation of 3 "product x" and 3 "product y" is registered, the availability (remaining quantity) of this quota would be 4.

A departure might include many quotas of the same product. If a traveller desires to travel from A to B, a subset of the quotas can apply. The applicability of a quota is determined by the desired travel segment and the quota-properties ods and useStoplist. This is further explained in the section Quota behavior.

API

Entity

A quota consists of the following information:

  • quota: The restricted quantity
  • products: A list of product-ids the quota should restrict
  • ods: The origin and destination pairs for this quota (see Quota behavior)
  • useStoplist: Whether to "flatten" non-overlapping reservations or not (see Quota behavior)
  • datedServiceJourney: The originalDatedServiceJourneyId of the departure this quota should apply to
  • quotaConfiguration: Optional - Reference to the quota-configuration used by this quota (see Nesting)
  • purchaseWindowStart: Optional - The start of the purchaseWindow on the associated quota (see Stock overrides)
  • purchaseWindowStop: Optional - The end of the purchaseWindow on the associated quota (see Stock overrides)

Quota behavior

Currently we have defined 4 possible quota behaviors which are defined by two binary properties: a boolean property use_stoplist and the presence of origin-destination pair(s) in the od-list defined on each quota.

Use stoplistOd-list on quotaResulting quota behavior
falseEmptySales quota
trueEmptyStoplist quota
falseNon-emptyPoint-to-point quota
trueNon-emptyConfined stoplist quota

Sales quota

A sales quota is a quota that is not reusable. That means the resource/product is not released after a passenger has disembarked. Traditional examples are sleeping cabins that are booked for the entire journey, even if the cabin is booked between intermediary stations. In a query for availability, a simple #(quota quantity) - #(sum(reserved quantities)) is performed. Even if the travel segments of 2 reservations does not overlap it is still counted as a decrement of 2 from availability. A sales quota applies to all travel searches.

Stoplist quota

A stoplist quota is used for reusable resources that are released after a passenger disembarks. Typical examples consist reusable resources such as seats and limited ticket groups (as part of yield management). The quota determines the maximal number of the products that can be reserved between any two stations. That is, the quota quantity is the maximal quantity that can be consumed by reservations crossing any neighboring stations. The calculation of availability is as follows: #(quota quantity) - #(max(sum_station(reservation))). The latter expression represents the maximal reserved quantity between two neighboring stations, considering reservations crossing the stations. Like a sales quota, a stoplist quota applies to all travel searches.

Point-to-point quota (P2P)

A point-to-point quota behaves as a simple counter restraining the travel between a specific set of stations. A P2P quota has a set of origin-destination pairs, and only applies if the potential traveller want to travel from o1 to d1 and (o1,d1) is in the od-list belonging to the quota.

Confined stoplist quota

A confined stoplist quota is used for limiting travellers crossing a specific segment of a journey. This allows a revenue management optimizer to restrict the availability of "products" for travel searches across that segment, thus pushing prices upwards on journey-segments where seats are limited. Confined stoplist quotas apply to reservations where the travel segment overlaps with one of the segments defined by ods the od-list. The availability is calculated in the same way as stoplist quotas, except we only consider reservations which overlap with the segments defined by the od-list.

Quota examples

The following examples use this picture to illustrate different quota setups:

Reservations on a departure between five different train stops
The arrows represent a single reservation of a product, and all quotas in these examples have the same product in their product-list.

Multi-tenancy

Only the authority running the service can access and update quotas on a departure. This is determined by which organisation the request's access token was issued to.

Quota Configurations

API

Nesting

The inventory supports the concept of nesting for yield optimization. This allows for similar tickets to be sold at different price levels, typically this is done to allow early birds to acquire the cheapest tickets. Early determination of ticket demand allows for better planning and optimization, like adding extra departures just before christmas or a grand concert, or using smaller trains in periods where you know few people will be travelling.

The inventory organize the different quota configuration rules in a tree structure called a nesting tree. The nodes themselves are quota configurations.

Visualization of a nesting tree.
This nesting tree includes 5 nodes with a root-node Ticket, and 3 leaf-nodes OrdinaryTicket, DiscountTicket1 and DiscountTicket2. The parent nodes, like the DiscountTicket node, are a grouping of nesting rules, and as a parent node it contains a selection rule, a consumption rule and a direction rule.

Selection rule

The selection rule is a hint to the offers module of whether the different child price levels should hide each other. The following two values are allowed:

  • COMBINED - The combined selection rule is a hint to offer tickets as they appear. If the end customer wants 4 tickets, and 5 Discount1 and 2 Discount2 are available he/she should be offered 2 Discount2 tickets and 2 Discount1 tickets.
  • SINGLE - The single selection rule is a hint that the nesting rules should hide each other. That is, the end customer should be offered only one price level for all tickets. Thus if the customer wants 4 tickets, and 5 Discount1 and 2 Discount2 are available, the customer should be offered 4 Discount1 tickets. There is not enough Discount2 tickets available, therefore the Discount1 price level has hidden the Discount2 level.

The value of the selection rules does not influence counting in inventory.

Direction rule

The direction rule determines which nodes overflowing consumption should be placed in first.

  • FROM_RIGHT - From right means that when moving over-consumption inventory starts with the node with the highest priority in the same group, in other words the rightmost node.
  • FROM_LEFT - From left means that when moving over-consumption it starts with the node with the lowest priority in the same group, in other words the first node to the left.

If overflowing consumption can't be placed in the first node the direction rule dictates it continues to the next node up or down the priority list. The direction rule also affect the direction when using the BY_PRIORITY rule.

Consumption rule

The consumption rule affects how reservations in inventory consumes the different price levels. It determines if the quota should consume the reservation immediately or act as if its own reservations are overflowing consumption.

  • DIRECT - A reservation of a product is counted as a reservation of a product as long as the reservation quantity does not surpass the associated quota. Any overflowing quantity is counted as over-consumption and moved towards the first quota to the left or rightmost quota, determined by the Direction rule.
  • BY_PRIORITY - A reservation of a product is viewed as overflowing and moved to the first quota on the left, or rightmost (decided by the Direction rule) product in the same group. E.g with the Direction rule set to FROM_RIGHT; Given 5 available DiscountTicket1 and 5 DiscountTicket2, a reservation of 3 DiscountTicket1 and 2 DiscountTicket2 would have the same result as a reservation of 5 DiscountTicket2. Thus, unless DiscountTicket2 is "filled", there is always 5 DiscountTicket1 available.

Nodes closing other nodes

The quota configurations can be configured to close other nodes in the same or other trees. This is to make sure that certain quotas are never offered if some other quota is empty. Say there are two different nesting trees for two different products, product A and B. A is a premium product and B an ordinary/standard product. If there for some reason is a high number of product B sales, a situation where Standard-tickets are more expensive than Premium-tickets could occur because B has exhausted several quotas. To avoid this the nodes in the nesting tree for product A can be configured to automatically close when certain nodes in the nesting tree for B are empty. The total capacity of the nesting tree is not affected. This means that nodes higher in the tree will still be able to overflow into the closed nodes.

Over-consumption

All nesting nodes has a priority which, in combination with the direction rule, determines ordering among siblings in the tree. In the above example, the nodes could have the following priorities:

  • Ticket priority=1
    • OrdinaryTicket priority=1
    • DiscountTicket priority=2
      • DiscountTicket1 priority=1
      • DiscountTicket2 priority=2

Quotas with nesting nodes in the same tree can be overspended. That is, it is possible to consume more than the quota for OrdinaryTicket, the overflowing quantity will then be deducted from the stock of cheaper tickets. This is the whole point of grouping nodes together in the same nesting tree.

If there had been another sibling GroupTicket (priority=3) of OrdinaryTicket and DiscountTicket, and the direction rule of DiscountTicket is set to FROM_RIGHT, the order of recipients of overspended consumption from OrdinaryTicket would be:

  1. GroupTicket
  2. DiscountTicket2
  3. DiscountTicket1

Only leaf-nodes are associated with quotas, when the DiscountTicket (parent) node receive overspended consumption it forwards it to its children. If one of these children are parent nodes this is repeated, and the nodes are traversed in the direction set by the direction rule.

Quota behavior in nesting trees

It is important to avoid mixing different quota behaviors in the same nesting tree. If one is using Point-to-point quotas for DiscountTicket1 the same od-list should be used in a point-to-point quota for DiscountTicket2. Mixing for different quota behaviors in the same nesting tree results in undefined results.

Reservations

A reservation is a claim on some of the availability of something, across a distance. A reservation must have a departure, a valid origin and destination on this departure, and one or more reservation lines. Reservation lines points to the product to reserve, a status, and the quantity. This means a reservation can reserve multiple products.

Reservations decrement the availability of quotas which they apply to. A reservation might affect multiple quotas depending on quota type and the origin and destination of the reservation.

Prerequisites

All reservations made must belong to a defined departure, which means that a line must also be defined.

API

Applicability to quotas

The applicability of a reservation to a quota is determined by the reserved product being in the quota product-list. It is also dependent on the quota type:

Sales quota

The reservation always apply.

Stoplist quota

The reservation always apply.

Point-to-point quota (P2P)

The reservation-od must be included in the quota's od-list.

Confined stoplist quota

The reservation-od must overlap with at least one of the segments created by letting the quota ods divide the stoplist into segments.

Statuses

A reservation have a status indicating where the reservation is in the purchase. A status also indicate how the reservation should affect the calculation of stock. A reservation can one of the following statuses:

DRAFT

Draft is a "soft-reservation" status. This means that whenever a user is in the process of buying a product we reserve the product with the status DRAFT. All reservations with DRAFT status will affect stock calculation similarly as reservations with status CONFIRMED. This way we're protected from overselling products and the customer is guaranteed their selected products after purchase.

Reservations with status DRAFT can only change status to either EXPIRED or CONFIRMED.

EXPIRED

If a customer decides not to complete a purchase, all soft-reservations made by the customer will eventually expire. When a reservation expire all reservation lines change status to EXPIRED. This means that the products are no longer reserved and the reservations won't affect stock calculation.

Reservations with status EXPIRED can not change to any other status.

CONFIRMED

CONFIRMED means the reservation is confirmed by either a successful transactions or some other way. Confirmed reservations can no longer expire and will affect stock calculation.

Reservations with status CONFIRMED can only change status to CANCELLED.

CANCELLED

If a customer cancels a confirmed reservation the status changes to CANCELLED. Cancelling a reservation is described more in detail below.

RELEASING

When a reservation is cancelled a releasing reservation is made to release the products. Cancelled and releasing reservations are described more in detail below.

Possible reservation status transitions

Visualization of reservation status transitions
Flowchart example with different outcomes of a reservation and its possible states.

Cancelling a reservation

To cancel a reservation it must exist in Inventory and have the status CONFIRMED. Reservations with any other status can not transition to a cancelled status.

When a reservation is cancelled the status changes to CANCELLED and the products made available again. Just making the originally reserved products available again can create situations where the price presented to customers change after a cancellation because there is now more lower priced products available. To prevent this from happening it's possible to configure what product to add back after cancellations.

When adding products back, a new reservation is made, the status RELEASING, and a negative quantity to negate the original reservation.

Multi tenancy

The reservation api is available to all operators, but only the authority running the service can access all reservations on a departure. Other operators can only access reservations they have created themselves.

Stock

The stock service is used to calculate available stock, meaning the quantity of available resources that are constrained by quotas on the departure. The query for available stock is on a given dated service journey from an origin to a destination. The stock calculation can roughly be summarized as follows:

Find all quotas and reservations on a dated service journey Filter only quotas applicable to the journey segment of the query For each remaining quota q: find reservations applicable to q Subtract reservationQuantities from quotas Apply nesting

The result displays the available stock on the segment between the starting and end stop place for that journey.

API

The stock response contains the following fields:

  • datedServiceJourney: The id for the given dated service journey
  • origin: The starting stop place
  • destination: The destination stop place
  • organisation: The owner of the departure
  • stock: A list of available stock components

The stock components can either be a root node of a quota nesting tree, or a simple quota without any nesting.

Simple quotas

These components contain the two following fields:

  • products: A list of products that the quota constrains
  • leftInQuota: The remaining quantity on this quota

Nested quotas

The fields of a quota nesting tree node are somewhat different whether this is a parent-node or a leaf-node. Only leaf-nodes have quotas associated with it.

Parent nodes has the following fields:

  • nestingGroup: Name of this quota nesting rule
  • aggregatedAvailability: The maximum quantity that can be reserved of quotas associated with decendants of this quota nesting rule
  • priority: The priority for quota nesting rule
  • components: A list of quota nesting rule children
  • consumptionRule: The consumption rule set on the quota nesting parent
  • selectionRule: The selection rule set on the quota nesting parent

Leaf nodes has the following fields:

  • nestingGroup: Name of this quota nesting rule
  • aggregatedAvailability: The maximum quantity that can be reserved of this resource, including possible quantities that can carry over to nested, higher prioritized, sibling components
  • priority: The priority for quota nesting rule
  • products: A list of product ids for the quota associated with the quota nesting rule
  • leftInQuota: The remaining available quantity of the resource
  • purchaseWindowStart: The start of the purchaseWindow on the associated quota
  • purchaseWindowStop: The end of the purchaseWindow on the associated quota

Stock overrides

The fields aggregatedAvailability and leftInQuota are set to zero if the associated quota is outside its purchaseWindow, or if a closing node is exhausted. Note that the availability of the node is not lost from the tree, only from the node itself. In other words, aggregatedAvailability is not reduced.