diff --git a/InvenTree/templates/js/build.html b/InvenTree/templates/js/build.html
index 4118e6ed54..0169fc0276 100644
--- a/InvenTree/templates/js/build.html
+++ b/InvenTree/templates/js/build.html
@@ -100,6 +100,7 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
return "{% trans "No BOM items found" %}";
},
name: 'build-allocation',
+ uniqueId: 'sub_part',
onPostBody: setupCallbacks,
onLoadSuccess: function(tableData) {
// Once the BOM data are loaded, request allocation data for this build output
@@ -111,11 +112,38 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
},
{
success: function(data) {
- // TODO
+ // Iterate through the returned data, and group by the part they point to
+ var allocations = {};
+
+ data.forEach(function(item) {
+
+ // Group BuildItem objects by part
+ var part = item.part;
+ var key = parseInt(part);
+
+ if (!(key in allocations)) {
+ allocations[key] = new Array();
+ }
+
+ allocations[key].push(item);
+ });
+
+ // Now update the allocations for each row in the table
+ for (var key in allocations) {
+ // Select the associated row in the table
+ var tableRow = $(table).bootstrapTable('getRowByUniqueId', key);
+
+ // Set the allocation list for that row
+ tableRow.allocations = allocations[key];
+
+ // Push the updated row back into the main table
+ $(table).bootstrapTable('updateByUniqueId', key, tableRow, true);
+ }
}
}
);
},
+ sortable: true,
showColumns: false,
detailViewByClick: true,
detailView: true,
@@ -123,8 +151,99 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
return row.allocations != null;
},
detailFormatter: function(index, row, element) {
- // TODO
- return '---';
+ // Contruct an 'inner table' which shows which stock items have been allocated
+
+ var subTableId = `allocation-table-${row.pk}`;
+
+ var html = `
`;
+
+ element.html(html);
+
+ var lineItem = row;
+
+ var subTable = $(`#${subTableId}`);
+
+ subTable.bootstrapTable({
+ data: row.allocations,
+ showHeader: true,
+ columns: [
+ {
+ width: '50%',
+ field: 'quantity',
+ title: '{% trans "Assigned Stock" %}',
+ formatter: function(value, row, index, field) {
+ var text = '';
+
+ var url = '';
+
+ if (row.serial && row.quantity == 1) {
+ text = `{% trans "Serial Number" %}: ${row.serial}`;
+ } else {
+ text = `{% trans "Quantity" %}: ${row.quantity}`;
+ }
+
+ {% if build.status == BuildStatus.COMPLETE %}
+ url = `/stock/item/${row.pk}/`;
+ {% else %}
+ url = `/stock/item/${row.stock_item}/`;
+ {% endif %}
+
+ return renderLink(text, url);
+ }
+ },
+ {
+ field: 'location',
+ title: '{% trans "Location" %}',
+ formatter: function(value, row, index, field) {
+ if (row.stock_item_detail.location) {
+ var text = row.stock_item_detail.location_name;
+ var url = `/stock/location/${row.stock_item_detail.location}/`;
+
+ return renderLink(text, url);
+ } else {
+ return '{% trans "No location set" %}';
+ }
+ }
+ },
+ {
+ field: 'actions',
+ formatter: function(value, row, index, field) {
+ /* Actions available for a particular stock item allocation:
+ *
+ * - Edit the allocation quantity
+ * - Delete the allocation
+ */
+
+ var pk = row.pk;
+
+ var html = ``;
+
+ html += makeIconButton('fa-edit icon-blue', 'button-allocation-edit', pk, '{% trans "Edit stock allocation" %}');
+
+ html += makeIconButton('fa-trash-alt icon-red', 'button-allocation-delete', pk, '{% trans "Delete stock allocation" %}');
+
+ html += `
`;
+
+ return html;
+ }
+ }
+ ]
+ });
+
+ // Assign button callbacks to the newly created allocation buttons
+ subTable.find('.button-allocation-edit').click(function() {
+ var pk = $(this).attr('pk');
+ launchModalForm(`/build/item/${pk}/edit/`, {
+ success: reloadTable,
+ });
+ });
+
+ subTable.find('.button-allocation-delete').click(function() {
+ var pk = $(this).attr('pk');
+ launchModalForm(`/build/item/${pk}/delete/`, {
+ success: reloadTable,
+ });
+ });
},
columns: [
{
@@ -148,12 +267,21 @@ function loadBuildOutputAllocationTable(buildId, partId, output, options={}) {
{
field: 'reference',
title: '{% trans "Reference" %}',
+ sortable: true,
},
{
field: 'allocated',
title: '{% trans "Allocated" %}',
+ sortable: true,
formatter: function(value, row, index, field) {
- var allocated = value || 0;
+ var allocated = 0;
+
+ if (row.allocations) {
+ row.allocations.forEach(function(item) {
+ allocated += item.quantity;
+ });
+ }
+
var required = row.quantity * output.quantity;
return makeProgressBar(allocated, required);