More stuff

This commit is contained in:
Oliver Walters 2020-04-22 22:22:22 +10:00
parent 6ab03bd05a
commit fd42149f67
7 changed files with 80 additions and 7 deletions

View File

@ -42,6 +42,10 @@
opacity: 60%;
}
.progress-bar-exceed {
background: #eeaa33;
}
.progress-value {
width: 100%;
color: #333;

View File

@ -113,11 +113,17 @@ function makeProgressBar(value, maximum, opts) {
percent = 100;
}
var extraclass = '';
if (value > maximum) {
extraclass='progress-bar-exceed';
}
var id = opts.id || 'progress-bar';
return `
<div id='${id}' class='progress'>
<div class='progress-bar' role='progressbar' aria-valuenow='${percent}' aria-valuemin='0' aria-valuemax='100' style='width:${percent}%'></div>
<div class='progress-bar ${extraclass}' role='progressbar' aria-valuenow='${percent}' aria-valuemin='0' aria-valuemax='100' style='width:${percent}%'></div>
<div class='progress-value'>${value} / ${maximum}</div>
</div>
`;

View File

@ -24,7 +24,7 @@ from stock import models as stock_models
from company.models import Company, SupplierPart
from InvenTree.fields import RoundingDecimalField
from InvenTree.helpers import decimal2string
from InvenTree.helpers import decimal2string, normalize
from InvenTree.status_codes import OrderStatus
from InvenTree.models import InvenTreeAttachment
@ -277,6 +277,15 @@ class SalesOrder(Order):
customer_reference = models.CharField(max_length=64, blank=True, help_text=_("Customer order reference code"))
def is_fully_allocated(self):
""" Return True if all line items are fully allocated """
for line in self.lines.all():
if not line.is_fully_allocated():
return False
return True
class PurchaseOrderAttachment(InvenTreeAttachment):
"""
@ -385,6 +394,12 @@ class SalesOrderLineItem(OrderLineItem):
return query['allocated']
def is_fully_allocated(self):
return self.allocated_quantity() >= self.quantity
def is_over_allocated(self):
return self.allocated_quantity() > self.quantity
class SalesOrderAllocation(models.Model):
"""
@ -457,7 +472,7 @@ class SalesOrderAllocation(models.Model):
if self.item.serial and self.quantity == 1:
return "# {sn}".format(sn=self.item.serial)
else:
return self.quantity
return normalize(self.quantity)
def get_location(self):
return self.item.location.id if self.item.location else None

View File

@ -9,6 +9,14 @@
InvenTree | {% trans "Sales Order" %}
{% endblock %}
{% block pre_content %}
{% if not order.is_fully_allocated %}
<div class='alert alert-block alert-danger'>
{% trans "This SalesOrder has not been fully allocated" %}
</div>
{% endif %}
{% endblock %}
{% block thumbnail %}
<img class='part-thumb'
{% if order.customer.image %}

View File

@ -190,7 +190,7 @@ $("#so-lines-table").on('load-success.bs.table', function() {
var pk = $(this).attr('pk');
launchModalForm(`/order/sales-order/allocation/new/`, {
reload: table,
success: reloadTable,
data: {
line: pk,
},

View File

@ -95,6 +95,9 @@ sales_order_urls = [
# URLs for sales order allocations
url(r'^allocation/', include([
url(r'^new/', views.SalesOrderAllocationCreate.as_view(), name='so-allocation-create'),
url(r'(?P<pk>\d+)/', include([
url(r'^edit/', views.SalesOrderAllocationEdit.as_view(), name='so-allocation-edit'),
])),
])),
url(r'^attachments/', include(sales_order_attachment_urls)),

View File

@ -1173,11 +1173,33 @@ class SalesOrderAllocationCreate(AjaxCreateView):
def get_initial(self):
initials = super().get_initial().copy()
line = self.request.GET.get('line', None)
line_id = self.request.GET.get('line', None)
if line is not None:
initials['line'] = SalesOrderLineItem.objects.get(pk=line)
if line_id is not None:
line = SalesOrderLineItem.objects.get(pk=line_id)
initials['line'] = line
# Search for matching stock items, pre-fill if there is only one
items = StockItem.objects.filter(part=line.part)
quantity = line.quantity - line.allocated_quantity()
if quantity < 0:
quantity = 0
if items.count() == 1:
item = items.first()
initials['item'] = item
# Reduce the quantity IF there is not enough stock
qmax = item.quantity - item.allocation_count()
if qmax < quantity:
quantity = qmax
initials['quantity'] = quantity
return initials
def get_form(self):
@ -1209,3 +1231,18 @@ class SalesOrderAllocationCreate(AjaxCreateView):
pass
return form
class SalesOrderAllocationEdit(AjaxUpdateView):
model = SalesOrderAllocation
ajax_form_title = _('Edit Allocation Quantity')
def get_form(self):
form = super().get_form()
# Prevent the user from editing particular fields
form.fields.pop('item')
form.fields.pop('line')
return form