diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index af2d724f58..8cd349c213 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -257,6 +257,7 @@ class StockList(generics.ListCreateAPIView): - location: Filter stock by location - category: Filter by parts belonging to a certain category - supplier: Filter by supplier + - ancestor: Filter by an 'ancestor' StockItem """ def get_serializer(self, *args, **kwargs): @@ -284,6 +285,7 @@ class StockList(generics.ListCreateAPIView): data = queryset.values( 'pk', + 'parent', 'quantity', 'serial', 'batch', @@ -347,7 +349,20 @@ class StockList(generics.ListCreateAPIView): else: stock_list = stock_list.filter(part=part_id) - except Part.DoesNotExist: + except (ValueError, Part.DoesNotExist): + pass + + # Does the client wish to filter by the 'ancestor'? + anc_id = self.request.query_params.get('ancestor', None) + + if anc_id: + try: + ancestor = StockItem.objects.get(pk=anc_id) + + # Only allow items which are descendants of the specified StockItem + stock_list = stock_list.filter(id__in=[item.pk for item in ancestor.children.all()]) + + except (ValueError, Part.DoesNotExist): pass # Does the client wish to filter by stock location? @@ -358,7 +373,7 @@ class StockList(generics.ListCreateAPIView): location = StockLocation.objects.get(pk=loc_id) stock_list = stock_list.filter(location__in=location.getUniqueChildren()) - except StockLocation.DoesNotExist: + except (ValueError, StockLocation.DoesNotExist): pass # Does the client wish to filter by part category? @@ -369,7 +384,7 @@ class StockList(generics.ListCreateAPIView): category = PartCategory.objects.get(pk=cat_id) stock_list = stock_list.filter(part__category__in=category.getUniqueChildren()) - except PartCategory.DoesNotExist: + except (ValueError, PartCategory.DoesNotExist): pass # Filter by supplier_part ID diff --git a/InvenTree/stock/fixtures/stock.yaml b/InvenTree/stock/fixtures/stock.yaml index 96e0a3ab72..ebc207f29c 100644 --- a/InvenTree/stock/fixtures/stock.yaml +++ b/InvenTree/stock/fixtures/stock.yaml @@ -7,6 +7,10 @@ location: 3 batch: 'B123' quantity: 4000 + level: 0 + tree_id: 0 + lft: 0 + rght: 0 # 5,000 screws in the bathroom - model: stock.stockitem @@ -14,6 +18,10 @@ part: 1 location: 2 quantity: 5000 + level: 0 + tree_id: 0 + lft: 0 + rght: 0 # 1234 2K2 resistors in 'Drawer_1' - model: stock.stockitem @@ -22,6 +30,10 @@ part: 3 location: 5 quantity: 1234 + level: 0 + tree_id: 0 + lft: 0 + rght: 0 # Some widgets in drawer 3 - model: stock.stockitem @@ -31,6 +43,10 @@ location: 7 quantity: 10 delete_on_deplete: False + level: 0 + tree_id: 0 + lft: 0 + rght: 0 - model: stock.stockitem pk: 101 @@ -38,10 +54,18 @@ part: 25 location: 7 quantity: 5 + level: 0 + tree_id: 0 + lft: 0 + rght: 0 - model: stock.stockitem pk: 102 fields: part: 25 location: 7 - quantity: 3 \ No newline at end of file + quantity: 3 + level: 0 + tree_id: 0 + lft: 0 + rght: 0 \ No newline at end of file diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index dcea62a4bb..1e11525703 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -385,12 +385,17 @@ class StockItem(MPTTModel): return True + @property + def children(self): + """ Return a list of the child items which have been split from this stock item """ + return self.get_descendants(include_self=False) + @property def child_count(self): """ Return the number of 'child' items associated with this StockItem. A child item is one which has been split from this one. """ - return self.get_descendants(include_self=False).count() + return self.children.count() @property def in_stock(self): diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index 3783f6a43f..4e32356101 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -59,7 +59,7 @@ {% endif %} {% if item.parent %}