mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Calculate quantity required for sales orders
- Cache data going to part detail view
This commit is contained in:
parent
cda97829ab
commit
28c9c80f54
@ -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. """
|
||||
|
@ -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 %}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user