mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 12:06:44 +00:00
Fixes for Stocktransfer API endpoint
This commit is contained in:
parent
5b2665edb1
commit
bc91975f2c
@ -214,69 +214,36 @@ class StockRemove(StockAdjust):
|
|||||||
return Response({"success": "Removed stock for {n} items".format(n=n)})
|
return Response({"success": "Removed stock for {n} items".format(n=n)})
|
||||||
|
|
||||||
|
|
||||||
class StockTransfer(APIView):
|
class StockTransfer(StockAdjust):
|
||||||
""" API endpoint for performing stock movements """
|
"""
|
||||||
|
API endpoint for performing stock movements
|
||||||
permission_classes = [
|
"""
|
||||||
permissions.IsAuthenticated,
|
|
||||||
]
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
||||||
|
self.get_items(request)
|
||||||
|
|
||||||
data = request.data
|
data = request.data
|
||||||
|
|
||||||
if 'location' not in data:
|
|
||||||
raise ValidationError({'location': 'Destination must be specified'})
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
loc_id = int(data.get('location'))
|
location = StockLocation.objects.get(pk=data.get('location', None))
|
||||||
except ValueError:
|
except (ValueError, StockLocation.DoesNotExist):
|
||||||
raise ValidationError({'location': 'Integer ID required'})
|
raise ValidationError({'location': 'Valid location must be specified'})
|
||||||
|
|
||||||
try:
|
n = 0
|
||||||
location = StockLocation.objects.get(pk=loc_id)
|
|
||||||
except StockLocation.DoesNotExist:
|
|
||||||
raise ValidationError({'location': 'Location does not exist'})
|
|
||||||
|
|
||||||
if 'stock' not in data:
|
for item in self.items:
|
||||||
raise ValidationError({'stock': 'Stock list must be specified'})
|
|
||||||
|
|
||||||
stock_list = data.get('stock')
|
# If quantity is not specified, move the entire stock
|
||||||
|
if item['quantity'] in [0, None]:
|
||||||
|
item['quantity'] = item['item'].quantity
|
||||||
|
|
||||||
if type(stock_list) is not list:
|
if item['item'].move(location, self.notes, request.user, quantity=item['quantity']):
|
||||||
raise ValidationError({'stock': 'Stock must be supplied as a list'})
|
n += 1
|
||||||
|
|
||||||
if 'notes' not in data:
|
return Response({'success': 'Moved {n} parts to {loc}'.format(
|
||||||
raise ValidationError({'notes': 'Notes field must be supplied'})
|
n=n,
|
||||||
|
loc=str(location),
|
||||||
for item in stock_list:
|
|
||||||
try:
|
|
||||||
stock_id = int(item['pk'])
|
|
||||||
if 'quantity' in item:
|
|
||||||
quantity = int(item['quantity'])
|
|
||||||
else:
|
|
||||||
# If quantity not supplied, we'll move the entire stock
|
|
||||||
quantity = None
|
|
||||||
except ValueError:
|
|
||||||
# Ignore this one
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Ignore a zero quantity movement
|
|
||||||
if quantity <= 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
stock = StockItem.objects.get(pk=stock_id)
|
|
||||||
except StockItem.DoesNotExist:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if quantity is None:
|
|
||||||
quantity = stock.quantity
|
|
||||||
|
|
||||||
stock.move(location, data.get('notes'), request.user, quantity=quantity)
|
|
||||||
|
|
||||||
return Response({'success': 'Moved parts to {loc}'.format(
|
|
||||||
loc=str(location)
|
|
||||||
)})
|
)})
|
||||||
|
|
||||||
|
|
||||||
@ -622,7 +589,7 @@ stock_api_urls = [
|
|||||||
url(r'count/?', StockCount.as_view(), name='api-stock-count'),
|
url(r'count/?', StockCount.as_view(), name='api-stock-count'),
|
||||||
url(r'add/?', StockAdd.as_view(), name='api-stock-add'),
|
url(r'add/?', StockAdd.as_view(), name='api-stock-add'),
|
||||||
url(r'remove/?', StockRemove.as_view(), name='api-stock-remove'),
|
url(r'remove/?', StockRemove.as_view(), name='api-stock-remove'),
|
||||||
# url(r'transfer/?', StockTransfer.as_view(), name='api-stock-transfer'),
|
url(r'transfer/?', StockTransfer.as_view(), name='api-stock-transfer'),
|
||||||
|
|
||||||
url(r'track/?', StockTrackingList.as_view(), name='api-stock-track'),
|
url(r'track/?', StockTrackingList.as_view(), name='api-stock-track'),
|
||||||
|
|
||||||
|
@ -154,3 +154,28 @@ class StocktakeTest(APITestCase):
|
|||||||
|
|
||||||
response = self.doPost(url, data)
|
response = self.doPost(url, data)
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
def test_transfer(self):
|
||||||
|
"""
|
||||||
|
Test stock transfers
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'item': {
|
||||||
|
'pk': 1234,
|
||||||
|
'quantity': 10,
|
||||||
|
},
|
||||||
|
'location': 1,
|
||||||
|
'notes': "Moving to a new location"
|
||||||
|
}
|
||||||
|
|
||||||
|
url = reverse('api-stock-transfer')
|
||||||
|
|
||||||
|
response = self.doPost(url, data)
|
||||||
|
self.assertContains(response, "Moved 1 parts to", status_code=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
# Now try one which will fail due to a bad location
|
||||||
|
data['location'] = 'not a location'
|
||||||
|
|
||||||
|
response = self.doPost(url, data)
|
||||||
|
self.assertContains(response, 'Valid location must be specified', status_code=status.HTTP_400_BAD_REQUEST)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user