diff --git a/InvenTree/InvenTree/static/script/inventree/inventree.js b/InvenTree/InvenTree/static/script/inventree/inventree.js
index 87fb53b294..238fc0a6a6 100644
--- a/InvenTree/InvenTree/static/script/inventree/inventree.js
+++ b/InvenTree/InvenTree/static/script/inventree/inventree.js
@@ -78,6 +78,14 @@ function getImageUrlFromTransfer(transfer) {
return url;
}
+function makeIconBadge(icon, title) {
+ // Construct an 'icon badge' which floats to the right of an object
+
+ var html = ``;
+
+ return html;
+}
+
function makeIconButton(icon, cls, pk, title, options={}) {
// Construct an 'icon button' using the fontawesome set
diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py
index e46a204a36..7cead39cb8 100644
--- a/InvenTree/build/models.py
+++ b/InvenTree/build/models.py
@@ -567,7 +567,7 @@ class Build(MPTTModel):
required = self.getRequiredQuantity(part, output=output)
allocated = self.getAllocatedQuantity(part, output=output)
- return max(required-allocated, 0)
+ return max(required - allocated, 0)
@property
def required_parts(self):
@@ -618,7 +618,6 @@ class Build(MPTTModel):
return items
-
@property
def can_build(self):
""" Return true if there are enough parts to supply build """
diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py
index 73d2561e09..94d661ef8d 100644
--- a/InvenTree/build/views.py
+++ b/InvenTree/build/views.py
@@ -179,11 +179,15 @@ class BuildOutputDelete(AjaxUpdateView):
valid = False
- if output:
- build.deleteBuildOutput(output)
- valid = True
+ if confirm:
+ if output:
+ build.deleteBuildOutput(output)
+ valid = True
+ else:
+ form.non_field_errors = [_('Build or output not specified')]
else:
- form.non_field_errors = [_('Build or output not specified')]
+ form.errors['confirm'] = [_('Confirm unallocation of build stock')]
+ form.non_field_errors = [_('Check the confirmation box')]
data = {
'form_valid': valid,
@@ -191,6 +195,7 @@ class BuildOutputDelete(AjaxUpdateView):
return self.renderJsonResponse(request, form, data)
+
class BuildUnallocate(AjaxUpdateView):
""" View to un-allocate all parts from a build.
diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html
index 2538dbd398..80eeb16ec5 100644
--- a/InvenTree/stock/templates/stock/item_base.html
+++ b/InvenTree/stock/templates/stock/item_base.html
@@ -37,13 +37,13 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}
{% for allocation in item.sales_order_allocations.all %}
{% endfor %}
{% for allocation in item.allocations.all %}
- {% trans "This stock item is allocated to Build" %}
#{{ allocation.build.id }} ({% trans "Quantity" %}: {% decimal allocation.quantity %})
+ {% trans "This stock item is allocated to Build" %}
#{{ allocation.build }} ({% trans "Quantity" %}: {% decimal allocation.quantity %})
{% endfor %}
diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js
index f92e1e5f89..78323b039e 100644
--- a/InvenTree/templates/js/stock.js
+++ b/InvenTree/templates/js/stock.js
@@ -276,7 +276,11 @@ function loadStockTable(table, options) {
// URL (optional)
var url = '';
- if (row.belongs_to) {
+ if (row.is_building && row.build) {
+ // StockItem is currently being built!
+ text = "{% trans "In production" %}";
+ url = `/build/${row.build}/`;
+ } else if (row.belongs_to) {
// StockItem is installed inside a different StockItem
text = `{% trans "Installed in Stock Item" %} ${row.belongs_to}`;
url = `/stock/item/${row.belongs_to}/installed/`;
@@ -288,10 +292,6 @@ function loadStockTable(table, options) {
// StockItem has been assigned to a sales order
text = "{% trans "Assigned to Sales Order" %}";
url = `/order/sales-order/${row.sales_order}/`;
- } else if (row.is_building && row.build) {
- // StockItem is currently being built!
- text = "{% trans "In production" %}";
- url = `/build/${row.build}/`;
} else if (row.location) {
text = row.location_detail.pathstring;
url = `/stock/location/${row.location}/`;
@@ -507,33 +507,35 @@ function loadStockTable(table, options) {
var html = renderLink(val, `/stock/item/${row.pk}/`);
- if (row.allocated) {
- html += ``;
+ if (row.is_building) {
+ html += makeIconBadge('fa-tools', '{% trans "Stock item is in production" %}');
+ }
+
+ if (row.sales_order) {
+ // Stock item has been assigned to a sales order
+ html += makeIconBadge('fa-truck', '{% trans "Stock item assigned to sales order" %}');
+ } else if (row.customer) {
+ // StockItem has been assigned to a customer
+ html += makeIconBadge('fa-user', '{% trans "Stock item assigned to customer" %}');
}
- if (row.customer) {
- html += ``;
- } else {
- if (row.build_order) {
- html += ``;
- } else if (row.sales_order) {
- html += ``;
- }
+ if (row.allocated) {
+ html += makeIconBadge('fa-bookmark', '{% trans "Stock item has been allocated" %}');
}
if (row.belongs_to) {
- html += ``;
+ html += makeIconBadge('fa-box', '{% trans "Stock item has been installed in another item" %}');
}
// Special stock status codes
// 65 = "REJECTED"
if (row.status == 65) {
- html += ``;
+ html += makeIconButton('fa-times-circle icon-red', '{% trans "Stock item has been rejected" %}');
}
// 70 = "LOST"
else if (row.status == 70) {
- html += ``;
+ html += makeIconButton('fa-question-circle','{% trans "Stock item is lost" %}');
}
if (row.quantity <= 0) {