From f0b44450fb9f790519aee30bba37d8cb8c93512d Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 27 Apr 2021 12:48:36 -0400 Subject: [PATCH] Updated 'Required for Build Orders' API queryset --- InvenTree/build/models.py | 18 ++++++++++++++++-- InvenTree/part/api.py | 30 ++++++++---------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 16c0e5bb7f..c5da505f43 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -996,14 +996,28 @@ class Build(MPTTModel): @property def required_parts(self): - """ Returns a dict of parts required to build this part (BOM) """ + """ Returns a list of parts required to build this part (BOM) """ parts = [] - for item in self.part.bom_items.all().prefetch_related('sub_part'): + for item in self.bom_items: parts.append(item.sub_part) return parts + @property + def required_parts_to_complete_build(self): + """ Returns a list of parts required to complete the full build """ + parts = [] + + for bom_item in self.bom_items: + # Get remaining quantity needed + required_quantity_to_complete_build = self.remaining * bom_item.quantity + # Compare to net stock + if bom_item.sub_part.net_stock < required_quantity_to_complete_build: + parts.append(bom_item.sub_part) + + return parts + def availableStockItems(self, part, output): """ Returns stock items which are available for allocation to this build. diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index a2d7609bed..6b26365b27 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals from django_filters.rest_framework import DjangoFilterBackend from django.http import JsonResponse -from django.db.models import Q, F, Count, Prefetch, Sum +from django.db.models import Q, F, Count from django.utils.translation import ugettext_lazy as _ from rest_framework import status @@ -635,29 +635,15 @@ class PartList(generics.ListCreateAPIView): # TODO: Need to figure out a cheaper way of making this filter query if stock_to_build is not None: - # Filter only active parts - queryset = queryset.filter(active=True) - # Prefetch current active builds - build_active_queryset = Build.objects.filter(status__in=BuildStatus.ACTIVE_CODES) - build_active_prefetch = Prefetch('builds', - queryset=build_active_queryset, - to_attr='current_builds') - parts = queryset.prefetch_related(build_active_prefetch) - + # Get active builds + builds = Build.objects.filter(status__in=BuildStatus.ACTIVE_CODES) # Store parts with builds needing stock - parts_need_stock = [] + parts_needed_to_complete_builds = [] + # Filter required parts + for build in builds: + parts_needed_to_complete_builds += [part.pk for part in build.required_parts_to_complete_build] - # Find parts with active builds - # where any subpart's stock is lower than quantity being built - for part in parts: - if part.current_builds: - builds_ids = [build.id for build in part.current_builds] - total_build_quantity = build_active_queryset.filter(pk__in=builds_ids).aggregate(quantity=Sum('quantity'))['quantity'] - - if part.can_build < total_build_quantity: - parts_need_stock.append(part.pk) - - queryset = queryset.filter(pk__in=parts_need_stock) + queryset = queryset.filter(pk__in=parts_needed_to_complete_builds) # Optionally limit the maximum number of returned results # e.g. for displaying "recent part" list