diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index a8ea357bfd..77c816cf99 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,13 +1,16 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 237 +INVENTREE_API_VERSION = 238 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v238 - 2024-08-14 : https://github.com/inventree/InvenTree/pull/7874 + - Add "assembly" filter to BuildLine API endpoint + v237 - 2024-08-13 : https://github.com/inventree/InvenTree/pull/7863 - Reimplement "bulk delete" operation for Attachment model - Fix permission checks for Attachment API endpoints diff --git a/src/backend/InvenTree/build/api.py b/src/backend/InvenTree/build/api.py index e84ffe4396..f1e4b4db9d 100644 --- a/src/backend/InvenTree/build/api.py +++ b/src/backend/InvenTree/build/api.py @@ -290,6 +290,7 @@ class BuildLineFilter(rest_filters.FilterSet): # Fields on related models consumable = rest_filters.BooleanFilter(label=_('Consumable'), field_name='bom_item__consumable') optional = rest_filters.BooleanFilter(label=_('Optional'), field_name='bom_item__optional') + assembly = rest_filters.BooleanFilter(label=_('Assembly'), field_name='bom_item__sub_part__assembly') tracked = rest_filters.BooleanFilter(label=_('Tracked'), field_name='bom_item__sub_part__trackable') allocated = rest_filters.BooleanFilter(label=_('Allocated'), method='filter_allocated') diff --git a/src/backend/InvenTree/order/models.py b/src/backend/InvenTree/order/models.py index f79c615321..1a8124cf5c 100644 --- a/src/backend/InvenTree/order/models.py +++ b/src/backend/InvenTree/order/models.py @@ -1161,7 +1161,8 @@ class SalesOrder(TotalPriceMixin, Order): # Schedule pricing update for any referenced parts for line in self.lines.all(): - line.part.schedule_pricing_update(create=True) + if line.part: + line.part.schedule_pricing_update(create=True) trigger_event('salesorder.completed', id=self.pk) diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index b84b24f70e..465c7f6920 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -4509,7 +4509,8 @@ def update_pricing_after_edit(sender, instance, created, **kwargs): """Callback function when a part price break is created or updated.""" # Update part pricing *unless* we are importing data if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData(): - instance.part.schedule_pricing_update(create=True) + if instance.part: + instance.part.schedule_pricing_update(create=True) @receiver(post_delete, sender=BomItem, dispatch_uid='post_delete_bom_item') @@ -4525,7 +4526,8 @@ def update_pricing_after_delete(sender, instance, **kwargs): """Callback function when a part price break is deleted.""" # Update part pricing *unless* we are importing data if InvenTree.ready.canAppAccessDatabase() and not InvenTree.ready.isImportingData(): - instance.part.schedule_pricing_update(create=False) + if instance.part: + instance.part.schedule_pricing_update(create=False) class BomItemSubstitute(InvenTree.models.InvenTreeMetadataModel): diff --git a/src/backend/InvenTree/stock/models.py b/src/backend/InvenTree/stock/models.py index de8be1ce79..3008f77970 100644 --- a/src/backend/InvenTree/stock/models.py +++ b/src/backend/InvenTree/stock/models.py @@ -2293,7 +2293,8 @@ def after_delete_stock_item(sender, instance: StockItem, **kwargs): ) # Schedule an update on parent part pricing - instance.part.schedule_pricing_update(create=False) + if instance.part: + instance.part.schedule_pricing_update(create=False) @receiver(post_save, sender=StockItem, dispatch_uid='stock_item_post_save_log') @@ -2312,7 +2313,8 @@ def after_save_stock_item(sender, instance: StockItem, created, **kwargs): ) # Schedule an update on parent part pricing - instance.part.schedule_pricing_update(create=True) + if instance.part: + instance.part.schedule_pricing_update(create=True) class StockItemTracking(InvenTree.models.InvenTreeModel): diff --git a/src/frontend/src/components/nav/PanelGroup.tsx b/src/frontend/src/components/nav/PanelGroup.tsx index d4a6d3e57f..2077e4c58c 100644 --- a/src/frontend/src/components/nav/PanelGroup.tsx +++ b/src/frontend/src/components/nav/PanelGroup.tsx @@ -22,6 +22,7 @@ import { import { ModelType } from '../../enums/ModelType'; import { identifierString } from '../../functions/conversion'; +import { cancelEvent } from '../../functions/events'; import { navigateToLink } from '../../functions/navigation'; import { usePluginPanels } from '../../hooks/UsePluginPanels'; import { useLocalState } from '../../states/LocalState'; @@ -98,12 +99,12 @@ function BasePanelGroup({ const handlePanelChange = useCallback( (panel: string | null, event?: any) => { if (activePanels.findIndex((p) => p.name === panel) === -1) { - setLastUsedPanel(''); - return navigate('../'); + panel = ''; } if (event && (event?.ctrlKey || event?.shiftKey)) { const url = `${location.pathname}/../${panel}`; + cancelEvent(event); navigateToLink(url, navigate, event); } else { navigate(`../${panel}`); @@ -137,12 +138,7 @@ function BasePanelGroup({ return ( - + {allPanels.map( (panel) => @@ -156,7 +152,6 @@ function BasePanelGroup({ )} // Enable when implementing Icon manager everywhere leftSection={panel.icon} hidden={panel.hidden} disabled={panel.disabled} diff --git a/src/frontend/src/forms/PartForms.tsx b/src/frontend/src/forms/PartForms.tsx index b6145ab553..8b93a65f86 100644 --- a/src/frontend/src/forms/PartForms.tsx +++ b/src/frontend/src/forms/PartForms.tsx @@ -13,6 +13,8 @@ export function usePartFields({ }: { create?: boolean; }): ApiFormFieldSet { + const settings = useGlobalSettingsState.getState(); + return useMemo(() => { const fields: ApiFormFieldSet = { category: { @@ -93,8 +95,6 @@ export function usePartFields({ }; } - const settings = useGlobalSettingsState.getState(); - if (settings.isSet('PART_REVISION_ASSEMBLY_ONLY')) { fields.revision_of.filters['assembly'] = true; } @@ -111,7 +111,7 @@ export function usePartFields({ } return fields; - }, [create]); + }, [create, settings]); } /** diff --git a/src/frontend/src/pages/build/BuildDetail.tsx b/src/frontend/src/pages/build/BuildDetail.tsx index 9438b39650..2e1148a337 100644 --- a/src/frontend/src/pages/build/BuildDetail.tsx +++ b/src/frontend/src/pages/build/BuildDetail.tsx @@ -95,6 +95,14 @@ export default function BuildDetail() { label: t`Part`, model: ModelType.part }, + { + type: 'text', + name: 'part_detail.IPN', + icon: 'part', + label: t`IPN`, + hidden: !build.part_detail?.IPN, + copy: true + }, { type: 'status', name: 'status', @@ -104,13 +112,15 @@ export default function BuildDetail() { { type: 'text', name: 'reference', - label: t`Reference` + label: t`Reference`, + copy: true }, { type: 'text', name: 'title', label: t`Description`, - icon: 'description' + icon: 'description', + copy: true }, { type: 'link', diff --git a/src/frontend/src/tables/bom/BomTable.tsx b/src/frontend/src/tables/bom/BomTable.tsx index a065c73aeb..c10c5db790 100644 --- a/src/frontend/src/tables/bom/BomTable.tsx +++ b/src/frontend/src/tables/bom/BomTable.tsx @@ -307,7 +307,7 @@ export function BomTable({ { name: 'sub_part_assembly', label: t`Assembled Part`, - description: t`Show asssmbled items` + description: t`Show assembled items` }, { name: 'available_stock', diff --git a/src/frontend/src/tables/build/BuildLineTable.tsx b/src/frontend/src/tables/build/BuildLineTable.tsx index f51e5d711a..7d5487efbe 100644 --- a/src/frontend/src/tables/build/BuildLineTable.tsx +++ b/src/frontend/src/tables/build/BuildLineTable.tsx @@ -56,6 +56,11 @@ export default function BuildLineTable({ label: t`Optional`, description: t`Show optional lines` }, + { + name: 'assembly', + label: t`Assembly`, + description: t`Show assembled items` + }, { name: 'tracked', label: t`Tracked`, diff --git a/src/frontend/src/tables/build/BuildOrderTable.tsx b/src/frontend/src/tables/build/BuildOrderTable.tsx index 18ff6f4f05..2041bd0915 100644 --- a/src/frontend/src/tables/build/BuildOrderTable.tsx +++ b/src/frontend/src/tables/build/BuildOrderTable.tsx @@ -43,6 +43,12 @@ function buildOrderTableColumns(): TableColumn[] { switchable: false, render: (record: any) => PartColumn(record.part_detail) }, + { + accessor: 'part_detail.IPN', + sortable: true, + switchable: true, + title: t`IPN` + }, { accessor: 'title', sortable: false