BOMs
List BOMs
Paginated list of BOMs. Supports Spatie filters (status, product_id, search) and sort.
Create BOM
Create a new BOM with output lines, component lines, and (optional) operations.
Bulk Delete BOMs
Permanently delete multiple BOMs in one call.
Get BOM
Get a single BOM with its product, component lines, output lines, operations (with work centers), and creator, plus `manufacturing_orders_count`.
Update BOM
Update a BOM. All fields are optional — omitted fields keep their current values.
Delete BOM
Delete BOM
Duplicate BOM
Deep-clones a BOM into a new draft (output lines, component lines, operations). The new BOM's name is the source's name with ' (Copy)' appended; if that name is already taken for the same product/variant the suffix becomes ' (Copy 2)', ' (Copy 3)', etc.
Save BOM as New Version
Create a new version of the BOM from the submitted fields, leaving the source version untouched. Accepts the same fields as Update BOM. The new version is created as Active with version_number set to the next number for the same product/variant.
Activate BOM
Transitions a draft BOM to active. Optionally overrides effective dates.
Deactivate BOM
Transitions an Active BOM back to Draft so it can be edited without archiving it (distinct from Archive, which retires the BOM). If the BOM was the default for its product/variant, the next eligible BOM is auto-promoted. Returns the refreshed BOM object under `data` (200), plus a root-level `promoted_default` object ({id, name, version_number}) naming the newly-promoted default — or `null` if nothing was promoted. The optional `reason` (nullable string, max 1000) is recorded on the BOM activity log.
Archive BOM
Archives an Active BOM, marking it as retired (sets `archived_at`). If the archived BOM was the default for its product/variant, the next eligible BOM is auto-promoted to default. Returns the refreshed BOM object under `data` (200), plus a root-level `promoted_default` object ({id, name, version_number}) naming the newly-promoted default — or `null` if nothing was promoted. The frontend uses this to show 'BOM archived — {name} v{version} is now the default'. The optional `reason` (nullable string, max 1000) is recorded on the BOM activity log.
Restore BOM
Restores an archived BOM back to Draft status. Clears `archived_at` and removes the `is_default` flag so it does not auto-promote on next activation. The caller can then re-activate from Draft when ready. Returns the refreshed BOM object (200). Returns 500 if the BOM is not currently archived. The optional `reason` (nullable string, max 1000) is recorded on the BOM activity log.
Bulk Archive BOMs
Archives multiple BOMs in one call. Body: `ids` (required array of BOM IDs, min 1; each must exist in `boms`). Only BOMs currently in `active` status are archived; BOMs in any other status are skipped. Each archived BOM that was a default triggers auto-promotion of the next eligible BOM for its product/variant. Returns a `message` summary and a `data` object: `{ totalCount, archivedCount, skippedCount, failCount }`.
Bulk Restore BOMs
Restores multiple archived BOMs back to Draft in one call. Body: `ids` (required array of BOM IDs, min 1; each must exist in `boms`). Only BOMs currently in `archived` status are restored; BOMs in any other status are skipped. Returns a `message` summary and a `data` object: `{ totalCount, restoredCount, skippedCount, failCount }`.
Set BOM as Default
Promotes the given BOM to be the default for its product/variant. Any other BOM currently marked default for the same product (and variant, if scoped) is automatically demoted to `is_default = false`. This is the single-record endpoint backing the kebab 'Set as Default' action; for status transitions use `activate`/`archive` instead. Returns the refreshed BOM object (200). No request body is required.
Get Current Default for BOM
Returns the BOM currently marked default for the same product/variant as the given BOM, excluding the given BOM itself. Used by the UI to name the existing default in a 'Set as Default' confirmation dialog (e.g. 'This will replace 'Vanilla Latte v2' as the default.'). Returns `{ 'data': { id, name, version_number } }` when another default exists; returns `{ 'data': null }` when there is no other default for that product/variant.
Explode BOM
Recursively explodes a BOM into its full multi-level component list for a target quantity.
List BOM Activity Log
Paginated audit trail of changes made to the BOM and its lines - who changed what and when, newest first.