From 638684c7240dd3af8da189155110654690d1ea2f Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 5 Oct 2025 22:33:23 +0200 Subject: [PATCH] more adoption --- src/backend/InvenTree/build/serializers.py | 179 +++++++++---------- src/backend/InvenTree/company/serializers.py | 57 +++--- 2 files changed, 103 insertions(+), 133 deletions(-) diff --git a/src/backend/InvenTree/build/serializers.py b/src/backend/InvenTree/build/serializers.py index 9361ad7ff4..4b4e3d23a8 100644 --- a/src/backend/InvenTree/build/serializers.py +++ b/src/backend/InvenTree/build/serializers.py @@ -38,6 +38,7 @@ from InvenTree.serializers import ( InvenTreeDecimalField, InvenTreeModelSerializer, NotesFieldMixin, + can_filter, ) from stock.generators import generate_batch_code from stock.models import StockItem, StockLocation @@ -117,8 +118,9 @@ class BuildSerializer( status_text = serializers.CharField(source='get_status_display', read_only=True) - part_detail = part_serializers.PartBriefSerializer( - source='part', many=False, read_only=True + part_detail = can_filter( + part_serializers.PartBriefSerializer(source='part', many=False, read_only=True), + True, ) part_name = serializers.CharField( @@ -171,7 +173,6 @@ class BuildSerializer( def __init__(self, *args, **kwargs): """Determine if extra serializer fields are required.""" - part_detail = kwargs.pop('part_detail', True) user_detail = kwargs.pop('user_detail', True) project_code_detail = kwargs.pop('project_code_detail', True) @@ -182,13 +183,12 @@ class BuildSerializer( if isGeneratingSchema(): return - if not part_detail: - self.fields.pop('part_detail', None) - + # TODO INVE-T1 support complex filters if not user_detail: self.fields.pop('issued_by_detail', None) self.fields.pop('responsible_detail', None) + # TODO INVE-T1 support complex filters if not project_code_detail: self.fields.pop('project_code', None) self.fields.pop('project_code_label', None) @@ -1192,28 +1192,17 @@ class BuildItemSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali def __init__(self, *args, **kwargs): """Determine which extra details fields should be included.""" - part_detail = kwargs.pop('part_detail', True) - location_detail = kwargs.pop('location_detail', True) stock_detail = kwargs.pop('stock_detail', True) - build_detail = kwargs.pop('build_detail', True) super().__init__(*args, **kwargs) if isGeneratingSchema(): return - if not part_detail: - self.fields.pop('part_detail', None) - - if not location_detail: - self.fields.pop('location_detail', None) - + # TODO INVE-T1 support complex filters if not stock_detail: self.fields.pop('stock_item_detail', None) - if not build_detail: - self.fields.pop('build_detail', None) - # Export-only fields bom_reference = serializers.CharField( source='build_line.bom_item.reference', label=_('BOM Reference'), read_only=True @@ -1239,13 +1228,16 @@ class BuildItemSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali ) # Extra (optional) detail fields - part_detail = part_serializers.PartBriefSerializer( - label=_('Part'), - source='stock_item.part', - many=False, - read_only=True, - allow_null=True, - pricing=False, + part_detail = can_filter( + part_serializers.PartBriefSerializer( + label=_('Part'), + source='stock_item.part', + many=False, + read_only=True, + allow_null=True, + pricing=False, + ), + True, ) stock_item_detail = StockItemSerializer( @@ -1263,19 +1255,25 @@ class BuildItemSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali label=_('Location'), source='stock_item.location', many=False, read_only=True ) - location_detail = LocationBriefSerializer( - label=_('Location'), - source='stock_item.location', - read_only=True, - allow_null=True, + location_detail = can_filter( + LocationBriefSerializer( + label=_('Location'), + source='stock_item.location', + read_only=True, + allow_null=True, + ), + True, ) - build_detail = BuildSerializer( - label=_('Build'), - source='build_line.build', - many=False, - read_only=True, - allow_null=True, + build_detail = can_filter( + BuildSerializer( + label=_('Build'), + source='build_line.build', + many=False, + read_only=True, + allow_null=True, + ), + True, ) supplier_part_detail = company.serializers.SupplierPartSerializer( @@ -1350,35 +1348,6 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali read_only_fields = ['build', 'bom_item', 'allocations'] - def __init__(self, *args, **kwargs): - """Determine which extra details fields should be included.""" - part_detail = kwargs.pop('part_detail', True) - assembly_detail = kwargs.pop('assembly_detail', True) - bom_item_detail = kwargs.pop('bom_item_detail', True) - build_detail = kwargs.pop('build_detail', True) - allocations = kwargs.pop('allocations', True) - - super().__init__(*args, **kwargs) - - if isGeneratingSchema(): - return - - if not bom_item_detail: - self.fields.pop('bom_item_detail', None) - - if not part_detail: - self.fields.pop('part_detail', None) - self.fields.pop('part_category_name', None) - - if not build_detail: - self.fields.pop('build_detail', None) - - if not allocations: - self.fields.pop('allocations', None) - - if not assembly_detail: - self.fields.pop('assembly_detail', None) - # Build info fields build_reference = serializers.CharField( source='build.reference', label=_('Build Reference'), read_only=True @@ -1395,7 +1364,9 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali read_only=True, ) - allocations = BuildItemSerializer(many=True, read_only=True, build_detail=False) + allocations = can_filter( + BuildItemSerializer(many=True, read_only=True, build_detail=False), True + ) # BOM item info fields reference = serializers.CharField( @@ -1426,44 +1397,56 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali bom_item = serializers.PrimaryKeyRelatedField(label=_('BOM Item'), read_only=True) # Foreign key fields - bom_item_detail = part_serializers.BomItemSerializer( - label=_('BOM Item'), - source='bom_item', - many=False, - read_only=True, - pricing=False, - substitutes=False, - sub_part_detail=False, - part_detail=False, - can_build=False, + bom_item_detail = can_filter( + part_serializers.BomItemSerializer( + label=_('BOM Item'), + source='bom_item', + many=False, + read_only=True, + pricing=False, + substitutes=False, + sub_part_detail=False, + part_detail=False, + can_build=False, + ), + True, ) - assembly_detail = part_serializers.PartBriefSerializer( - label=_('Assembly'), - source='bom_item.part', - many=False, - read_only=True, - allow_null=True, - pricing=False, + assembly_detail = can_filter( + part_serializers.PartBriefSerializer( + label=_('Assembly'), + source='bom_item.part', + many=False, + read_only=True, + allow_null=True, + pricing=False, + ), + True, ) - part_detail = part_serializers.PartBriefSerializer( - label=_('Part'), - source='bom_item.sub_part', - many=False, - read_only=True, - pricing=False, + part_detail = can_filter( + part_serializers.PartBriefSerializer( + label=_('Part'), + source='bom_item.sub_part', + many=False, + read_only=True, + pricing=False, + ), + True, ) - build_detail = BuildSerializer( - label=_('Build'), - source='build', - many=False, - read_only=True, - allow_null=True, - part_detail=False, - user_detail=False, - project_code_detail=False, + build_detail = can_filter( + BuildSerializer( + label=_('Build'), + source='build', + many=False, + read_only=True, + allow_null=True, + part_detail=False, + user_detail=False, + project_code_detail=False, + ), + True, ) # Annotated (calculated) fields diff --git a/src/backend/InvenTree/company/serializers.py b/src/backend/InvenTree/company/serializers.py index 20d16a1ac0..5dec85407c 100644 --- a/src/backend/InvenTree/company/serializers.py +++ b/src/backend/InvenTree/company/serializers.py @@ -26,6 +26,7 @@ from InvenTree.serializers import ( InvenTreeTagModelSerializer, NotesFieldMixin, RemoteImageMixin, + can_filter, ) from .models import ( @@ -275,8 +276,6 @@ class ManufacturerPartSerializer( def __init__(self, *args, **kwargs): """Initialize this serializer with extra detail fields as required.""" - part_detail = kwargs.pop('part_detail', True) - manufacturer_detail = kwargs.pop('manufacturer_detail', True) prettify = kwargs.pop('pretty', False) super().__init__(*args, **kwargs) @@ -284,21 +283,22 @@ class ManufacturerPartSerializer( if isGeneratingSchema(): return - if part_detail is not True: - self.fields.pop('part_detail', None) - - if manufacturer_detail is not True: - self.fields.pop('manufacturer_detail', None) - + # TODO INVE-T1 support complex filters if prettify is not True: self.fields.pop('pretty_name', None) - part_detail = part_serializers.PartBriefSerializer( - source='part', many=False, read_only=True, allow_null=True + part_detail = can_filter( + part_serializers.PartBriefSerializer( + source='part', many=False, read_only=True, allow_null=True + ), + True, ) - manufacturer_detail = CompanyBriefSerializer( - source='manufacturer', many=False, read_only=True, allow_null=True + manufacturer_detail = can_filter( + CompanyBriefSerializer( + source='manufacturer', many=False, read_only=True, allow_null=True + ), + True, ) pretty_name = serializers.CharField(read_only=True, allow_null=True) @@ -334,6 +334,7 @@ class ManufacturerPartParameterSerializer( super().__init__(*args, **kwargs) + # TODO INVE-T1 support complex filters if not man_detail and not isGeneratingSchema(): self.fields.pop('manufacturer_part_detail', None) @@ -402,13 +403,11 @@ class SupplierPartSerializer( def __init__(self, *args, **kwargs): """Initialize this serializer with extra detail fields as required.""" # Check if 'available' quantity was supplied - self.has_available_quantity = 'available' in kwargs.get('data', {}) + # TODO INVE-T1 support complex filters brief = kwargs.pop('brief', False) - detail_default = not brief - part_detail = kwargs.pop('part_detail', detail_default) supplier_detail = kwargs.pop('supplier_detail', detail_default) manufacturer_detail = kwargs.pop('manufacturer_detail', detail_default) @@ -563,22 +562,6 @@ class SupplierPriceBreakSerializer( 'updated', ] - def __init__(self, *args, **kwargs): - """Initialize this serializer with extra fields as required.""" - supplier_detail = kwargs.pop('supplier_detail', False) - part_detail = kwargs.pop('part_detail', False) - - super().__init__(*args, **kwargs) - - if isGeneratingSchema(): - return - - if not supplier_detail: - self.fields.pop('supplier_detail', None) - - if not part_detail: - self.fields.pop('part_detail', None) - @staticmethod def annotate_queryset(queryset): """Prefetch related fields for the queryset.""" @@ -596,11 +579,15 @@ class SupplierPriceBreakSerializer( source='part.supplier', many=False, read_only=True ) - supplier_detail = CompanyBriefSerializer( - source='part.supplier', many=False, read_only=True, allow_null=True + supplier_detail = can_filter( + CompanyBriefSerializer( + source='part.supplier', many=False, read_only=True, allow_null=True + ) ) # Detail serializer for SupplierPart - part_detail = SupplierPartSerializer( - source='part', brief=True, many=False, read_only=True, allow_null=True + part_detail = can_filter( + SupplierPartSerializer( + source='part', brief=True, many=False, read_only=True, allow_null=True + ) )