Merge branch 'master' into pui-plugins

This commit is contained in:
Oliver Walters
2024-08-14 09:57:08 +00:00
11 changed files with 46 additions and 21 deletions

View File

@ -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

View File

@ -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')

View File

@ -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)

View File

@ -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):

View File

@ -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):

View File

@ -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 (
<Boundary label={`PanelGroup-${pageKey}`}>
<Paper p="sm" radius="xs" shadow="xs">
<Tabs
value={panel}
orientation="vertical"
onChange={handlePanelChange}
keepMounted={false}
>
<Tabs value={panel} orientation="vertical" keepMounted={false}>
<Tabs.List justify="left">
{allPanels.map(
(panel) =>
@ -156,7 +152,6 @@ function BasePanelGroup({
<Tabs.Tab
p="xs"
value={panel.name}
// icon={(<InvenTreeIcon icon={panel.name}/>)} // Enable when implementing Icon manager everywhere
leftSection={panel.icon}
hidden={panel.hidden}
disabled={panel.disabled}

View File

@ -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]);
}
/**

View File

@ -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',

View File

@ -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',

View File

@ -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`,

View File

@ -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