# Stock Movement

## Overview

Stock movements record the physical flow of goods across locations in the warehouse system. Every time inventory enters, leaves, or moves within the organization, a stock move record is created to capture the transaction. There are three movement types: goods receipts (inbound from suppliers), goods issues (outbound to customers or scrap), and internal transfers (between internal locations). Additionally, block and unblock operations shift stock between available and blocked states without physically moving it.

Each movement follows a DRAFT to CONFIRMED to DONE state machine, ensuring that moves are reviewed before execution. When a movement reaches the DONE state, it automatically updates stock levels at both the source and destination locations via the stock-tracking feature. Virtual locations (supplier, customer, scrap) serve as logical endpoints for receipts and issues where no physical stock is tracked.

## Business Purpose

- Provide a complete audit trail of all inventory changes with who, what, when, where, and why
- Enable goods receipt processing to increase on-hand stock when items arrive from suppliers
- Enable goods issue processing to decrease on-hand stock when items are shipped to customers or scrapped
- Support internal transfers to rebalance stock across warehouses, zones, or bin locations
- Enforce a confirmation workflow so movements can be reviewed before stock levels are affected
- Feed downstream processes such as inventory valuation, lot/batch tracking, and serial number tracking with movement data

## Process Flow

```mermaid
flowchart TD
    A[Create Movement] --> B[DRAFT]
    B --> C{Action?}
    C -->|Confirm| D[CONFIRMED]
    C -->|Cancel| E[CANCELLED]
    D --> F{Action?}
    F -->|Execute| G[DONE]
    F -->|Cancel| E
    G --> H{Movement Type?}
    H -->|Goods Receipt| I[Supplier Location *virtual*] --> I2[Warehouse Location]
    H -->|Goods Issue| J[Warehouse Location] --> J2[Customer / Scrap Location *virtual*]
    H -->|Internal Transfer| K[Source Location] --> K2[Destination Location]
    I2 --> L[Update Stock Levels]
    J2 --> L
    K2 --> L
```

## Scenario Patterns

- **Goods Receipt**: Items arrive from a supplier. A movement is created from the virtual supplier location to a warehouse receiving location, increasing on-hand stock at the destination once executed.
- **Goods Issue (Sales)**: Items are shipped to a customer. A movement is created from a warehouse location to the virtual customer location, decreasing on-hand stock at the source once executed.
- **Goods Issue (Scrap)**: Damaged or expired items are written off. A movement is created from a warehouse location to the virtual scrap location.
- **Internal Transfer**: Items are relocated between warehouses or between zones within the same warehouse. Stock decreases at the source location and increases at the destination location.
- **Draft Correction**: A movement in DRAFT status is found to have incorrect quantities or locations. The user updates the draft before confirming it.
- **Stock Block**: Damaged or suspect items are blocked at a warehouse location. A block movement increases the blocked quantity and reduces available stock without physically moving the items. Requires a reason (e.g., damage, recall, quality hold).
- **Stock Unblock**: After investigation, previously blocked items are released. An unblock movement decreases the blocked quantity and restores available stock.
- **Cancellation Before Execution**: A confirmed movement is no longer needed (e.g., supplier shipment was rejected). The movement is cancelled before reaching DONE, so no stock levels are affected.
- **Multi-line Movement**: A single receipt or shipment contains multiple items. Each item-location combination is recorded as a separate stock move line within the movement.

## Test Cases

- Stock movement follows DRAFT -> CONFIRMED -> DONE state machine
- Movements in DRAFT or CONFIRMED state can be cancelled; DONE movements cannot be cancelled
- Goods receipt creates a move from a virtual supplier location to a physical warehouse location
- Goods issue creates a move from a physical warehouse location to a virtual customer or scrap location
- Internal transfer creates a move between two physical warehouse locations
- Executing a movement (transition to DONE) triggers stock level updates at both source and destination locations
- Cancelling a movement does not affect stock levels
- Each move line records item, quantity, unit of measure, source location, destination location, movement date, and reference
- Quantity on a move line must be greater than zero
- Source and destination locations must be different
- Only items in ACTIVE status can be referenced in a stock movement
- A goods issue cannot be executed if the source location has insufficient available (non-blocked) stock for the item
- Block movement increases blocked quantity and is rejected if the requested quantity exceeds available stock
- Unblock movement decreases blocked quantity and is rejected if the requested quantity exceeds currently blocked stock
- Block and unblock movements require a reason code

## Reference Links

- [SAP Goods Movements (Material Documents)](https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/f47baaae096c4cf58ad427a8f68493f6/4a28f2e8456c3040e10000000a42189e.html)
- [Odoo Stock Move Model](https://www.odoo.com/documentation/17.0/developer/reference/backend/orm.html)
- [Oracle Inventory Transactions](https://docs.oracle.com/en/cloud/saas/supply-chain-and-manufacturing/25a/fammi/inventory-transactions.html)
