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;