# Inventory Valuation

## Overview

Inventory Valuation calculates and tracks the monetary value of on-hand stock using configurable costing methods: FIFO (First In, First Out), Weighted Average Cost (AVCO), and Standard Cost. Each InventoryLedger entry -- created by atomic commands (receiveStock, issueStock) or by confirmStockAdjustment -- triggers a recalculation of cost-per-unit and total inventory value for the affected item. Source types that affect valuation include GOODS_RECEIPT, GOODS_ISSUE, CORRECTION, and SCRAP. BLOCK and UNBLOCK are internal transfers and do not affect valuation.

The valuation method is configured through ValuationPolicy — an entity owned by the inventory module that defines the costing strategy (FIFO, AVCO, or Standard Cost) and related parameters such as standard cost rate. Each item is associated with a ValuationPolicy, allowing operators to assign different costing strategies per item or group items under a shared policy by convention. When a valuation change occurs, the module emits events that downstream systems (such as accounting) can consume to create journal entries. The inventory module owns cost tracking, valuation configuration, and valuation calculation; general ledger posting is explicitly out of scope.

## Business Purpose

- **Financial reporting accuracy**: Maintain up-to-date inventory asset values for balance sheet reporting
- **Cost of Goods Sold (COGS) calculation**: Determine the cost assigned to goods issued or sold, using the configured costing method
- **Costing method flexibility**: Support multiple valuation strategies (FIFO, AVCO, Standard Cost) to meet different industry and regulatory requirements
- **Transaction-driven updates**: Automatically recalculate valuations on every InventoryLedger entry (triggered by atomic commands such as receiveStock/issueStock and by confirmStockAdjustment), eliminating manual revaluation effort
- **Audit trail**: Record cost-per-unit at the time of each transaction for traceability and variance analysis
- **Downstream integration**: Emit valuation events so accounting or other modules can create corresponding financial entries without tight coupling

## Process Flow

```mermaid
flowchart TD
    A[InventoryLedger Created] --> B{Transaction Type?}
    B -->|GOODS_RECEIPT| C[Record unit cost from receipt]
    B -->|GOODS_ISSUE| D[Calculate issue cost using costing method]
    B -->|CORRECTION / SCRAP| E[Apply cost impact based on transaction type]

    C --> G{Costing Method?}
    G -->|FIFO| H[Add receipt as new cost layer]
    G -->|AVCO| I[Recalculate weighted average cost]
    G -->|Standard Cost| J[Record at standard rate, capture variance]

    D --> K{Costing Method?}
    K -->|FIFO| L[Consume oldest cost layer first]
    K -->|AVCO| M[Issue at current average cost]
    K -->|Standard Cost| N[Issue at standard rate]

    H --> O[Update total valuation]
    I --> O
    J --> O
    L --> O
    M --> O
    N --> O
    E --> O

    O --> P[Emit valuation change event]
    P --> Q[Downstream systems consume event]
```

## Scenario Patterns

- **FIFO receipt and issue**: A goods receipt creates a new cost layer with the purchase unit cost and quantity. A subsequent goods issue consumes the oldest cost layer first; if that layer is exhausted, the next layer is used. This produces accurate COGS that reflects actual purchase prices in chronological order.
- **Weighted average receipt**: A goods receipt recalculates the average cost by combining the existing on-hand value with the new receipt value, then dividing by the total quantity. All subsequent issues use this updated average cost until the next receipt.
- **Standard cost with variance capture**: Goods are received and issued at a predefined standard cost. Any difference between the actual purchase price and the standard cost is recorded as a purchase price variance. Periodic revaluation can update the standard rate, producing a revaluation variance.
- **Inventory adjustment impact**: A positive adjustment (e.g., found stock) increases on-hand quantity at the current cost-per-unit. A negative adjustment (e.g., shrinkage) removes quantity and reduces total valuation, using the current costing method to determine the cost removed.
- **Scrap disposal**: Scrapped items are issued at their current cost-per-unit, reducing total inventory valuation. The valuation event includes the scrapped cost for downstream write-off accounting.

## Test Cases

- Given an item configured with FIFO costing, when 10 units are received at 100 currency and then 5 units at 120 currency, then issuing 12 units should consume all 10 units at 100 and 2 units at 120, producing a COGS of 1240
- Given an item configured with AVCO costing, when 10 units are received at 100 currency (total value 1000) and then 10 units are received at 200 currency, the average cost-per-unit should be 150
- Given an item configured with AVCO costing with an average cost of 150 per unit and 20 units on hand, when 5 units are issued, the issue cost should be 750 and remaining valuation should be 2250
- Given an item configured with standard cost of 50 per unit, when 10 units are received at an actual cost of 55 per unit, the inventory should be valued at 500 and a purchase price variance of 50 should be recorded
- Given a standard cost item, when the standard cost is updated from 50 to 60 with 100 units on hand, a revaluation event should be emitted with a variance of 1000
- Given any costing method, when an InventoryLedger entry updates the valuation, a valuation change event should be emitted containing the item identifier, old and new cost-per-unit, old and new total valuation, and the originating source reference (sourceType and sourceId)
- Given a negative inventory adjustment of 3 units for an AVCO item with a current average cost of 120, the total valuation should decrease by 360
- Given a FIFO item with two cost layers (5 units at 100, 5 units at 110), when all 10 units are scrapped, the total valuation removal should be 1050

## Reference Links

- [Inventory Module README](../../README.md) — module scope and dependency overview
- [Inventory Request](./inventory-request.md) — request types that trigger valuation updates
- [Inventory Adjustment](./inventory-adjustment.md) — adjustment scenarios with valuation impact
- [Scrap Management](./scrap-management.md) — scrap disposal and valuation write-off
