From a9f7457c12bcd27a4bb5984b3c42fc05a56d591b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20R=C3=B3zsahegyi?= Date: Sat, 2 Apr 2022 15:51:21 +0200 Subject: [PATCH 1/4] New part table filter on available stock --- InvenTree/InvenTree/version.py | 5 ++++- InvenTree/part/api.py | 14 ++++++++++++++ InvenTree/templates/js/translated/table_filters.js | 6 +++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py index fe28d780c7..0a9d39225b 100644 --- a/InvenTree/InvenTree/version.py +++ b/InvenTree/InvenTree/version.py @@ -12,11 +12,14 @@ import common.models INVENTREE_SW_VERSION = "0.7.0 dev" # InvenTree API version -INVENTREE_API_VERSION = 35 +INVENTREE_API_VERSION = 36 """ Increment this API version number whenever there is a significant change to the API that any clients need to know about +v36 -> 2022-04-03 + - Adds ability to filter part list endpoint by unallocated_stock argument + v35 -> 2022-04-01 : https://github.com/inventree/InvenTree/pull/2797 - Adds stock allocation information to the Part API - Adds calculated field for "unallocated_quantity" diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 3a2bb6eeb3..f7bb81520d 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -798,6 +798,20 @@ class PartFilter(rest_filters.FilterSet): return queryset + # unallocated_stock filter + unallocated_stock = rest_filters.BooleanFilter(label='Unallocated stock', method='filter_unallocated_stock') + + def filter_unallocated_stock(self, queryset, name, value): + + value = str2bool(value) + + if value: + queryset = queryset.filter(Q(unallocated_stock__gt=0)) + else: + queryset = queryset.filter(Q(unallocated_stock__lte=0)) + + return queryset + is_template = rest_filters.BooleanFilter() assembly = rest_filters.BooleanFilter() diff --git a/InvenTree/templates/js/translated/table_filters.js b/InvenTree/templates/js/translated/table_filters.js index 81d43d2c3f..6212568950 100644 --- a/InvenTree/templates/js/translated/table_filters.js +++ b/InvenTree/templates/js/translated/table_filters.js @@ -427,12 +427,16 @@ function getAvailableTableFilters(tableKey) { }, has_stock: { type: 'bool', - title: '{% trans "Stock available" %}', + title: '{% trans "In stock" %}', }, low_stock: { type: 'bool', title: '{% trans "Low stock" %}', }, + unallocated_stock: { + type: 'bool', + title: '{% trans "Available stock" %}', + }, assembly: { type: 'bool', title: '{% trans "Assembly" %}', From d912846e41d496623f8d7f1f1dee2eea9dae8036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20R=C3=B3zsahegyi?= Date: Sat, 2 Apr 2022 15:58:04 +0200 Subject: [PATCH 2/4] Use available quantities in part table, enhance stock badge --- InvenTree/templates/js/translated/part.js | 52 +++++++++++++++-------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index b0283a1b35..16d6062565 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -1160,12 +1160,14 @@ function partGridTile(part) { if (!part.in_stock) { stock = `{% trans "No Stock" %}`; + } else if (!part.unallocated_stock) { + stock = `{% trans "Not available" %}`; } rows += `{% trans "Stock" %}${stock}`; - if (part.on_order) { - rows += `{$ trans "On Order" %}${part.on_order}`; + if (part.ordering) { + rows += `{% trans "On Order" %}${part.ordering}`; } if (part.building) { @@ -1322,31 +1324,47 @@ function loadPartTable(table, url, options={}) { columns.push(col); col = { - field: 'in_stock', - title: '{% trans "Stock" %}', + field: 'unallocated_stock', + title: '{% trans "Available" %}', searchable: false, formatter: function(value, row) { var link = '?display=part-stock'; - if (value) { + if (row.in_stock) { // There IS stock available for this part // Is stock "low" (below the 'minimum_stock' quantity)? - if (row.minimum_stock && row.minimum_stock > value) { + if (row.minimum_stock && row.minimum_stock > row.in_stock) { value += `{% trans "Low stock" %}`; + } else if (value == 0) { + if (row.ordering) { + // There is no available stock, but stock is on order + value = `0{% trans "On Order" %}: ${row.ordering}`; + link = '?display=purchase-orders'; + } else if (row.building) { + // There is no available stock, but stock is being built + value = `0{% trans "Building" %}: ${row.building}`; + link = '?display=build-orders'; + } else { + // There is no available stock + value = `0{% trans "Not available" %}`; + } } - - } else if (row.on_order) { - // There is no stock available, but stock is on order - value = `0{% trans "On Order" %}: ${row.on_order}`; - link = '?display=purchase-orders'; - } else if (row.building) { - // There is no stock available, but stock is being built - value = `0{% trans "Building" %}: ${row.building}`; - link = '?display=build-orders'; } else { - // There is no stock available - value = `0{% trans "No Stock" %}`; + // There IS NO stock available for this part + + if (row.ordering) { + // There is no stock, but stock is on order + value = `0{% trans "On Order" %}: ${row.ordering}`; + link = '?display=purchase-orders'; + } else if (row.building) { + // There is no stock, but stock is being built + value = `0{% trans "Building" %}: ${row.building}`; + link = '?display=build-orders'; + } else { + // There is no stock + value = `0{% trans "No Stock" %}`; + } } return renderLink(value, `/part/${row.pk}/${link}`); From bc4b66e7d3fee0d96cdeb56195ce3150910b4145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20R=C3=B3zsahegyi?= Date: Sat, 2 Apr 2022 16:01:12 +0200 Subject: [PATCH 3/4] Render partStockLabel based on available/in stock quantites --- InvenTree/templates/js/translated/part.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index 16d6062565..1c6bd56d90 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -494,7 +494,11 @@ function duplicateBom(part_id, options={}) { function partStockLabel(part, options={}) { if (part.in_stock) { - return `{% trans "Stock" %}: ${part.in_stock}`; + if (part.unallocated_stock) { + return `{% trans "Available" %}: ${part.unallocated_stock}/${part.in_stock}`; + } else { + return `{% trans "Available" %}: ${part.unallocated_stock}/${part.in_stock}`; + } } else { return `{% trans "No Stock" %}`; } From ade5a81a1ab7f012b0ee85f624a2313b93a03c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20R=C3=B3zsahegyi?= Date: Sat, 2 Apr 2022 16:25:42 +0200 Subject: [PATCH 4/4] Enhance partStockLabel with ordering/building quantites --- InvenTree/templates/js/translated/part.js | 34 ++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index 1c6bd56d90..1c66c32b6e 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -494,14 +494,40 @@ function duplicateBom(part_id, options={}) { function partStockLabel(part, options={}) { if (part.in_stock) { - if (part.unallocated_stock) { - return `{% trans "Available" %}: ${part.unallocated_stock}/${part.in_stock}`; + // There IS stock available for this part + + // Is stock "low" (below the 'minimum_stock' quantity)? + if (part.minimum_stock && part.minimum_stock > part.in_stock) { + return `{% trans "Low stock" %}: ${part.in_stock}${part.units}`; + } else if (part.unallocated_stock == 0) { + if (part.ordering) { + // There is no available stock, but stock is on order + return `{% trans "On Order" %}: ${part.ordering}${part.units}`; + } else if (part.building) { + // There is no available stock, but stock is being built + return `{% trans "Building" %}: ${part.building}${part.units}`; + } else { + // There is no available stock + return `{% trans "Available" %}: 0/${part.in_stock}${part.units}`; + } } else { - return `{% trans "Available" %}: ${part.unallocated_stock}/${part.in_stock}`; + return `{% trans "Available" %}: ${part.unallocated_stock}/${part.in_stock}${part.units}`; } } else { - return `{% trans "No Stock" %}`; + // There IS NO stock available for this part + + if (part.ordering) { + // There is no stock, but stock is on order + return `{% trans "On Order" %}: ${part.ordering}${part.units}`; + } else if (part.building) { + // There is no stock, but stock is being built + return `{% trans "Building" %}: ${part.building}${part.units}`; + } else { + // There is no stock + return `{% trans "No Stock" %}`; + } } + }