mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
Build category filter (#8940)
* Add 'category' filter to BuildList - Allows filtering by part category * Add filter element to build table * Bump API version
This commit is contained in:
parent
19d7825fa6
commit
e9bc4645ca
@ -1,36 +1,39 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 303
|
INVENTREE_API_VERSION = 304
|
||||||
|
|
||||||
"""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 = """
|
||||||
|
|
||||||
v303 - 2025-01-20 - https://github.com/inventree/InvenTree/pull/8915
|
v304 - 2025-01-22 : https://github.com/inventree/InvenTree/pull/8940
|
||||||
|
- Adds "category" filter to build list API
|
||||||
|
|
||||||
|
v303 - 2025-01-20 : https://github.com/inventree/InvenTree/pull/8915
|
||||||
- Adds "start_date" field to Build model and API endpoints
|
- Adds "start_date" field to Build model and API endpoints
|
||||||
- Adds additional API filtering and sorting options for Build list
|
- Adds additional API filtering and sorting options for Build list
|
||||||
|
|
||||||
v302 - 2025-01-18 - https://github.com/inventree/InvenTree/pull/8905
|
v302 - 2025-01-18 : https://github.com/inventree/InvenTree/pull/8905
|
||||||
- Fix schema definition on the /label/print endpoint
|
- Fix schema definition on the /label/print endpoint
|
||||||
|
|
||||||
v301 - 2025-01-14 - https://github.com/inventree/InvenTree/pull/8894
|
v301 - 2025-01-14 : https://github.com/inventree/InvenTree/pull/8894
|
||||||
- Remove ui preferences from the API
|
- Remove ui preferences from the API
|
||||||
|
|
||||||
v300 - 2025-01-13 - https://github.com/inventree/InvenTree/pull/8886
|
v300 - 2025-01-13 : https://github.com/inventree/InvenTree/pull/8886
|
||||||
- Allow null value for 'expiry_date' field introduced in #8867
|
- Allow null value for 'expiry_date' field introduced in #8867
|
||||||
|
|
||||||
v299 - 2025-01-10 - https://github.com/inventree/InvenTree/pull/8867
|
v299 - 2025-01-10 : https://github.com/inventree/InvenTree/pull/8867
|
||||||
- Adds 'expiry_date' field to the PurchaseOrderReceive API endpoint
|
- Adds 'expiry_date' field to the PurchaseOrderReceive API endpoint
|
||||||
- Adds 'default_expiry` field to the PartBriefSerializer, affecting API endpoints which use it
|
- Adds 'default_expiry` field to the PartBriefSerializer, affecting API endpoints which use it
|
||||||
|
|
||||||
v298 - 2025-01-07 - https://github.com/inventree/InvenTree/pull/8848
|
v298 - 2025-01-07 : https://github.com/inventree/InvenTree/pull/8848
|
||||||
- Adds 'created_by' field to PurchaseOrder API endpoints
|
- Adds 'created_by' field to PurchaseOrder API endpoints
|
||||||
- Adds 'created_by' field to SalesOrder API endpoints
|
- Adds 'created_by' field to SalesOrder API endpoints
|
||||||
- Adds 'created_by' field to ReturnOrder API endpoints
|
- Adds 'created_by' field to ReturnOrder API endpoints
|
||||||
|
|
||||||
v297 - 2024-12-29 - https://github.com/inventree/InvenTree/pull/8438
|
v297 - 2024-12-29 : https://github.com/inventree/InvenTree/pull/8438
|
||||||
- Adjustments to the CustomUserState API endpoints and serializers
|
- Adjustments to the CustomUserState API endpoints and serializers
|
||||||
|
|
||||||
v296 - 2024-12-25 : https://github.com/inventree/InvenTree/pull/8732
|
v296 - 2024-12-25 : https://github.com/inventree/InvenTree/pull/8732
|
||||||
|
@ -13,7 +13,7 @@ from rest_framework.exceptions import ValidationError
|
|||||||
import build.admin
|
import build.admin
|
||||||
import build.serializers
|
import build.serializers
|
||||||
import common.models
|
import common.models
|
||||||
import part.models
|
import part.models as part_models
|
||||||
from build.models import Build, BuildItem, BuildLine
|
from build.models import Build, BuildItem, BuildLine
|
||||||
from build.status_codes import BuildStatus, BuildStatusGroups
|
from build.status_codes import BuildStatus, BuildStatusGroups
|
||||||
from generic.states.api import StatusView
|
from generic.states.api import StatusView
|
||||||
@ -77,7 +77,10 @@ class BuildFilter(rest_filters.FilterSet):
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
part = rest_filters.ModelChoiceFilter(
|
part = rest_filters.ModelChoiceFilter(
|
||||||
queryset=part.models.Part.objects.all(), field_name='part', method='filter_part'
|
queryset=part_models.Part.objects.all(),
|
||||||
|
field_name='part',
|
||||||
|
method='filter_part',
|
||||||
|
label=_('Part'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def filter_part(self, queryset, name, part):
|
def filter_part(self, queryset, name, part):
|
||||||
@ -94,6 +97,17 @@ class BuildFilter(rest_filters.FilterSet):
|
|||||||
else:
|
else:
|
||||||
return queryset.filter(part=part)
|
return queryset.filter(part=part)
|
||||||
|
|
||||||
|
category = rest_filters.ModelChoiceFilter(
|
||||||
|
queryset=part_models.PartCategory.objects.all(),
|
||||||
|
method='filter_category',
|
||||||
|
label=_('Category'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def filter_category(self, queryset, name, category):
|
||||||
|
"""Filter by part category (including sub-categories)."""
|
||||||
|
categories = category.get_descendants(include_self=True)
|
||||||
|
return queryset.filter(part__category__in=categories)
|
||||||
|
|
||||||
ancestor = rest_filters.ModelChoiceFilter(
|
ancestor = rest_filters.ModelChoiceFilter(
|
||||||
queryset=Build.objects.all(),
|
queryset=Build.objects.all(),
|
||||||
label=_('Ancestor Build'),
|
label=_('Ancestor Build'),
|
||||||
@ -417,7 +431,7 @@ class BuildLineFilter(rest_filters.FilterSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
part = rest_filters.ModelChoiceFilter(
|
part = rest_filters.ModelChoiceFilter(
|
||||||
queryset=part.models.Part.objects.all(),
|
queryset=part_models.Part.objects.all(),
|
||||||
label=_('Part'),
|
label=_('Part'),
|
||||||
field_name='bom_item__sub_part',
|
field_name='bom_item__sub_part',
|
||||||
)
|
)
|
||||||
@ -729,7 +743,7 @@ class BuildItemFilter(rest_filters.FilterSet):
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
part = rest_filters.ModelChoiceFilter(
|
part = rest_filters.ModelChoiceFilter(
|
||||||
queryset=part.models.Part.objects.all(),
|
queryset=part_models.Part.objects.all(),
|
||||||
label=_('Part'),
|
label=_('Part'),
|
||||||
method='filter_part',
|
method='filter_part',
|
||||||
field_name='stock_item__part',
|
field_name='stock_item__part',
|
||||||
|
@ -179,10 +179,17 @@ function FilterAddGroup({
|
|||||||
|
|
||||||
// Determine the "type" of filter (default = boolean)
|
// Determine the "type" of filter (default = boolean)
|
||||||
const filterType: TableFilterType = useMemo(() => {
|
const filterType: TableFilterType = useMemo(() => {
|
||||||
return (
|
const filter = availableFilters?.find((flt) => flt.name === selectedFilter);
|
||||||
availableFilters?.find((flt) => flt.name === selectedFilter)?.type ??
|
|
||||||
'boolean'
|
if (filter?.type) {
|
||||||
);
|
return filter.type;
|
||||||
|
} else if (filter?.choices) {
|
||||||
|
// If choices are provided, it is a choice filter
|
||||||
|
return 'choice';
|
||||||
|
} else {
|
||||||
|
// Default fallback
|
||||||
|
return 'boolean';
|
||||||
|
}
|
||||||
}, [selectedFilter]);
|
}, [selectedFilter]);
|
||||||
|
|
||||||
const setSelectedValue = useCallback(
|
const setSelectedValue = useCallback(
|
||||||
|
@ -8,7 +8,9 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
|
|||||||
import { ModelType } from '../../enums/ModelType';
|
import { ModelType } from '../../enums/ModelType';
|
||||||
import { UserRoles } from '../../enums/Roles';
|
import { UserRoles } from '../../enums/Roles';
|
||||||
import { useBuildOrderFields } from '../../forms/BuildForms';
|
import { useBuildOrderFields } from '../../forms/BuildForms';
|
||||||
|
import { shortenString } from '../../functions/tables';
|
||||||
import {
|
import {
|
||||||
|
useFilters,
|
||||||
useOwnerFilters,
|
useOwnerFilters,
|
||||||
useProjectCodeFilters,
|
useProjectCodeFilters,
|
||||||
useUserFilters
|
useUserFilters
|
||||||
@ -131,6 +133,17 @@ export function BuildOrderTable({
|
|||||||
const ownerFilters = useOwnerFilters();
|
const ownerFilters = useOwnerFilters();
|
||||||
const userFilters = useUserFilters();
|
const userFilters = useUserFilters();
|
||||||
|
|
||||||
|
const categoryFilters = useFilters({
|
||||||
|
url: apiUrl(ApiEndpoints.category_list),
|
||||||
|
transform: (item) => ({
|
||||||
|
value: item.pk,
|
||||||
|
label: shortenString({
|
||||||
|
str: item.pathstring,
|
||||||
|
len: 50
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
const tableFilters: TableFilter[] = useMemo(() => {
|
const tableFilters: TableFilter[] = useMemo(() => {
|
||||||
const filters: TableFilter[] = [
|
const filters: TableFilter[] = [
|
||||||
OutstandingFilter(),
|
OutstandingFilter(),
|
||||||
@ -177,7 +190,13 @@ export function BuildOrderTable({
|
|||||||
description: t`Filter by user who issued this order`,
|
description: t`Filter by user who issued this order`,
|
||||||
choices: userFilters.choices
|
choices: userFilters.choices
|
||||||
},
|
},
|
||||||
ResponsibleFilter({ choices: ownerFilters.choices })
|
ResponsibleFilter({ choices: ownerFilters.choices }),
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
label: t`Category`,
|
||||||
|
description: t`Filter by part category`,
|
||||||
|
choices: categoryFilters.choices
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// If we are filtering on a specific part, we can include the "include variants" filter
|
// If we are filtering on a specific part, we can include the "include variants" filter
|
||||||
@ -193,6 +212,7 @@ export function BuildOrderTable({
|
|||||||
return filters;
|
return filters;
|
||||||
}, [
|
}, [
|
||||||
partId,
|
partId,
|
||||||
|
categoryFilters.choices,
|
||||||
projectCodeFilters.choices,
|
projectCodeFilters.choices,
|
||||||
ownerFilters.choices,
|
ownerFilters.choices,
|
||||||
userFilters.choices
|
userFilters.choices
|
||||||
|
Loading…
x
Reference in New Issue
Block a user