# BillOfMaterial

## Description

BillOfMaterial stores the manufacturing-owned recipe used to build one finished item or subassembly at company or site scope. It owns version identity, effectivity, `bomType`, default-selection behavior, and the component-line structure that production orders later snapshot at release time.

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Draft: createBillOfMaterial
    Draft --> Draft: updateBillOfMaterial
    Draft --> Active: activateBillOfMaterial
    Active --> Inactive: deactivateBillOfMaterial
```

### Command Definitions

- [createBillOfMaterial](../commands/CreateBillOfMaterial.md) - Create a draft BOM version for one manufactured parent item.
- [updateBillOfMaterial](../commands/UpdateBillOfMaterial.md) - Revise mutable draft metadata, effectivity, and component lines.
- [activateBillOfMaterial](../commands/ActivateBillOfMaterial.md) - Validate the draft structure and make the version selectable for release.
- [deactivateBillOfMaterial](../commands/DeactivateBillOfMaterial.md) - Prevent future selection while preserving existing production-order snapshots.

### Query Definitions

- [getBillOfMaterial](../queries/GetBillOfMaterial.md) - Retrieve one BOM version with component lines and effectivity details.
- [explodeBillOfMaterial](../queries/ExplodeBillOfMaterial.md) - Expand one BOM version into multi-level component requirements on a specific effectivity date.
- [listBillOfMaterialsByItem](../queries/ListBillOfMaterialsByItem.md) - List BOM versions for one parent item and scope.
- [detectBillOfMaterialCircularReference](../queries/DetectBillOfMaterialCircularReference.md) - Detect direct or indirect loops across manufactured child items.

### Models

- BillOfMaterial
- BillOfMaterialLine

### Invariants

- Every BOM version belongs to exactly one manufactured parent item and one company, with optional site-specific scope.
- The parent item must be ACTIVE and manufacturable when the BOM is created or activated.
- `bomType` must always be one of `MANUFACTURE`, `PHANTOM`, or `KIT`.
- A draft or active BOM contains at least one component line with positive required quantity.
- Component lines may reference stocked items or manufactured subassemblies, but inactive items cannot appear as newly added components.
- Active BOM versions may only reference ACTIVE component items.
- An active BOM must not introduce a direct or indirect circular manufactured-item reference.
- Overlapping active effectivity windows for the same parent item and scope are allowed only when default-selection rules keep the active version unambiguous.
- Production-order release snapshots the selected BOM version, lines, and `bomType` semantics so later BOM edits never mutate released work.

### Relationships

- **References Item (cross-module)**: `parentItemId` and component `itemId` point to [Item](../../../item-management/docs/models/Item.md).
- **Belongs To Company and optional Site**: scope is constrained by [Company](../../../organization/docs/models/Company.md) and optionally [Site](../../../organization/docs/models/Site.md).
- **Has Many BillOfMaterialLines**: component structure, scrap assumptions, and subassembly references live under the parent BOM version.
- **Referenced By ProductionOrder**: [ProductionOrder](./ProductionOrder.md) resolves and snapshots one active BOM version at release.
- **Depends On primitives**: component and parent quantities use primitives-owned unit-of-measure compatibility.
