From a78b26f93af6285dde05c53cdd2b530f0a50633a Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 28 Jun 2023 15:22:23 +1000 Subject: [PATCH] Child items table (#5114) * Template cleanup - Remove "buttons" attribute (outdated) * Fix filters for "child stock items" table * Fix 'ancestor' stock filter --- InvenTree/build/templates/build/detail.html | 3 --- .../company/templates/company/detail.html | 3 --- .../templates/company/supplier_part.html | 1 - .../order/purchase_order_detail.html | 3 --- InvenTree/part/templates/part/detail.html | 3 --- InvenTree/stock/api.py | 26 +++++++++---------- InvenTree/stock/templates/stock/item.html | 8 +++--- InvenTree/stock/templates/stock/location.html | 3 --- InvenTree/templates/js/translated/stock.js | 26 +++++++++---------- 9 files changed, 29 insertions(+), 47 deletions(-) diff --git a/InvenTree/build/templates/build/detail.html b/InvenTree/build/templates/build/detail.html index 2da2410fc8..7e6efff2af 100644 --- a/InvenTree/build/templates/build/detail.html +++ b/InvenTree/build/templates/build/detail.html @@ -306,9 +306,6 @@ onPanelLoad('completed', function() { build: {{ build.id }}, is_building: false, }, - buttons: [ - '#stock-options', - ], }); }); diff --git a/InvenTree/company/templates/company/detail.html b/InvenTree/company/templates/company/detail.html index 6a653d2d0d..7d380d7c2f 100644 --- a/InvenTree/company/templates/company/detail.html +++ b/InvenTree/company/templates/company/detail.html @@ -319,9 +319,6 @@ supplier_part_detail: true, location_detail: true, }, - buttons: [ - '#stock-options', - ], filterKey: "companystock", }); }); diff --git a/InvenTree/company/templates/company/supplier_part.html b/InvenTree/company/templates/company/supplier_part.html index 9fc84ce123..5a37cbae43 100644 --- a/InvenTree/company/templates/company/supplier_part.html +++ b/InvenTree/company/templates/company/supplier_part.html @@ -322,7 +322,6 @@ loadStockTable($("#stock-table"), { location_detail: true, part_detail: false, }, - buttons: ['#stock-options'], }); $("#item-create").click(function() { diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index d7491f753e..85065ff46f 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -150,9 +150,6 @@ supplier_part_detail: true, location_detail: true, }, - buttons: [ - '#stock-options', - ], filterkey: "postock" }); diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index 8ecac03b6c..32bd4ac3a8 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -769,9 +769,6 @@ part_detail: true, supplier_part_detail: true, }, - buttons: [ - '#stock-options', - ], }); $('#item-create').click(function () { diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py index 3dd9480ac1..3011e2e9df 100644 --- a/InvenTree/stock/api.py +++ b/InvenTree/stock/api.py @@ -552,6 +552,19 @@ class StockFilter(rest_filters.FilterSet): else: return queryset.filter(purchase_price=None) + ancestor = rest_filters.ModelChoiceFilter( + label='Ancestor', + queryset=StockItem.objects.all(), + method='filter_ancestor' + ) + + def filter_ancestor(self, queryset, name, ancestor): + """Filter based on ancestor stock item""" + + return queryset.filter( + parent__in=ancestor.get_descendants(include_self=True) + ) + # Update date filters updated_before = rest_filters.DateFilter(label='Updated before', field_name='updated', lookup_expr='lte') updated_after = rest_filters.DateFilter(label='Updated after', field_name='updated', lookup_expr='gte') @@ -929,19 +942,6 @@ class StockList(APIDownloadMixin, ListCreateDestroyAPIView): except (ValueError, Part.DoesNotExist): raise ValidationError({"part": "Invalid Part ID specified"}) - # Does the client wish to filter by the 'ancestor'? - anc_id = params.get('ancestor', None) - - if anc_id: - try: - ancestor = StockItem.objects.get(pk=anc_id) - - # Only allow items which are descendants of the specified StockItem - queryset = queryset.filter(id__in=[item.pk for item in ancestor.children.all()]) - - except (ValueError, Part.DoesNotExist): - raise ValidationError({"ancestor": "Invalid ancestor ID specified"}) - # Does the client wish to filter by stock location? loc_id = params.get('location', None) diff --git a/InvenTree/stock/templates/stock/item.html b/InvenTree/stock/templates/stock/item.html index 81ec9ef059..a36dd54f91 100644 --- a/InvenTree/stock/templates/stock/item.html +++ b/InvenTree/stock/templates/stock/item.html @@ -65,6 +65,7 @@
{% if item.child_count > 0 %} + {% include "filter_list.html" with id="stock-childs" %} {% include "stock_table.html" with prefix="childs-" %} {% else %}
@@ -300,14 +301,11 @@ {% if item.child_count > 0 %} loadStockTable($("#childs-stock-table"), { params: { - location_detail: true, - part_detail: false, ancestor: {{ item.id }}, }, name: 'item-childs', - buttons: [ - '#stock-options', - ], + filterTarget: '#filter-list-stock-childs', + filterKey: 'stock', }); {% endif %} diff --git a/InvenTree/stock/templates/stock/location.html b/InvenTree/stock/templates/stock/location.html index 98a8283002..60dad09d64 100644 --- a/InvenTree/stock/templates/stock/location.html +++ b/InvenTree/stock/templates/stock/location.html @@ -403,9 +403,6 @@ onPanelLoad('stock', function() { loadStockTable($("#stock-table"), { - buttons: [ - '#stock-options', - ], params: { {% if location %} location: {{ location.pk }}, diff --git a/InvenTree/templates/js/translated/stock.js b/InvenTree/templates/js/translated/stock.js index 09351e0bc1..af07802601 100644 --- a/InvenTree/templates/js/translated/stock.js +++ b/InvenTree/templates/js/translated/stock.js @@ -1834,6 +1834,8 @@ function makeStockActions(table) { */ function loadStockTable(table, options) { + options.params = options.params || {}; + // List of user-params which override the default filters options.params['location_detail'] = true; options.params['part_detail'] = true; @@ -1841,8 +1843,6 @@ function loadStockTable(table, options) { // Determine if installed items are displayed in the table let show_installed_items = global_settings.STOCK_SHOW_INSTALLED_ITEMS; - var params = options.params || {}; - let filters = {}; if (!options.disableFilters) { @@ -1850,7 +1850,7 @@ function loadStockTable(table, options) { const filterTarget = options.filterTarget || '#filter-list-stock'; const filterKey = options.filterKey || options.name || 'stock'; - filters = loadTableFilters(filterKey, params); + filters = loadTableFilters(filterKey, options.params); setupFilterList(filterKey, table, filterTarget, { download: true, @@ -1886,7 +1886,7 @@ function loadStockTable(table, options) { }); } - filters = Object.assign(filters, params); + filters = Object.assign(filters, options.params); var col = null; @@ -1909,8 +1909,8 @@ function loadStockTable(table, options) { field: 'part', title: '{% trans "Part" %}', sortName: 'part__name', - visible: params['part_detail'], - switchable: params['part_detail'], + visible: options.params['part_detail'], + switchable: options.params['part_detail'], formatter: function(value, row) { let html = ''; @@ -1948,8 +1948,8 @@ function loadStockTable(table, options) { field: 'IPN', title: '{% trans "IPN" %}', sortName: 'part__IPN', - visible: params['part_detail'], - switchable: params['part_detail'], + visible: options.params['part_detail'], + switchable: options.params['part_detail'], formatter: function(value, row) { var ipn = row.part_detail.IPN; if (ipn) { @@ -1969,8 +1969,8 @@ function loadStockTable(table, options) { columns.push({ field: 'part_detail.description', title: '{% trans "Description" %}', - visible: params['part_detail'], - switchable: params['part_detail'], + visible: options.params['part_detail'], + switchable: options.params['part_detail'], formatter: function(value, row) { var description = row.part_detail.description; return withTitle(shortenString(description), description); @@ -2168,8 +2168,8 @@ function loadStockTable(table, options) { field: 'supplier_part', title: '{% trans "Supplier Part" %}', - visible: params['supplier_part_detail'] || false, - switchable: params['supplier_part_detail'] || false, + visible: options.params['supplier_part_detail'] || false, + switchable: options.params['supplier_part_detail'] || false, formatter: function(value, row) { if (!value) { return '-'; @@ -2358,7 +2358,7 @@ function loadStockTable(table, options) { queryParams: filters, sidePagination: 'server', name: 'stock', - original: params, + original: options.params, showColumns: true, showFooter: true, columns: columns,