Correctly serialize stock when creating via the API

This commit is contained in:
Oliver 2021-11-03 07:41:47 +11:00
parent ad4c4f2a6d
commit 2b69d9c2af
2 changed files with 62 additions and 17 deletions

View File

@ -7,9 +7,11 @@ from __future__ import unicode_literals
from datetime import datetime, timedelta from datetime import datetime, timedelta
from django.core.exceptions import ValidationError as DjangoValidationError
from django.conf.urls import url, include from django.conf.urls import url, include
from django.http import JsonResponse from django.http import JsonResponse
from django.db.models import Q from django.db.models import Q
from django.db import transaction
from rest_framework import status from rest_framework import status
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
@ -39,7 +41,7 @@ import common.models
import stock.serializers as StockSerializers import stock.serializers as StockSerializers
from InvenTree.helpers import str2bool, isNull from InvenTree.helpers import str2bool, isNull, extract_serial_numbers
from InvenTree.api import AttachmentMixin from InvenTree.api import AttachmentMixin
from InvenTree.filters import InvenTreeOrderingFilter from InvenTree.filters import InvenTreeOrderingFilter
@ -380,28 +382,67 @@ class StockList(generics.ListCreateAPIView):
""" """
user = request.user user = request.user
data = request.data
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
item = serializer.save() # Check if a set of serial numbers was provided
serial_numbers = data.get('serial_numbers', '')
# A location was *not* specified - try to infer it quantity = data['quantity']
if 'location' not in request.data:
item.location = item.part.get_default_location()
# An expiry date was *not* specified - try to infer it! notes = data.get('notes', '')
if 'expiry_date' not in request.data:
if item.part.default_expiry > 0: serials = None
item.expiry_date = datetime.now().date() + timedelta(days=item.part.default_expiry)
# Finally, save the item if serial_numbers:
item.save(user=user) # If serial numbers are specified, check that they match!
try:
serials = extract_serial_numbers(serial_numbers, data['quantity'])
except DjangoValidationError as e:
raise ValidationError({
'quantity': e.messages,
'serial_numbers': e.messages,
})
# Return a response with transaction.atomic():
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) # Create an initial stock item
item = serializer.save()
# A location was *not* specified - try to infer it
if 'location' not in data:
item.location = item.part.get_default_location()
# An expiry date was *not* specified - try to infer it!
if 'expiry_date' not in data:
if item.part.default_expiry > 0:
item.expiry_date = datetime.now().date() + timedelta(days=item.part.default_expiry)
# Finally, save the item (with user information)
item.save(user=user)
# Serialize the stock, if required
if serials:
try:
item.serializeStock(
quantity,
serials,
user,
notes=notes,
location=item.location,
)
except DjangoValidationError as e:
raise ValidationError({
'quantity': e.messages,
'serial_numbers': e.messages,
})
# 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): def list(self, request, *args, **kwargs):
""" """

View File

@ -216,12 +216,16 @@ function duplicateStockItem(pk, options) {
inventreeGet(`/api/stock/${pk}/`, {}, { inventreeGet(`/api/stock/${pk}/`, {}, {
success: function(data) { success: function(data) {
options.create = true; // Do not duplicate the serial number
delete data['serial'];
options.data = data; options.data = data;
options.method = 'POST';
options.create = true;
options.fields = stockItemFields(options); options.fields = stockItemFields(options);
options.groups = stockItemGroups(options); options.groups = stockItemGroups(options);
options.method = 'POST';
options.title = '{% trans "Duplicate Stock Item" %}'; options.title = '{% trans "Duplicate Stock Item" %}';
constructForm('{% url "api-stock-list" %}', options); constructForm('{% url "api-stock-list" %}', options);