# `PhoenixKitWarehouse.Turnover`
[🔗](https://github.com/BeamLabEU/phoenix_kit_warehouse/blob/0.4.0/lib/phoenix_kit_warehouse/turnover.ex#L1)

Context for the warehouse turnover report (§8, no export — see
`Web.TurnoverReportLive`).

`compute/3` derives per-item inflow/outflow totals for a date window by
reading the `lines` of already-posted documents — `GoodsReceipt`,
`GoodsIssue`, `Transfer`, and `InventoryDocument` — there is no separate
ledger/journal table in the module to query instead.

Only items with nonzero `inflow` or `outflow` in the window are returned:
the base item set is the union of items appearing in a posted movement,
not every item with a `Stock` row — an item sitting untouched in the
warehouse for the whole period isn't part of a *movement* report. `balance`
is then looked up per item on top of that set, not the other way around.

## Wave-1 limitations

  - `balance` is the item's **current** on-hand quantity (from
    `StockLedger.stock_map/0` or `stock_map_for_location/1`), NOT a
    historical balance as of `date_to`. Reconstructing a point-in-time
    balance would require a ledger/journal of every stock-affecting event
    in order, which the module doesn't have — this is an accepted wave-1
    limitation, not a bug. Re-surface it in the UI (see
    `Web.TurnoverReportLive`), don't just document it here.
  - `balance` doesn't see stock "in transit" on an unfinished
    (`in_transit`) `Transfer` — same limitation as
    `Deficits.available_by_item/0`.
  - A `Transfer` that shipped (counted as outflow via `shipped_at`) and
    was LATER cancelled from `in_transit` — crediting the quantity back to
    the source, see `Transfers.cancel_transfer/2` — still counts as an
    outflow here if `shipped_at` falls in the window: the cancellation's
    reversal credit isn't a receipt, a transfer receive, or an inventory
    count, so it isn't one of the fields this report reads. Not
    compensated for in wave 1.
  - `posted_at` / `shipped_at` / `received_at` are not indexed on the
    underlying tables, so `compute/3`'s date-range scan gets slower as
    document volume grows. A known tech-debt item (to be recorded in
    `dev_docs/DEVELOPMENT_PLAN.md` — see T22), not fixed here.

# `compute`

Computes per-item turnover for the closed window `[date_from, date_to]`
(both `Date`, inclusive), optionally scoped to a single warehouse via
`location_uuid` (`nil` sums every warehouse).

Returns a list of `%{item_uuid:, name:, sku:, unit:, inflow:, outflow:,
balance:}`, `inflow`/`outflow`/`balance` all `Decimal`, one entry per item
that had a posted movement in the window (see moduledoc for exactly what
counts, and for the `balance` limitations).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
