Skip to content

Moving stock between your locations — declare, prep, ship, receive

The rule: pre-declare every cross-venue transfer. The chef declares intent, the prep batch fulfils it, the destination confirms receipt. No batch, no transfer; no declaration, no movement.

io osteria centrale has the big kitchen and the head chef. io osteria nord opens at lunch and runs a tighter prep schedule. The pizza dough for both locations is made once a day at centrale — and a chunk of it goes to nord by van at 10am.

The system models this as a transfer: a row that says “5kg of pizza dough from centrale → nord” and walks through pending → shipped → received as the chef preps, ships, and confirms. The stock moves cleanly at both ends. The audit trail is in place. The destination’s expiry clock starts from the source batch’s producedAt, not from receipt — so the receiving venue knows exactly how much shelf life they have left.

What it does

Three states, each with a clear trigger:

StateWhat happenedWhat you do next
PendingChef pre-declared the transfer. No stock has moved.Run the matching prep batch at the source.
ShippedSource prep batch completed. Source stock debited, transfer linked to the batch.Physically deliver. Destination receives.
ReceivedDestination staff tapped “receive”. Destination stock credited, new production batch at destination.Use the stock.

You can cancel a transfer that’s still pending (no stock has moved, no harm done). After it’s shipped, cancellation means physical recall — not a workflow the system models in v1.

How to use it

Centrale → nord: pizza dough

The morning starts at centrale. The head chef opens the prep board, sees today’s plan (5 batches: dough, sauce, mozzarella prep, two stocks). Before starting the dough batch, they tap Transfer on the dough row, pick nord as the destination, enter 5kg, optionally add a note (“for tonight’s service”), and confirm.

The transfer is now pending. The dough recipe at centrale shows a small badge: “Outgoing transfer attached: 5kg → nord”.

The chef now runs the dough batch normally:

  1. Tap Start.
  2. Wait for the resting clock.
  3. Tap Ready.
  4. Tap Complete (the chef typically tweaks actualQty here if they got slightly more or less than planned — say, 10.2kg actual vs 10kg planned).

At Complete, the system:

  • Credits centrale’s pizza-dough stock by 10.2kg (the producedQty).
  • Scans pending transfers on this output item. Finds the 5kg → nord transfer. Debits centrale’s stock by 5kg, marks the transfer shipped, and links it to the production batch.
  • Leaves the remaining 5.2kg at centrale.

The head chef sees a confirmation: “Shipped 5kg pizza dough to nord.”

Receiving at nord

Around 10am, the van arrives at nord. Staff opens the admin app, navigates to Incoming transfers, sees the shipped row, taps Receive. The destination stock is credited (5kg arrives), a new production batch is created at nord carrying the source batch’s expiry — so nord’s chef knows the dough will go off at the same time centrale’s would have.

If the actual quantity is different (a kilo got lost, the bag tore), the receiver can enter actualQty at confirmation. The system credits the actual, not the declared.

When the two locations are different companies

If centrale belongs to one company and nord to another, the transfer is a sale between two legal entities. The flow is identical, with one difference at the destination: when the receiver confirms, a banner appears that says “Cross-entity transfer — generate invoice via Tax Invoices.” The receiver clicks through to the existing tax-invoice flow and issues an invoice from centrale’s company to nord’s. The stock movement is recorded; the invoice is a separate document the operator drives manually.

Auto-drafting that invoice is a follow-up feature. Same-company transfers (the common case) are zero-VAT internal reclassification and need no invoice.

Constraints that the system enforces

  • Both venues must belong to the same group. The system rejects a transfer between two unrelated venues.
  • The destination must already have a local inventory row for the item being transferred. If the destination is brand-new and hasn’t been seeded yet, the operator must seed first.
  • A pending transfer doesn’t reserve source stock — it’s intent-only. Two chefs declaring simultaneous transfers totalling more than the planned batch is fine; whichever fits in the prep batch’s actual yield ships first, the rest stays pending for the next batch.

The chef’s view of pending transfers

On the prep board, each batch that has outgoing transfers attached shows a small badge with the destinations: “5kg → nord, 3kg → sud”. If the actual production yield is short, the system fulfils transfers in initiatedAt order — earliest declaration ships first.

A transfer that doesn’t fit the current batch’s yield stays pending. It’ll fulfil from the next batch with matching output.

Seeing what’s inside, and what’s waiting

The transfers board lists each move by what it carries — the item name, the quantity, and the unit (“Pizza dough · 5 kg”) — alongside the route from one venue to the other. Click any row and a panel slides open with the full picture: how much, the cost per unit and total value, whether it’s a plain move between your own kitchens or a cross-entity transfer that needs an invoice, any notes, and a timeline of who declared it, when it shipped, and who received it. The buttons you need are right there in the panel — Mark shipped and Cancel if you’re the sender, Receive if you’re the destination.

You don’t have to go looking, either. The Transfers link in the sidebar carries a small number whenever a move still needs attention at the venue you’re currently in: as the sender, it counts what you still have to ship; as the receiver, what’s on its way or waiting for you to receive. The moment a transfer is received, the number clears on both sides. Switch venues in the top bar and the count follows you — so the kitchen that’s expecting a delivery sees it without opening the page.

When you start one with New transfer, pick the venue you’re sending to first, then use the Item box — it’s a search field, so start typing the item’s name and the matching ones appear. You can find a single ingredient among thousands without scrolling a long list.

Try this on your own data

  1. Make sure both venues are members of the same group.
  2. At venue A, log some stock on an inventory item that has a groupInventoryItemId. (If you don’t see one, the item hasn’t been linked to a group master yet.)
  3. Initiate a transfer of a small quantity to venue B.
  4. Run a prep batch at venue A that produces the same item. Confirm the transfer flips to shipped automatically and source stock decremented by the transfer quantity.
  5. Switch to venue B, open Incoming transfers, tap Receive. Confirm the stock arrives with the source expiry carried over.