2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 12:35:46 +00:00

Adds API endpoint to "ship" a sales order shipment

This commit is contained in:
Oliver
2021-11-30 00:02:03 +11:00
parent c6b11b5e38
commit f3f3030b37
5 changed files with 119 additions and 9 deletions

View File

@ -767,6 +767,32 @@ class SOShipmentDetail(generics.RetrieveUpdateAPIView):
serializer_class = serializers.SalesOrderShipmentSerializer
class SOShipmentComplete(generics.CreateAPIView):
"""
API endpoint for completing (shipping) a SalesOrderShipment
"""
queryset = models.SalesOrderShipment.objects.all()
serializer_class = serializers.SalesOrderShipmentCompleteSerializer
def get_serializer_context(self):
"""
Pass the request object to the serializer
"""
ctx = super().get_serializer_context()
ctx['request'] = self.request
try:
ctx['shipment'] = models.SalesOrderShipment.objects.get(
pk=self.kwargs.get('pk', None)
)
except:
pass
return ctx
class POAttachmentList(generics.ListCreateAPIView, AttachmentMixin):
"""
API endpoint for listing (and creating) a PurchaseOrderAttachment (file upload)
@ -829,6 +855,7 @@ order_api_urls = [
url(r'^shipment/', include([
url(r'^(?P<pk>\d+)/', include([
url(r'^ship/$', SOShipmentComplete.as_view(), name='api-so-shipment-ship'),
url(r'^.*$', SOShipmentDetail.as_view(), name='api-so-shipment-detail'),
])),
url(r'^.*$', SOShipmentList.as_view(), name='api-so-shipment-list'),

View File

@ -996,6 +996,15 @@ class SalesOrderShipment(models.Model):
help_text=_('Shipment tracking information'),
)
def check_can_complete(self):
if self.shipment_date:
# Shipment has already been sent!
raise ValidationError(_("Shipment has already been sent"))
if self.allocations.count() == 0:
raise ValidationError(_("Shipment has no allocated stock items"))
@transaction.atomic
def complete_shipment(self, user):
"""
@ -1006,12 +1015,13 @@ class SalesOrderShipment(models.Model):
3. Set the "shipment_date" to now
"""
if self.shipment_date:
# Ignore, shipment has already been sent!
return
# Check if the shipment can be completed (throw error if not)
self.check_can_complete()
allocations = self.allocations.all()
# Iterate through each stock item assigned to this shipment
for allocation in self.allocations.all():
for allocation in allocations:
# Mark the allocation as "complete"
allocation.complete_allocation(user)

View File

@ -25,7 +25,6 @@ from InvenTree.helpers import normalize
from InvenTree.serializers import InvenTreeModelSerializer
from InvenTree.serializers import InvenTreeDecimalField
from InvenTree.serializers import InvenTreeMoneySerializer
from InvenTree.serializers import InvenTreeAttachmentSerializerField
from InvenTree.status_codes import StockStatus
import order.models
@ -617,6 +616,46 @@ class SalesOrderShipmentSerializer(InvenTreeModelSerializer):
]
class SalesOrderShipmentCompleteSerializer(serializers.ModelSerializer):
"""
Serializer for completing (shipping) a SalesOrderShipment
"""
class Meta:
model = order.models.SalesOrderShipment
fields = [
'tracking_number',
]
def validate(self, data):
data = super().validate(data)
shipment = self.context.get('shipment', None)
if not shipment:
raise ValidationError(_("No shipment details provided"))
shipment.check_can_complete()
return data
def save(self):
shipment = self.context.get('shipment', None)
if not shipment:
return
data = self.validated_data
request = self.context['request']
user = request.user
shipment.complete_shipment(user)
class SOShipmentAllocationItemSerializer(serializers.Serializer):
"""
A serializer for allocating a single stock-item against a SalesOrder shipment