Warehouse Operations¶
Who this is for
Warehouse team. You'll use this for everything physical — moving devices around, packing shipments, and tracking where each phone is at any moment.
What you'll accomplish: work through the warehouse task queue, pack shipments, and trace any device's movement history.
The three tools you'll use¶
| Tool | When you use it |
|---|---|
| My Tasks | Daily work list — things the system wants you to do (putaway, pick, relocate) |
| Packing Boxes | Prep and scan shipments out the door |
| Movement History | Trace where a specific device has been — useful for disputes or audits |
Warehouse tasks¶
A task is any unit of physical work the system has queued up for a warehouse operator. Tasks are created automatically when certain events fire (a manifest completes, a relocate is requested, QC opens a batch).
Open your task list¶
Go to Inventory → Device Inventory → My Tasks (tasks assigned to you) or All Tasks (the full queue).

What kinds of tasks you'll see¶
| Type | What it means |
|---|---|
| Putaway | Devices just arrived in receiving — move them to their shelf homes |
| Pick | A sale needs devices pulled from storage for shipping (mostly automated by the packing box now) |
| Relocate | Generic move between two storage locations (restocking, inventory rebalance) |
| QC Move | Move devices into or out of the QC area |
| Pack | Pack devices into a shipping container (handled in Packing Boxes, see below) |
The task lifecycle¶
- Pending — nobody's picked it up yet
- Assigned — someone claimed it (themselves or a supervisor assigned)
- In Progress — actively being worked
- Done — all devices processed
Working a task¶
-
Open My Tasks, click a task to open it.

-
Click Start — task moves to
In Progress. - Scan each device with your barcode gun. The task ticks off each one as you go.
- When all devices are scanned (or any missing ones acknowledged), click Complete.
The corresponding device.movement records are written as you scan so the movement history is live.
Packing boxes¶
Packing boxes group physical devices into a shipping container — the primary way you prep an outbound delivery.
Open the packing box list¶
Inventory → Device Inventory → Packing Boxes.

A packing box is auto-created when a device sales order is confirmed. You'll also see boxes created for retail reservations being physically shipped out.
Box states¶
- Draft — just created, no devices packed yet
- Packing — actively scanning devices in
- Ready to Ship — all expected devices scanned and Mark Ready to Ship has been clicked; waiting for Mark Shipped
- Shipped — gone out the door; triggers COGS / invoice / settlement (see Delivery Manifests)
The scan-to-pack flow¶
- Open the box.
- Use the barcode scanner on the box form (or the Barcode app → Packing).
- For each device you're putting in the physical box, scan its IMEI.
- The box tracks packed-vs-expected in real time.
- When packed equals expected, click Mark Ready in the scanner or Mark Ready to Ship on the box form.
- Back on the box form, click Mark Shipped to post the shipment.
Each scan simultaneously:
- Packs the device into this box
- Picks it on the linked delivery manifest (if any)
- Writes a movement record
You don't have to pick separately from packing — it's one action. See the Delivery Manifests guide for the full scan-to-ship flow.
Print a box label¶
When the box is Ready to Ship, click Print Label to get a PDF with the box barcode and contents summary. Stick it on the outside of the carton.
Movement history¶
Every physical move a device makes gets logged. If you ever need to answer "where has this phone been?" this is the source of truth.
Open the movement list¶
Inventory → Device Inventory → Movement History.

What counts as a movement¶
| Type | When it's logged |
|---|---|
| Receiving | Device scanned into an IMEI manifest |
| Putaway | Moved from receiving dock to a storage location |
| Pick | Retrieved from storage for an order |
| Pack | Placed in a packing box |
| QC In / QC Out | Moved into or out of the QC area |
| Relocate | Generic location-to-location move |
| Ship | Shipped to customer |
| Retail Transfer | Moved to a retail-partner location |
Each record has: device (IMEI), type, source location, destination location, user who performed it, timestamp.
Finding one device's history¶
Open All Devices, find the IMEI, click into the device form, and open the Movements tab (or smart button). You'll see every move in chronological order.
Barcode scanning — where to find it¶
Scanning works the same wherever you do it: point gun at IMEI, pull trigger. But there are a few entry points:
| Where you scan | What the scan does |
|---|---|
| Barcode app → Manifest Receiving | Receives into the selected incoming manifest |
| Manifest form → Scan button | Same, but from the manifest directly |
| Packing box → scan panel | Packs into the box + picks on delivery manifest |
| Warehouse task → scan | Ticks off the next expected device in the task |
All scan flows are protected against double-scan and cross-order conflicts — if two people scan the same IMEI at the same time, only one wins and the other gets a clear error message.
Manifest receiving scanner¶
The Barcode app's Manifest Receiving view shows each incoming PO as a scan card with received/expected progress. Use the barcode button on the card to open the receiving scan surface for that manifest.

Packing scanner¶
The packing scan surface is intentionally full-screen and focused: scan field, packed/expected progress, and the current box lines. It is the preferred outbound scan surface because one scan packs the box and picks the delivery manifest.

Common problems¶
A task is 'Pending' forever and nobody picks it up
Go to All Tasks, open it, and click Assign to me (or assign it to someone). Tasks don't auto-assign — someone has to claim them.
Box won't let me mark it shipped — says 'not all devices packed'
The box has more expected devices than scanned. Options: (a) keep scanning, or (b) if an expected device is truly missing, remove that allocation from the linked SO and the box's expected count drops. You can't ship a box with an empty slot. If everything is packed but Mark Shipped is not visible, click Mark Ready to Ship first.
Movement history shows a move I didn't make
Check the user column — that's who scanned. If it's unrecognized, the scan was probably automated (e.g. the inter-company flow generates moves in the background). Automated moves are tagged with a specific user, typically OdooBot or the impersonating service account.
Device's current location is wrong
A location field drifts if a move happened outside the system (someone physically moved the phone without scanning). Fix: do a location-update scan via a Relocate task, which writes a movement record and updates current_location_id.
Under the hood¶
Technical details for developers
Models
warehouse.task+warehouse.task.line— task queuepacking.box+packing.box.line— shipping containersdevice.movement— append-only audit log of all physical movesstock.lot.current_location_id— cached "where is this device now" pointer
Task auto-creation triggers
- Putaway task: created by
device.manifest._create_putaway_task()after a receiving manifest completes - QC Move task: created when QC handoff wizard activates
- Pick task: no longer auto-created (removed in v2.26 with the unified delivery flow — packing box handles it)
Packing box scan entrypoint
packing_box.scan_device(imei) — called via JSON-RPC from the OWL barcode UI. Acquires advisory lock on the lot, calls _sync_to_packing_box() on the allocation, which in turn calls _quick_pick() on the matching delivery-manifest line.
Movement creation side effects
Every device.movement.create() call also:
- Updates
stock.lot.current_location_idtodest_location_id - Creates a
stock.move(withis_inventory=True, no move_line_ids) for warehouse-app traceability — introduced in v2.21 to make devices trackable in Odoo's standard Stock reports - Relocates the lot's
stock.quantto the new location (except for outbound moves where the quant is removed)
Odoo 19 stock.move gotcha
stock.move has no name field — use origin (writable) or reference (computed). Uses product_uom, not product_uom_id. Creating a done move with move_line_ids triggers check_quantity() and fails with serial-uniqueness errors if a quant already exists; use is_inventory=True without move_line_ids for traceability-only moves.
Locking
All scan entry points wrap in pg_try_advisory_xact_lock(hash(imei)) to serialize concurrent scans of the same device. The lock is held for the transaction; failure to acquire returns a user-facing "busy" error rather than silently overwriting.