Calculate quantity required for sales orders

- Cache data going to part detail view
This commit is contained in:
Oliver Walters 2021-02-17 10:57:17 +11:00
parent cda97829ab
commit 28c9c80f54
3 changed files with 63 additions and 25 deletions

View File

@ -41,7 +41,7 @@ from InvenTree.models import InvenTreeTree, InvenTreeAttachment
from InvenTree.fields import InvenTreeURLField
from InvenTree.helpers import decimal2string, normalize
from InvenTree.status_codes import BuildStatus, PurchaseOrderStatus
from InvenTree.status_codes import BuildStatus, PurchaseOrderStatus, SalesOrderStatus
from build import models as BuildModels
from order import models as OrderModels
@ -940,6 +940,42 @@ class Part(MPTTModel):
return quantity
def requiring_sales_orders(self):
"""
Return a list of sales orders which require this part
"""
orders = set()
# Get a list of line items for open orders which match this part
open_lines = OrderModels.SalesOrderLineItem.objects.filter(
order__status__in=SalesOrderStatus.OPEN,
part=self
)
for line in open_lines:
orders.add(line.order)
return orders
def required_sales_order_quantity(self):
"""
Return the quantity of this part required for active sales orders
"""
# Get a list of line items for open orders which match this part
open_lines = OrderModels.SalesOrderLineItem.objects.filter(
order__status__in=SalesOrderStatus.OPEN,
part=self
)
quantity = 0
for line in open_lines:
quantity += line.quantity
return quantity
@property
def quantity_to_order(self):
""" Return the quantity needing to be ordered for this part. """

View File

@ -126,28 +126,6 @@
<td>{% trans "In Stock" %}</td>
<td>{% include "part/stock_count.html" %}</td>
</tr>
{% if not part.is_template %}
{% if part.required_build_order_quantity > 0 %}
<tr>
<td><span class='fas fa-hand-holding'></span></td>
<td>{% trans "Required for Build Orders" %}</td>
<td>{% decimal part.required_build_order_quantity %}</td>
</tr>
{% endif %}
{% if part.build_order_allocation_count > 0 %}
<tr>
<td><span class='fas fa-dolly'></span></td>
<td>{% trans "Allocated to Build Orders" %}</td>
<td>{% decimal part.build_order_allocation_count %}</td>
</tr>
{% endif %}
{% if part.sales_order_allocation_count > 0 %}
<tr>
<td><span class='fas fa-dolly'></span></td>
<td>{% trans "Allocated to Sales Orders" %}</td>
<td>{% decimal part.sales_order_allocation_count %}</td>
</tr>
{% endif %}
{% if part.on_order > 0 %}
<tr>
<td><span class='fas fa-shopping-cart'></span></td>
@ -155,7 +133,21 @@
<td>{% decimal part.on_order %}</td>
</tr>
{% endif %}
{% if required > 0 %}
<tr>
<td><span class='fas fa-clipboard-list'></span></td>
<td>{% trans "Required for Orders" %}</td>
<td>{% decimal required %}
</tr>
{% endif %}
{% if allocated > 0 %}
<tr>
<td><span class='fas fa-dolly'></span></td>
<td>{% trans "Allocated to Orders" %}</td>
<td>{% decimal allocated %}</td>
</tr>
{% endif %}
{% if not part.is_template %}
{% if part.assembly %}
<tr>
@ -169,11 +161,11 @@
<td>{% trans "Can Build" %}</td>
<td>{% decimal part.can_build %}</td>
</tr>
{% if part.quantity_being_built > 0 %}
{% if quantity_being_built > 0 %}
<tr>
<td></td>
<td>{% trans "Underway" %}</td>
<td>{% decimal part.quantity_being_built %}</td>
<td>{% decimal quantity_being_built %}</td>
</tr>
{% endif %}
{% endif %}

View File

@ -792,6 +792,16 @@ class PartDetail(InvenTreeRoleMixin, DetailView):
context['starred'] = part.isStarredBy(self.request.user)
context['disabled'] = not part.active
# Pre-calculate complex queries so they only need to be performed once
context['required_build_order_quantity'] = part.required_build_order_quantity()
context['allocated_build_order_quantity'] = part.build_order_allocation_count()
context['required_sales_order_quantity'] = part.required_sales_order_quantity()
context['allocated_sales_order_quantity'] = part.sales_order_allocation_count()
context['required'] = context['required_build_order_quantity'] + context['required_sales_order_quantity']
context['allocated'] = context['allocated_build_order_quantity'] + context['allocated_sales_order_quantity']
return context