diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index ba802b75d9..ab70c98322 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -324,8 +324,31 @@ class StockList(generics.ListCreateAPIView): serializer_class = StockItemSerializer queryset = StockItem.objects.all() - # TODO - Override the 'create' method for this view, - # to allow the user to be recorded when a new StockItem object is created + def create(self, request, *args, **kwargs): + """ + Create a new StockItem object via the API. + + We override the default 'create' implementation. + + If a location is *not* specified, but the linked *part* has a default location, + we can pre-fill the location automatically. + """ + + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + + item = serializer.save() + + # A location was *not* specified - try to infer it + if 'location' not in request.data: + location = item.part.get_default_location() + if location is not None: + item.location = location + item.save() + + # Return a response + headers = self.get_success_headers(serializer.data) + return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def list(self, request, *args, **kwargs): """ diff --git a/InvenTree/stock/test_api.py b/InvenTree/stock/test_api.py index 8348a3e331..45a1669535 100644 --- a/InvenTree/stock/test_api.py +++ b/InvenTree/stock/test_api.py @@ -97,6 +97,53 @@ class StockItemTest(StockAPITestCase): response = self.client.get(self.list_url, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) + def test_create_default_location(self): + """ + Test the default location functionality, + if a 'location' is not specified in the creation request. + """ + + # The part 'R_4K7_0603' (pk=4) has a default location specified + + response = self.client.post( + self.list_url, + data={ + 'part': 4, + 'quantity': 10 + } + ) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(response.data['location'], 2) + + # What if we explicitly set the location to a different value? + + response = self.client.post( + self.list_url, + data={ + 'part': 4, + 'quantity': 20, + 'location': 1, + } + ) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(response.data['location'], 1) + + # And finally, what if we set the location explicitly to None? + + response = self.client.post( + self.list_url, + data={ + 'part': 4, + 'quantity': 20, + 'location': '', + } + ) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(response.data['location'], None) + def test_stock_item_create(self): """ Test creation of a StockItem via the API