diff --git a/InvenTree/InvenTree/static/script/inventree/bom.js b/InvenTree/InvenTree/static/script/inventree/bom.js index 55337e3fa8..f93d882630 100644 --- a/InvenTree/InvenTree/static/script/inventree/bom.js +++ b/InvenTree/InvenTree/static/script/inventree/bom.js @@ -185,26 +185,20 @@ function loadBomTable(table, options) { if (!options.editable) { cols.push( { - field: 'sub_part_detail.total_stock', + field: 'sub_part_detail.stock', title: 'Available', searchable: false, sortable: true, formatter: function(value, row, index, field) { - var text = ""; - - if (row.quantity < row.sub_part_detail.total_stock) - { - text = "" + value + ""; + + var url = `/part/${row.sub_part_detail.pk}/stock/`; + var text = value; + + if (value == null || value <= 0) { + text = `No Stock`; } - else - { - if (!value) { - value = 'No Stock'; - } - text = "" + value + ""; - } - - return renderLink(text, row.sub_part_detail.url + "stock/"); + + return renderLink(text, url); } }); diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 51a4a35938..c265bf77fd 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -468,15 +468,15 @@ class BomList(generics.ListCreateAPIView): # Do we wish to include extra detail? try: - part_detail = str2bool(self.request.GET.get('part_detail', None)) - sub_part_detail = str2bool(self.request.GET.get('sub_part_detail', None)) + kwargs['part_detail'] = str2bool(self.request.GET.get('part_detail', None)) except AttributeError: - part_detail = None - sub_part_detail = None - - kwargs['part_detail'] = part_detail - kwargs['sub_part_detail'] = sub_part_detail + pass + try: + kwargs['sub_part_detail'] = str2bool(self.request.GET.get('sub_part_detail', None)) + except AttributeError: + pass + # Ensure the request context is passed through! kwargs['context'] = self.get_serializer_context() @@ -486,6 +486,12 @@ class BomList(generics.ListCreateAPIView): queryset = BomItem.objects.all() queryset = self.get_serializer_class().setup_eager_loading(queryset) + return queryset + + def filter_queryset(self, queryset): + + query = super().filter_queryset(queryset) + # Filter by part? part = self.request.query_params.get('part', None) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 021695f9bf..6f6b0d7ddf 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -1242,6 +1242,17 @@ class BomItem(models.Model): child=self.sub_part.full_name, n=helpers.decimal2string(self.quantity)) + def available_stock(self): + """ + Return the available stock items for the referenced sub_part + """ + + query = self.sub_part.stock_items.filter(StockModels.StockItem.IN_STOCK_FILTER).aggregate( + available=Coalesce(Sum('quantity'), 0) + ) + + return query['available'] + def get_overage_quantity(self, quantity): """ Calculate overage quantity """ diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 8cb3584664..b56bbc588f 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -54,6 +54,8 @@ class PartBriefSerializer(InvenTreeModelSerializer): thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True) + stock = serializers.FloatField(source='total_stock') + class Meta: model = Part fields = [ @@ -65,6 +67,7 @@ class PartBriefSerializer(InvenTreeModelSerializer): 'assembly', 'purchaseable', 'salable', + 'stock', 'virtual', ] @@ -236,6 +239,8 @@ class BomItemSerializer(InvenTreeModelSerializer): price_range = serializers.CharField(read_only=True) quantity = serializers.FloatField() + + available = serializers.FloatField(source='available_stock') part_detail = PartBriefSerializer(source='part', many=False, read_only=True) sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True) @@ -277,6 +282,7 @@ class BomItemSerializer(InvenTreeModelSerializer): 'sub_part', 'sub_part_detail', 'quantity', + 'available', 'reference', 'price_range', 'overage', diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 36e8064138..f514eea3da 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -137,7 +137,6 @@ class StockItem(MPTTModel): sales_order=None, build_order=None, belongs_to=None, - status__in=StockStatus.AVAILABLE_CODES ) def save(self, *args, **kwargs):