From 09083d2de1eeeb637aa60bb95ecee6e9da0b696c Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 6 May 2023 08:39:10 +1000 Subject: [PATCH] Build filters (#4773) * Add optional callback to table filtering function * Add custom filters to build item table --- .../build/templates/build/build_base.html | 6 -- InvenTree/templates/js/translated/build.js | 55 +++++++++++++++++-- InvenTree/templates/js/translated/filters.js | 9 ++- .../templates/js/translated/table_filters.js | 25 +++++++++ InvenTree/templates/js/translated/tables.js | 8 ++- 5 files changed, 87 insertions(+), 16 deletions(-) diff --git a/InvenTree/build/templates/build/build_base.html b/InvenTree/build/templates/build/build_base.html index fecc6638f6..f811d30474 100644 --- a/InvenTree/build/templates/build/build_base.html +++ b/InvenTree/build/templates/build/build_base.html @@ -117,12 +117,6 @@ src="{% static 'img/blank_image.png' %}" {% trans "No build outputs have been created for this build order" %}
{% endif %} - {% if build.parent %} -
- {% object_link 'build-detail' build.parent.id build.parent as link %} - {% blocktrans %}This Build Order is a child of Build Order {{link}}{% endblocktrans %} -
- {% endif %} {% if build.active %} {% if build.can_complete %} diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js index f22eec19a4..deb971d7f7 100644 --- a/InvenTree/templates/js/translated/build.js +++ b/InvenTree/templates/js/translated/build.js @@ -1461,16 +1461,58 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) { ); } - var table = options.table; + // Apply filters to build table + // As the table is constructed locally, we can apply filters directly + function filterBuildAllocationTable(filters={}) { + $(table).bootstrapTable( + 'filterBy', + filters, + { + 'filterAlgorithm': function(row, filters) { + let result = true; - if (options.table == null) { - table = `#allocation-table-${outputId}`; + if (!filters) { + return true; + } + + // Filter by 'consumable' flag + if ('consumable' in filters) { + result &= filters.consumable == '1' ? row.consumable : !row.consumable; + } + + // Filter by 'optional' flag + if ('optional' in filters) { + result &= filters.optional == '1' ? row.optional : !row.optional; + } + + // Filter by 'allocated' flag + if ('allocated' in filters) { + let fully_allocated = row.consumable || isRowFullyAllocated(row); + result &= filters.allocated == '1' ? fully_allocated : !fully_allocated; + } + + // Filter by 'available' flag + if ('available' in filters) { + let available = row.available_stock > 0; + result &= filters.available == '1' ? available : !available; + } + + return result; + } + } + ); } + var table = options.table || `#allocation-table-${outputId}`; + // Filters let filters = loadTableFilters('builditems', options.params); - setupFilterList('builditems', $(table), options.filterTarget); + setupFilterList('builditems', $(table), options.filterTarget, { + callback: function(table, filters, options) { + filterBuildAllocationTable(filters); + } + }); var allocated_items = output == null ? null : output.allocations; @@ -1685,6 +1727,9 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) { search: options.search || false, queryParams: filters, original: options.params, + onRefresh: function(data) { + filterBuildAllocationTable(filters); + }, onPostBody: function(data) { // Setup button callbacks setupCallbacks(); @@ -2037,6 +2082,8 @@ function loadBuildOutputAllocationTable(buildInfo, output, options={}) { }, ] }); + + filterBuildAllocationTable(filters); } diff --git a/InvenTree/templates/js/translated/filters.js b/InvenTree/templates/js/translated/filters.js index bc352edf33..0390bc1052 100644 --- a/InvenTree/templates/js/translated/filters.js +++ b/InvenTree/templates/js/translated/filters.js @@ -429,7 +429,7 @@ function setupFilterList(tableKey, table, target, options={}) { // Callback for reloading the table element.find(`#reload-${tableKey}`).click(function() { - reloadTableFilters(table); + reloadTableFilters(table, {}, options); }); // Add a callback for downloading table data @@ -472,7 +472,7 @@ function setupFilterList(tableKey, table, target, options={}) { // Only add the new filter if it is not empty! if (tag && tag.length > 0) { var filters = addTableFilter(tableKey, tag, val); - reloadTableFilters(table, filters); + reloadTableFilters(table, filters, options); // Run this function again setupFilterList(tableKey, table, target, options); @@ -491,8 +491,7 @@ function setupFilterList(tableKey, table, target, options={}) { element.find(`#${clear}`).click(function() { var filters = clearTableFilters(tableKey); - reloadTableFilters(table, filters); - + reloadTableFilters(table, filters, options); setupFilterList(tableKey, table, target, options); }); @@ -504,7 +503,7 @@ function setupFilterList(tableKey, table, target, options={}) { var filters = removeTableFilter(tableKey, filter); - reloadTableFilters(table, filters); + reloadTableFilters(table, filters, options); // Run this function again! setupFilterList(tableKey, table, target, options); diff --git a/InvenTree/templates/js/translated/table_filters.js b/InvenTree/templates/js/translated/table_filters.js index 6c5d94a4c4..d2b290cac1 100644 --- a/InvenTree/templates/js/translated/table_filters.js +++ b/InvenTree/templates/js/translated/table_filters.js @@ -459,6 +459,29 @@ function getBuildTableFilters() { } +// Return a dictionary of filters for the "build item" table +function getBuildItemTableFilters() { + return { + allocated: { + type: 'bool', + title: '{% trans "Allocated" %}', + }, + available: { + type: 'bool', + title: '{% trans "Available" %}', + }, + consumable: { + type: 'bool', + title: '{% trans "Consumable" %}', + }, + optional: { + type: 'bool', + title: '{% trans "Optional" %}', + }, + }; +} + + // Return a dictionary of filters for the "purchase order line item" table function getPurchaseOrderLineItemFilters() { return { @@ -682,6 +705,8 @@ function getAvailableTableFilters(tableKey) { return getBOMTableFilters(); case 'build': return getBuildTableFilters(); + case 'builditems': + return getBuildItemTableFilters(); case 'location': return getStockLocationFilters(); case 'parts': diff --git a/InvenTree/templates/js/translated/tables.js b/InvenTree/templates/js/translated/tables.js index cc38763e14..2af0f72529 100644 --- a/InvenTree/templates/js/translated/tables.js +++ b/InvenTree/templates/js/translated/tables.js @@ -247,7 +247,13 @@ function isNumeric(n) { * Reload a table which has already been made into a bootstrap table. * New filters can be optionally provided, to change the query params. */ -function reloadTableFilters(table, filters) { +function reloadTableFilters(table, filters, options={}) { + + // If a callback is specified, let's use that + if (options.callback) { + options.callback(table, filters, options); + return; + } // Simply perform a refresh if (filters == null) {