openactive / modelling-opportunity-data

OpenActive Modelling Opportunity Data specification
https://www.openactive.io/modelling-opportunity-data/
Other
6 stars 6 forks source link

Replace IndividualFacilityUse with IndividualSlot #218

Open nickevansuk opened 4 years ago

nickevansuk commented 4 years ago

Based on observation of implementation barriers for IndividualFacilityUse, one of the key challenges is relating IndividualFacilityUse Slots to FacilityUse Slots - there is currently no direct link between the two in the model. This makes it difficult to normalise one into the other.

Ideally a feed would contain the following, though the model does not allow it, and arguably it is also confusing:

It would appear that the following proposal would resolve the issue

The problem here is that if the IndividualFacilityUse requires a photo (e.g. of Court 1), and the FacilityUse requires a photo (e.g. of the Badminton Courts), then where does this go in the above proposed model? Additionally how do you reliably group IndividualFacilityUse to e.g. build a timetable for "Court 1"?

nickevansuk commented 4 years ago

Where does this go in the above proposed model?

This is potentially modelled as follows:

                         IndividualFacilityUse (Badminton at ExampleCentre, Court 1)
                                  ||                                    /\
                                  \/                                    ||
FacilityUse (Badminton at ExampleCentre) <= Slot (7:30) <= IndividualSlot (7:30, Court 1)

The IndividualSlot references both the Slot and the IndividualFacilityUse, while providing enough information to be stand alone without an IndividualFacilityUse. This is key as not all systems will have the capability to provide useful IndividualFacilityUse details (e.g. photos of individual courts), but may still want to provide the ability to book a specific court.

In terms of feeds:

An example Slot feed would look like this:

{
  "id": "PTLBASKETBALL_2019-09-06T21-30-00",
  "modified": 3190715,
  "kind": "FacilityUse/Slot",
  "state": "updated",
  "data": {
    "@context": [
      "https://openactive.io/",
      "https://openactive.io/ns-beta"
    ],
    "type": "Slot",
    "id": "https://opendata.fusion-lifestyle.com/OpenActive/api/slots/PTLBASKETBALL_2019-09-06T21-30-00",
    "identifier": "PTLBASKETBALL_2019-09-06T21-30-00",
    "duration": "PT1H",
    "facilityUse": "https://opendata.fusion-lifestyle.com/OpenActive/api/facility-uses/PTLBASKETBALL",
    "maximumUses": 1,
    "offers": [
      {
        "type": "Offer",
        "price": 51,
        "priceCurrency": "GBP"
      }
    ],
    "remainingUses": 1,
    "startDate": "2019-09-06T20:30:00Z",
    "endDate": "2019-09-06T21:30:00Z",
    "individualSlot": [
      {
        "type": "IndividualSlot",
        "name": "Court 1-4",
        "id": "https://opendata.fusion-lifestyle.com/OpenActive/api/slots/PTLBASKETBALL_2019-09-06T21-30-00/Court-1-4",
        "individualFacilityUse": "https://opendata.fusion-lifestyle.com/OpenActive/api/individual-facility-uses/PTLBASKETBALL/Court-1-4",
        "remainingUses": 1
      },
      {
        "type": "IndividualSlot",
        "name": "Court 5-8",
        "id": "https://opendata.fusion-lifestyle.com/OpenActive/api/slots/PTLBASKETBALL_2019-09-06T21-30-00/Court-5-8",
        "individualFacilityUse": "https://opendata.fusion-lifestyle.com/OpenActive/api/individual-facility-uses/PTLBASKETBALL/Court-5-8",
        "remainingUses": 1
      }
    ]
  }
}

Modelling notes:

Alternative option:

nickevansuk commented 4 years ago

@nathansalter, I've seen from https://github.com/openactive/models-php/issues/48 that you're using IndividualFacilityUse... which has been a problematic part of the model to date for the reasons outlined in the issue above, and we've not seen any implementations yet

The challenge comes when mixing FacilityUse (which Legend / GLL implements) with IndividualFacilityUse

Just wondered if you had any thoughts on the above?

nathansalter commented 4 years ago

@nickevansuk When choosing which to use out of FacilityUse and IndividualFacilityUse we went for the latter because it closely models how we store this data. It's useful for a Venue manager to know the difference between 'a tennis court is booked' and 'Tennis Court A has been booked' for when bookings are made through other means than the API. We don't specifically link different IndividualFacilityUses together, so in order to group them to a FacilityUse we'd have to rewrite how we provide that.

Complicating the issue further, grouping the slots together causes other problems. There's no reason why two separate facilities need the same price, duration or even opening hours, so that would have to be taken into account when grouping the slots together. If you do end up implementing this we'll just have to have a single IndividualSlot per Slot which I think would have the same issues as you're describing above.

We've come across a similar problem before when building a previous booking system, either you can model it as 'I want to book Tennis Court A' or 'I want to book a tennis court'. Modelling it as both is very complicated, as it's not a simple grouping. That's why in our system we opted for higher granularity to get around a lot of these issues.

nickevansuk commented 4 years ago

That's really helpful, thanks @nathansalter !

So where IndividualFacilityUses aren't linked together, how are they displayed to the user?

Back to the Burgess Park example, the bookings screen looks like this:

Screenshot 2020-05-22 at 09 28 06

So to present the above UI there would need to be some grouping of the IndividualFacilityUse? Are they simply grouped by activity and location? (i.e. "display all the Tennis courts in Burgess Park in columns")

nathansalter commented 4 years ago

Glad to help!

Facilities are linked together by 'Space' which is a physical location:

Indoor Sports Hall:
  Badminton A
  Badminton B
  Badminton C
  Badminton D
Outdoor Pitches
  Football 11-A-Side A
  Football 6-A-Side A
  Football 6-A-Side B

So in the booking screen, we just allow the venue to click a slot which links to a specific facility at a specific time. When we're booking from Playfinder we manually match up the multiple facilities to a single 'pitch' and do the grouping there.

nickevansuk commented 4 years ago

Ok interesting, so in fact it sounds like within the current model your feed of IndividualFacilityUse ("Badminton A") items should each have an embedded FacilityUse ("Indoor Sports Hall"). This be achieved using the facilityUse property.

So the relevant part of the existing model is: FacilityUse -> IndividualFacilityUse -> Slot

E.g. Tennis at Burgess Park -> Court 4 -> 9:30

In feeds:

That works on the booking system side, however on the search side we still have an issue around how to normalise between slots of IndividualFacilityUse and FacilityUse as you say.

Perhaps introducing a IndividualSlot might help with this, as in theory you could then display a Slot and IndividualSlot differently in the UI?

nickevansuk commented 2 years ago

The discussion above clearly indicates that the existing IndividualFacilityUse model is sufficient for data publishing, if used correctly.

Given that the proposed solution of IndividualSlot is only helpful to Brokers/Data Users when combining data models between FacilityUse and IndividualFacilityUse (and hence does not actually need to be added to the OA specifications), given that implementation experience has shown that all systems can implement IndividualFacilityUse (and in some use cases can only implement IndividualFacilityUse), and given that reducing the number of potential feed combinations is a goal we are all aiming towards, the likely most effective way forward here is to encourage convergence around an IndividualFacilityUse-based model (while still retaining compatibility with the previous FacilityUse approach).

This recommendation also improves overall functionality for the end user, as they will be able to select specific courts to book when multiple are available.

Suggest this issue is closed, and documentation and guidance be updated to promote use of IndividualFacilityUse.

nathansalter commented 2 years ago

I'd definitely agree with this, it's the brokers responsibility to group the IndividualFacilityUse objects in a manner in which makes sense for their use-case. If you're handling a lot of repeat bookings, you'd want to model that differently than if you just want people to be able to book 'any tennis court'. As for the booking system, it should be trivial to expand a FacilityUse out into an IndividualFacilityUse by Activity/Location if they have that modelling in their internal systems.