# Scrap Management

## Overview

Scrap management handles the controlled removal of damaged, expired, defective, or obsolete stock from usable inventory. Scrap is modeled as an `InventoryAdjustment` with `adjustmentType = SCRAP`. When confirmed, the adjustment moves stock from the source storage location to a virtual "scrap" location, effectively removing it from available stock and reducing inventory valuation.

Organizations may enforce approval workflows for scrap adjustments that exceed a defined value threshold, ensuring proper oversight of material losses. Scrap adjustments follow the same approval workflow as correction adjustments (DRAFT → PENDING_APPROVAL → CONFIRMED). Once confirmed, the adjustment is immutable — if scrap was created in error, a new CORRECTION adjustment with a positive quantityDelta can restore the stock.

Inventory accepts scrap input both from direct inventory users and from upstream manufacturing execution. Manufacturing-originated scrap enters inventory through the `ManufacturingScrapHandoff` contract defined in manufacturing `work-order-execution.md`, after which inventory creates or updates the `InventoryAdjustment` that owns stock and valuation effects.

## Business Purpose

- Remove physically damaged, expired, or quality-rejected stock from available inventory so it is not accidentally picked, sold, or consumed
- Maintain accurate inventory valuation by writing off the cost of scrapped items at the time of disposal
- Provide an auditable trail of why, when, and by whom stock was disposed, supporting regulatory and internal compliance requirements
- Enable approval controls for high-value scrap events, preventing unauthorized write-offs
- Support root-cause analysis by categorizing scrap reasons (damage, expiration, quality failure, obsolescence), feeding continuous improvement initiatives
- Preserve lot and serial traceability through the scrap process for recall and warranty tracking

## Process Flow

```mermaid
flowchart TD
    A[Identify unusable stock] --> B[Create inventory adjustment with type=SCRAP]
    B --> C{Approval required?}
    C -- Yes --> D[Submit for approval]
    D --> E{Approved?}
    E -- Yes --> F[Confirm adjustment]
    E -- No --> G[Reject / return to draft]
    C -- No --> F
    F --> H[Move stock to virtual scrap location]
    H --> I[Adjust inventory valuation]
    I --> J[Scrap completed]
```

## Scenario Patterns

- **Damaged goods scrap**: Warehouse staff discover physically damaged items during handling or counting and create a SCRAP adjustment referencing the damage reason and source location
- **Expired stock disposal**: Items that have passed their expiration date are identified (often via lot tracking) and scrapped to clear them from available inventory
- **Quality failure scrap**: Items that fail incoming or in-process quality inspection are immediately scrapped, with the quality rejection linked as the scrap reason
- **Obsolescence write-off**: Slow-moving or discontinued items are scrapped as part of a periodic inventory review to reflect their true recoverable value
- **High-value approval scrap**: A scrap adjustment exceeds the organization's value threshold, triggering a manager approval step before the stock movement is executed
- **Manufacturing-originated scrap**: A work order reports scrap and sends `ManufacturingScrapHandoff`; inventory resolves the source location, creates a SCRAP adjustment, and runs the same approval policy as any other scrap event
- **Scrap error correction**: A scrap adjustment is found to have been created in error; a new CORRECTION adjustment with positive quantityDelta restores the stock to the source location
- **Lot/serial-tracked scrap**: Specific lots or serial numbers are scrapped, maintaining full traceability from receipt through disposal. Serial numbers transition to SCRAPPED state on confirmation.

Inventory accepts `ManufacturingScrapHandoff` from manufacturing work-order execution with the following minimum fields:

- `productionOrderReference`
- `workOrderReference`
- `itemReference`
- `scrapQuantity`
- `unitOfMeasure`
- `scrapReasonCode`
- `siteReference`
- `postingDate`

Optional and conditional fields:

- `sourceStorageLocationReference`: optional when inventory can derive the source location from prior issue, backflush, or site-level manufacturing scrap policy; otherwise required
- `inventoryLotReference`: required when the scrapped item is lot-tracked
- `serialReferences`: required when the scrapped item is serial-tracked
- `scrapDispositionCode`: optional classification retained for downstream analysis

Inventory maps the handoff into an inventory-owned `InventoryAdjustment` as follows:

- `adjustmentType = SCRAP`
- `itemReference`, `siteReference`, `postingDate`, and reason fields come directly from the handoff
- `productionOrderReference` and `workOrderReference` are retained as source-document traceability fields on the adjustment
- `sourceStorageLocationReference` is taken from the payload when present; otherwise inventory must derive it from manufacturing issue history, staging-location policy, or other site-level configuration before the adjustment can proceed
- `inventoryLotReference` and `serialReferences` flow into the same lot or serial validation rules used by direct inventory scrap

Approval and confirmation rules are inventory-owned:

- If the resulting scrap value exceeds the configured approval threshold, inventory creates the adjustment in `PENDING_APPROVAL`
- If the threshold is not exceeded, inventory may confirm the adjustment immediately
- If location, lot, serial, or quantity resolution fails, inventory rejects the handoff and does not mutate stock

## Test Cases

- Creating a SCRAP adjustment with positive quantityDelta is rejected
- Confirming a SCRAP adjustment removes the specified quantity from the source location's available stock
- Scrapped stock appears in the virtual scrap location and is excluded from available-to-promise calculations
- Inventory valuation decreases by the cost of the scrapped items upon confirmation
- SCRAP adjustments record the item, quantity, source location, reason, date, and responsible user
- When lot tracking is enabled, the scrap adjustment must reference a valid lot number with sufficient quantity
- When serial tracking is enabled, the scrap adjustment must reference specific serial numbers in the source location; serial transitions to SCRAPPED on confirmation
- SCRAP adjustments exceeding the configured value threshold require approval before confirmation
- Rejected SCRAP adjustments remain in draft and do not affect stock or valuation
- Scrapped items cannot re-enter available stock without a new CORRECTION adjustment
- Scrap reason is mandatory and must be one of the defined reason categories
- Listing adjustments filtered by `adjustmentType = SCRAP` returns only scrap records
- A valid `ManufacturingScrapHandoff` must create or update a SCRAP adjustment that preserves the production-order and work-order references for traceability
- Manufacturing-originated scrap must follow the same approval threshold policy as manually entered scrap adjustments
- If inventory cannot resolve the source storage location required for `ManufacturingScrapHandoff`, the handoff must be rejected without mutating stock

## Reference Links

- [Odoo Scrap Management](https://www.odoo.com/documentation/17.0/applications/inventory_and_mrp/inventory/warehouses_storage/removal_strategies.html)
- [SAP Movement Types 551/552 for Scrapping](https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/f7fddfe4caca43b4a511ab5e99f65567/e457ae2bbbf71014bfc0e6eee74504ce.html)
- [Oracle Inventory Scrap Transactions](https://docs.oracle.com/en/cloud/saas/supply-chain-and-manufacturing/25a/fammi/inventory-transactions.html)
