FinishedGoodsInventory
Owns the finished-goods inventory ledger (append-only event log) and the derived current-stock view. Parallel structure to MaterialsInventory — same shape, different table, different event types.
Tables owned
| Table | Purpose |
|---|---|
org.finished_goods_inventory_ledger | Append-only event log. Columns include event_type, sku_id, location_id, quantity, ref, event_date, notes. |
Operations
Writes
recordReceipt(conn, input)→LedgerEntry.event_type = RECEIVE. Used by FG-target PO receipts and transfer completion.input:{ skuId, locationId, quantity, ref, eventDate, notes? }.recordOrder(conn, input)→LedgerEntry.event_type = ORDER. Records expected inbound from FG-target PO placement, or expected output from a WO atPlaced/Production.recordProduction(conn, input)→LedgerEntry.event_type = PRODUCE. Used by WO receipts (alongsiderecordConsumptionon the materials side). Distinct fromRECEIVEso reporting can separate purchased FG from in-house production.recordDemand(conn, input)→LedgerEntry.event_type = DEMAND. Used at SO creation (and on WO creation for SKU sub-assembly inputs).recordAllocation(conn, input)→LedgerEntry.event_type = ALLOCATE. Used as an SO transitions toEntered, or a WO toProduction.recordConsumption(conn, input)→LedgerEntry.event_type = CONSUME. Used on SO ship and on WO receipts for SKU sub-assembly inputs.recordTransfer(conn, input)→{ ledgerEntry: LedgerEntry, ref: string }.event_type = TRANSFER. Storesto_location_idand carriesunit_costforward to the paired RECEIVE. Auto-generates aTFR-FG-xxxref.recordAdjustment(conn, input)→LedgerEntry.event_type = ADJUST.refnull.recordDisposal(conn, input)→LedgerEntry.event_type = DISPOSE.refnull.
Writes — reversals
Append-only. Same shape as the materials-side reversals; each op takes the original entry id and writes a paired reverse row (positive quantity, direction encoded in event_type, source_type and source_id copied from the original).
recordReverseOrder(conn, { originalEntryId, eventDate? })→LedgerEntry.event_type = REVERSE_ORDER. Used by PO and WO cancellation.recordReverseReceive(conn, { originalEntryId, eventDate? })→LedgerEntry.event_type = REVERSE_RECEIVE. Used by FG-target PO receipt delete and transfer reversal.recordReverseProduce(conn, { originalEntryId, eventDate? })→LedgerEntry.event_type = REVERSE_PRODUCE. Used by WO receipt delete.recordReverseDemand(conn, { originalEntryId, eventDate? })→LedgerEntry.event_type = REVERSE_DEMAND. Used by SORejectedtransitions, SO delete, and WO cancellation.recordReverseAllocate(conn, { originalEntryId, eventDate? })→LedgerEntry.event_type = REVERSE_ALLOCATE. (Was namedrecordReleasein earlier drafts.)recordReverseConsume(conn, { originalEntryId, eventDate? })→LedgerEntry.event_type = REVERSE_CONSUME. Used by SO delete after shipment and WO receipt delete (sub-assembly inputs).recordReverseTransfer(conn, { originalEntryId, eventDate? })→LedgerEntry.event_type = REVERSE_TRANSFER. Used when an in-transit transfer is voided before completion.
Reads
getEntryById(conn, entryId)→LedgerEntry | null.listEntries(conn, filters?)→LedgerEntry[]. Filters:{ skuId?, locationId?, eventType?, refLike?, dateFrom?, dateTo? }.listEntriesByRef(conn, ref)→LedgerEntry[].getSummary(conn, filters?)→Array<{ skuId, locationId, onHand: string, demand: string, allocated: string, available: string }>. Aggregates by event-type rollup.getInTransitByDestination(conn, destinationLocationId)→Array<{ ref, skuId, quantity, sourceLocationId, sentDate }>. OpenTFR-FG-%transfers.
Notes
- Same single-writer rule as
MaterialsInventory— SO / WO / PO components never insert here directly. - Event type set is richer than the materials side (
DEMAND,ALLOCATE,PRODUCE, plus the shared ones, plus the matching reverses) because finished goods have an order-driven lifecycle materials don't. - Append-only. No
deleteEntryop. Cancellations write reverse rows;getSummarynets reverse pairs by default.