diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py
index ddedd60ce6..dc2e81b978 100644
--- a/InvenTree/build/api.py
+++ b/InvenTree/build/api.py
@@ -5,12 +5,10 @@ JSON API for the Build app
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_object_or_404
from django.conf.urls import url, include
from rest_framework import filters, generics
-from rest_framework.serializers import ValidationError
from django_filters.rest_framework import DjangoFilterBackend
from django_filters import rest_framework as rest_filters
diff --git a/InvenTree/build/templates/build/detail.html b/InvenTree/build/templates/build/detail.html
index cfba2046e3..d715149718 100644
--- a/InvenTree/build/templates/build/detail.html
+++ b/InvenTree/build/templates/build/detail.html
@@ -218,26 +218,21 @@
{% trans "Incomplete Build Outputs" %}
-
- {% if build.active %}
+ {% if build.active %}
+
- {% endif %}
+
- {% if build.incomplete_outputs %}
{% for item in build.incomplete_outputs %}
{% include "build/allocation_card.html" with item=item tracked_items=build.has_tracked_bom_items %}
{% endfor %}
- {% else %}
-
- {% trans "Create a new build output" %}
- {% trans "No incomplete build outputs remain." %}
- {% trans "Create a new build output using the button above" %}
-
+
+
{% endif %}
{% endif %}
@@ -321,8 +316,22 @@ var buildInfo = {
{% if build.take_from %}
source_location: {{ build.take_from.pk }},
{% endif %}
+ {% if build.has_tracked_bom_items %}
+ tracked_parts: true,
+ {% else %}
+ tracked_parts: false,
+ {% endif %}
};
+{% if build.active %}
+loadBuildOutputTable(
+ buildInfo,
+ {
+
+ }
+);
+{% endif %}
+
{% for item in build.incomplete_outputs %}
// Get the build output as a javascript object
inventreeGet('{% url 'api-stock-detail' item.pk %}', {},
diff --git a/InvenTree/build/test_api.py b/InvenTree/build/test_api.py
index a1068d3e60..e14f52ee04 100644
--- a/InvenTree/build/test_api.py
+++ b/InvenTree/build/test_api.py
@@ -153,7 +153,7 @@ class BuildCompleteTest(BuildAPITest):
self.assertEqual(self.build.completed, 0)
# We shall complete 4 of these outputs
- outputs = self.build.incomplete_outputs[0:4]
+ outputs = self.build.incomplete_outputs[0:4]
self.post(
self.url,
diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py
index 0a540c3412..42ed28dff0 100644
--- a/InvenTree/order/api.py
+++ b/InvenTree/order/api.py
@@ -5,7 +5,6 @@ JSON API for the Order app
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.utils.translation import ugettext_lazy as _
from django.conf.urls import url, include
from django.db.models import Q, F
from django.shortcuts import get_object_or_404
@@ -14,7 +13,6 @@ from django_filters import rest_framework as rest_filters
from rest_framework import generics
from rest_framework import filters, status
from rest_framework.response import Response
-from rest_framework.serializers import ValidationError
from InvenTree.filters import InvenTreeOrderingFilter
diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js
index 686e8e1bfa..672c7013ac 100644
--- a/InvenTree/templates/js/translated/build.js
+++ b/InvenTree/templates/js/translated/build.js
@@ -108,10 +108,64 @@ function newBuildOrder(options={}) {
}
+/*
+ * Construct a set of output buttons for a particular build output
+ */
+function makeBuildOutputButtons(output_id, build_info, options={}) {
+
+ var html = `
`;
+
+ // Tracked parts? Must be individually allocated
+ if (build_info.tracked_parts) {
+
+ // Add a button to allocate stock against this build output
+ html += makeIconButton(
+ 'fa-sign-in-alt icon-blue',
+ 'button-output-allocate',
+ output_id,
+ '{% trans "Allocate stock items to this build output" %}',
+ );
+
+ // Add a button to unallocate stock from this build output
+ html += makeIconButton(
+ 'fa-minus-circle icon-red',
+ 'build-output-unallocate',
+ output_id,
+ '{% trans "Unallocate stock from build output" %}',
+ );
+ }
+
+ // Add a button to "complete" this build output
+ html += makeIconButton(
+ 'fa-check-circle icon-green',
+ 'build-output-complete',
+ output_id,
+ '{% trans "Complete build output" %}',
+ )
+
+ // Add a button to "delete" this build output
+ html += makeIconButton(
+ 'fa-trash-alt icon-red',
+ 'button-output-delete',
+ output_id,
+ '{% trans "Delete build output" %}',
+ );
+
+ html += `
`;
+
+ return html;
+
+}
+
+
+// TODO "delete me"
+
function makeBuildOutputActionButtons(output, buildInfo, lines) {
/* Generate action buttons for a build output.
*/
+ var todo = "delete this function ok";
+
var buildId = buildInfo.pk;
var partId = buildInfo.part;
@@ -357,17 +411,110 @@ function loadBuildOrderAllocationTable(table, options={}) {
}
+/*
+ * Display a "build output" table for a particular build.
+ *
+ * This displays a list of "active" (i.e. "in production") build outputs for a given build
+ *
+ */
+function loadBuildOutputTable(build_info, options={}) {
+
+ var table = options.table || '#build-output-table';
+
+ var params = options.params || {};
+
+ // Mandatory query filters
+ params.part_detail = true;
+ params.is_building = true;
+ params.build = build_info.pk;
+
+ var filters = {};
+
+ for (var key in params) {
+ filters[key] = params[key];
+ }
+
+ // TODO: Initialize filter list
+
+ $(table).inventreeTable({
+ url: '{% url "api-stock-list" %}',
+ queryParams: filters,
+ original: params,
+ showColumns: true,
+ name: 'build-outputs',
+ sortable: true,
+ search: true,
+ sidePagination: 'server',
+ formatNoMatches: function() {
+ return '{% trans "No active build outputs found" %}';
+ },
+ onPostBody: function() {
+ // TODO
+ },
+ columns: [
+ {
+ field: 'part',
+ title: '{% trans "Part" %}',
+ formatter: function(value, row) {
+ var thumb = row.part_detail.thumbnail;
+
+ return imageHoverIcon(thumb) + row.part_detail.full_name + makePartIcons(row.part_detail);
+ }
+ },
+ {
+ field: 'quantity',
+ title: '{% trans "Quantity" %}',
+ formatter: function(value, row) {
+
+ var url = `/stock/item/${row.pk}/`;
+
+ var text = '';
+
+ if (row.serial && row.quantity == 1) {
+ text = `{% trans "Serial Number" %}: ${row.serial}`;
+ } else {
+ text = `{% trans "Quantity" %}: ${row.quantity}`;
+ }
+
+ return renderLink(text, url);
+ }
+ },
+ {
+ field: 'allocated',
+ title: '{% trans "Allocated" %}',
+ formatter: function(value, row) {
+ return "TODO";
+ }
+ },
+ {
+ field: 'actions',
+ title: '',
+ formatter: function(value, row) {
+ return makeBuildOutputButtons(
+ row.pk,
+ build_info,
+ );
+ }
+ }
+ ]
+ });
+}
+
+
+/*
+ * Display the "allocation table" for a particular build output.
+ *
+ * This displays a table of required allocations for a particular build output
+ *
+ * Args:
+ * - buildId: The PK of the Build object
+ * - partId: The PK of the Part object
+ * - output: The StockItem object which is the "output" of the build
+ * - options:
+ * -- table: The #id of the table (will be auto-calculated if not provided)
+ */
function loadBuildOutputAllocationTable(buildInfo, output, options={}) {
- /*
- * Load the "allocation table" for a particular build output.
- *
- * Args:
- * - buildId: The PK of the Build object
- * - partId: The PK of the Part object
- * - output: The StockItem object which is the "output" of the build
- * - options:
- * -- table: The #id of the table (will be auto-calculated if not provided)
- */
+
var buildId = buildInfo.pk;
var partId = buildInfo.part;