From 4f84febbd11abc7852b14542a3f362e18526e84b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 7 May 2019 22:46:37 +1000 Subject: [PATCH] More intelligent BuildItem allocation - Set initial value for quantity based on how many parts are left to allocate - Auto select the StockItem to take from (if there is only one) --- InvenTree/build/models.py | 34 +++++++++++++++++++++++++++++ InvenTree/build/views.py | 21 +++++++++++++++++- InvenTree/templates/modal_form.html | 3 +++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 504b57cc75..2a998dc26e 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -13,9 +13,11 @@ from django.core.exceptions import ValidationError from django.urls import reverse from django.db import models, transaction +from django.db.models import Sum from django.core.validators import MinValueValidator from stock.models import StockItem +from part.models import BomItem class Build(models.Model): @@ -219,6 +221,38 @@ class Build(models.Model): self.status = self.COMPLETE self.save() + def getAllocatedQuantity(self, part): + """ Calculate the total number of currently allocated to this build + """ + + allocated = BuildItem.objects.filter(build=self.id, stock_item__part=part.id).aggregate(Sum('quantity')) + + q = allocated['quantity__sum'] + + if q: + return int(q) + else: + return 0 + + def getUnallocatedQuantity(self, part): + """ Calculate the quantity of which still needs to be allocated to this build. + + Args: + Part - the part to be tested + + Returns: + The remaining allocated quantity + """ + + try: + bom_item = BomItem.objects.get(part=self.part.id, sub_part=part.id) + except BomItem.DoesNotExist: + return 0 + + quantity = bom_item.quantity * self.quantity + + return quantity - self.getAllocatedQuantity(part) + @property def required_parts(self): """ Returns a dict of parts required to build this part (BOM) """ diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py index cd2c87e814..cccd705e43 100644 --- a/InvenTree/build/views.py +++ b/InvenTree/build/views.py @@ -289,6 +289,12 @@ class BuildItemCreate(AjaxCreateView): query = query.exclude(id__in=[item.stock_item.id for item in BuildItem.objects.filter(build=build_id, stock_item__part=part_id)]) form.fields['stock_item'].queryset = query + + stocks = query.all() + # If there is only one item selected, select it + if len(stocks) == 1: + form.fields['stock_item'].initial = stocks[0].id + except Part.DoesNotExist: pass @@ -303,10 +309,23 @@ class BuildItemCreate(AjaxCreateView): initials = super(AjaxCreateView, self).get_initial().copy() build_id = self.get_param('build') + part_id = self.get_param('part') + + if part_id: + try: + part = Part.objects.get(pk=part_id) + except Part.DoesNotExist: + part = None if build_id: try: - initials['build'] = Build.objects.get(pk=build_id) + build = Build.objects.get(pk=build_id) + initials['build'] = build + + # Try to work out how many parts to allocate + if part: + initials['quantity'] = build.getUnallocatedQuantity(part) + except Build.DoesNotExist: pass diff --git a/InvenTree/templates/modal_form.html b/InvenTree/templates/modal_form.html index 566671c657..3c0674fec8 100644 --- a/InvenTree/templates/modal_form.html +++ b/InvenTree/templates/modal_form.html @@ -14,6 +14,9 @@ {% crispy form %} + + {% block form_data %} + {% endblock %} {% block post_form_content %}