# README

## Overview

The Inventory module manages physical stock tracking across storage locations. It provides real-time visibility into on-hand quantities, records all stock movements (receipts, issues, adjustments), and supports lot/batch and serial number traceability. The module also handles inventory valuation, physical inventory counts, and scrap disposal.

Inventory operates at the Item level (from item-management) and tracks stock within StorageLocations that the module owns. Organization's Site entity represents the physical facility (with address); each StorageLocation belongs directly to a Site.

## Key Features

- **Location Management**: Define StorageLocations under organizational Sites
- **Stock Tracking**: Real-time on-hand, blocked, in-transit, and location-level stock plus site-level reservation availability
- **Supply Planning**: Site-level future inbound supply projections via InventorySupplyPlan for planning and ATP workflows
- **Stock Movement**: Goods receipt / goods issue execution commands for externally driven changes, plus StockAdjustment workflow (CORRECTION / SCRAP / BLOCK / UNBLOCK) for operator-initiated changes — all producing immutable InventoryLedger records
- **Inventory Adjustment**: Manual corrections for discrepancies, damage, and shrinkage via StockAdjustment(CORRECTION)
- **Lot and Batch Tracking**: Lot/batch-level traceability with expiration date management
- **Serial Number Tracking**: Individual item tracking by unique serial number across lifecycle
- **Inventory Valuation**: Cost calculation using FIFO, weighted average, or standard cost methods
- **Inventory Count**: Physical inventory counts and cycle counts with variance review and approval
- **Scrap Management**: Record and track disposal of damaged, expired, or defective stock via StockAdjustment(SCRAP)

## Module Scope

### In Scope

- Storage location definition and management (flat, no zone/bin hierarchy)
- Real-time stock tracking per item/location and source-line reservations per item/site
- Future inbound supply projections per item and site using InventorySupplyPlan
- Goods receipt / goods issue execution commands and StockAdjustment approval workflow (CORRECTION / SCRAP / BLOCK / UNBLOCK)
- Immutable inventory ledger recording for all stock changes (InventoryLedger) linked to InventoryExecution for execution type and source document context
- Inventory adjustment with reason codes via StockAdjustment(CORRECTION)
- Lot/batch assignment, tracking, and expiration date management
- Serial number assignment and lifecycle tracking
- Inventory valuation method configuration (FIFO, weighted average, standard cost)
- Cost-per-unit tracking and valuation amount calculation
- Physical inventory count and cycle count workflows
- Scrap/disposal recording with quantity and valuation impact via StockAdjustment(SCRAP)

### Out of Scope

- Purchase order lifecycle management (purchasing module)
- Sales order and fulfillment workflows (sales module)
- Automated reorder point and replenishment rules (purchasing module)
- Pick/pack/ship multi-step fulfillment (warehouse operations / sales module)
- Putaway rules and automated storage location assignment
- Removal strategies — automated FIFO/FEFO/LIFO picking rules
- Demand forecasting and automated replenishment planning
- Drop-shipping and cross-docking
- Landed cost allocation (purchasing / future management-accounting module)
- Journal entry posting to general ledger (financial-accounting module)
- Barcode scanning device integration (application layer)
- Shipping carrier integration (application layer)

### Scope Decision Rationale

Inventory owns **physical stock state** -- where items are, how many exist, and what they cost. This is separated from purchasing (which owns the procurement lifecycle) and sales (which owns the fulfillment lifecycle) because stock tracking follows its own business rules and update patterns.

StorageLocation is owned by this module (not organization) because it represents an operational storage type with inventory-specific attributes (capacity, storage conditions). Organization's Site represents the physical facility identity and address; StorageLocation layers the storage layout directly on top of a Site. We intentionally do not introduce an intermediate "Warehouse" entity — locations belong directly to a Site, matching SAP MM's Plant → Storage Location pattern.

Lot/batch and serial number tracking live here (not in item-management) because they are inventory-layer concepts -- they track "which specific instances" of an item exist, not "what the item is." Item-management explicitly defers these concerns to the inventory module.

Stock changes flow through two complementary patterns, both landing in the immutable **InventoryLedger**:

- **Execution commands** create and post goods receipts / goods issues. They are driven by external modules — purchase goods receipts, sales shipments, manufacturing completions — that have already gone through their own approval lifecycle
- **StockAdjustment** provides an approval workflow (DRAFT → SUBMITTED → CONFIRMED) for operator-initiated changes (CORRECTION, SCRAP, BLOCK, UNBLOCK). Ledger writes occur only on confirmation

InventoryLedger entries carry `inventoryExecutionId` and reach execution type plus source document context through InventoryExecution. This keeps the immutable ledger focused on stock facts while avoiding duplicate source references on each ledger row.

StockLevel is maintained as a per-(item, location, stockType) physical/logical balance cache derived from InventoryLedger. Reservation (`createStockReservation` / `updateStockReservation` / `closeStockReservation`) updates StockReservation instead of StockLevel and does not produce ledger entries, because reservations represent source-line demand commitments against site-level available stock rather than physical movement. Issue execution consumes reservations internally. Site-level availability is computed as the sum of `StockLevel(stockType=AVAILABLE)` across active site locations minus OPEN reservation quantity for the item and site, where open reservation quantity is `max(reservedQuantity - consumedQuantity, 0)`.

Inventory valuation is included because cost-per-unit is intrinsically tied to inventory transactions (receipt costs, adjustment impacts). CostLayer references InventoryLedger for accurate cost traceability. However, posting journal entries to the general ledger is excluded -- that responsibility belongs to the financial-accounting module. Inventory will emit valuation events for downstream consumption.

## Module Dependencies

- [item-management](../item-management/README.md) — Item entity as the primary trackable unit (itemId/SKU)
- [organization](../organization/README.md) — Company for multi-company scoping, Site for physical facility (address, and parent of StorageLocation)
- [primitives](../primitives/README.md) — Unit of Measure for stock quantities, Currency for valuation amounts
