Skip to main content

Understanding the order lifecycle

In Propeller, orders, quotes and quote requests are all the same object: an Order. What distinguishes them is the combination of type and status on the order. This unified model means you query, display and manage all three using the same API. Understanding how the order lifecycle works helps you build checkout flows, quote request forms, order history pages and status displays correctly.

The unified order model

Every order in Propeller has two fields that define what it represents:

  • type (OrderType) categorizes the order by its business purpose.
  • status (a string matching a configured OrderStatus code) determines where the order sits in its lifecycle.

OrderType

The type field is an enum with four values:

TypePurpose
dropshipmentA standard order fulfilled by shipping to the customer
quotationA quote or quote request
purchaseA purchase order (procurement)
stockA stock order (internal inventory)

For most frontend applications, you work with dropshipment (orders) and quotation (quotes and quote requests).

OrderStatus

Each order status is a configured object with its own fields:

FieldDescription
codeThe status identifier (e.g. NEW, QUOTATION, SHIPPED)
nameHuman-readable label
orderTypeCategorizes the status as ORDER, QUOTATION or REQUEST
typeWhether the status is SYSTEM (built-in) or CUSTOM (user-defined)
isPublicWhether the status is visible to customers
isDefaultWhether this is the default status for its order type
nextStatusesWhich statuses this status can transition to
previousStatusesWhich statuses can transition to this status
statusSetThe parent group this status belongs to

The orderType field on a status is what ultimately tells you whether an order is a quote request (REQUEST), a quote (QUOTATION) or an order (ORDER).

How type and status combine

What it representsOrderTypeOrderStatus orderTypeStatus examples
Quote requestquotationREQUESTQUOTE_REQUEST
Draft quotequotationQUOTATIONDRAFT_QUOTATION
Published quotequotationQUOTATIONQUOTATION
OrderdropshipmentORDERNEW, PROCESSING, SHIPPED

Because quotes and orders share the same data model, you query them using the same orders query and filter by type or status to display the right records in the right context.

How orders are created

There are three paths to creating an order. Each produces the same Order object but serves a different use case.

Cart (storefront checkout)

The most common path for customer-facing applications. A customer builds a cart, sets addresses, selects shipping and payment, then converts the cart into an order using cartProcess.

cartStart → add items → set addresses → choose shipping → choose payment → cartProcess

The cartProcess mutation takes an orderStatus (typically UNFINISHED for orders requiring payment or NEW for orders on account) and returns the created order with its cartOrderId.

This is the path covered in Cart management and Checkout flow.

Tender (sales portal)

A tender is an extended cart used by sales representatives. It allows adjusting item prices, applying discounts, viewing margins and managing customer-specific pricing. Tenders are typically used in a sales portal, not in a frontend customer portal.

tenderStart → add items → adjust pricing and discounts → tenderProcess

Key differences from a cart:

AspectCartTender
UserCustomerSales representative
PricingFixed (based on price sheets and rules)Adjustable per item
DiscountsApplied via action codesManually set with margin visibility
OwnerThe customer placing the orderThe sales rep (ownerId), separate from the customer
OutputcartProcess → ordertenderProcess → order

When a tender is processed, it creates the same Order object as a cart would. The source field on the resulting order indicates where it originated (e.g. "Sales Portal").

Direct creation (API and admin)

For integrations and backend systems, orders can be created directly using the orderCreate mutation. This creates a complete order in a single call without going through the cart or tender flow.

All paths converge

Regardless of how an order is created, the result is the same Order object. The cartId field on an order indicates whether it originated from a cart. The source field records where the order came from.

Cart (storefront)     ──→
Tender (sales portal) ──→ Order
orderCreate (API) ──→

Order statuses and transitions

Order statuses in Propeller are not just labels. They form a directed graph of allowed transitions. Each status defines which other statuses it can move to (nextStatuses) and which statuses can move to it (previousStatuses).

Status sets

Statuses are organized into sets (OrderStatusSet). A set is a named group of related statuses. This is useful for workflow organization, for example grouping all quote-related statuses into one set and all fulfillment statuses into another.

Common statuses

These are common system statuses found in a typical Propeller environment. Statuses are fully configurable, so your environment may have different codes and transitions.

Status codeOrder typeDescription
QUOTE_REQUESTREQUESTCustomer submitted a quote request
DRAFT_QUOTATIONQUOTATIONSales rep is drafting a quote (not visible to customer)
QUOTATIONQUOTATIONPublished quote, visible to customer
UNFINISHEDORDEROrder created, awaiting payment
NEWORDERConfirmed order
PROCESSINGORDEROrder is being processed
SHIPPEDORDEROrder has been shipped
COMPLETEDORDEROrder delivered and completed

Enforced transitions

The orderSetStatus mutation enforces valid transitions. If you attempt a transition that is not allowed by the status configuration, the API returns an ORDER_STATUS_TRANSITION_NOT_ALLOWED error.

The orderSetStatus input accepts:

FieldDescription
orderIdThe order to update
statusThe new status code
payStatusOptional payment status update
sendOrderConfirmationEmailWhether to send a confirmation email
addPDFAttachmentWhether to attach a PDF to the email
deleteCartWhether to delete the originating cart

Public vs. internal statuses

The isPublic flag on a status controls whether it is visible to customers. Internal statuses (where isPublic is false) are only visible to admin users and sales representatives. Use this flag to decide which statuses to display in a customer-facing order history page.

Example lifecycle: quote to order

This example walks through a complete lifecycle from quote request to fulfilled order, showing how the same Order object moves through different statuses.

1. Customer submits a quote request

A customer builds a cart and processes it with a quote request status. The resulting order has type quotation and status QUOTE_REQUEST.

2. Sales rep creates a draft quote

A sales representative opens the order in the sales portal and adjusts pricing and discounts. The status moves to DRAFT_QUOTATION. This status is not public, so the customer cannot see the draft.

3. Sales rep publishes the quote

When the quote is ready, the sales rep transitions the status to QUOTATION. This status is public, so the customer can now view the quote and its pricing. The quote may have a validUntil date after which it expires.

4. Sales rep revises the quote

If changes are needed, the sales rep transitions back to DRAFT_QUOTATION, makes adjustments and publishes again. Each change is tracked in the version history (see below).

5. Customer accepts the quote

The customer accepts the quote, which transitions the status from QUOTATION to an order status like NEW. At this point the order type remains quotation but the status order type changes from QUOTATION to ORDER.

6. Order moves through fulfillment

The order progresses through fulfillment statuses: PROCESSINGSHIPPEDCOMPLETED. Shipments are created and tracked along the way.

QUOTE_REQUEST → DRAFT_QUOTATION → QUOTATION → DRAFT_QUOTATION → QUOTATION → NEW → PROCESSING → SHIPPED → COMPLETED
(1) (2) (3) (4) (4) (5) (6) (6) (6)

Version history

Orders track every change as a revision. Each revision stores a sequential number, a timestamp, who made the change and a snapshot of the order state at that point.

Revision fields

FieldDescription
revisionNumberSequential number, starting at 1
createdAtWhen the revision was created
createdByAdminUserThe admin user who made the change (if applicable)
createdByContactThe contact who made the change (if applicable)
createdByCustomerThe customer who made the change (if applicable)
createdFromRevisionNumberThe revision this one was branched from

Snapshots

Each revision contains a snapshot of the order state, including the status, type and visibility flags. Two fields are particularly relevant for frontends:

  • public: whether this revision is visible to customers.
  • publicVersionNumber: the version number that customers see.

Public revisions get an incrementing publicVersionNumber. Private revisions (like draft edits) do not increment this number and are not visible to customers.

Example revision trail

For the quote-to-order lifecycle described above, the revision history might look like this:

RevisionStatusPublicCustomer sees
1DRAFT_QUOTATIONNoNothing
2QUOTATIONYesVersion 1
3DRAFT_QUOTATIONNoStill version 1
4QUOTATIONYesVersion 2
5NEWYesVersion 3 (order confirmed)

Revision mutations

Two mutations manage revisions:

  • orderRevisionRestore restores an order to a previous revision state. Takes orderId and revisionNumber.
  • orderRevisionsInvalidate marks specific revisions as invalid.

Shipment tracking

After an order is confirmed, shipments track the physical fulfillment. Each shipment has a status that progresses through delivery stages:

StatusDescription
CREATEDShipment record created
PROCESSINGBeing prepared
IN_TRANSITPicked up by carrier
OUT_FOR_DELIVERYOut for final delivery
DELIVEREDSuccessfully delivered
PARTIALLY_DELIVEREDSome items delivered
FAILED_DELIVERYDelivery attempt failed
CANCELEDShipment canceled
EXCEPTIONAn exception occurred

An order can have multiple shipments for partial deliveries. Each shipment can carry track-and-trace codes for carrier tracking.

Key fields on the Order object

These are the fields most relevant to understanding the order lifecycle. For complete field documentation, see the GraphQL API reference.

FieldDescription
idAuto-increment order ID
uuidUUID identifier
statusCurrent status code
typeOrder type (dropshipment, quotation, purchase, stock)
sourceWhere the order was created (e.g. webshop name, "Sales Portal")
cartIdThe originating cart ID, if created via cartProcess
originalOrderIdReference to the original order (for copies)
validUntilExpiry date (used for quotes)
createdAtCreation timestamp
lastModifiedAtLast modification timestamp
statusDateWhen the status was last changed
companyIdThe company this order belongs to
invoiceUserIdThe user responsible for payment
itemsThe order line items
totalOrder totals (subtotal, tax, shipping, grand total)
orderAddressesBilling and shipping addresses
shipmentsAssociated shipments

What this means for your frontend

Understanding the order lifecycle helps you build the right features for each stage:

  1. Cart management creates and manages the mutable cart before checkout. See Cart management.
  2. Checkout flow sets addresses, shipping and payment on the cart and converts it to an order with cartProcess. See Checkout flow.
  3. Quote requests use cartProcess with a quote request status to submit the cart as a request for quotation.
  4. Order history queries orders and filters by type or status to display the right records. Use isPublic on statuses to decide which statuses to show customers. See Order history.
  5. Payment integration handles the payment flow after cartProcess creates an order with status UNFINISHED. See Payment integration.
  6. Shipment tracking displays shipment statuses and track-and-trace codes for fulfilled orders.