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) {