2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 12:06:44 +00:00

Ability to filter StockItemList API by sales_order or sales_order_line

This commit is contained in:
Oliver Walters 2020-04-21 17:33:02 +10:00
parent 0d1919f10b
commit 2c6e8da90e
3 changed files with 41 additions and 9 deletions

View File

@ -12,6 +12,7 @@ from django.db.models import Q
from .models import StockLocation, StockItem from .models import StockLocation, StockItem
from .models import StockItemTracking from .models import StockItemTracking
from order.models import SalesOrder
from part.models import Part, PartCategory from part.models import Part, PartCategory
from .serializers import StockItemSerializer from .serializers import StockItemSerializer
@ -387,7 +388,7 @@ class StockList(generics.ListCreateAPIView):
stock_list = stock_list.filter(part=part_id) stock_list = stock_list.filter(part=part_id)
except (ValueError, Part.DoesNotExist): except (ValueError, Part.DoesNotExist):
pass raise ValidationError({"part": "Invalid Part ID specified"})
# Does the client wish to filter by the 'ancestor'? # Does the client wish to filter by the 'ancestor'?
anc_id = self.request.query_params.get('ancestor', None) anc_id = self.request.query_params.get('ancestor', None)
@ -400,7 +401,7 @@ class StockList(generics.ListCreateAPIView):
stock_list = stock_list.filter(id__in=[item.pk for item in ancestor.children.all()]) stock_list = stock_list.filter(id__in=[item.pk for item in ancestor.children.all()])
except (ValueError, Part.DoesNotExist): except (ValueError, Part.DoesNotExist):
pass raise ValidationError({"ancestor": "Invalid ancestor ID specified"})
# Does the client wish to filter by stock location? # Does the client wish to filter by stock location?
loc_id = self.request.query_params.get('location', None) loc_id = self.request.query_params.get('location', None)
@ -433,7 +434,7 @@ class StockList(generics.ListCreateAPIView):
stock_list = stock_list.filter(part__category__in=category.getUniqueChildren()) stock_list = stock_list.filter(part__category__in=category.getUniqueChildren())
except (ValueError, PartCategory.DoesNotExist): except (ValueError, PartCategory.DoesNotExist):
pass raise ValidationError({"category": "Invalid category id specified"})
# Filter by StockItem status # Filter by StockItem status
status = self.request.query_params.get('status', None) status = self.request.query_params.get('status', None)
@ -465,10 +466,22 @@ class StockList(generics.ListCreateAPIView):
if manufacturer is not None: if manufacturer is not None:
stock_list = stock_list.filter(supplier_part__manufacturer=manufacturer) stock_list = stock_list.filter(supplier_part__manufacturer=manufacturer)
# Filter by sales order
sales_order = self.request.query_params.get('sales_order', None)
if sales_order is not None:
try:
sales_order = SalesOrder.objects.get(pk=sales_order)
lines = [line.pk for line in sales_order.lines.all()]
stock_list = stock_list.filter(sales_order_line__in=lines)
except (SalesOrder.DoesNotExist, ValueError):
raise ValidationError({'sales_order': 'Invalid SalesOrder object specified'})
# Also ensure that we pre-fecth all the related items # Also ensure that we pre-fecth all the related items
stock_list = stock_list.prefetch_related( stock_list = stock_list.prefetch_related(
'part', 'part',
'part__category', 'part__category',
'sales_order_line__order',
'location' 'location'
) )
@ -493,6 +506,7 @@ class StockList(generics.ListCreateAPIView):
'customer', 'customer',
'belongs_to', 'belongs_to',
'build', 'build',
'sales_order_line'
] ]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2020-04-21 07:24
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('stock', '0027_stockitem_sales_order'),
]
operations = [
migrations.RenameField(
model_name='stockitem',
old_name='sales_order',
new_name='sales_order_line',
),
]

View File

@ -266,13 +266,13 @@ class StockItem(MPTTModel):
try: try:
# If this StockItem is assigned to a SalesOrderLineItem, # If this StockItem is assigned to a SalesOrderLineItem,
# the "Part" that the line item references is the same as the part that THIS references # the "Part" that the line item references is the same as the part that THIS references
if self.sales_order is not None: if self.sales_order_line is not None:
if self.sales_order.part == None: if self.sales_order_line.part == None:
raise ValidationError({'sales_order': _('Stock item cannot be assigned to a LineItem which does not reference a part')}) raise ValidationError({'sales_order_line': _('Stock item cannot be assigned to a LineItem which does not reference a part')})
if not self.sales_order.part == self.part: if not self.sales_order_line.part == self.part:
raise ValidationError({'sales_order': _('Stock item does not reference the same part object as the LineItem')}) raise ValidationError({'sales_order_line': _('Stock item does not reference the same part object as the LineItem')})
except SalesOrderLineItem.DoesNotExist: except SalesOrderLineItem.DoesNotExist:
pass pass
@ -369,7 +369,7 @@ class StockItem(MPTTModel):
help_text=_('Purchase order for this stock item') help_text=_('Purchase order for this stock item')
) )
sales_order = models.ForeignKey( sales_order_line = models.ForeignKey(
SalesOrderLineItem, SalesOrderLineItem,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
related_name='stock_items', related_name='stock_items',