mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-18 02:36:31 +00:00
[UI] Build page tweak (#10027)
* Hide "consumed stock" panel if not required * Docs updates * Hide allocation fields if the build has no required parts * Additional serializer options
This commit is contained in:
@@ -119,14 +119,33 @@ The *Build Details* panel provides an overview of the Build Order:
|
|||||||
|
|
||||||
{{ image ("build/build_panel_details.png", title="Build Details") }}
|
{{ 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") }}
|
{{ 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.
|
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
|
### Incomplete Outputs
|
||||||
|
|
||||||
The *Incomplete Outputs* panel shows the list of in-progress [build outputs](./output.md) (created stock items) associated with this build.
|
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:
|
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
|
### Child Builds
|
||||||
|
|
||||||
If there exist any build orders which are *children* of the selected build order, they are displayed in the *Child Builds* tab:
|
If there exist any build orders which are *children* of the selected build order, they are displayed in the *Child Builds* tab:
|
||||||
|
@@ -532,8 +532,10 @@ class BuildLineEndpoint:
|
|||||||
try:
|
try:
|
||||||
params = self.request.query_params
|
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['part_detail'] = str2bool(params.get('part_detail', True))
|
||||||
kwargs['build_detail'] = str2bool(params.get('build_detail', False))
|
kwargs['build_detail'] = str2bool(params.get('build_detail', False))
|
||||||
|
kwargs['allocations'] = str2bool(params.get('allocations', True))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@@ -1328,19 +1328,27 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Determine which extra details fields should be included."""
|
"""Determine which extra details fields should be included."""
|
||||||
part_detail = kwargs.pop('part_detail', True)
|
part_detail = kwargs.pop('part_detail', True)
|
||||||
|
bom_item_detail = kwargs.pop('bom_item_detail', True)
|
||||||
build_detail = kwargs.pop('build_detail', True)
|
build_detail = kwargs.pop('build_detail', True)
|
||||||
|
allocations = kwargs.pop('allocations', True)
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
if isGeneratingSchema():
|
if isGeneratingSchema():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not bom_item_detail:
|
||||||
|
self.fields.pop('bom_item_detail', None)
|
||||||
|
|
||||||
if not part_detail:
|
if not part_detail:
|
||||||
self.fields.pop('part_detail', None)
|
self.fields.pop('part_detail', None)
|
||||||
|
|
||||||
if not build_detail:
|
if not build_detail:
|
||||||
self.fields.pop('build_detail', None)
|
self.fields.pop('build_detail', None)
|
||||||
|
|
||||||
|
if not allocations:
|
||||||
|
self.fields.pop('allocations', None)
|
||||||
|
|
||||||
# Build info fields
|
# Build info fields
|
||||||
build_reference = serializers.CharField(
|
build_reference = serializers.CharField(
|
||||||
source='build.reference', label=_('Build Reference'), read_only=True
|
source='build.reference', label=_('Build Reference'), read_only=True
|
||||||
|
@@ -2,6 +2,7 @@ import { t } from '@lingui/core/macro';
|
|||||||
import { Alert, Grid, Skeleton, Stack, Text } from '@mantine/core';
|
import { Alert, Grid, Skeleton, Stack, Text } from '@mantine/core';
|
||||||
import {
|
import {
|
||||||
IconChecklist,
|
IconChecklist,
|
||||||
|
IconCircleCheck,
|
||||||
IconClipboardCheck,
|
IconClipboardCheck,
|
||||||
IconClipboardList,
|
IconClipboardList,
|
||||||
IconInfoCircle,
|
IconInfoCircle,
|
||||||
@@ -19,6 +20,7 @@ import { ModelType } from '@lib/enums/ModelType';
|
|||||||
import { UserRoles } from '@lib/enums/Roles';
|
import { UserRoles } from '@lib/enums/Roles';
|
||||||
import { apiUrl } from '@lib/functions/Api';
|
import { apiUrl } from '@lib/functions/Api';
|
||||||
import { getDetailUrl } from '@lib/functions/Navigation';
|
import { getDetailUrl } from '@lib/functions/Navigation';
|
||||||
|
import type { ApiFormFieldSet } from '@lib/types/Forms';
|
||||||
import AdminButton from '../../components/buttons/AdminButton';
|
import AdminButton from '../../components/buttons/AdminButton';
|
||||||
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
|
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
|
||||||
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
||||||
@@ -130,6 +132,10 @@ export default function BuildDetail() {
|
|||||||
endpoint: ApiEndpoints.build_line_list,
|
endpoint: ApiEndpoints.build_line_list,
|
||||||
params: {
|
params: {
|
||||||
build: id,
|
build: id,
|
||||||
|
allocations: false,
|
||||||
|
part_detail: false,
|
||||||
|
build_detail: false,
|
||||||
|
bom_item_detail: false,
|
||||||
limit: 1
|
limit: 1
|
||||||
},
|
},
|
||||||
disabled: !id,
|
disabled: !id,
|
||||||
@@ -417,7 +423,8 @@ export default function BuildDetail() {
|
|||||||
icon: <IconList />,
|
icon: <IconList />,
|
||||||
hidden:
|
hidden:
|
||||||
build.status == buildStatus.COMPLETE ||
|
build.status == buildStatus.COMPLETE ||
|
||||||
build.status == buildStatus.CANCELLED,
|
build.status == buildStatus.CANCELLED ||
|
||||||
|
(buildLineData?.count ?? 0) <= 0, // Hide if no required parts
|
||||||
content: (
|
content: (
|
||||||
<BuildAllocationsPanel
|
<BuildAllocationsPanel
|
||||||
build={build}
|
build={build}
|
||||||
@@ -430,6 +437,7 @@ export default function BuildDetail() {
|
|||||||
name: 'consumed-stock',
|
name: 'consumed-stock',
|
||||||
label: t`Consumed Stock`,
|
label: t`Consumed Stock`,
|
||||||
icon: <IconListCheck />,
|
icon: <IconListCheck />,
|
||||||
|
hidden: (buildLineData?.count ?? 0) <= 0, // Hide if no required parts
|
||||||
content: (
|
content: (
|
||||||
<StockItemTable
|
<StockItemTable
|
||||||
allowAdd={false}
|
allowAdd={false}
|
||||||
@@ -590,17 +598,33 @@ export default function BuildDetail() {
|
|||||||
successMessage: t`Order issued`
|
successMessage: t`Order issued`
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const completeOrderFields: ApiFormFieldSet = useMemo(() => {
|
||||||
|
const hasBom = (buildLineData?.count ?? 0) > 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
accept_overallocated: {
|
||||||
|
hidden: !hasBom
|
||||||
|
},
|
||||||
|
accept_unallocated: {
|
||||||
|
hidden: !hasBom
|
||||||
|
},
|
||||||
|
accept_incomplete: {}
|
||||||
|
};
|
||||||
|
}, [buildLineData.count]);
|
||||||
|
|
||||||
const completeOrder = useCreateApiFormModal({
|
const completeOrder = useCreateApiFormModal({
|
||||||
url: apiUrl(ApiEndpoints.build_order_complete, build.pk),
|
url: apiUrl(ApiEndpoints.build_order_complete, build.pk),
|
||||||
title: t`Complete Build Order`,
|
title: t`Complete Build Order`,
|
||||||
onFormSuccess: refreshInstance,
|
onFormSuccess: refreshInstance,
|
||||||
preFormWarning: t`Mark this order as complete`,
|
preFormContent: (
|
||||||
|
<Alert
|
||||||
|
color='green'
|
||||||
|
icon={<IconCircleCheck />}
|
||||||
|
title={t`Mark this order as complete`}
|
||||||
|
/>
|
||||||
|
),
|
||||||
successMessage: t`Order completed`,
|
successMessage: t`Order completed`,
|
||||||
fields: {
|
fields: completeOrderFields
|
||||||
accept_overallocated: {},
|
|
||||||
accept_unallocated: {},
|
|
||||||
accept_incomplete: {}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const buildActions = useMemo(() => {
|
const buildActions = useMemo(() => {
|
||||||
|
Reference in New Issue
Block a user