mirror of
https://github.com/inventree/InvenTree
synced 2025-07-25 12:54:23 +00:00
Merge branch 'master' into pui-plugins
This commit is contained in:
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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}
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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`,
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user