Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Support for Block Bookings #299

Open
nickevansuk opened this issue Oct 21, 2021 · 3 comments
Open

Proposal: Support for Block Bookings #299

nickevansuk opened this issue Oct 21, 2021 · 3 comments
Labels
proposal Proposed changes to the specification

Comments

@nickevansuk
Copy link
Contributor

nickevansuk commented Oct 21, 2021

Proposer

On behalf of School Space, Badminton England and Playfinder

Use Case

There is currently an implicit assumption that block bookings are handled in the same way as ad-hoc booking by the OpenActive specifications.

Block bookings generally happen several months in advance (e.g. 6 months in the future), where as ad-hoc bookings tend to happen only a few weeks in advance (e.g. only 2 weeks in the future).

Search for block booking availability generally happens with a particular day and time in mind, and a number of weeks.

Additionally there may be other differences between ad-hoc and block bookings, including pricing, duration of slot and even the type of slot itself. For example a block booking may be for a "half sports hall (containing 3 badminton courts)", whereas an ad-hoc booking is likely to be for "1 badminton court". Different booking rules and approval processes also often apply to both.

Proposal

Instead of treating both block bookings and ad-hoc bookings using the same data model, feeds and assumptions, they should be treated separately.

For example a dataset may contain:

  • IndividualFacilityUse and Slot
  • IndividualFacilityUse and BlockBookingSlotSchedule

So the Slot and BlockBookingSlotSchedule feeds would be separated, and could both be linked to the same IndividualFacilityUse (though IndividualFacilityUses could also be separated for simplicity).

A new type e.g. BlockBookingSlotSchedule would be defined to represent the potential block booking, with availableDate used to indicate which days of the block are available (or exceptDate, startDate and endDate could be used instead for the inverse, which could simplify modelling but add complexity to implementation due to shifting startDates and the need for data processors to maintain schedule generation logic).

Note availableDate is suggested instead of timespans here as it is likely simpler to process and reason about, and also simplifies the model. Additionally most organisations allow block bookings for 6 or 12 months in advance, so the maximum number of items in this array is small (26 or 52).

BlockBookingSlotSchedule would be booked together in the usual way (e.g. 2 hour contiguous booking = 4 x 30 minute BlockBookingSlotSchedule), as per openactive/open-booking-api#219.

This representation should greatly reduce data volume in the feed, as a BlockBookingSlotSchedule is only updated each time a block booking is confirmed, so the volume of updates is roughly equal to the volume of bookings made. This is in contrast to the Slot representation for this usecase, where a large number of updates are generated for each block booking made. Additionally this more compact representation also significantly reduces the volume of data in the feed (e.g. by a factor of 26 for 6-months of availability).

For data users this format is also easier to process and query, as the data is organised according to the most common search request. It also allows the data to be easily displayed week-by-week in a GUI.

Example

An illustrative example of a BlockBookingSlotSchedule is as follows (note this is far from a final suggested modelling):

{
  "next": "http://www.example.org/feeds/individual-facility-use-block-booking-slots?afterChangeNumber=44254329",
  "items": [
    {
      "state": "updated",
      "kind": "FacilityUse/BlockBookingSlotSchedule",
      "id": "009/2018-03-01T10:00:00Z",
      "modified": 44234351,
      "data": {
        "@context": "https://openactive.io/",
        "@type": "BlockBookingSlotSchedule",
        "@id": "http://www.example.org/api/individual-facility-use/432#/block-booking-slot-schedule/2018-03-01T10:00:00Z",
        "facilityUse": "http://www.example.org/api/individual-facility-uses/432",
        "duration": "PT30M",
        "startTime": "20:15",
        "endTime": "20:45",
        "byDay": "https://schema.org/Tuesday",
        "scheduleTimezone": "Europe/London",
        "availableDate": [
          "2018-01-05",
          "2018-01-12",
          "2018-01-19",
          "2018-02-02",
          "2018-02-09",
          "2018-02-16",
          "2018-02-23"
        ],
        "offers": [
          {
            "@type": "Offer",
            "name": "30 minute weekly hire",
            "price": 10,
            "priceCurrency": "http://www.example.org/api/individual-facility-use/432#/block-booking-slots/2018-03-01T10:00:00Z"
          }
        ]
      }
    }
  ],
  "license": "https://creativecommons.org/licenses/by/4.0/"
}
@nickevansuk nickevansuk added the proposal Proposed changes to the specification label Oct 21, 2021
@nickevansuk nickevansuk changed the title proposal: Support for Block Bookings Proposal: Support for Block Bookings Oct 21, 2021
@nathansalter
Copy link

nathansalter commented Oct 22, 2021

I'm really excited about this proposal! So the duration you are seeing as a way to show the shortest possible time to book for a block booking? Also I'm not sure about byDay being an array, surely it would only ever have a single element in it? Otherwise the availableDate property doesn't make sense.

I guess the more complicated part is working out how to specify this on the OrderItem when making a booking. I guess add the schedule and days in the request? e.g.

{
  "@context": "https://openactive.io/",
  "@type": "OrderQuote",
  "brokerRole": "https://openactive.io/AgentBroker",
  ...
  "orderedItem": [
    {
      "@type": "OrderItem",
      "position": 0,
      "acceptedOffer": "https://example.com/events/452#/offers/878",
      "orderedItem": {
        "@type": "BlockBookingSlotSchedule",
        "@id": "http://www.example.org/api/individual-facility-use/432#/block-booking-slot-schedule/2018-03-01T10:00:00Z",
        "requiredDay": [
          "2018-01-05",
          "2018-01-12",
          "2018-01-19",
          "2018-02-16",
          "2018-02-23"
        ]
      }
    }
  ]
}

@nickevansuk
Copy link
Contributor Author

:) Good catch on byDay, have updated the example. Yes so duration would be the granularity (the minimum being specified via openactive/open-booking-api#219).

Yes for OrderItem, I must admit having been keen to avoid nesting for addons, I wonder whether this is actually a second use case for some kind of nesting (e.g. in the example above, how does someone cancel a single day?). Though this could add quite a bit of complexity.

An alternative could be to use the existing idTemplate to generate an OrderItem for each requiredDay, but the payload size for an Order would grow significantly.

I wonder if there might be another approach here that solves this slightly differently... hmm...

@nathansalter
Copy link

An alternative could be to use the existing idTemplate to generate an OrderItem for each requiredDay, but the payload size for an Order would grow significantly.

I think Payload size probably won't be an issue, as even with 100 bookings, it's still less than 1,000 lines. I think you're right about avoiding nesting, it can cause lots of issues and makes the cancellation/modification flow much more complex. I like the idea for idTemplates, do you have an example of how this would work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal Proposed changes to the specification
Projects
None yet
Development

No branches or pull requests

2 participants