diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index b474538cfd..904e2f199d 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,12 +1,15 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 397 +INVENTREE_API_VERSION = 398 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v398 -> 2025-10-05 : https://github.com/inventree/InvenTree/pull/10487 + - Refactors 'part_detail', 'path_detail', 'supplier_part_detail', 'location_detail' and 'tests' params in Stock API endpoint + v397 -> 2025-10-01 : https://github.com/inventree/InvenTree/pull/10444 - Refactors 'path_detail' param in StockLocation API endpoint - Refactors 'user_detail' and 'template_detail' params in StockItemTestResult API endpoint diff --git a/src/backend/InvenTree/stock/api.py b/src/backend/InvenTree/stock/api.py index 0702436ed4..76a16a6ab2 100644 --- a/src/backend/InvenTree/stock/api.py +++ b/src/backend/InvenTree/stock/api.py @@ -1039,7 +1039,21 @@ class StockApiMixin: return super().get_serializer(*args, **kwargs) -class StockList(DataExportViewMixin, StockApiMixin, ListCreateDestroyAPIView): +class StockOutputOptions(OutputConfiguration): + """Output options for StockItem serializers.""" + + OPTIONS = [ + InvenTreeOutputOption('part_detail', default=True), + InvenTreeOutputOption('path_detail'), + InvenTreeOutputOption('supplier_part_detail'), + InvenTreeOutputOption('location_detail'), + InvenTreeOutputOption('tests'), + ] + + +class StockList( + DataExportViewMixin, StockApiMixin, OutputOptionsMixin, ListCreateDestroyAPIView +): """API endpoint for list view of Stock objects. - GET: Return a list of all StockItem objects (with optional query filters) @@ -1048,6 +1062,7 @@ class StockList(DataExportViewMixin, StockApiMixin, ListCreateDestroyAPIView): """ filterset_class = StockFilter + output_options = StockOutputOptions def create(self, request, *args, **kwargs): """Create a new StockItem object via the API. @@ -1285,9 +1300,11 @@ class StockList(DataExportViewMixin, StockApiMixin, ListCreateDestroyAPIView): ] -class StockDetail(StockApiMixin, RetrieveUpdateDestroyAPI): +class StockDetail(StockApiMixin, OutputOptionsMixin, RetrieveUpdateDestroyAPI): """API detail endpoint for a single StockItem instance.""" + output_options = StockOutputOptions + class StockItemSerialNumbers(RetrieveAPI): """View extra serial number information for a given stock item. diff --git a/src/backend/InvenTree/stock/test_api.py b/src/backend/InvenTree/stock/test_api.py index bec2773835..68bfbf1ca5 100644 --- a/src/backend/InvenTree/stock/test_api.py +++ b/src/backend/InvenTree/stock/test_api.py @@ -1527,6 +1527,36 @@ class StockItemTest(StockAPITestCase): data = self.get(url).data self.assertEqual(data['purchase_price_currency'], 'NZD') + def test_output_options(self): + """Test the output options for StockItemt detail.""" + url = reverse('api-stock-detail', kwargs={'pk': 1}) + + # Test cases: (parameter_name, response_field_name) + test_cases = [ + ('part_detail', 'part_detail'), + ('path_detail', 'location_path'), + ('supplier_part_detail', 'supplier_part_detail'), + ('location_detail', 'location_detail'), + ('tests', 'tests'), + ] + + for param, field in test_cases: + # Test with parameter set to 'true' + response = self.get(url, {param: 'true'}, expected_code=200) + self.assertIn( + field, + response.data, + f"Field '{field}' should be present when {param}='true'", + ) + + # Test with parameter set to 'false' + response = self.get(url, {param: 'false'}, expected_code=200) + self.assertNotIn( + field, + response.data, + f"Field '{field}' should not be present when {param}='false'", + ) + def test_install(self): """Test that stock item can be installed into another item, via the API.""" # Select the "parent" stock item