Skip to main content

Multiple transactions

Stock transaction service is transactional, so transactions are immutable, and a single transaction updates a single stock type. Some operations therefore result in several transactions — and in a transfer, in two different business units.

They are published as separate events, linked by linkIdRelated, which every transaction produced from the same operation shares. A consumer that needs to see an operation as a whole should group on that field.

Stock transfer​

Sending the goods — one operation, three transactions:

#Business unitStock typeChangeWhy
1A (sending)SalesStockdecreaseno longer available to sell
2A (sending)InTransitincreaseon its way, still A's stock
3B (receiving)InOrderincreaseincoming, visible to B before it arrives

Receiving the goods — the receiving store performs a stock transfer received operation, producing three more:

#Business unitStock typeChangeWhy
4A (sending)InTransitdecreaseno longer in transit
5B (receiving)InOrderdecreaseno longer incoming
6B (receiving)SalesStockincreaseavailable to sell

Note that the goods remain accounted for at every step. Between transactions 1 and 6 they are neither sellable at A nor sellable at B, but they are never invisible — they sit in InTransit and InOrder.

A stock transfer of 10 coffees from Stockholm to Uppsala. Sending is one operation and three transactions: Stockholm SalesStock 30 to 20, Stockholm InTransit 0 to 10, Uppsala InOrder 0 to 10. Receiving is three more: Stockholm InTransit back to 0, Uppsala InOrder back to 0, and Uppsala SalesStock 4 to 14. The 10 are accounted for at every step.

The receiving store's SalesStock grows by exactly what arrived, whatever it already held — the 4 coffees Uppsala had before are not touched. A receipt can be corrected by sending it again for the same transfer: the correction moves SalesStock by the difference from what that transfer received before. Receiving 10, selling 1 and then correcting the receipt to 15 adds 5, not 6 — what was sold in between does not count.

Store transfer​

A store transfer adds a reservation step, so goods can be committed to a transfer while still physically present in the sending store.

Initiating the transfer:

Business unitStock typeChangeWhy
A (sending)Reservedincreasecommitted to the transfer, must not be sold
B (receiving)InOrderincreaseincoming

Completing the transfer — when the goods actually leave A:

Business unitStock typeChangeWhy
A (sending)SalesStockdecreasehas now left the store
A (sending)InTransitincreaseon its way
A (sending)Reservedreleased in fullthe whole reservation is released, whatever quantity shipped
B (receiving)InOrderset to the quantity shippedno longer expects what did not ship

The receiving store then performs a stock transfer received operation, exactly as above.

Why the extra step matters: the quantity actually shipped may differ from the quantity requested. The completion reconciles both the reservation at A and the incoming quantity at B against what really left, so a partial transfer does not leave a permanent phantom reservation or a permanent phantom incoming quantity.

A store transfer where 10 coffees are requested and 8 are shipped. Initiating reserves 10 in Stockholm and shows 10 incoming in Uppsala, while SalesStock is untouched. Completing with 8 shipped takes 8 out of Stockholm SalesStock into InTransit, releases the whole reservation of 10, and sets Uppsala InOrder to the 8 that actually shipped. Receiving then moves the 8 into Uppsala SalesStock.

Sales that touch a reservation​

A sale submitted through the Input API (POST /business-units/{businessUnitId}/receipts) can name the reservation it fulfils in reservationId. It then releases the sold quantity from Reserved (or ReservedInOrder) as well as reducing SalesStock, so the same grouping applies — one receipt line, two transactions, sharing linkIdRelated. Sales from the POS arrive as PosLog, which carries no reservation, so they reduce SalesStock only.

Note: The transactions are immutable, so any adjustment of previously created transactions needs to be handled by creating a delta transaction. This is also how movements that arrive out of sequence are corrected — see Delayed transactions.


Return