Updating items
The Loaded API supports PATCH
requests for sending updates. This makes it simple for a client to just update specific parts of an eixsting Order. But what about updating the Items in an Order? We've tried to make this as simple as possible too, specifically our design avoids the client from having to care about keeping track of any Loaded ids so we know which items the client is trying to update.
The tricky bit the API design has to cater for is differentiating between a PATCH
where there are multiple items in an Order and only some are being updated, and a PATCH
where there are also multiple items in the Order but some are being removed.
Positional updates
In the Order items property the API uses the position of each item to know what to update. E.g. if an Order has three items in it, [A1, B1, C1], when a PATCH
request arrives which also has three items, [A2, B2, C2], they will be updated based on their position.
I.e. the order of items in the array matters!
Removing items
The positional nature of how updates apply can be used to remove items too. Lets say our Order has items [A1, B1, and C1] and we want to remove item B1. To do that we send a PATCH
request with only two items in it, [A2, C2].
Removing all items
Removing all items is simply a matter of sending a PATCH
with an empty array of items - [].
Adding items
You can always add more items, just put them at the end of the array in your PATCH
request. E.g. with our order that has three items, [A1, B1, C1], to add a fourth item we would send in an update with the items [A2, B2, C2, D2]
Minimising data sent in an update
When you're sending a PATCH
you don't have to send the full state of each object. The original value of properties you don't send will be maintained. So if you've got a list of items on an Order and want to update the status of only one of them you may want to avoid sending a bunch of unnecessary data. However you still need to send something over for the items you're not wanting to change because if you don't the positional update behaviour will think you're actually wanting to remove them!
The solution is simple, just sending a null
placeholder (or if you like an empty object {}
) for each item that you don't want to be altered. So if we wanted to update item B in an order that has three items, [A1, B1, C1] we'd send a PATCH
with the structure [null, B1, null].
Examples
Updating an item
In this example we're modelling the scenario where an initial order has gone through the POS for a cheeseburger menu item, and a fries menu item. However when the food was delivered for some reason the fries were rejected - Loaded want's to know about this so that it can report on overall wastage and accurately track the usage of stock items.
Here's the Order that was initially placed:
{
"externalId": "my-order-id",
"createdAt": "2023-07-02T12:30:00Z",
"status": "Created",
"staffMemberExternalId": "jane-doe-id"
"items": [
{
"externalId": "my-cheeseburger-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 25,
"unitTax": 3.26,
"status": "Open"
},
{
"externalId": "my-fries-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 7,
"unitTax": 0.91,
"status": "Open"
}
]
}
When the POS marks the fries item as being rejected it'll send a request to the Loaded API to set the status of the fries item to VoidWithWastage
. With this update the only thing that needs to change is the status
property of the second item in the Order. As the Loaded API supports PATCH
requests, the data that needs to be sent is quite minimal.
The JSON we're going to send in our PATCH
request looks like:
{
"items": [
null,
{
"status": "VoidWithWastage"
}
]
}
The interesting piece of the JSON to be sent is the null
placeholder in the items array. This represents that there are no updates to the first item in the Order. If we didn't include this, and just sent a single object in the request with the status
parameter, the Loaded API would think that the update was actually setting the status of the first item in the Order and removing the second item.
We send that as a PATCH
request to update the Order:
curl \
-X PATCH \
-d '{ "items": [ null, { "status": "VoidWithWastage" } ] }' \
-H "Content-Type: application/json" \
-H '"Authorization=Bearer {token}"' \
https://api.loadedreports.com/v1/pos/orders/eid:my-order-id
Splitting an Order into two
It's quite common for POS systems to allow splitting an order by item when payment is processed, resulting in two separate orders that payment is processed against. In this scenario the Loaded API will have a single Order to start with that contains all the items that have been ordered. When the split is applied in the POS system the existing Loaded Order needs to have some items removed from it, and a second Order created with these items on it instead.
The example here shows how that can be achieved.
We'll start with an order with three items in it, and assume that at the point of payment the bill is being split. One payment will be for the cheeseburger and lemonade items, and a second payment will be for the fries.
{
"externalId": "my-order-id",
"createdAt": "2023-07-02T12:30:00Z",
"status": "Created",
"staffMemberExternalId": "jane-doe-id"
"items": [
{
"externalId": "my-cheeseburger-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 25,
"unitTax": 3.26,
"status": "Open"
},
{
"externalId": "my-fries-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 7,
"unitTax": 0.91,
"status": "Open"
},
{
"externalId": "my-lemonade-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 3,
"unitTax": 0.39,
"status": "Open"
},
]
}
To process the split the following requests will need to be sent:
First, a PATCH
to the original Order to remove the fries item, add a tender, and update to final statuses.
{
"completedAt": "2023-07-02T12:50:00Z",
"status": "Completed",
"items": [
{
"externalId": "my-cheeseburger-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 25,
"unitTax": 3.26,
"status": "Open"
},
{
"externalId": "my-lemonade-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 3,
"unitTax": 0.39,
"status": "Open"
}
],
"tenders": {
{
"externalId": "my-tender-id-1",
"tenderedAt": "2023-07-02T12:50:00Z",
"type": "DebitCard",
"invoiceAmount": 28
}
}
}
and the PATCH
request to update the original Order:
curl \
-X PATCH \
-d '{ "completedAt": "2023-07-02T12:50:00Z", "status": "Completed", "items": [ { "externalId": "my-cheeseburger-item-id", "requestedTime": "2023-07-02T12:30:00Z", "quantity": 1, "unitPrice": 25, "unitTax": 3.26, "status": "Open" }, { "externalId": "my-lemonade-item-id", "requestedTime": "2023-07-02T12:30:00Z", "quantity": 1, "unitPrice": 3, "unitTax": 0.39, "status": "Open" } ], "tenders": { { "externalId": "my-tender-id-1", "tenderedAt": "2023-07-02T12:50:00Z", "type": "DebitCard", "invoiceAmount": 28 } } }' \
-H "Content-Type: application/json" \
-H '"Authorization=Bearer {token}"' \
https://api.loadedreports.com/v1/pos/orders/eid:my-order-id
Notice in this example how we're PATCH
ing with the full object for the items. This is necessary because what we're doing is replacing the existing items at each position with the values we've sent. In this case we are removing the fries item from the Order.
Secondly, we create a new Order immediately in the Completed
status which has the fries attached to it and an associated tender.
{
"externalId": "my-order-id-split-2",
"createdAt": "2023-07-02T12:30:00Z",
"completedAt": "2023-07-02T12:50:00Z",
"status": "Completed",
"staffMemberExternalId": "jane-doe-id"
"items": [
{
"externalId": "my-fries-item-id",
"requestedTime": "2023-07-02T12:30:00Z",
"quantity": 1,
"unitPrice": 7,
"unitTax": 0.91,
"status": "Paid"
}
],
"tenders": {
{
"externalId": "my-tender-id-2",
"tenderedAt": "2023-07-02T12:50:00Z",
"type": "Cash",
"invoiceAmount": 7
}
}
}
and the POST
request to create this split portion of the original Order:
curl \
-X POST \
-d '{ "externalId": "my-order-id-split-2", "createdAt": "2023-07-02T12:30:00Z", "completedAt": "2023-07-02T12:50:00Z", "status": "Completed", "staffMemberExternalId": "jane-doe-id" "items": [ { "externalId": "my-fries-item-id", "requestedTime": "2023-07-02T12:30:00Z", "quantity": 1, "unitPrice": 7, "unitTax": 0.91, "status": "Paid" } ], "tenders": { { "externalId": "my-tender-id-2", "tenderedAt": "2023-07-02T12:50:00Z", "type": "Cash", "invoiceAmount": 7 } } }' \
-H "Content-Type: application/json" \
-H '"Authorization=Bearer {token}"' \
https://api.loadedreports.com/v1/pos/orders