# Ordering food and beverage items

Each client can be configured with a set of food and beverage items for sale which can vary by site. This is known as an *item profile*. Use the [GetItemProfileForSite](/openapi/digital-platform/openapi/items/ocapiitemprofiles_getitemprofileforsite/) endpoint to load the item profile for a particular site.

```json
{
    "itemProfile": {
        "siteId": "0002",
        "pages": [
            {
                "number": 1,
                "title": {
                    "text": "Snacks",
                    "translations": []
                },
                "buttons": [
                    {
                        "title": null,
                        "displayPriority": 0,
                        "itemId": "0002-001",
                        "prices": [
                            {
                                "price": {
                                    "valueIncludingTax": 10.0,
                                    "valueExcludingTax": 8.5,
                                    "tax": 1.5
                                },
                                "isDefault": true,
                                "restrictions": [],
                                "rewardId": null,
                                "discount": null,
                                "discountId": null
                            }
                        ]
                    },
                    {
                        "title": null,
                        "displayPriority": 1,
                        "itemId": "0002-021",
                        "prices": [
                            {
                                "price": {
                                    "valueIncludingTax": 8.0,
                                    "valueExcludingTax": 6.8,
                                    "tax": 1.2
                                },
                                "isDefault": true,
                                "restrictions": [],
                                "rewardId": null,
                                "discount": null,
                                "discountId": null
                            }
                        ]
                    },
                    {
                        "title": null,
                        "displayPriority": 1,
                        "itemId": "0002-003",
                        "prices": [
                            {
                                "price": {
                                    "valueIncludingTax": 5.0,
                                    "valueExcludingTax": 4.25,
                                    "tax": 0.75
                                },
                                "isDefault": true,
                                "restrictions": [],
                                "rewardId": null,
                                "discount": null,
                                "discountId": null
                            }
                        ]
                    }
                ],
                "displayPriority": 1
            }
        ]
    },
    "relatedData": {
        "items": [
            {
                "type": "Normal",
                "modifierGroups": [],
                "id": "0002-001",
                "name": {
                    "text": "Popcorn"
                },
                "restrictions": [],
                "itemClassId": "0004",
                "isPreparationRequired": false,
                "allowedDeliveryMethods": ["CounterPickup"]
            },
            {
                "type": "Normal",
                "modifierGroups": [],
                "id": "0002-002",
                "name": {
                    "text": "Milkshake"
                },
                "restrictions": ["AvailableHours"],
                "itemClassId": "0004",
                "isPreparationRequired": false,
                "allowedDeliveryMethods": ["CounterPickup"],
                "availableHoursId": "0002-1"
            },
            {
                "type": "Normal",
                "modifierGroups": [],
                "id": "0002-003",
                "name": {
                    "text": "Exclusive to Senior Members - Regular Coffee"
                },
                "restrictions": ["Member", "AvailableHours"],
                "itemClassId": "0004",
                "isPreparationRequired": false,
                "allowedDeliveryMethods": ["CounterPickup"],
                "availableHoursId": "0002-1"
            }
        ],
        "availableHours": [
            {
                "id": "0002-1",
                "siteId": "0002",
                "days": [
                    {
                        "day": "Sunday",
                        "startTime": "2000-01-01T06:00:00",
                        "endTime": "2000-01-01T06:00:00"
                    },
                    {
                        "day": "Saturday",
                        "startTime": "2000-01-01T06:00:00",
                        "endTime": "2000-01-01T06:00:00"
                    }
                ]
            }
        ]
    }
}
```

## Buttons, prices, and items

Buttons define the intended `displayPriority` of the items as well as the potential for a custom `title` which can be
used to override the default `name` of the item.

Each button has one or more prices. The price includes the actual price of the item as well as details as to what special conditions (restrictions) are required for purchase.

The details of the item itself are returned in the `relatedData` section. This data should be combined with the pricing
data to present the item selection interface.

## Price restrictions

The `restrictions` property of an item's price indicates a special requirement the patron must fulfil in order to be eligible
for the price. These include:

- `MemberReward` - patron must be a loyalty member and have an associated reward against their membership
- `InheritedMemberReward` - patron must be a loyalty member and have an associated reward against their membership
- `Discount` - discount identifier must be provided for the discounted price
- `InheritedDiscount` - discount identifier must be provided for the discounted price


Clients must have custom handling for each restriction for users to be able to purchase the item for a specific price.
If the client has not been built to handle a certain restriction it should hide the price from the interface until it
can be implemented.

Clients may implement their own logic based on known item pricing configuration to automatically favour one item
price over another or potentially even auto-select the item prices if appropriate.

## Item restrictions

The `restrictions` property of an item indicates there is a special restriction that limits when the item can be purchased. These include:

- `Member` - the item is exclusive to a Vista Loyalty membership
- `AvailableHours` - the item may only be sold at specific times, as defined in the `availableHours` related data property


Clients must have custom handling for each restriction to hide each item and it's associated prices when a restriction
cannot be met by the patron. If the client has not been built to handle a certain restriction it should hide the price from the interface until it
can be implemented.

An item with an `AvailableHours` restriction can only be sold when the purchase time is within one of the available hours.
The Digital Platform API applies one of the following rules to determine when the purchase time is for an order:

1. For an order with tickets, the start time of the earliest showtime indicates the purchase time
2. For an order that only contains items, the current time indicates the purchase time


## Weight-based item pricing

Price information returned as part of the [GetItemProfileForSite](/openapi/digital-platform/openapi/items/ocapiitemprofiles_getitemprofileforsite/) endpoint reflect the **per-unit** price of the weight-based item.

## Setting items for an order

The [SetItems](/openapi/digital-platform/openapi/items/ocapiorderitems_setitems/) endpoint sets all items for an order in one request. Subsequent requests will replace/remove any items
added via the previous call. Items cannot be added and removed individually.

Ordering multiple of a single item requires sending multiple entries. This allows each instance of the item to be
modified separately as required.

The [SetItems](/openapi/digital-platform/openapi/items/ocapiorderitems_setitems/) makes use of polymorphism,
so the `type` enumeration is required for each item being requested.

```json
{
  "items": [
    {
      "itemId": "string",
      "type": "Normal",
      "modifierGroups": []
    },
    {
      "itemId": "string",
      "type": "Package",
      "items": []
    },
    {
      "itemId": "string",
      "type": "Recipe",
      "components": [],
      "modifierGroups": []
    }
  ]
}
```

### Setting weight-based items for an order

When setting a weight-based item for an order, the `WeightBased` type must be specified, along with the desired weight:

```json
{
  "items": [
    {
      "itemId": "string",
      "type": "WeightBased",
      "weight": 1.25
    }
  ]
}
```

NOTE
**The following are not able to be specified when requesting a weight-based item:**

- Smart modifiers
- Smart modifier extras
- Package child items
- Recipe items
- Upsold item


**The following constraints apply for the `weight` field:**

- Requested weight cannot exceed `1,000,000` units.
- Requested weight must be greater than `0`.
- Requested weight cannot exceed a decimal accuracy of 6 decimal points.


## Member reward items

- A price with a `MemberReward` restriction means the price is only available to loyalty members.
- The `rewardId` property of the price must then be checked against the available rewards returned from the [GetMemberRewards](/openapi/digital-platform/openapi/members/ocapimemberrewards_getmemberrewards/) endpoint.
- The `availableQuantity` of the member's reward as well as the `limitPerOrder` on the reward itself must be taken into
account when presenting the amount of items available at this price.
- The relevant `rewardId` must be specified in the [SetItems](/openapi/digital-platform/openapi/items/ocapiorderitems_setitems/) request to apply the reward-restricted price.


```json
{
  "items": [
    {
      "itemId": "0000000003-1223456",
      "type": "Normal",
      "rewardId": 56
    }
  ]
}
```

## Discounted items

- A price with a `Discount` restriction means the item is only available via a discount.
- The `discountId` property indicates the discount required to purchase this price.
- The `discount` property describes the actual amount to be saved by purchasing with the discount.
- Discount details are available in the `relatedData` section of the response.
- Discounts have their own set of restrictions which work similar to the item price restrictions.


### Discount restrictions

- `MemberReward` - patron must be a loyalty member and have an associated reward against their membership
- `Availability` - discount is only available at certain times


NOTE
The `Voucher` restriction does not currently apply to item price discounts.

### Discounts restricted to member reward

Discounts with a `MemberReward` restriction require the `discountId` and the `rewardId` to be supplied in the [SetItems](/openapi/digital-platform/openapi/items/ocapiorderitems_setitems/) request to apply the discount.

```json
{
  "items": [
    {
      "itemId": "0000000003-1223456",
      "type": "Normal",
      "discountId": "DISC123",
      "rewardId": 56
    }
  ]
}
```

### Discounts restricted by availability

A discount with an `Availability` restriction indicates the item is only available for sale during certain times of the
day and certain days of the week. The `availableHoursId` property of the item itself will link to one of the
`availableHours` returned in the `relatedData`.

For a client to support this kind of discount, the client must process the availability data, as well as know the current
time in the timezone of the order's site.

If the items are being purchased along with a ticket then the availability values apply to the start time of the showtime at
the site. If items are being purchased in an order that doesn't contain tickets, then the available values apply to the *current* time
at the site.

### Discount mechanics and limitations for weight-based items

Discounts are applied to the *per-unit* price of the weight-based item, not the final price.
Fixed-price-off discounts are not currently supported for weight-based items.

## Item deliveries

When ordering food and beverage items, the client may also indicate when and where the items should be delivered.

See [item deliveries](/digital-platform/orders/item-deliveries) and [item delivery preparation](/digital-platform/completed-orders/item-delivery-preparation) for more info.