From e9e4d135416e554bffea39d0997d8540087e5773 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 25 Oct 2021 23:34:58 +1100 Subject: [PATCH] Add list and detail API endpoints for SalesOrderShipment - Filter by order - Filter by "shipped" status - SalesOrderShipment serializer includes information on items allocated to that shipment --- InvenTree/order/api.py | 60 ++++++++++++++++++- ...056_alter_salesorderallocation_shipment.py | 2 +- InvenTree/order/models.py | 1 + InvenTree/order/serializers.py | 23 ++++++- 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index f4ebff4dfb..80708c9922 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -26,10 +26,11 @@ from .models import PurchaseOrder, PurchaseOrderLineItem from .models import PurchaseOrderAttachment from .serializers import POSerializer, POLineItemSerializer, POAttachmentSerializer -from .models import SalesOrder, SalesOrderLineItem, SalesOrderAllocation +from .models import SalesOrder, SalesOrderLineItem, SalesOrderShipment, SalesOrderAllocation from .models import SalesOrderAttachment + from .serializers import SalesOrderSerializer, SOLineItemSerializer, SOAttachmentSerializer -from .serializers import SalesOrderAllocationSerializer +from .serializers import SalesOrderShipmentSerializer, SalesOrderAllocationSerializer from .serializers import POReceiveSerializer @@ -700,6 +701,54 @@ class SOAllocationList(generics.ListCreateAPIView): ] +class SOShipmentFilter(rest_filters.FilterSet): + """ + Custom filterset for the SOShipmentList endpoint + """ + + shipped = rest_filters.BooleanFilter(label='shipped', method='filter_shipped') + + def filter_shipped(self, queryset, name, value): + + value = str2bool(value) + + if value: + queryset = queryset.exclude(shipment_date=None) + else: + queryset = queryset.filter(shipment_date=None) + + return queryset + + class Meta: + model = SalesOrderShipment + fields = [ + 'order', + ] + + +class SOShipmentList(generics.ListCreateAPIView): + """ + API list endpoint for SalesOrderShipment model + """ + + queryset = SalesOrderShipment.objects.all() + serializer_class = SalesOrderShipmentSerializer + filterset_class = SOShipmentFilter + + filter_backends = [ + rest_filters.DjangoFilterBackend, + ] + + +class SOShipmentDetail(generics.RetrieveUpdateAPIView): + """ + API detail endpooint for SalesOrderShipment model + """ + + queryset = SalesOrderShipment.objects.all() + serializer_class = SalesOrderShipmentSerializer + + class POAttachmentList(generics.ListCreateAPIView, AttachmentMixin): """ API endpoint for listing (and creating) a PurchaseOrderAttachment (file upload) @@ -760,6 +809,13 @@ order_api_urls = [ url(r'^.*$', SOAttachmentList.as_view(), name='api-so-attachment-list'), ])), + url(r'^shipment/', include([ + url(r'^(?P\d)+/', include([ + url(r'^.*$', SOShipmentDetail.as_view(), name='api-so-shipment-detail'), + ])), + url(r'^.*$', SOShipmentList.as_view(), name='api-so-shipment-list'), + ])), + url(r'^(?P\d+)/$', SODetail.as_view(), name='api-so-detail'), url(r'^.*$', SOList.as_view(), name='api-so-list'), ])), diff --git a/InvenTree/order/migrations/0056_alter_salesorderallocation_shipment.py b/InvenTree/order/migrations/0056_alter_salesorderallocation_shipment.py index 7a2c255be3..340a8d4ab5 100644 --- a/InvenTree/order/migrations/0056_alter_salesorderallocation_shipment.py +++ b/InvenTree/order/migrations/0056_alter_salesorderallocation_shipment.py @@ -14,6 +14,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='salesorderallocation', name='shipment', - field=models.ForeignKey(help_text='Sales order shipment reference', on_delete=django.db.models.deletion.CASCADE, to='order.salesordershipment', verbose_name='Shipment'), + field=models.ForeignKey(help_text='Sales order shipment reference', on_delete=django.db.models.deletion.CASCADE, related_name='allocations', to='order.salesordershipment', verbose_name='Shipment'), ), ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 7277897488..c6ff6dc5bd 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -1039,6 +1039,7 @@ class SalesOrderAllocation(models.Model): shipment = models.ForeignKey( SalesOrderShipment, on_delete=models.CASCADE, + related_name='allocations', verbose_name=_('Shipment'), help_text=_('Sales order shipment reference'), ) diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 40cd2def58..70bef86ae4 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -34,7 +34,7 @@ from stock.serializers import LocationBriefSerializer, StockItemSerializer, Loca from .models import PurchaseOrder, PurchaseOrderLineItem from .models import PurchaseOrderAttachment, SalesOrderAttachment from .models import SalesOrder, SalesOrderLineItem -from .models import SalesOrderAllocation +from .models import SalesOrderShipment, SalesOrderAllocation from common.settings import currency_code_mappings @@ -590,6 +590,27 @@ class SOLineItemSerializer(InvenTreeModelSerializer): ] +class SalesOrderShipmentSerializer(InvenTreeModelSerializer): + """ + Serializer for the SalesOrderShipment class + """ + + allocations = SalesOrderAllocationSerializer(many=True, read_only=True, location_detail=True) + + class Meta: + model = SalesOrderShipment + + fields = [ + 'pk', + 'order', + 'allocations', + 'shipment_date', + 'checked_by', + 'reference', + 'notes', + ] + + class SOAttachmentSerializer(InvenTreeAttachmentSerializer): """ Serializers for the SalesOrderAttachment model