FIFO layer fields, statuses & enums
This page is the lookup for a FIFO layer — the costed batch of stock SKU.io creates every time inventory arrives — and for the revaluation ledger that records each change to a layer's cost. It defines every quantity, cost, and lot field on a layer; the columns you see on the FIFO layers list; the fields on a dated revaluation row; the availability lifecycle a layer moves through; the three enums that drive COGS sourcing, revaluation reasons, and layer allocation; and the guards that stop a layer from being written into an impossible state.
For the model behind these fields — how a layer is created, consumed, and how COGS is realized — read FIFO layers & how COGS is realized. For the difference between the three ways to change a layer's cost, read Correcting COGS: revalue vs rebuild vs recalculate.
Before you begin
- FIFO layers are derived, not entered. SKU.io mints and consumes them automatically as you receive stock, ship orders, transfer, and adjust. You never type a layer's quantities directly — you change them by adjusting stock, receiving a purchase order or transfer, or fulfilling an order, and the layer follows.
- The only fields you edit by hand are lot details (batch, expiry, notes) and a layer's cost, through Revalue COGS. Every cost change lands as a row in the revaluation ledger described below.
FIFO layer core fields
These are the quantity and cost fields on a FIFO layer. Two of them — Available quantity and Average cost — are database-generated columns: SKU.io computes them from the other fields and never writes them directly.
| Field | Type | What it holds |
|---|---|---|
| FIFO layer date | date-time | The layer's cost-effective date — when the stock landed. Drives FIFO consumption order (oldest date first). |
| Original quantity | number | The quantity the layer started with when it was created. Never negative. |
| Fulfilled quantity | number | How much of the layer has been consumed. A cache reconciled from the layer's active negative movements; never negative, and never more than Original quantity (see Write guards below). |
| Available quantity | number (generated) | Remaining uncosted-out stock: Original − Fulfilled. A stored generated column — read-only, refreshed after every save. |
| Total cost | number | The layer's full landed cost for its original quantity. |
| Average cost | number (generated) | Per-unit cost derived from Total cost and quantity. A stored generated column; it's NULL until the layer is refreshed after a save, which is why internal cost snapshots use Total cost ÷ Original quantity instead. |
| Cost breakdown | map | A per-category landed-cost map (for example freight, duty, handling) that sums to Total cost. Sliced proportionally when a layer is split. |
| Cost version | number | Increments by one on every revaluation. The revaluation ledger chains on it (see The revaluation ledger row). |
| Condition | text | The stock condition pool the layer belongs to (for example sellable vs. a damaged pool). |
| Warehouse | link | The warehouse holding the layer. Can't be a supplier warehouse (see Write guards). |
| Consignment | yes / no | When yes, the layer holds supplier-owned stock — cost-carrying for later COGS but excluded from inventory valuation and GL reconciliation. Surfaced as Consigned in stock states. |
Lot & expiry fields
A layer can also carry lot and expiry data, which drives FEFO (first-expiry-first-out) consumption, expiry reporting, and recall genealogy.
| Field | Type | What it holds |
|---|---|---|
| Batch number | text | The lot identifier. Optional. When a lot-tracked positive event leaves it blank, SKU.io stamps an AUTO--prefixed fallback so every lot-tracked layer carries a batch for FEFO and recall. |
| Manufacture date | date | When the lot was produced. |
| Expiry date | date | When the lot expires. Drives FEFO ordering and the expiry buckets in demand planning. |
| Lot notes | text | Free-text notes about the lot. |
| Actual unit weight | number | The measured per-unit weight for the lot, when captured. |
When you stamp lot details onto stock that came in un-lotted, SKU.io preserves cost exactly using one of three paths: it merges into an existing matching lot, stamps in place when the whole layer is being lotted and nothing has been consumed, or carves a new lot layer off the source and reduces the source by the exact carved cost and a proportional slice of the cost breakdown (rounded to four decimal places). A blank batch is treated as distinct in the unique key, so un-lotted layers never collide. See FIFO layers & how COGS is realized.
FIFO layer list & detail fields
The FIFO layers list shows these columns; the layer detail view exposes the full field set below (the API resource behind both).
List columns, in order: ID, Date, SKU, Product Name, Warehouse, Original Qty, Fulfilled Qty, Available Qty, Avg Cost, Total Cost, Origin, Created, Updated.
Additional detail fields:
| Field | What it holds |
|---|---|
| Days to expiry | A signed whole-day countdown to the expiry date — negative means already expired, null when the lot has no expiry. Computed date-only against your application timezone's "today". |
| Cost breakdown | The per-category landed-cost map (see core fields). |
| Origin | The polymorphic source that created the layer: its type (for example a purchase order receipt, transfer, adjustment, or manufacturing order), the linked record's ID, its human reference, and a parent reference where one exists. Rendered as a cross-linked chip with a tooltip showing the exact link type and ID. |
| Is FBA | Yes when the layer's warehouse is an Amazon FBA warehouse. |
| Is consignment | Yes when the layer holds consigned stock. |
| Condition | The stock condition pool. |
| Allocated quantity | How much of the layer is pinned to open orders (defaults to zero). See Browse allocations. |
| Archived at | The timestamp the layer was archived, or empty when active. |
The list and detail views show Available quantity as Original − Fulfilled computed on read, rather than reading the stored generated column. The two always agree; the recompute just guarantees a value even on a row that hasn't been refreshed since its last write.
The availability lifecycle
A layer's availability is described by two independent axes — an availability state derived from its quantities, and an archived flag. The FIFO layers list filters on both.
Availability state (the Availability filter):
| State | Meaning |
|---|---|
| Available | Has remaining stock: Original − Fulfilled is greater than zero. |
| Depleted | Fully consumed: Original − Fulfilled is zero or below. |
| Used | Has been drawn on at all: Fulfilled is above zero. |
| Unused | Never drawn on: Fulfilled is exactly zero. |
Available and Used overlap on purpose — a partially consumed layer is both. Choose Available to find layers you can still ship from; choose Depleted to find spent layers.
Archived axis (the All / Active / Archived toggle): archiving a layer hides it from the default (Active) view without deleting its cost history. The toggle switches between all layers, active-only, and archived-only.
A fully Depleted layer can be archived to tidy the list; its movement and cost history are kept. Archiving is reversible from the row's Unarchive action. A layer also auto-unarchives on save if it regains available quantity — so an archived layer that later receives stock back (for example a returned unit re-costed against it) quietly returns to the active view.
The revaluation ledger row
Every change to a layer's per-unit cost writes exactly one row to the revaluation ledger — the audit trail behind Revalue COGS and Rebuild COGS. Rows chain: each row's old unit cost equals the prior row's new unit cost, which is what makes point-in-time valuation and per-period GL reconciliation possible.
| Field | What it holds |
|---|---|
| Cost version before / after | The layer's cost version immediately before and after the change. After always advances by one past before; the write is serialized under a row lock so two concurrent revaluations can't mint the same version. |
| Old total cost / new total cost | The layer's full cost before and after. |
| Old unit cost / new unit cost | The per-unit cost before and after. A revaluation is skipped entirely when the rounded per-unit cost is unchanged. |
| Units on hand at time | The layer's available quantity when the row was written. |
| Units consumed at time | The layer's fulfilled quantity when the row was written. |
| COGS source | The valuation source that set the cost — a CogsSource value. |
| Reason | Why the cost changed — an InventoryRevaluationReason value. |
| Reason notes | Free-text detail supporting the reason. |
| Effective at | The accounting date the change takes effect. Honors the accounting lock date: if the natural date falls in a locked period, SKU.io moves it to the first open-period boundary so closed books are never rewritten. |
| Posted at | When the row was actually recorded (defaults to now). |
| User | The user who made the change, when a person made it (empty for automated paths). |
CogsSource enum
The COGS source records where a layer's cost came from. It's stored on each revaluation row and surfaced in the revalue UI and the SKU COGS Health dashboard. A source is either locked (backed by a document or an explicit user action, and treated as an actual cost) or editable (an estimate or fallback that automatic recalculation may update).
| Value | Label | Sourced from | Cost |
|---|---|---|---|
manual | Manual COGS Value | A user's explicit entry | Locked |
purchase_order_line | Purchase Order Value | The purchase order line's landed cost | Locked |
assembly_line | Assembly Line Value | The summed component costs of an assembly | Locked |
warehouse_transfer_shipment_line_weighted_average_cost | Warehouse Transfer Shipment Line | The transfer shipment line's weighted average | Locked |
sales_order_line_weighted_average_cost | Sales Order Line | The originating sales order line's weighted average (for a sales credit) | Locked |
initial_fnsku_product_cost | Initial FNSKU Product Cost | An FNSKU product's seeded initial cost | Locked |
awd_fifo_layer | AWD FIFO Layer | An Amazon AWD source layer | Locked |
awd_pending_inbound | AWD Pending Inbound | An in-flight AWD inbound | Locked |
oldest_active_fifo | Oldest Open Layer | The oldest still-available FIFO layer | Editable |
newest_closed_fifo | Newest Closed Layer | The most recent fully consumed layer | Editable |
unit_cost | Default Cost | The product's default unit cost | Editable |
amazon_fifo_layer | Amazon FIFO Layer | An Amazon FBA source layer | Editable |
amazon_weighted_average_cost | Amazon Weighted Average Cost | Amazon's reported weighted average | Editable |
none | None | No cost source resolved yet | Editable |
weighted_average_cost_cache, any_fifo, and supplier_pricing are retained so old layers and ledger rows that carry them still render, but SKU.io no longer produces them when it picks a cost automatically. You will only ever see them on historic records.
InventoryRevaluationReason enum
The reason explains why a cost changed and rides on every revaluation row.
| Value | Meaning | Set by |
|---|---|---|
market_value_adjustment | The cost was adjusted to reflect current market value. | Manual revaluation |
system_error | The cost is being corrected after a system or data error. | Manual revaluation |
other | Another reason — detail it in Reason notes. | Manual revaluation |
landed_cost_added | Landed cost (freight, duty, handling) was added after receipt. | Automated paths |
vendor_invoice_correction | The vendor invoice corrected the cost after the fact. | Automated paths |
When you revalue a layer by hand, the Revaluation Reason menu offers only Market Value Adjustment, System Error, and Other. landed_cost_added and vendor_invoice_correction are reserved for automated cost paths (landed-cost application and invoice corrections) and can't be chosen manually — so a hand revaluation you want to attribute to a late invoice should use Other with a note.
FifoLayerAllocationStrategy enum
When SKU.io distributes a consumption quantity across a product's available layers, it uses one of two strategies. FIFO is the default and the one that governs normal order fulfillment and adjustments.
| Value | Behavior |
|---|---|
fifo | Consume oldest layer first, walking forward by FIFO layer date until the quantity is satisfied. This is the default everywhere. |
qty_match | Prefer a single layer whose available quantity exactly matches the needed quantity; otherwise pick the layer with the most total capacity. Used when moving an existing usage onto an alternative layer rather than consuming fresh stock. |
Write guards
Two invariants are enforced whenever a layer is saved. Both raise an error rather than let a layer reach an impossible or nonsensical state.
Oversubscription guard. A save is rejected when Fulfilled quantity would exceed Original quantity (the layer would be consumed past what it holds), or when either quantity is negative. Because Fulfilled quantity is a cache reconciled from the layer's active negative movements, the cache-heal paths — which recompute it from the movements — are permitted to save with overage allowed so they can correct a drifted cache back into range. You can audit drifted or oversubscribed layers from the SKU COGS Health dashboard; the count of oversubscribed layers is one of its integrity signals.
Supplier-warehouse block. A layer can't be saved against a supplier warehouse — those warehouses model supplier-held stock you don't own, so they never carry owned FIFO cost. The save fails with a clear message naming the warehouse. This is also why manually receiving a channel-managed (Amazon FBA, AWD, or WFS) transfer is refused with an explanation rather than offered in the UI — that stock is costed through its channel path, not a manual owned-stock layer.
Next steps
- Browse & manage FIFO layers — find, filter, and archive layers.
- Revalue COGS (single, bulk & the COGS report) — change a layer's cost and write a ledger row.
- Rebuild COGS & the SKU COGS Health dashboard — repair drifted costs and caches in bulk.
- FIFO layers & how COGS is realized — the concept behind these fields.
- Correcting COGS: revalue vs rebuild vs recalculate — which correction to reach for.
- Stock states & fields reference — how layers roll up into on-hand, available, and consigned stock.