SOP: Short-Pick Recovery
Document ID: WMS-PICK-003 Version: 1.0 Effective date: 04/30/2026 Owner: Warehouse Operations Manager Next review: [six months from effective date] Applies to: Pickers who short-picked an item; managers deciding what to do with the affected order; counters running the follow-up cycle count
1. Purpose
This procedure governs what happens after a short pick. The pick session itself (per WMS-PICK-001 §4.5) records the short and finishes the order's pick task — but the system records the short as-is without taking corrective action. The order ends up PICKED regardless of the short, the missing inventory is not auto-adjusted, the customer is not auto-notified, and downstream packing/shipping continues. Without this SOP's procedural discipline, every short pick leaves two problems behind:
- An order problem. The customer paid for a quantity they're not getting (yet, or at all). Someone must decide: ship partial now, split the order, hold it for restock, or cancel.
- An inventory problem. The system thinks more stock exists at the location than physically does. Until reconciled, future allocations will pull against the same phantom stock and produce more shorts.
Both must be resolved. This SOP runs them in parallel.
2. Scope
In scope:
- Recognizing a short pick from the system signals (
Allocation.PARTIALLY_PICKED,TaskItem.SHORT,WorkTask.shortItems > 0) - Order-side decisions: ship partial, split the order via
splitBackorder(per WMS-INV-006 §4.6), hold for restock, or cancel - Inventory-side reconciliation: cycle count the affected location per WMS-INV-002
- The natural downstream behavior —
Order.status: PARTIALLY_SHIPPEDafter a partial ship completes - Reporting: pulling shorts from the past 7 days for trend review
Out of scope:
- The mechanics of the short pick itself during the session — see WMS-PICK-001 §4.5
- Short-pick prevention (allocation policy, pick-bin coverage, scan validation) — see WMS-PICK-001 §8 (engineering escalations)
- Customer communication about the short — outside the WMS
- Vendor follow-up when shorts trace back to receiving variance — see WMS-AUD-003
3. Roles & permissions
API enforcement: the relevant downstream endpoints are auth-only:
POST /orders/:id/split-backorder— auth only (per WMS-INV-006 §3)POST /orders/:id/cancel(where it exists) — auth only- Cycle-count creation and approval — auth only (per WMS-INV-002 §3)
| Role | Identify the short | Decide order disposition | Cycle-count the bin | Approve the cycle count |
|---|---|---|---|---|
| READONLY | ✓ | — | — | — |
| STAFF | ✓ | — (escalate) | ✓ | — (operational expectation) |
| MANAGER | ✓ | ✓ | ✓ | ✓ |
| ADMIN | ✓ | ✓ | ✓ | ✓ |
| SUPER_ADMIN | ✓ | ✓ | ✓ | ✓ |
Operational expectations:
- Pickers do not decide order disposition. When you short-pick, you flag it and pass to a manager — the customer-facing decision (partial ship vs. hold vs. cancel) requires manager judgment, often with awareness of customer agreements, fulfillment SLAs, and inventory ETA.
- Pickers can and should initiate the inventory reconciliation cycle count immediately. The bin is right there; the picker knows the variance. Walking back to count it is the fastest path. A manager approves the count later per WMS-INV-002 §4.8.
- Cycle-count self-approval discipline. Per WMS-INV-002 §3, the picker who shorted should not approve their own follow-up count — the audit trail looks suspicious. Manager approval is the control.
4. Procedures
4.1 Recognizing a short pick
Use when: Reviewing a finished pick task, the order detail page, or the post-pick handoff to packing.
The system records a short pick in three places:
| Location | What it shows |
|---|---|
WorkTask.shortItems | Count of items on the pick task that went short. The order detail page surfaces this as ({n} short) next to the task progress (per pages/orders/[id].tsx:1193). |
TaskItem.status: SHORT | Per-line. The shorted line has quantityCompleted < quantityRequired and a shortReason field reading Short pick: {actual}/{required}. |
Allocation.status: PARTIALLY_PICKED | The allocation that was supposed to fulfill the line is partially picked. The OrderItem.quantityPicked reflects what was actually picked (less than the ordered quantity). |
What's not visible in the UI:
- The
Order.statusdoes not differentiate. Even with shorts, the order goes toPICKEDonce the task completes (perpicking.repo.ts:427-430). There is noPARTIALLY_PICKEDorder status — only the line-levelAllocation.PARTIALLY_PICKED. - The pick queue at
/pickdoes not flag orders with shorts. Once they'rePICKED, they leave the queue and head to the packing flow. - There is no shorts-specific dashboard. To find recent shorts, query
task_eventsforeventType: 'ITEM_SHORT'(see §6).
⚠ Don't rely on the order's status to tell you a short happened. Two orders can both be
PICKED— one fully picked, one short by 50 units — and the dashboard makes them look identical. Always checkWorkTask.shortItemswhen reviewing.
4.2 The decision tree (manager)
Use when: A short pick has happened, you've been notified by the picker, and you need to decide what to do with the order.
Each branch is fast — most short pick decisions take less than five minutes.
Step 1 — How short, and how much does the customer care?
| Situation | Path |
|---|---|
| Short by 1-2 units on a 50+ unit line, customer is a wholesale repeat client | Likely §4.3 (ship partial). Note in customer profile, follow up after. |
| Short by ≥30% of the ordered quantity, customer is direct-to-consumer | Likely §4.4 (split) or §4.6 (hold). DTC customers expect what they ordered. |
| Item is back-ordered with vendor for ≥10 days | Likely §4.4 (split — let the rest ship now) or §4.7 (cancel — give the customer the option to reorder when stock returns) |
| Item is one of multiple lines on the order, the rest of the order is fully picked | Likely §4.4 (split — ship the picked items, child-order the shorted line) |
| Item is the only line on the order | Likely §4.6 (hold) or §4.7 (cancel). No split is meaningful when there's only one line. |
| Customer escalation already in progress | §4.7 (cancel + refund) is usually safer than a partial ship that prolongs the dispute |
Step 2 — Whatever you choose, also kick off §4.5 (cycle count). Inventory reconciliation is independent of the order decision and runs in parallel.
4.3 Path: ship partial (do nothing on the order)
Use when: The short is acceptable to the customer (with notification), the partial value is high enough to justify the shipping cost, and you don't expect to backfill the missing units soon enough to be worth holding.
What this means:
- No special action. The picked goods continue through the normal flow: pack (WMS-PACK-001), ship (WMS-SHIP-001).
- The shipping flow naturally detects the partial: at ship completion,
quantityShipped < quantityfor the shorted line, soOrder.statusbecomesPARTIALLY_SHIPPED(notSHIPPED). This is automatic — seeshipping.service.ts:951-962. - The customer receives a partial shipment. They may or may not be notified by the WMS — the WMS does not send customer-facing partial-ship notifications today; that's an integration concern.
What needs to happen outside the WMS:
- Customer notification. The customer should know they're getting a partial. Send manually or via your CRM/Shopify flow.
- Adjustment / refund decision. Did the customer pay for items they're not getting? If yes, issue a refund or credit for the shorted units. Outside the WMS.
Aftercare:
- The remaining unshipped quantity sits as
OrderItem.quantity - OrderItem.quantityShipped > 0permanently — it's not auto-backordered. If you later want to fulfill it, you'd need to manually create a new allocation or order. Most operations treat shorted lines as "lost sale" rather than "future fulfillment" once they ship partial. - The
Allocation.RELEASEDstatus is set on the shipped allocations when shipping completes — they're closed out.
⚠ "Ship partial" is a one-way door for the order. Once
PARTIALLY_SHIPPEDis recorded, the order is treated as fulfilled. The unshipped quantity is not in any retry queue. If you want a future-fulfillment path with a tracked child order, use §4.4 (split) before shipping the partial.
4.4 Path: split the order
Use when: Some items on the order can ship today, others are short and will be sourced later. The customer agreed (or you're confident they will) to receive them in two shipments. This is the cleanest path for "ship what we have, fulfill the rest separately" — gives both portions independent tracking and audit.
Prerequisites:
- Order is
PICKED(orPARTIALLY_ALLOCATED/BACKORDEREDif caught earlier — see WMS-INV-006 §4.6). - Customer has agreed to a split. The system does not validate this — manager judgment.
- At least one line item is fully allocated (otherwise nothing to ship; use §4.6 hold instead).
Steps:
- (No UI button on the orders page or pick page mounted today — see WMS-INV-006 §8.) Call
POST /orders/:id/split-backorderdirectly via API. - The
OrderAllocationService.splitBackorder()transaction (per WMS-INV-006 §4.6):- Items where
quantityAllocated >= quantitystay on the original order. - Items where
quantityAllocated < quantity(the shorted line in our case, plus any unshipped items) move to a new childOrderrow withstatus: BACKORDERED. - The original order's status is recalculated based on what remains.
- Items where
- The original order proceeds to packing/shipping normally with its remaining items.
- The child order shows up on the backorders dashboard (per WMS-INV-006 §4.3) and the auto-retry pipeline picks it up the next time stock arrives for the variant.
What this writes:
- New
Orderrow (the child) with the unfilled items, the customer info, andstatus: BACKORDERED. - The original
Orderrow updates to reflect what remains. - Allocation rows on the original order are adjusted — the shorted-allocation moves with the child item (via
orderItemIdre-pointer) or is released and re-created depending on the implementation specifics insplitBackorder.
Result:
- The original order ships the partial today. Customer gets one shipment now.
- The child order is on the backorder dashboard. It will auto-retry on receiving (per WMS-REC-003) or cycle-count approval (per WMS-INV-002) for the affected variant. Customer gets the second shipment when stock arrives.
- Both shipments produce their own tracking numbers. Customer-service has clean record.
⚠ Split is irreversible (per WMS-INV-006 §4.6). Confirm the customer's agreement before splitting. Once split, you cannot merge the child back into the parent through any UI or API.
⚠ The child order's
createdAtis set to the split time, not the original order's creation date. This affectsdaysPendingon the backorder dashboard. A customer who waited 14 days, then got a split, then waited another 14 on the child shows up as a 14-day order on the dashboard. Take the original order's age into account when prioritizing — don't rely on the dashboard'sdaysPendingalone.
4.5 Path (parallel): cycle count the bin
Use when: Always run this in parallel with whichever order-disposition path you chose. Inventory reconciliation is independent of the order outcome.
Why this matters: A short pick is a 100% reliable indicator that the system stock differs from physical stock. The pick session writes Allocation.PARTIALLY_PICKED and decrements InventoryUnit.quantity by the picked amount — but the missing 2 units (or whatever the variance is) are still recorded on the unit. The system thinks they're still there. The next allocation against that variant may pull from the same bin and short again. Until you cycle-count, every order waiting on this SKU is at risk.
Steps:
- Open
/cycle-count/startper WMS-INV-002 §4.2. - Pick the affected location (the bin where the short happened).
- Start the session. The lines load from
InventoryUnitrows at the location — including the now-decremented unit that the short pick partially drained. - Count physically. For the shorted SKU, the count will likely be less than the system quantity (because the system thinks units are there that aren't, or because the originally short variance is still uncorrected).
- Submit per WMS-INV-002 §4.6.
- Manager approves per WMS-INV-002 §4.8 — this is what creates the formal
InventoryAdjustmentrow (per WMS-INV-007 §4.1 Path A) that closes the variance.
Why immediately:
- Walking back is faster than a separate trip later. The picker is already at or near the bin.
- The shorter the gap between the short pick and the cycle count, the cleaner the audit story. A cycle count 4 hours later is fine. A cycle count 4 days later may have additional drift mixed in (other shorts, additional moves) that confuse the variance.
- The cycle-count approval enqueues
enqueueCheckBackorders(per WMS-INV-002 §4.8) which will retry any waiting backorders for the variant — including any child order from a §4.4 split if cycle-count adjusted the available stock upward.
What if the count matches the system?
If the cycle count comes back with no variance (the system quantity is right, the short was due to physical placement error rather than missing stock), document and move on. The short was a one-off — the picker may have looked in the wrong location, or the units were briefly displaced. No adjustment needed. The order disposition still stands per §4.3 / §4.4 / §4.6 / §4.7.
⚠ Don't skip the cycle count. Every short pick that doesn't get cycle-counted leaves system stock overstated. After 5-10 unreconciled shorts on the same SKU, the variance compounds and your allocator becomes the source of customer-facing problems. The discipline here is the difference between a healthy inventory and slow drift.
4.6 Path: hold the order for restock
Use when: The customer wants what they ordered, not a partial. Stock is arriving soon (within the next few days) — either via receiving (vendor PO landing) or cycle-count adjustment lifting the available count.
Steps:
- Don't ship. The pick has already happened — the
PickBinis staged. Don't move it to packing yet. - Manually update the order status to
ON_HOLD:- There is no UI button mounted for "hold this order for restock" today. The path is direct DB update or a custom API call. The schema supports
Order.status: ON_HOLDplusholdReasonandholdAtfields.
- There is no UI button mounted for "hold this order for restock" today. The path is direct DB update or a custom API call. The schema supports
- Document the hold reason:
holdReason: "Short pick on {sku}; awaiting restock per PO {ref} expected {date}". - Park the pick bin physically at the staging area with a hold tag (sticky note:
HOLD — restock, plus order number). - Run §4.5 cycle count immediately. Holding the order doesn't change the inventory hygiene problem.
When the restock arrives:
- Receiving approval (per WMS-REC-003) auto-enqueues
checkBackordersfor the variant (per WMS-INV-006 §4.2). The pipeline retries anyBACKORDEREDorders for the variant. - Your
ON_HOLDorder is NOT automatically retried —ON_HOLDis excluded from the auto-retry per WMS-INV-006 §5.1. You must manually pull the hold off:- Update
Order.statusback toPICKED(orALLOCATEDif the previous pick was insufficient and a re-pick is needed). - If the existing
PickBinstill has the partial picked goods, top them up from the new stock and proceed to packing. - If the bin was disturbed, restart the pick from
ALLOCATED.
- Update
⚠
ON_HOLDis a manual procedure today. No UI button creates the hold; no UI button releases it; no automatic retry. This is operational discipline through the database. Engineering ticket: build a "hold for restock" CTA on the order page that sets the status, captures the reason, and posts to a#warehouse-holdsSlack channel for visibility. See §8.
4.7 Path: cancel the order line
Use when: Stock isn't coming back in any reasonable timeframe (vendor discontinued, lot recalled, etc.) and the customer is willing to accept a refund.
Steps:
- Manager confirms cancellation with customer (or customer-initiated cancellation request).
- Cancel the affected line — today, this is typically a full-order cancellation since per-line cancellation is not surfaced as a UI. Trade-off: cancel the whole order and refund, or split per §4.4 first then cancel only the child.
- If the partial pick has already happened, the picked goods need to return to inventory:
- Move them from the staging pick bin back to a stocking location via WMS-INV-001 §4.1 (Move Location).
- This produces
inventory:unit_movedaudit rows.
- Process the refund through your payment gateway (outside the WMS).
- Run §4.5 cycle count immediately. Same reason as every other branch.
⚠ Returning picked goods to inventory needs care. The
Allocation.PARTIALLY_PICKEDrows tied to the cancelled order should be released. Today the system doesn't have a clean "rollback a short pick" workflow — see §8. The least-error path: cancel the order, then move the bin's goods back via WMS-INV-001 with a note in the move documenting the source. The allocation rows become stale but harmless (the order isCANCELLEDso they don't trigger anything downstream).
5. Reference
5.1 What gets written by a short pick (recap from PICK-001 §4.5)
| Field | Value |
|---|---|
TaskItem.status | SHORT |
TaskItem.quantityCompleted | What was actually picked (less than quantityRequired) |
TaskItem.shortReason | "Short pick: {actual}/{required}" |
Allocation.status | PARTIALLY_PICKED |
OrderItem.quantityPicked | Increments by the picked qty (not the required) |
WorkTask.shortItems | Increments by 1 |
task_events | One row, eventType: ITEM_SHORT |
Order.status does not distinguish. After the task completes, the order is PICKED regardless of shorts.
5.2 The four recovery paths — quick comparison
| Path | When | Order ends up | Cycle count required |
|---|---|---|---|
| §4.3 Ship partial | Customer accepts; small shortage | PARTIALLY_SHIPPED after ship completes | ✓ |
| §4.4 Split | Some lines complete, some short; child order tracks the rest | Original ships normally; child is BACKORDERED | ✓ |
| §4.6 Hold | Customer wants what they ordered, restock soon | ON_HOLD (manual), then back to PICKED after restock | ✓ |
| §4.7 Cancel | Stock unavailable, customer accepts refund | CANCELLED | ✓ |
5.3 Querying recent shorts (no UI today)
For a manager pulling a weekly shorts report:
SELECT
te.createdAt AS short_at,
ti.quantityRequired,
ti.quantityCompleted,
ti.shortReason,
v.sku,
l.name AS location,
o.orderNumber,
o.status AS order_status,
u.name AS picker_name
FROM task_events te
JOIN task_items ti ON te.taskItemId = ti.id
JOIN work_tasks wt ON te.taskId = wt.id
JOIN product_variants v ON ti.productVariantId = v.id
JOIN locations l ON ti.locationId = l.id
LEFT JOIN orders o ON o.id = ANY(string_to_array(wt.orderIds::text, ','))
LEFT JOIN users u ON te.userId = u.id
WHERE te.eventType = 'ITEM_SHORT'
AND te.createdAt > NOW() - INTERVAL '7 days'
ORDER BY te.createdAt DESC;
The orderIds joining is awkward because the schema stores it as an array of order IDs on the work task — adapt as needed for your DB shape. Alternative: join through Allocation.orderId for cleaner FK.
5.4 Related SOPs
- WMS-PICK-001 §4.5 — The short pick itself during the session
- WMS-INV-002 — Cycle counts (the §4.5 reconciliation step)
- WMS-INV-006 §4.6 —
splitBackorder(the §4.4 path) - WMS-INV-007 §4.1 Path A — The
InventoryAdjustmentrow that cycle-count approval creates - WMS-PACK-001 — Packing (where partials get packed and shipped)
- WMS-SHIP-001 — Shipping (where
PARTIALLY_SHIPPEDis set) - WMS-AUD-002 — Shrinkage investigation (where short-pick patterns get analyzed at scale)
- WMS-AUD-003 — Receiving variance investigation (when shorts trace back to receiving math, not warehouse drift)
6. Audit & compliance
The short-pick recovery flow has good audit data on the pick side, partial audit data on the order disposition side, and good audit data on the inventory reconciliation side when it happens.
Pick-side (always written):
task_eventsrow of typeITEM_SHORTper shorted lineTaskItem.shortReasonper lineWorkTask.shortItemsaggregateAllocation.status: PARTIALLY_PICKED
Order-disposition-side (varies by path):
- §4.3 (ship partial) —
Order.status: PARTIALLY_SHIPPEDrecorded automatically. Good audit. - §4.4 (split) — new child
Orderrow +splitBackorderevent infulfillment_events(per WMS-INV-006 §5.2). Good audit. - §4.6 (hold) —
Order.status: ON_HOLD+holdReason+holdAt. Good audit if discipline is followed; no enforced format onholdReason, so quality varies. - §4.7 (cancel) —
Order.status: CANCELLED. The picked-goods-return-to-inventory step writesinventory:unit_movedevents per WMS-INV-001 §4.1, but the link between the cancellation and the inventory return is implicit — no foreign key, only timestamp correlation.
Inventory-reconciliation-side:
- When §4.5 happens: full
InventoryAdjustmentrow per WMS-INV-007 §4.1 Path A, pluscycle_count_auditsrows. - When §4.5 is skipped: no record at all that there was variance. The system's stock count remains overstated until something else triggers a cycle count.
Manager weekly review (recommended):
- Run the §5.3 query. For each short-pick row in the past 7 days:
- Confirm an order disposition was recorded (one of
PARTIALLY_SHIPPED, child split order,ON_HOLD,CANCELLED). - Confirm a cycle count was completed for the affected location since the short.
- Anything missing either step is technical debt — the order is in limbo or the inventory is unreconciled.
- Confirm an order disposition was recorded (one of
- Per-picker: count of
ITEM_SHORTevents. Note who's high — if it's the same person consistently, coaching, location-assignment review, or scanner issues. - Per-SKU: count of shorts. Recurring shorts on the same SKU = stocking issue, vendor variance, or chronic miscount. Cross-reference WMS-AUD-002 / WMS-AUD-003.
- Per-location: count of shorts. Recurring shorts at the same bin = bad pick face, mislabeled location, or systemic miscount on that bin.
Quarterly governance (Warehouse Operations Manager):
- Short-pick rate (shorts / total picks). Trending direction. > 1% across the warehouse is concerning.
- Time-to-cycle-count after short. Median should be < 24 hours; trending up means discipline is slipping.
- Recovery-path distribution (% partial-ship / % split / % hold / % cancel). If too high % cancel, you may have a sourcing problem; if too high % partial-ship, your customers may be receiving subpar service.
7. Troubleshooting
| Symptom | Cause | Resolution |
|---|---|---|
Order is PICKED but I know there were shorts | The order status doesn't differentiate. Check WorkTask.shortItems and Allocation.status for the actual story | Per §4.1, query the pick task. The order status is the dashboard-level summary, not the truth. |
Tried to call splitBackorder on a PICKED order; got status error | splitBackorder only accepts PARTIALLY_ALLOCATED or BACKORDERED per WMS-INV-006 §4.6. After picking, the order's status is PICKED, not eligible | Two options: (a) Use §4.3 ship-partial — let the partial flow through, the order naturally goes PARTIALLY_SHIPPED. The unshipped lines stay un-fulfilled but are visible via OrderItem.quantityShipped < quantity queries. (b) Manual intervention: move the order back to a pre-pick state via DB update, then split. Risky; involve IT. |
| Cycle count after short comes back zero variance | The short was a placement issue, not missing stock | Document and move on. Order disposition still stands. The bin is correctly stocked according to the count. |
| Cycle count after short shows variance > the picker's short | The system was further off than the short revealed | Approve the cycle count. The adjustment makes the system stock match physical. Some past short or move was unreconciled. Cross-reference WMS-AUD-002. |
ON_HOLD order I created isn't auto-retrying after restock | Per WMS-INV-006 §5.1, ON_HOLD is intentionally excluded from the auto-retry pipeline | Manually move the order back to PICKED (or ALLOCATED if a re-pick is needed) after the restock arrives. See §4.6. |
| Cancelled an order with a partial pick bin and forgot to return the goods to inventory | The picked goods are sitting in the staging area, not in any sellable bin | Find them physically. Move them via WMS-INV-001 §4.1 to the appropriate stocking location. The system's Allocation rows for that order are stale (PARTIALLY_PICKED status on a CANCELLED order); leave them for the audit trail. |
Picker reports a short, but I don't see the task_events row | The short pick wasn't actually confirmed — the picker may have closed the page before tapping Confirm | Either re-walk the picker through finishing the confirm, or use bulk-confirm per WMS-PICK-001 §4.6 (with the caveats there). The short isn't recorded until the confirm fires. |
| Partial shipment went out and now the customer wants the rest | If you didn't split first, the unshipped quantity is not in any retry queue | Manually create a new order or new allocation against the customer's account for the shorted quantity. There's no "ship the rest" UI today. |
| Multiple shorts on the same SKU in one day | Stocking issue, vendor variance, or chronic miscount | Run a full-location cycle count for the SKU per WMS-INV-002 §4.x with type SKU. Block further allocations until the count is approved. Cross-reference with the buyer for vendor-side issues. |
8. Escalation
- Build the per-line ship/hold/split UI on the order detail page. Today, all four recovery paths require either accepting the default, calling APIs directly, or DB intervention. A "Resolve Short" CTA on the order page that opens a modal with the four paths (ship partial, split, hold, cancel) and the right server-side action behind each is the single highest-leverage outbound feature improvement. Probably 1-2 days of work; closes most of the friction documented in this SOP.
- Auto-create cycle count on short pick (cross-listed from WMS-PICK-001 §8). A short pick is a 100% reliable indicator of variance. Auto-enqueueing a cycle-count task for the bin removes the discipline burden. Engineering ticket — simple to wire, big impact on the §4.5 compliance rate.
- Auto-retry
ON_HOLDshort-pick orders on inflow. TodayON_HOLDis excluded by design (per WMS-INV-006 §5.1) because hold reasons vary. But hold reasons sourced from short-pick recovery (specifically) could be allowed to auto-retry. Add aholdSubtypeor use theholdReasontext to differentiate, then carve out the short-pick-recovery holds from the auto-retry exclusion. - Build a shorts dashboard. The §5.3 SQL query is fine for one-off analysis but not for daily ops. A
/reports/shortspage with the same data + filters + sortable columns + a "review" workflow that requires a manager to acknowledge each short within 7 days. Closes the discipline loop. - Capture cancellation→inventory-return as a transaction. Today, cancelling an order and moving the partial goods back to inventory are two unrelated operations from the system's perspective. A single "cancel and return picked goods" workflow that does both atomically (releases allocations, moves units back, marks order cancelled, writes a single audit event) would close the §4.7 audit gap.
- Persistent shorts on a single SKU. Cross-functional escalation — buyer + warehouse manager + senior staff. Either receiving math is wrong, vendor is shipping under, the SKU is poorly stocked, or there's shrinkage. Cross-reference WMS-AUD-002 and WMS-AUD-003.
- Suspected fraudulent shorts (picker repeatedly reports shorts that cycle counts don't confirm): manager investigates with the audit trail, cross-reference WMS-AUD-002 §4 (when written). The combination of
ITEM_SHORTevents with no follow-up cycle count is itself a signal.
9. Revision history
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0 | [DATE] | [NAME] | Initial release. Documents the four order-disposition paths after a short pick (ship partial / split / hold / cancel) and the parallel inventory-reconciliation cycle count. Documents the order-status non-differentiation — Order.status becomes PICKED regardless of shorts, only WorkTask.shortItems and Allocation.PARTIALLY_PICKED carry the signal (per picking.repo.ts:427-430). Documents the natural downstream PARTIALLY_SHIPPED flow for path §4.3 — the shipping service detects partial via quantityShipped < quantity (per shipping.service.ts:951-962) and sets the order status accordingly. Documents the absence of UI for hold and cancel paths — both are manual today, requiring DB intervention or direct API calls. Documents the §5.3 SQL query for pulling recent shorts (no dashboard exists). Cross-references WMS-PICK-001 §4.5 (the short pick itself), WMS-INV-002 (cycle count for §4.5), WMS-INV-006 §4.6 (split backorder for §4.4), WMS-INV-007 §4.1 Path A (the adjustment that cycle-count approval creates), WMS-PACK-001, WMS-SHIP-001 (PARTIALLY_SHIPPED natural flow), WMS-AUD-002, WMS-AUD-003. Code references: picking.repo.ts:340-350, 355-360, 416-440, shipping.service.ts:951-962, pages/orders/[id].tsx:1193-1198. |