From 31398b4c10d2732fa132c539c222e9b19d22a2ca Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 4 Dec 2021 13:50:11 +1100 Subject: [PATCH] Sales order can now be completed via the API --- InvenTree/order/api.py | 2 +- InvenTree/order/models.py | 44 ++++++++++++++----- InvenTree/order/serializers.py | 11 ++++- .../templates/order/sales_order_base.html | 9 +++- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index a46215fb0d..1ae6ae0184 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -683,7 +683,7 @@ class SalesOrderComplete(generics.CreateAPIView): """ queryset = models.SalesOrder.objects.all() - serializer_class = serializers.SalesOrderShipmentCompleteSerializer + serializer_class = serializers.SalesOrderCompleteSerializer def get_serializer_context(self): diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index c036e15190..434e6a9d15 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -621,23 +621,43 @@ class SalesOrder(Order): return self.lines.count() > 0 and all([line.is_completed() for line in self.lines.all()]) + def can_complete(self, raise_error=False): + """ + Test if this SalesOrder can be completed. + + Throws a ValidationError if cannot be completed. + """ + + # Order without line items cannot be completed + if self.lines.count() == 0: + if raise_error: + raise ValidationError(_('Order cannot be completed as no parts have been assigned')) + + # Only a PENDING order can be marked as SHIPPED + elif self.status != SalesOrderStatus.PENDING: + if raise_error: + raise ValidationError(_('Only a pending order can be marked as complete')) + + elif self.pending_shipment_count > 0: + if raise_error: + raise ValidationError(_("Order cannot be completed as there are incomplete shipments")) + + elif self.pending_line_count > 0: + if raise_error: + raise ValidationError(_("Order cannot be completed as there are incomplete line items")) + + else: + return True + + return False + def complete_order(self, user): """ Mark this order as "complete" """ - if self.lines.count() == 0: - # Order without line items cannot be completed - raise ValidationError(_('Order cannot be completed as no parts have been assigned')) - - if self.status != SalesOrderStatus.PENDING: - # Only a PENDING order can be marked as SHIPPED - raise ValidationError(_('Only a pending order can be marked as complete')) - - # Check if there are any incomplete shipments - for shipment in self.shipments.all(): - if not shipment.shipment_date: - raise ValidationError(_('Order cannot be completed as there are pending shipments')) + if not self.can_complete(): + return self.status = SalesOrderStatus.SHIPPED self.shipped_by = user diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index fd43164833..32e50943b1 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -749,11 +749,20 @@ class SalesOrderCompleteSerializer(serializers.Serializer): DRF serializer for manually marking a sales order as complete """ + def validate(self, data): + + data = super().validate(data) + + order = self.context['order'] + + order.can_complete(raise_error=True) + + return data + def save(self): request = self.context['request'] order = self.context['order'] - # data = self.validated_data user = getattr(request, 'user', None) diff --git a/InvenTree/order/templates/order/sales_order_base.html b/InvenTree/order/templates/order/sales_order_base.html index 2781b26a30..c8718d54d8 100644 --- a/InvenTree/order/templates/order/sales_order_base.html +++ b/InvenTree/order/templates/order/sales_order_base.html @@ -63,7 +63,7 @@ src="{% static 'img/blank_image.png' %}" {% if order.status == SalesOrderStatus.PENDING %} - {% endif %} @@ -224,7 +224,12 @@ $("#cancel-order").click(function() { }); $("#complete-order").click(function() { - completeSalesOrder({{ order.pk }}); + constructForm('{% url "api-so-complete" order.id %}', { + method: 'POST', + title: '{% trans "Complete Sales Order" %}', + confirm: true, + reload: true, + }); }); {% if report_enabled %}