Availability

Availabilities are the successive or concurrent states of an Asset reachability to your business needs.

An Availability object impacts Search results according to its dates and quantity parameters.

Availabilities can only be created for Assets having an Asset Type that is not timeBased or has infiniteStock.

Absolute or relative

Availability can be expressed in several ways for best flexibility, using startDate, endDate and quantity:

  • absolute: stock quantity of an Asset. For instance, a car can’t be rented out if it’s ongoing reparations, setting its quantity to 0.
  • or relative stock variation denoted by leading + or - sign, e.g. "-1", due to an order of a single item.

Setting absolute stock quantity of an Asset to 3 during two days in the future just takes a single call:

await stelace.availabilities.create({
  assetId: 'ast_2l7fQps1I3a1gJYz2I3a',
  startDate: '2019-09-13T00:00:00.000Z',
  endDate: '2019-09-16T00:00:00.000Z',
  quantity: 3
})

Using curl:

curl https://api.stelace.com/availabilities \
  -u seck_test_rylx3ebUg0bNs1HkJKlqNHkI: \
  -d assetId=ast_2l7fQps1I3a1gJYz2I3a \
  -d startDate="2019-09-13T00:00:00.000Z" \
  -d endDate="2019-09-16T00:00:00.000Z" \
  -d quantity=3

Your Assets can also be available in infinite quantity, like digital goods, or their availability can have nothing to do with time frames. You can easily set this with an Asset Type.

Stacking Availabilities

Should several absolute availabilities overlap, the most recently created availability takes precedence during its full date range.

await stelace.availabilities.create({
  assetId: 'ast_2l7fQps1I3a1gJYz2I3a',
  startDate: '2019-09-14T00:00:00.000Z',
  endDate: '2019-09-15T00:00:00.000Z',
  quantity: 0
})

Given the two previous API calls made above, ast_2l7fQps1I3a1gJYz2I3a will be unavailable during one day (2019-09-14), surrounded by two single days when its stock quantity is 3.

Quantities of concurrent relative Availabilities will simply add up when overlapping.

Default Availability

On any other day, available stock of ast_2l7fQps1I3a1gJYz2I3a is the quantity set in the Asset object itself, used as default quantity available.

This means you can make an Asset unavailable by default if you set its quantity to 0, and use Availability API calls to make it available in specific time windows.

Recurring Availability

An Availability can also be defined using a recurringPattern with cron format.

Here is one API call making an Asset unavailable on every Tuesday at midnight "0 0 * * 2", for the full day:

await stelace.availabilities.create({
  assetId: 'ast_2l7fQps1I3a1gJYz2I3a',
  startDate: '2019-01-01T00:00:00.000Z',
  endDate: '2019-12-31T23:59:59.999Z',
  quantity: 2,
  recurringPattern: '0 0 * * 2',
  recurringDuration: { d: 1 }
})

recurringDuration is set to one day using { d: 1 } but you can also use hours h and minutes m.

Recurring Availabilities are an advanced feature only enabled for some API plans.

Availability graph

The evolution of the available Asset quantity over time can be represented by an Availability graph. This is especially useful for users to know when an Asset is available and in what quantity, or when it’s not.

You can design any kind of dynamic UI with Availability graph data:

  • disabling booking calendar dates when Asset quantity requested by user is not available
  • showing the maximum available quantity for the period selected by user
  • displaying some bar chart with available Asset quantity each day
  • highlighting popular Assets with many ongoing Transactions.

Let’s explore some examples of Availability graphs and see how to interpret them.

Graph at Asset creation

When an Asset is created,

const asset = await stelace.assets.create({
  name: 'My asset',
  quantity: 5
})

the Availability graph can be retrieved via:

await stelace.availabilities.getGraph({
  assetId: asset.id
})

Here’s the response:

{
  defaultQuantity: 5,
  totalUsedQuantity: 0,
  graphDates: []
}

defaultQuantity has the same value as asset.quantity. This is the available quantity by default.

totalUsedQuantity represents the sum of all Transaction quantities of which status is included in the associated Asset Type array property unavailableWhen.

graphDates is empty here because the Asset has no Availabilities or Transactions attached.

Graph with Availabilities

Let’s now suppose the Asset owner wants to create an unavailable period:

await stelace.availabilities.create({
  assetId: asset.id,
  startDate: '2019-09-01T01:12:20.000Z',
  endDate: '2019-09-10T09:54:10.000Z',
  quantity: 0
})

Graph:

{
  defaultQuantity: 5,
  totalUsedQuantity: 0,
  graphDates: [
    // Two graph date objects have been added
    {
      date: '2019-09-01T01:12:20.000Z',
      usedQuantity: 0,
      availableQuantity: 0
    },
    {
      date: '2019-09-10T09:54:10.000Z',
      usedQuantity: 0,
      availableQuantity: 5
    }
  ]
}

Interpretation of graphDates (for readability, hours and minutes are omitted):

  1. Until 2019-09-01, the availableQuantity is 5.
  2. From 2019-09-01 to 2019-09-10, the availableQuantity is 0.
  3. Finally after 2019-09-10, the availableQuantity is 5.

Should the Availability object created above be removed, corresponding graphDates objects would be removed in next requests too.

graphDates objects represent any changes in quantity and have three properties:

  • usedQuantity: total number of units used by Transactions
  • availableQuantity: total number of theoretically available units defined by Availabilities
  • date: two previous properties only apply to dates equal to or past this date and before the next graphDates.date, if there is any

To get the quantity effectively available for new Transactions, you just need to compute the following:

const remainingQuantity = Math.min(availableQuantity - usedQuantity)

Graph with Transaction

For illustration purposes, let’s suppose Transactions consume their quantity of Asset units as soon as they are created. We just have to include the default status draft in the Asset Type array property unavailableWhen to enable this behavior.

A user creates a Transaction:

await stelace.transactions.create({
  assetId: asset.id,
  startDate: '2019-09-14T12:42:30.000Z',
  duration: { d: 7 },
  quantity: 2
})

Graph:

{
  defaultQuantity: 5,
  totalUsedQuantity: 2,
  graphDates: [
    {
      date: '2019-09-01T01:12:20.000Z',
      usedQuantity: 0,
      availableQuantity: 0
    },
    {
      date: '2019-09-10T09:54:10.000Z',
      usedQuantity: 0,
      availableQuantity: 5
    },
    // The two following objects have been added
    {
      date: '2019-09-14T12:42:30.000Z',
      usedQuantity: 2,
      availableQuantity: 5
    },
    { // 7 days later
      date: '2019-09-21T12:42:30.000Z',
      usedQuantity: 0,
      availableQuantity: 5
    }
  ]
}

Interpretation:

The two first graphDates objects are the same as in the previous graph.

  1. From 2019-09-14 to 2019-09-21, the quantity available for new Transactions is 3 (availableQuantity - usedQuantity = 5 - 2 = 3).
  2. After 2019-09-21, the availableQuantity is 5, same as quantity available for new Transactions since usedQuantity is zero.

Note: root property totalUsedQuantity of Availability graph has been updated. The new value is equal to the quantity consumed by the Transaction.

Graph with overlapping Transactions

From 2019-09-14 to 2019-09-21, there is still room for new Transactions with quantity lower or equal to 3.

Let’s create one:

await stelace.transactions.create({
  assetId: asset.id,
  startDate: '2019-09-16T18:34:50.000Z',
  duration: { d: 3 },
  quantity: 3
})

Graph:

{
  defaultQuantity: 5,
  totalUsedQuantity: 5,
  graphDates: [
    {
      date: '2019-09-01T01:12:20.000Z',
      usedQuantity: 0,
      availableQuantity: 0
    },
    {
      date: '2019-09-10T09:54:10.000Z',
      usedQuantity: 0,
      availableQuantity: 5
    },
    {
      date: '2019-09-14T12:42:30.000Z',
      usedQuantity: 2,
      availableQuantity: 5
    },

    // the two following graphDates objects have been inserted
    {
      date: '2019-09-16T18:34:50.000Z',
      usedQuantity: 5,
      availableQuantity: 5
    },
    {
      date: '2019-09-19T18:34:50.000Z',
      usedQuantity: 2,
      availableQuantity: 5
    },

    {
      date: '2019-09-21T12:42:30.000Z',
      usedQuantity: 0,
      availableQuantity: 5
    }
  ]
}

Interpretation:

Now, from 2019-09-16 to 2019-09-19 (the second transaction period), there is no more quantity available for new Transactions.

Bravo! You’re an expert on reading Availability graphs and you can now use them to build your app faster.