diff --git a/InvenTree/InvenTree/static/css/inventree.css b/InvenTree/InvenTree/static/css/inventree.css
index a8efcd0844..29eac04c55 100644
--- a/InvenTree/InvenTree/static/css/inventree.css
+++ b/InvenTree/InvenTree/static/css/inventree.css
@@ -158,6 +158,15 @@
background-color: #ebf4f4;
}
+.sub-table {
+ margin-left: 25px;
+ margin-right: 25px;
+}
+
+.detail-icon .glyphicon {
+ color: #98d296;
+}
+
/* Force select2 elements in modal forms to be full width */
.select-full-width {
width: 100%;
diff --git a/InvenTree/InvenTree/static/script/inventree/bom.js b/InvenTree/InvenTree/static/script/inventree/bom.js
index 3d1e8fc594..def3910999 100644
--- a/InvenTree/InvenTree/static/script/inventree/bom.js
+++ b/InvenTree/InvenTree/static/script/inventree/bom.js
@@ -221,7 +221,6 @@ function loadBomTable(table, options) {
}
}
});
-
}
// Part notes
diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html
index 59ac73cd0a..53b3dd869c 100644
--- a/InvenTree/order/templates/order/sales_order_detail.html
+++ b/InvenTree/order/templates/order/sales_order_detail.html
@@ -44,6 +44,67 @@ $("#so-lines-table").inventreeTable({
part_detail: true,
},
url: "{% url 'api-so-line-list' %}",
+ detailView: true,
+ detailFilter: function(index, row) {
+ return row.allocated > 0;
+ },
+ detailFormatter: function(index, row, element) {
+ inventreeGet("{% url 'api-stock-list' %}",
+ {
+ location_detail: true,
+ sales_order_line: row.pk,
+ },
+ {
+ success: function(response) {
+
+ var html = `
`;
+
+ element.html(html);
+
+ $(`#allocation-table-${row.pk}`).bootstrapTable({
+ data: response,
+ showHeader: false,
+ columns: [
+ {
+ width: '50%',
+ field: 'quantity',
+ title: 'Quantity',
+ formatter: function(value, row, index, field) {
+ var html = '';
+ if (row.serial && row.quantity == 1) {
+ html = `Serial Number: ${row.serial}`;
+ } else {
+ html = `Quantity: ${row.quantity}`;
+ }
+
+ return renderLink(html, `/stock/item/${row.pk}/`);
+ },
+ },
+ {
+ field: 'location',
+ title: 'Location',
+ formatter: function(value, row, index, field) {
+ return renderLink(row.location_detail.pathstring, `/stock/location/${row.location}/`);
+ },
+ },
+ {
+ field: 'buttons',
+ title: 'Actions',
+ formatter: function(value, row, index, field) {
+ return '';
+ },
+ },
+ ],
+ });
+ },
+ error: function(response) {
+ console.log("An error!");
+ },
+ }
+ );
+
+ return "{% trans 'Loading data' %}";
+ },
columns: [
{
field: 'pk',
@@ -73,12 +134,29 @@ $("#so-lines-table").inventreeTable({
title: 'Quantity',
formatter: function(value, row, index, field) {
return makeProgressBar(row.allocated, row.quantity);
+ },
+ sorter: function(valA, valB, rowA, rowB) {
+
+ if (rowA.allocated == 0 && rowB.allocated == 0) {
+ return (rowA.quantity > rowB.quantity) ? 1 : -1;
+ }
+
+ var progressA = rowA.allocated / rowA.quantity;
+ var progressB = rowB.allocated / rowA.quantity;
+
+ return (progressA < progressB) ? 1 : -1;
}
},
{
field: 'notes',
title: 'Notes',
},
+ {
+ field: 'buttons',
+ formatter: function(value, row, index, field) {
+ return '-';
+ }
+ },
],
});
diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py
index a7305dcb2e..4da079d4cc 100644
--- a/InvenTree/part/serializers.py
+++ b/InvenTree/part/serializers.py
@@ -233,9 +233,11 @@ class PartStarSerializer(InvenTreeModelSerializer):
class BomItemSerializer(InvenTreeModelSerializer):
""" Serializer for BomItem object """
+ price_range = serializers.CharField(read_only=True)
+
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
sub_part_detail = PartBriefSerializer(source='sub_part', many=False, read_only=True)
- price_range = serializers.CharField(read_only=True)
+
validated = serializers.BooleanField(read_only=True, source='is_line_valid')
def __init__(self, *args, **kwargs):
diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html
index f339258d0f..bcb6de9af8 100644
--- a/InvenTree/stock/templates/stock/item_base.html
+++ b/InvenTree/stock/templates/stock/item_base.html
@@ -5,10 +5,10 @@
{% load i18n %}
{% block content %}
-{% if item.sales_order %}
+{% if item.sales_order_line %}
{% endif %}