mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Sales Order Allocation Improvements (#4556)
* Do not remove sales order allocations when returning an item against a return order * Also do not clear allocations when returning manually * stock item display tweaks * Add extra column to sales order allocation table * Improve methods for introspecting sales order allocations for stockitems * Only display "active" sales order allocations on a stock item detail page - All allocations are still visible in the allocation table * Can't have available quantity if you're not available tap's side of nose
This commit is contained in:
parent
847d49a42d
commit
4d8cfd77ff
@ -1766,9 +1766,6 @@ class ReturnOrder(TotalPriceMixin, Order):
|
||||
|
||||
stock_item = line.item
|
||||
|
||||
# Remove any allocations against the returned StockItem
|
||||
stock_item.clearAllocations()
|
||||
|
||||
deltas = {
|
||||
'status': StockStatus.QUARANTINED,
|
||||
'returnorder': self.pk,
|
||||
|
@ -33,7 +33,8 @@ from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
|
||||
InvenTreeURLField)
|
||||
from InvenTree.models import (InvenTreeAttachment, InvenTreeBarcodeMixin,
|
||||
InvenTreeTree, extract_int)
|
||||
from InvenTree.status_codes import StockHistoryCode, StockStatus
|
||||
from InvenTree.status_codes import (SalesOrderStatus, StockHistoryCode,
|
||||
StockStatus)
|
||||
from part import models as PartModels
|
||||
from plugin.events import trigger_event
|
||||
from plugin.models import MetadataMixin
|
||||
@ -1013,7 +1014,6 @@ class StockItem(InvenTreeBarcodeMixin, MetadataMixin, common.models.MetaMixin, M
|
||||
location=location
|
||||
)
|
||||
|
||||
self.clearAllocations()
|
||||
self.customer = None
|
||||
self.belongs_to = None
|
||||
self.sales_order = None
|
||||
@ -1059,9 +1059,33 @@ class StockItem(InvenTreeBarcodeMixin, MetadataMixin, common.models.MetaMixin, M
|
||||
|
||||
return total
|
||||
|
||||
def sales_order_allocation_count(self):
|
||||
def get_sales_order_allocations(self, active=True):
|
||||
"""Return a queryset for SalesOrderAllocations against this StockItem, with optional filters.
|
||||
|
||||
Arguments:
|
||||
active: Filter by 'active' status of the allocation
|
||||
"""
|
||||
query = self.sales_order_allocations.all()
|
||||
|
||||
if active is True:
|
||||
query = query.filter(
|
||||
line__order__status__in=SalesOrderStatus.OPEN,
|
||||
shipment__shipment_date=None
|
||||
)
|
||||
elif active is False:
|
||||
query = query.exclude(
|
||||
line__order__status__in=SalesOrderStatus.OPEN
|
||||
).exclude(
|
||||
shipment__shipment_date=None
|
||||
)
|
||||
|
||||
return query
|
||||
|
||||
def sales_order_allocation_count(self, active=True):
|
||||
"""Return the total quantity allocated to SalesOrders."""
|
||||
query = self.sales_order_allocations.aggregate(q=Coalesce(Sum('quantity'), Decimal(0)))
|
||||
|
||||
query = self.get_sales_order_allocations(active=active)
|
||||
query = query.aggregate(q=Coalesce(Sum('quantity'), Decimal(0)))
|
||||
|
||||
total = query['q']
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
{% include "filter_list.html" with id="salesorderallocation" %}
|
||||
</div>
|
||||
</div>
|
||||
<table class='table table-striped table-condensed' data-toolbar='#sales-order-allocation-toolbar' id='sales-order-allocation-table'></table>
|
||||
<table class='table table-striped table-condensed' data-toolbar='#sales-order-allocations-toolbar' id='sales-order-allocation-table'></table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -266,6 +266,12 @@
|
||||
|
||||
<div class='info-messages'>
|
||||
|
||||
{% if not item.in_stock %}
|
||||
<div class='alert alert-block alert-danger'>
|
||||
<span class='fas fa-info-circle'></span> {% trans "This stock item is unavailable" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if item.is_building %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "This stock item is in production and cannot be edited." %}<br>
|
||||
@ -281,12 +287,12 @@
|
||||
{% endif %}
|
||||
|
||||
{% if item.hasRequiredTests and not item.passedAllRequiredTests %}
|
||||
<div class='alert alert-block alert-danger'>
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% trans "This stock item has not passed all required tests" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% for allocation in item.sales_order_allocations.all %}
|
||||
{% for allocation in item.get_sales_order_allocations.all %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% object_link 'so-detail' allocation.line.order.id allocation.line.order as link %}
|
||||
{% decimal allocation.quantity as qty %}
|
||||
@ -301,12 +307,6 @@
|
||||
{% trans "This stock item is allocated to Build Order" %} {{ link }} {% if qty < item.quantity %}({% trans "Quantity" %}: {{ qty }}){% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% if item.serialized %}
|
||||
<div class='alert alert-block alert-warning'>
|
||||
{% trans "This stock item is serialized - it has a unique serial number and the quantity cannot be adjusted." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock details %}
|
||||
|
||||
@ -320,7 +320,7 @@
|
||||
<h5><span class='fas fa-hashtag'></span></h5>
|
||||
</td>
|
||||
<td>
|
||||
<h5>{% trans "Serial Number" %}</h5>
|
||||
<h5 title='{% trans "This stock item is serialized. It has a unique serial number and the quantity cannot be adjusted" %}'>{% trans "Serial Number" %}</h5>
|
||||
</td>
|
||||
<td><h5>
|
||||
{{ item.serial }}
|
||||
@ -348,7 +348,11 @@
|
||||
<h5><div class='fas fa-boxes'></div></h5>
|
||||
</td>
|
||||
<td>
|
||||
{% if item.in_stock %}
|
||||
<h5>{% trans "Available Quantity" %}</h5>
|
||||
{% else %}
|
||||
<h5>{% trans "Quantity" %}</h5>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<h5>{% if item.quantity != available %}{% decimal available %} / {% endif %}{% decimal item.quantity %} {% include "part/part_units.html" with part=item.part %}</h5>
|
||||
@ -367,7 +371,7 @@
|
||||
</tr>
|
||||
{% elif item.sales_order %}
|
||||
<tr>
|
||||
<td><span class='fas fa-user-tie'></span></td>
|
||||
<td><span class='fas fa-th-list'></span></td>
|
||||
<td>{% trans "Sales Order" %}</td>
|
||||
<td><a href="{% url 'so-detail' item.sales_order.id %}">{{ item.sales_order.reference }}</a> - <a href="{% url 'company-detail' item.sales_order.customer.id %}">{{ item.sales_order.customer.name }}</a></td>
|
||||
</tr>
|
||||
|
@ -1387,6 +1387,7 @@ function loadSalesOrderAllocationTable(table, options={}) {
|
||||
},
|
||||
{
|
||||
field: 'item',
|
||||
switchable: false,
|
||||
title: '{% trans "Stock Item" %}',
|
||||
formatter: function(value, row) {
|
||||
// Render a link to the particular stock item
|
||||
@ -1409,6 +1410,18 @@ function loadSalesOrderAllocationTable(table, options={}) {
|
||||
title: '{% trans "Quantity" %}',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'shipment_date',
|
||||
title: '{% trans "Shipped" %}',
|
||||
sortable: true,
|
||||
formatter: function(value, row) {
|
||||
if (value) {
|
||||
return renderDate(value);
|
||||
} else {
|
||||
return `<em>{% trans "Not shipped" %}</em>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user