diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index 127ae7399a..d5ba2ce83e 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -19,8 +19,8 @@ from company.models import SupplierPart from .models import PurchaseOrder, PurchaseOrderLineItem from .serializers import POSerializer, POLineItemSerializer -from .models import SalesOrder, SalesOrderLineItem -from .serializers import SalesOrderSerializer, SOLineItemSerializer +from .models import SalesOrder, SalesOrderLineItem, SalesOrderAllocation +from .serializers import SalesOrderSerializer, SOLineItemSerializer, SalesOrderAllocationSerializer class POList(generics.ListCreateAPIView): @@ -324,6 +324,11 @@ class SOLineItemList(generics.ListCreateAPIView): except AttributeError: pass + try: + kwargs['allocations'] = str2bool(self.request.query_params.get('allocations', False)) + except AttributeError: + pass + kwargs['context'] = self.get_serializer_context() return self.serializer_class(*args, **kwargs) @@ -345,6 +350,7 @@ class SOLineItemList(generics.ListCreateAPIView): filter_fields = [ 'order', + 'part', ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 3452cc6bb7..db7dc8c29b 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -451,3 +451,13 @@ class SalesOrderAllocation(models.Model): ) quantity = RoundingDecimalField(max_digits=15, decimal_places=5, validators=[MinValueValidator(0)], default=1) + + def get_location(self): + return self.item.location.id if self.item.location else None + + def get_location_path(self): + if self.item.location: + return self.item.location.pathstring + else: + return "" + \ No newline at end of file diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index deb470baab..721aaa6338 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -12,9 +12,11 @@ from django.db.models import Count from InvenTree.serializers import InvenTreeModelSerializer from company.serializers import CompanyBriefSerializer from part.serializers import PartBriefSerializer +from stock.serializers import StockItemSerializer from .models import PurchaseOrder, PurchaseOrderLineItem from .models import SalesOrder, SalesOrderLineItem +from .models import SalesOrderAllocation class POSerializer(InvenTreeModelSerializer): @@ -143,6 +145,28 @@ class SalesOrderSerializer(InvenTreeModelSerializer): ] +class SalesOrderAllocationSerializer(InvenTreeModelSerializer): + """ + Serializer for the SalesOrderAllocation model. + This includes some fields from the related model objects. + """ + + location_path = serializers.CharField(source='get_location_path') + location_id = serializers.IntegerField(source='get_location') + + class Meta: + model = SalesOrderAllocation + + fields = [ + 'pk', + 'line', + 'location_id', + 'location_path', + 'quantity', + 'item', + ] + + class SOLineItemSerializer(InvenTreeModelSerializer): """ Serializer for a SalesOrderLineItem object """ @@ -150,6 +174,7 @@ class SOLineItemSerializer(InvenTreeModelSerializer): part_detail = kwargs.pop('part_detail', False) order_detail = kwargs.pop('order_detail', False) + allocations = kwargs.pop('allocations', False) super().__init__(*args, **kwargs) @@ -159,8 +184,12 @@ class SOLineItemSerializer(InvenTreeModelSerializer): if order_detail is not True: self.fields.pop('order_detail') + if allocations is not True: + self.fields.pop('allocations') + order_detail = SalesOrderSerializer(source='order', many=False, read_only=True) part_detail = PartBriefSerializer(source='part', many=False, read_only=True) + allocations = SalesOrderAllocationSerializer(many=True, read_only=True) quantity = serializers.FloatField() allocated = serializers.FloatField(source='allocated_quantity', read_only=True) @@ -171,6 +200,7 @@ class SOLineItemSerializer(InvenTreeModelSerializer): fields = [ 'pk', 'allocated', + 'allocations', 'quantity', 'reference', 'notes', diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index c90ca6aaba..e0a69e15fb 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -17,18 +17,18 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% for allocation in item.sales_order_allocations.all %}
- {% trans "This stock item is allocated to Sales Order" %} #{{ allocation.line.order.id }} ({% trans "Quantity" %}: {% decimal allocation.quantity %}) + {% trans "This stock item is allocated to Sales Order" %} #{{ allocation.line.order.reference }} ({% trans "Quantity" %}: {% decimal allocation.quantity %})
{% endfor %} {% for allocation in item.allocations.all %}
- {% trans "This stock item is allocated to Build" %} #{{ allocation.build.id }} ({% trans "Quantity" %}: {% decimal allocation.quantity %}) + {% trans "This stock item is allocated to Build" %} #{{ allocation.build.id }} ({% trans "Quantity" %}: {% decimal allocation.quantity %})
{% endfor %} {% if item.serialized %} -
+
{% trans "This stock item is serialized - it has a unique serial number and the quantity cannot be adjusted." %}
{% elif item.child_count > 0 %}