2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-11-13 19:36:46 +00:00

[UI] BOM part category (#10772)

* Add "Category" column to BOM Table

* Enable sorting by category in BOM table

* Add Category column to Buildline table

* Add Category filter to BuildLineTable

* Adjust queryset prefetch

* Bump API version and update CHANGELOG
This commit is contained in:
Oliver
2025-11-05 10:04:28 +11:00
committed by GitHub
parent fc3d130888
commit dbb799a0e0
8 changed files with 60 additions and 4 deletions

View File

@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Adds "Category" columns to BOM and Build Item tables and APIs in [#10722](https://github.com/inventree/InvenTree/pull/10772)
### Changed ### Changed
### Removed ### Removed

View File

@@ -1,11 +1,15 @@
"""InvenTree API version information.""" """InvenTree API version information."""
# InvenTree API version # InvenTree API version
INVENTREE_API_VERSION = 422 INVENTREE_API_VERSION = 423
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" """Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """ INVENTREE_API_TEXT = """
v423 -> 2025-11-05 : https://github.com/inventree/InvenTree/pull/10772
- Adds "category_detail" field to BomItem API endpoints
- Adds "category_detail" field to BuildLine API endpoints
v422 -> 2025-11-03 : https://github.com/inventree/InvenTree/pull/10750 v422 -> 2025-11-03 : https://github.com/inventree/InvenTree/pull/10750
- Adds ability to search StockItem API by supplier SKU - Adds ability to search StockItem API by supplier SKU
- Adds ability to search StockItem API by manufacturer MPN - Adds ability to search StockItem API by manufacturer MPN

View File

@@ -597,6 +597,7 @@ class BuildLineList(
ordering_fields = [ ordering_fields = [
'part', 'part',
'allocated', 'allocated',
'category',
'consumed', 'consumed',
'reference', 'reference',
'quantity', 'quantity',
@@ -613,6 +614,7 @@ class BuildLineList(
'part': 'bom_item__sub_part__name', 'part': 'bom_item__sub_part__name',
'reference': 'bom_item__reference', 'reference': 'bom_item__reference',
'unit_quantity': 'bom_item__quantity', 'unit_quantity': 'bom_item__quantity',
'category': 'bom_item__sub_part__category__name',
'consumable': 'bom_item__consumable', 'consumable': 'bom_item__consumable',
'optional': 'bom_item__optional', 'optional': 'bom_item__optional',
'trackable': 'bom_item__sub_part__trackable', 'trackable': 'bom_item__sub_part__trackable',

View File

@@ -1339,6 +1339,7 @@ class BuildLineSerializer(
'bom_item_detail', 'bom_item_detail',
'assembly_detail', 'assembly_detail',
'part_detail', 'part_detail',
'category_detail',
'build_detail', 'build_detail',
] ]
read_only_fields = ['build', 'bom_item', 'allocations'] read_only_fields = ['build', 'bom_item', 'allocations']
@@ -1430,6 +1431,17 @@ class BuildLineSerializer(
True, True,
) )
category_detail = enable_filter(
part_serializers.CategorySerializer(
label=_('Category'),
source='bom_item.sub_part.category',
many=False,
read_only=True,
allow_null=True,
),
False,
)
build_detail = enable_filter( build_detail = enable_filter(
BuildSerializer( BuildSerializer(
label=_('Build'), label=_('Build'),
@@ -1505,6 +1517,7 @@ class BuildLineSerializer(
'bom_item', 'bom_item',
'bom_item__part', 'bom_item__part',
'bom_item__sub_part', 'bom_item__sub_part',
'bom_item__sub_part__category',
'bom_item__sub_part__stock_items', 'bom_item__sub_part__stock_items',
'bom_item__sub_part__stock_items__allocations', 'bom_item__sub_part__stock_items__allocations',
'bom_item__sub_part__stock_items__sales_order_allocations', 'bom_item__sub_part__stock_items__sales_order_allocations',

View File

@@ -1672,6 +1672,7 @@ class BomList(
ordering_fields = [ ordering_fields = [
'can_build', 'can_build',
'category',
'quantity', 'quantity',
'setup_quantity', 'setup_quantity',
'attrition', 'attrition',
@@ -1692,6 +1693,7 @@ class BomList(
] ]
ordering_field_aliases = { ordering_field_aliases = {
'category': 'sub_part__category__name',
'sub_part': 'sub_part__name', 'sub_part': 'sub_part__name',
'pricing_min': 'sub_part__pricing_data__overall_min', 'pricing_min': 'sub_part__pricing_data__overall_min',
'pricing_max': 'sub_part__pricing_data__overall_max', 'pricing_max': 'sub_part__pricing_data__overall_max',

View File

@@ -1668,13 +1668,11 @@ class BomItemSerializer(
'rounding_multiple', 'rounding_multiple',
'note', 'note',
'pk', 'pk',
'part_detail',
'pricing_min', 'pricing_min',
'pricing_max', 'pricing_max',
'pricing_min_total', 'pricing_min_total',
'pricing_max_total', 'pricing_max_total',
'pricing_updated', 'pricing_updated',
'sub_part_detail',
'substitutes', 'substitutes',
'validated', 'validated',
# Annotated fields describing available quantity # Annotated fields describing available quantity
@@ -1688,6 +1686,10 @@ class BomItemSerializer(
'building', 'building',
# Annotate the total potential quantity we can build # Annotate the total potential quantity we can build
'can_build', 'can_build',
# Optional detail fields
'part_detail',
'sub_part_detail',
'category_detail',
] ]
quantity = InvenTree.serializers.InvenTreeDecimalField(required=True) quantity = InvenTree.serializers.InvenTreeDecimalField(required=True)
@@ -1744,6 +1746,17 @@ class BomItemSerializer(
True, True,
) )
category_detail = enable_filter(
CategorySerializer(
source='sub_part.category',
label=_('Category'),
many=False,
read_only=True,
allow_null=True,
),
False,
)
on_order = serializers.FloatField( on_order = serializers.FloatField(
label=_('On Order'), read_only=True, allow_null=True label=_('On Order'), read_only=True, allow_null=True
) )

View File

@@ -42,6 +42,7 @@ import { useTable } from '../../hooks/UseTable';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { import {
BooleanColumn, BooleanColumn,
CategoryColumn,
DescriptionColumn, DescriptionColumn,
NoteColumn, NoteColumn,
ReferenceColumn ReferenceColumn
@@ -133,6 +134,13 @@ export function BomTable({
title: t`IPN`, title: t`IPN`,
sortable: true sortable: true
}, },
CategoryColumn({
accessor: 'category_detail',
defaultVisible: false,
switchable: true,
sortable: true,
ordering: 'category'
}),
DescriptionColumn({ DescriptionColumn({
accessor: 'sub_part_detail.description' accessor: 'sub_part_detail.description'
}), }),
@@ -662,6 +670,7 @@ export function BomTable({
params: { params: {
...params, ...params,
part: partId, part: partId,
category_detail: true,
part_detail: true, part_detail: true,
sub_part_detail: true sub_part_detail: true
}, },

View File

@@ -43,12 +43,14 @@ import { useTable } from '../../hooks/UseTable';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { import {
BooleanColumn, BooleanColumn,
CategoryColumn,
DecimalColumn, DecimalColumn,
DescriptionColumn, DescriptionColumn,
LocationColumn, LocationColumn,
PartColumn, PartColumn,
RenderPartColumn RenderPartColumn
} from '../ColumnRenderers'; } from '../ColumnRenderers';
import { PartCategoryFilter } from '../Filter';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
import RowExpansionIcon from '../RowExpansionIcon'; import RowExpansionIcon from '../RowExpansionIcon';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
@@ -214,7 +216,8 @@ export default function BuildLineTable({
name: 'tracked', name: 'tracked',
label: t`Tracked`, label: t`Tracked`,
description: t`Show tracked lines` description: t`Show tracked lines`
} },
PartCategoryFilter()
]; ];
}, []); }, []);
@@ -327,6 +330,13 @@ export default function BuildLineTable({
sortable: false, sortable: false,
title: t`IPN` title: t`IPN`
}, },
CategoryColumn({
accessor: 'category_detail',
defaultVisible: false,
switchable: true,
sortable: true,
ordering: 'category'
}),
DescriptionColumn({ DescriptionColumn({
accessor: 'part_detail.description' accessor: 'part_detail.description'
}), }),
@@ -947,6 +957,7 @@ export default function BuildLineTable({
...params, ...params,
build: build.pk, build: build.pk,
assembly_detail: false, assembly_detail: false,
category_detail: true,
part_detail: true part_detail: true
}, },
tableActions: tableActions, tableActions: tableActions,