models:
- name: Scrap
collection: scraps
read_only: true
description: "A scrap (disposal) record — moves a quantity to a scrap location via a scrapped stock move minted and validated through the ONE move engine (the move is the load-bearing artifact, stored on move_id)"
fields:
id:
type: uuid
attributes: ["@id", "@default(uuid)"]
description: "Unique scrap identifier"
name:
type: string
attributes: ["@required", "@max(40)", "@default(\"/\")"]
description: "Reference (sequence-filled; unique per org unit)"
state:
type: ScrapState
attributes: ["@default(draft)"]
lifecycle: hand_set
description: "draft / done — flipped to done by the scrap door's action_done; no cancel state (a wrong scrap is corrected by scrapping back / a return move, never by editing the row)"
origin:
type: string?
attributes: ["@max(200)"]
description: "Origin document reference"
date_expected:
type: datetime
attributes: ["@required", "@default(now)"]
description: "Expected processing date"
item_id:
type: uuid
attributes: ["@required", "@exclude_from_foreign_key_check"]
description: "The item being scrapped # logical FK to catalog.Item.id"
scrap_qty:
type: decimal
attributes: ["@required", "@default(1)", "@precision(18,4)"]
description: "Quantity to scrap (> 0 — the §8 positivity guard; the door refuses a non-positive quantity)"
location_id:
type: uuid
attributes: ["@required", "@foreign_key(Location.id)"]
description: "Source location (usage ≠ view; same org unit — R9-location posture)"
scrap_location_id:
type: uuid
attributes: ["@required", "@foreign_key(Location.id)"]
description: "Scrap destination (an inventory-loss / scrap usage location)"
lot_id:
type: uuid?
attributes: ["@foreign_key(Lot.id)"]
description: "Lot / serial of the scrapped stock"
package_id:
type: uuid?
attributes: ["@foreign_key(Package.id)"]
description: "Source package"
owner_id:
type: uuid?
attributes: ["@exclude_from_foreign_key_check"]
description: "Consignment owner # logical FK to party.Party.id"
picking_id:
type: uuid?
attributes: ["@foreign_key(Transfer.id)"]
description: "Optional linked picking"
move_id:
type: uuid?
attributes: ["@foreign_key(StockMove.id)"]
description: "The scrapped stock move minted and validated by the door (the actual mutation; set when state flips to done)"
scrap_reason_tag_ids:
type: uuid[]
description: "Reason tags # logical m2m to ScrapReasonTag.id (R7 keeps the labels unique)"
metadata:
type: Metadata
attributes: ["@audit_metadata"]
description: "Audit metadata"
indexes:
- type: index
fields: [state]
- type: index
fields: [item_id]
- type: index
fields: [picking_id]
- name: ScrapReasonTag
collection: scrap_reason_tags
description: "A reason tag for scrap records (unique label — guard R7, _name_uniq)"
fields:
id:
type: uuid
attributes: ["@id", "@default(uuid)"]
description: "Unique tag identifier"
name:
type: string
attributes: ["@required", "@max(150)"]
description: "Tag label (unique — guard R7, _name_uniq)"
active:
type: bool
attributes: ["@default(true)"]
description: "Archive support"
metadata:
type: Metadata
attributes: ["@audit_metadata"]
description: "Audit metadata"
indexes: []
enums:
- name: ScrapState
description: "stock.scrap.state — a trivial hand-set document lifecycle (draft → done, no cancel; ADR-0016 hand_set)"
variants:
- name: draft
description: "Recorded, not yet processed"
default: true
- name: done
description: "The scrapped move is validated (terminal — corrections are reversal moves)"