diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index 002f98c3fe..219c5128dc 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,13 +1,17 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 274 +INVENTREE_API_VERSION = 275 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v274 - 2024-10-31 : https://github.com/inventree/InvenTree/pull/8396 + - Adds SKU and MPN fields to the StockItem serializer + - Additional export options for the StockItem serializer + v274 - 2024-10-29 : https://github.com/inventree/InvenTree/pull/8392 - Add more detailed information to NotificationEntry API serializer diff --git a/src/backend/InvenTree/stock/api.py b/src/backend/InvenTree/stock/api.py index 9afa8ee2cf..5d26a75c65 100644 --- a/src/backend/InvenTree/stock/api.py +++ b/src/backend/InvenTree/stock/api.py @@ -1175,6 +1175,7 @@ class StockList(DataExportViewMixin, ListCreateDestroyAPIView): ordering_field_aliases = { 'location': 'location__pathstring', 'SKU': 'supplier_part__SKU', + 'MPN': 'supplier_part__manufacturer_part__MPN', 'stock': ['quantity', 'serial_int', 'serial'], } @@ -1191,6 +1192,7 @@ class StockList(DataExportViewMixin, ListCreateDestroyAPIView): 'stock', 'status', 'SKU', + 'MPN', ] ordering = ['part__name', 'quantity', 'location'] diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py index 7d8f9e92ee..f00192c0f3 100644 --- a/src/backend/InvenTree/stock/serializers.py +++ b/src/backend/InvenTree/stock/serializers.py @@ -340,7 +340,7 @@ class StockItemSerializer( - Includes serialization for the item location """ - export_exclude_fields = ['tracking_items'] + export_exclude_fields = ['tags', 'tracking_items'] export_only_fields = ['part_pricing_min', 'part_pricing_max'] @@ -351,7 +351,14 @@ class StockItemSerializer( model = StockItem fields = [ + 'pk', + 'part', + 'quantity', + 'serial', 'batch', + 'location', + 'location_name', + 'location_path', 'belongs_to', 'build', 'consumed_by', @@ -361,32 +368,23 @@ class StockItemSerializer( 'in_stock', 'is_building', 'link', - 'location', - 'location_name', - 'location_detail', - 'location_path', 'notes', 'owner', 'packaging', 'parent', - 'part', - 'part_detail', 'purchase_order', 'purchase_order_reference', - 'pk', - 'quantity', 'sales_order', 'sales_order_reference', - 'serial', 'status', 'status_text', 'status_custom_key', - 'stocktake_date', 'supplier_part', - 'sku', - 'supplier_part_detail', + 'SKU', + 'MPN', 'barcode_hash', 'updated', + 'stocktake_date', 'purchase_price', 'purchase_price_currency', 'use_pack_size', @@ -399,6 +397,10 @@ class StockItemSerializer( 'stale', 'tracking_items', 'tags', + # Detail fields (FK relationships) + 'supplier_part_detail', + 'part_detail', + 'location_detail', # Export only fields 'part_pricing_min', 'part_pricing_max', @@ -575,9 +577,19 @@ class StockItemSerializer( return queryset - status_text = serializers.CharField(source='get_status_display', read_only=True) + status_text = serializers.CharField( + source='get_status_display', read_only=True, label=_('Status') + ) - sku = serializers.CharField(source='supplier_part.SKU', read_only=True) + SKU = serializers.CharField( + source='supplier_part.SKU', read_only=True, label=_('Supplier Part Number') + ) + + MPN = serializers.CharField( + source='supplier_part.manufacturer_part.MPN', + read_only=True, + label=_('Manufacturer Part Number'), + ) # Optional detail fields, which can be appended via query parameters supplier_part_detail = company_serializers.SupplierPartSerializer( @@ -588,6 +600,7 @@ class StockItemSerializer( many=False, read_only=True, ) + part_detail = part_serializers.PartBriefSerializer( source='part', many=False, read_only=True ) diff --git a/src/frontend/src/tables/stock/StockItemTable.tsx b/src/frontend/src/tables/stock/StockItemTable.tsx index 22c18694bd..a8348a877b 100644 --- a/src/frontend/src/tables/stock/StockItemTable.tsx +++ b/src/frontend/src/tables/stock/StockItemTable.tsx @@ -217,24 +217,26 @@ function stockItemTableColumns(): TableColumn[] { LocationColumn({ accessor: 'location_detail' }), - DateColumn({ - accessor: 'stocktake_date', - title: t`Stocktake Date`, + { + accessor: 'purchase_order', + title: t`Purchase Order`, + render: (record: any) => { + return record.purchase_order_reference; + } + }, + { + accessor: 'SKU', + title: t`Supplier Part`, sortable: true - }), - DateColumn({ - title: t`Expiry Date`, - accessor: 'expiry_date', - hidden: !useGlobalSettingsState.getState().isSet('STOCK_ENABLE_EXPIRY') - }), - DateColumn({ - title: t`Last Updated`, - accessor: 'updated' - }), - // TODO: purchase order - // TODO: Supplier part + }, + { + accessor: 'MPN', + title: t`Manufacturer Part`, + sortable: true + }, { accessor: 'purchase_price', + title: t`Unit Price`, sortable: true, switchable: true, render: (record: any) => @@ -242,10 +244,6 @@ function stockItemTableColumns(): TableColumn[] { currency: record.purchase_price_currency }) }, - { - accessor: 'packaging', - sortable: true - }, { accessor: 'stock_value', title: t`Stock Value`, @@ -264,9 +262,24 @@ function stockItemTableColumns(): TableColumn[] { } }, { - accessor: 'notes', - sortable: false - } + accessor: 'packaging', + sortable: true + }, + + DateColumn({ + title: t`Expiry Date`, + accessor: 'expiry_date', + hidden: !useGlobalSettingsState.getState().isSet('STOCK_ENABLE_EXPIRY') + }), + DateColumn({ + title: t`Last Updated`, + accessor: 'updated' + }), + DateColumn({ + accessor: 'stocktake_date', + title: t`Stocktake Date`, + sortable: true + }) ]; }