# ListStockLevels

## Overview

ListStockLevels lists stock levels filtered by item, storage location, or site. It supports multi-location visibility for transfer planning and stock inquiry. At least one filter must be provided.

## Business Rules

- Accepts optional filters (at least one required):
  - `itemId` — filter by specific item
  - `storageLocationId` — filter by specific storage location
  - `siteId` — filter by site, including all storage locations within that site
- Returns a list of StockLevel records, each with computed `availableQuantity` for AVAILABLE rows. This subtracts only location-specific open reservation quantity, derived as `max(reservedQuantity - consumedQuantity, 0)`; site-level unallocated reservations are reflected by getSiteStockSummary.
- When filtering by `siteId`, includes stock levels from all storage locations belonging to that site
- Returns an empty list if no matching records exist

## Process Flow

```mermaid
flowchart TD
    A[Receive filter criteria] --> B{Which filters provided?}
    B -->|itemId| C[SELECT from StockLevel where itemId matches]
    B -->|storageLocationId| D[SELECT from StockLevel where storageLocationId matches]
    B -->|siteId| E[Resolve all storageLocationIds in site]
    E --> F[SELECT from StockLevel where storageLocationId in resolved list]
    C --> G[Read location-specific StockReservation and compute availableQuantity for each record]
    D --> G
    F --> G
    G --> H{Records found?}
    H -->|Yes| I[Return list of StockLevel records]
    H -->|No| J[Return empty list]
```

## External Dependencies

- None

## Error Scenarios

- **NO_FILTER_PROVIDED**: At least one filter must be specified
- Returns empty list if no matching records exist

## Test Cases

- lists stock levels by item across all locations
- lists stock levels by storage location
- lists stock levels by site (aggregates all locations)
- returns empty list when no matches
- returns error when no filter is provided
- includes computed available quantity
- sums multiple open reservations per item and location
