Skip to content
Log in

Open orders reference

On this page

An open order is an order that stays editable while a customer keeps adding to it, then is paid at the end of the visit. Hospitality businesses describe it as a tab or a table order. This topic covers how one is stored and what each stage does to the records, for anyone building an integration, a report, or a custom POS layout around the feature.

For the operator procedure, see Start an open order. For enabling the feature, see Configure open orders.

Requirements

Requirement Value
Package version 21.3.0 or later (21.2.0 adds s_c__Memo__c, 21.3.0 adds the order item cancellation fields)
Store variable pos.open_orders.enabled set to true
Optional store variable pos.memo.label to rename the memo label shown to staff

How an open order is stored

An open order is an ordinary Order record with two things that distinguish it: a type stamp and a live link to a cart.

Record Field Meaning
Order s_c__POS_Order_Type__c Set to OPEN while the order is open. The same field carries other POS order types, such as Layby.
Order s_c__Memo__c The staff-facing identifier, Text(80), for example a table number or a customer name.
Cart s_c__Order_Id__c Links the working cart to the open order. Resuming an order finds its cart through this lookup.
Order Item s_c__Cancelled_At__c When a submitted line was canceled.
Order Item s_c__Cancelled_By_User_Id__c The user who canceled it.

The cart is the working surface and the order is the committed record. Items exist on the cart as soon as staff add them, and reach the order only when they are submitted. Query s_c__POS_Order_Type__c = 'OPEN' to list the orders currently running in a venue.

An open order is created as a shell: no payments, no fulfillments, and no finalization. It is not put through the checkout pipeline until it is paid.

What submit does

Submitting sends the whole cart to the linked order, not a narrow patch of the changes. That matters when building anything that reads the result.

  • Idempotent by line. The server upserts each line by its sc_id, so resubmitting an unchanged order changes nothing.
  • Repricing. Every line is repriced on submit, because a customer change can move prices across the whole order. Once a payment has been recorded against the order, repricing is skipped so a settled total cannot drift away from what was paid.
  • Quantity splitting. A line with a quantity above 1 is split into individual single-unit lines on both the cart and the order, so each unit is tracked, prepared, and canceled independently. A unit discount carries across unchanged and a line-level transaction discount is distributed across the split lines, leaving the total unchanged.
  • Fulfillment fan-out. Each submit creates fulfillments only for lines that route to a fulfillment station and do not have one yet, grouped by fulfillment type, stock location, and fulfillment station. Lines with no station get their fulfillments at checkout, so in a store without station routing a submit creates no fulfillments. Successive submits therefore produce separate fulfillments, which is what makes each round its own kitchen ticket. Lines with a delivery fulfillment type are left for the checkout shipping flow.
  • Cancellation. A line submitted with a quantity of 0 is stamped canceled on the server. Restoring the quantity clears the stamp.
  • Commit only. Submitting does not clear the cart. The POS cart’s Submit button pairs the submit with cart:new to free the register.

Lifecycle actions

The actions below drive the feature and can be placed on POS action items or called from custom JavaScript through scAction. Parameters for each are documented in the POS actions reference.

Stage Action
Create against a fresh cart cart:new:open_order
Convert the active cart cart:update:open_order
Edit the memo in place open_order:update
Commit the cart to the order open_order:submit
Resume for another round order:resume
Cancel a single submitted line cart:item:cancel
Cancel the order order:cancel

Taking payment

An open order is paid by resuming its cart and checking out, not by an order-level payment. Calling checkout:start with the order_sc_id of an open order is declined with This order is still open. Resume it to take payment. Resume it with order:resume and start checkout from the resulting cart instead.

Offline behavior

Creating, updating, submitting, and canceling all work offline. Each change is queued through the unsaved-changes engine on the device and syncs when the register reconnects.

Resuming is the exception. An order the register does not already hold locally has to be fetched, so order:resume fails while offline with Can't continue this order while offline.

Cross-register contention only warns. When a second register resumes an order’s cart that another register already has open, the cart shows a banner, This cart is currently open on another register (<register name>)., but editing and submitting are not blocked, so the last submit wins. A workflow that expects exclusive access needs to enforce that itself.

Was this article helpful?

Was this article helpful?