diff --git a/docs/docs/manufacturing/build.md b/docs/docs/manufacturing/build.md
index 0b8ae2fb0c..ae4b9bf8e9 100644
--- a/docs/docs/manufacturing/build.md
+++ b/docs/docs/manufacturing/build.md
@@ -119,14 +119,33 @@ The *Build Details* panel provides an overview of the Build Order:
{{ image ("build/build_panel_details.png", title="Build Details") }}
-### Line Items
+### Required Parts
-The *Line Items* panel displays all the line items (as defined by the [bill of materials](./bom.md)) required to complete the build order.
+The *Required Parts* panel displays all the line items (as defined by the [bill of materials](./bom.md)) required to complete the build order.
{{ image("build/build_panel_line_items.png", title="Line Items") }}
The allocation table (as shown above) provides an interface to allocate required stock, and also shows the stock allocation progress for each line item in the build.
+### Allocated Stock
+
+The *Allocated Stock* tab displays all stock items which have been *allocated* to this build order. These stock items are reserved for this build, and will be consumed when the build is completed:
+
+{{ image("build/allocated_stock_table.png", title="Allocated Stock Table") }}
+
+!!! info "No BOM"
+ If the part being built does not have a BOM, then the *Allocated Stock* tab will not be displayed.
+
+### Consumed Stock
+
+The *Consumed Stock* tab displays all stock items which have been *consumed* by this build order. These stock items remain in the database after the build order has been completed, but are no longer available for use.
+
+- [Tracked stock items](./allocate.md#tracked-stock) are consumed by specific build outputs
+- [Untracked stock items](./allocate.md#untracked-stock) are consumed by the build order
+
+!!! info "No BOM"
+ If the part being built does not have a BOM, then the *Consumed Stock* tab will not be displayed.
+
### Incomplete Outputs
The *Incomplete Outputs* panel shows the list of in-progress [build outputs](./output.md) (created stock items) associated with this build.
@@ -144,19 +163,6 @@ The *Incomplete Outputs* panel shows the list of in-progress [build outputs](./o
This panel displays all the completed build outputs (stock items) which have been created by this build order:
-### Allocated Stock
-
-The *Allocated Stock* tab displays all stock items which have been *allocated* to this build order. These stock items are reserved for this build, and will be consumed when the build is completed:
-
-{{ image("build/allocated_stock_table.png", title="Allocated Stock Table") }}
-
-### Consumed Stock
-
-The *Consumed Stock* tab displays all stock items which have been *consumed* by this build order. These stock items remain in the database after the build order has been completed, but are no longer available for use.
-
-- [Tracked stock items](./allocate.md#tracked-stock) are consumed by specific build outputs
-- [Untracked stock items](./allocate.md#untracked-stock) are consumed by the build order
-
### Child Builds
If there exist any build orders which are *children* of the selected build order, they are displayed in the *Child Builds* tab:
diff --git a/src/backend/InvenTree/build/api.py b/src/backend/InvenTree/build/api.py
index 42e5f4f1b2..ad0f229443 100644
--- a/src/backend/InvenTree/build/api.py
+++ b/src/backend/InvenTree/build/api.py
@@ -532,8 +532,10 @@ class BuildLineEndpoint:
try:
params = self.request.query_params
+ kwargs['bom_item_detail'] = str2bool(params.get('bom_item_detail', True))
kwargs['part_detail'] = str2bool(params.get('part_detail', True))
kwargs['build_detail'] = str2bool(params.get('build_detail', False))
+ kwargs['allocations'] = str2bool(params.get('allocations', True))
except AttributeError:
pass
diff --git a/src/backend/InvenTree/build/serializers.py b/src/backend/InvenTree/build/serializers.py
index b52192fa99..f16e029b91 100644
--- a/src/backend/InvenTree/build/serializers.py
+++ b/src/backend/InvenTree/build/serializers.py
@@ -1328,19 +1328,27 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
def __init__(self, *args, **kwargs):
"""Determine which extra details fields should be included."""
part_detail = kwargs.pop('part_detail', True)
+ bom_item_detail = kwargs.pop('bom_item_detail', True)
build_detail = kwargs.pop('build_detail', True)
+ allocations = kwargs.pop('allocations', True)
super().__init__(*args, **kwargs)
if isGeneratingSchema():
return
+ if not bom_item_detail:
+ self.fields.pop('bom_item_detail', None)
+
if not part_detail:
self.fields.pop('part_detail', None)
if not build_detail:
self.fields.pop('build_detail', None)
+ if not allocations:
+ self.fields.pop('allocations', None)
+
# Build info fields
build_reference = serializers.CharField(
source='build.reference', label=_('Build Reference'), read_only=True
diff --git a/src/frontend/src/pages/build/BuildDetail.tsx b/src/frontend/src/pages/build/BuildDetail.tsx
index ac850c4f54..646de48483 100644
--- a/src/frontend/src/pages/build/BuildDetail.tsx
+++ b/src/frontend/src/pages/build/BuildDetail.tsx
@@ -2,6 +2,7 @@ import { t } from '@lingui/core/macro';
import { Alert, Grid, Skeleton, Stack, Text } from '@mantine/core';
import {
IconChecklist,
+ IconCircleCheck,
IconClipboardCheck,
IconClipboardList,
IconInfoCircle,
@@ -19,6 +20,7 @@ import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { getDetailUrl } from '@lib/functions/Navigation';
+import type { ApiFormFieldSet } from '@lib/types/Forms';
import AdminButton from '../../components/buttons/AdminButton';
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
@@ -130,6 +132,10 @@ export default function BuildDetail() {
endpoint: ApiEndpoints.build_line_list,
params: {
build: id,
+ allocations: false,
+ part_detail: false,
+ build_detail: false,
+ bom_item_detail: false,
limit: 1
},
disabled: !id,
@@ -417,7 +423,8 @@ export default function BuildDetail() {
icon: ,
hidden:
build.status == buildStatus.COMPLETE ||
- build.status == buildStatus.CANCELLED,
+ build.status == buildStatus.CANCELLED ||
+ (buildLineData?.count ?? 0) <= 0, // Hide if no required parts
content: (
,
+ hidden: (buildLineData?.count ?? 0) <= 0, // Hide if no required parts
content: (
{
+ const hasBom = (buildLineData?.count ?? 0) > 0;
+
+ return {
+ accept_overallocated: {
+ hidden: !hasBom
+ },
+ accept_unallocated: {
+ hidden: !hasBom
+ },
+ accept_incomplete: {}
+ };
+ }, [buildLineData.count]);
+
const completeOrder = useCreateApiFormModal({
url: apiUrl(ApiEndpoints.build_order_complete, build.pk),
title: t`Complete Build Order`,
onFormSuccess: refreshInstance,
- preFormWarning: t`Mark this order as complete`,
+ preFormContent: (
+ }
+ title={t`Mark this order as complete`}
+ />
+ ),
successMessage: t`Order completed`,
- fields: {
- accept_overallocated: {},
- accept_unallocated: {},
- accept_incomplete: {}
- }
+ fields: completeOrderFields
});
const buildActions = useMemo(() => {