From cb636e000d4c97b45bf0b564eb14864a6ff3c9ab Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 21 Apr 2020 21:38:04 +1000 Subject: [PATCH] Display a sub-list of stock items which are allocated to a SalseOrderLineItem --- InvenTree/InvenTree/static/css/inventree.css | 9 +++ .../InvenTree/static/script/inventree/bom.js | 1 - .../templates/order/sales_order_detail.html | 78 +++++++++++++++++++ InvenTree/part/serializers.py | 4 +- .../stock/templates/stock/item_base.html | 6 +- 5 files changed, 93 insertions(+), 5 deletions(-) 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 %}
- {% trans "This stock item is allocated to " %} - {{ item.sales_order.order }} + {% trans "This stock item is allocated to Sales Order" %} + {{ item.sales_order_line.order }}
{% endif %}