mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Refactor BuildOrder pages
This commit is contained in:
parent
533a3aa368
commit
0fc558068f
@ -1,101 +0,0 @@
|
||||
{% extends "build/build_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block page_title %}
|
||||
{% inventree_title %} | {% trans "Allocate Parts" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "build/navbar.html" with tab='allocate' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Allocate Stock to Build" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% if build.has_untracked_bom_items %}
|
||||
{% if build.active %}
|
||||
<div class='btn-group' role='group'>
|
||||
<button class='btn btn-success' type='button' id='btn-auto-allocate' title='{% trans "Allocate stock to build" %}'>
|
||||
<span class='fas fa-magic'></span> {% trans "Auto Allocate" %}
|
||||
</button>
|
||||
<button class='btn btn-danger' type='button' id='btn-unallocate' title='{% trans "Unallocate stock" %}'>
|
||||
<span class='fas fa-minus-circle'></span> {% trans "Unallocate Stock" %}
|
||||
</button>
|
||||
<!--
|
||||
<button class='btn btn-primary' type='button' id='btn-order-parts' title='{% trans "Order required parts" %}'>
|
||||
<span class='fas fa-shopping-cart'></span> {% trans "Order Parts" %}
|
||||
</button>
|
||||
-->
|
||||
</div>
|
||||
{% if build.areUntrackedPartsFullyAllocated %}
|
||||
<div class='alert alert-block alert-success'>
|
||||
{% trans "Untracked stock has been fully allocated for this Build Order" %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Untracked stock has not been fully allocated for this Build Order" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<table class='table table-striped table-condensed' id='allocation-table-untracked'></table>
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "This Build Order does not have any associated untracked BOM items" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
var buildInfo = {
|
||||
pk: {{ build.pk }},
|
||||
quantity: {{ build.quantity }},
|
||||
completed: {{ build.completed }},
|
||||
part: {{ build.part.pk }},
|
||||
};
|
||||
|
||||
{% if build.has_untracked_bom_items %}
|
||||
// Load allocation table for un-tracked parts
|
||||
loadBuildOutputAllocationTable(buildInfo, null);
|
||||
{% endif %}
|
||||
|
||||
function reloadTable() {
|
||||
$('#allocation-table-untracked').bootstrapTable('refresh');
|
||||
}
|
||||
|
||||
{% if build.active %}
|
||||
$("#btn-auto-allocate").on('click', function() {
|
||||
launchModalForm(
|
||||
"{% url 'build-auto-allocate' build.id %}",
|
||||
{
|
||||
success: reloadTable,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#btn-unallocate').on('click', function() {
|
||||
launchModalForm(
|
||||
"{% url 'build-unallocate' build.id %}",
|
||||
{
|
||||
success: reloadTable,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$("#btn-order-parts").click(function() {
|
||||
launchModalForm("/order/purchase-order/order-parts/", {
|
||||
data: {
|
||||
build: {{ build.id }},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,84 +0,0 @@
|
||||
{% extends "build/build_base.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "build/navbar.html" with tab='attachments' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Attachments" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% include "attachment_table.html" with attachments=build.attachments.all %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-build-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
build: {{ build.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Callback for creating a new attachment
|
||||
$('#new-attachment').click(function() {
|
||||
|
||||
constructForm('{% url "api-build-attachment-list" %}', {
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
build: {
|
||||
value: {{ build.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
method: 'POST',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
});
|
||||
});
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-build-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
build: {{ build.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/build/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
|
||||
constructForm(`/api/build/attachment/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
{% endblock %}
|
@ -238,4 +238,10 @@ src="{% static 'img/blank_image.png' %}"
|
||||
);
|
||||
});
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'buildorder',
|
||||
default: 'details'
|
||||
});
|
||||
|
||||
|
||||
{% endblock %}
|
@ -1,40 +0,0 @@
|
||||
{% extends "build/build_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "build/navbar.html" with tab="children" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Child Build Orders" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block details %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid float-right'>
|
||||
<div class='filter-list' id='filter-list-sub-build'>
|
||||
<!-- Empty div for filters -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='sub-build-table' data-toolbar='#button-toolbar'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
loadBuildTable($('#sub-build-table'), {
|
||||
url: '{% url "api-build-list" %}',
|
||||
filterTarget: "#filter-list-sub-build",
|
||||
params: {
|
||||
ancestor: {{ build.pk }},
|
||||
}
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,103 +0,0 @@
|
||||
{% extends "build/build_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "build/navbar.html" with tab='output' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_panels %}
|
||||
|
||||
{% if not build.is_complete %}
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
{% trans "Incomplete Build Outputs" %}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'>
|
||||
<div class='btn-group' role='group'>
|
||||
{% if build.active %}
|
||||
<button class='btn btn-primary' type='button' id='btn-create-output' title='{% trans "Create new build output" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Create New Output" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if build.incomplete_outputs %}
|
||||
<div class="panel-group" id="build-output-accordion" role="tablist" aria-multiselectable="true">
|
||||
{% for item in build.incomplete_outputs %}
|
||||
{% include "build/allocation_card.html" with item=item tracked_items=build.has_tracked_bom_items %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
<b>{% trans "Create a new build output" %}</b><br>
|
||||
{% trans "No incomplete build outputs remain." %}<br>
|
||||
{% trans "Create a new build output using the button above" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
{% trans "Completed Build Outputs" %}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'>
|
||||
{% include "stock_table.html" with read_only=True %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$('#btn-create-output').click(function() {
|
||||
launchModalForm('{% url "build-output-create" build.id %}',
|
||||
{
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
location_detail: true,
|
||||
part_detail: true,
|
||||
build: {{ build.id }},
|
||||
},
|
||||
groupByField: 'location',
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
|
||||
var buildInfo = {
|
||||
pk: {{ build.pk }},
|
||||
quantity: {{ build.quantity }},
|
||||
completed: {{ build.completed }},
|
||||
part: {{ build.part.pk }},
|
||||
};
|
||||
|
||||
{% for item in build.incomplete_outputs %}
|
||||
// Get the build output as a javascript object
|
||||
inventreeGet('{% url 'api-stock-detail' item.pk %}', {},
|
||||
{
|
||||
success: function(response) {
|
||||
loadBuildOutputAllocationTable(buildInfo, response);
|
||||
}
|
||||
}
|
||||
);
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% endblock %}
|
@ -2,142 +2,446 @@
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load status_codes %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "build/navbar.html" with tab='details' %}
|
||||
{% include "build/navbar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Build Details" %}
|
||||
{% endblock %}
|
||||
{% block page_content %}
|
||||
|
||||
{% block details %}
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<table class='table table-striped'>
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-info'></span></td>
|
||||
<td>{% trans "Description" %}</td>
|
||||
<td>{{ build.title }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>{% trans "Part" %}</td>
|
||||
<td><a href="{% url 'part-detail' build.part.id %}?display=build-orders">{{ build.part.full_name }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans "Quantity" %}</td><td>{{ build.quantity }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-map-marker-alt'></span></td>
|
||||
<td>{% trans "Stock Source" %}</td>
|
||||
<td>
|
||||
{% if build.take_from %}
|
||||
<a href="{% url 'stock-location-detail' build.take_from.id %}">{{ build.take_from }}</a>{% include "clip.html"%}
|
||||
{% else %}
|
||||
<i>{% trans "Stock can be taken from any available location." %}</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-map-marker-alt'></span></td>
|
||||
<td>{% trans "Destination" %}</td>
|
||||
<td>
|
||||
{% if build.destination %}
|
||||
<a href="{% url 'stock-location-detail' build.destination.id %}">
|
||||
{{ build.destination }}
|
||||
</a>{% include "clip.html"%}
|
||||
{% else %}
|
||||
<i>{% trans "Destination location not specified" %}</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-info'></span></td>
|
||||
<td>{% trans "Status" %}</td>
|
||||
<td>{% build_status_label build.status %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-spinner'></span></td>
|
||||
<td>{% trans "Progress" %}</td>
|
||||
<td>{{ build.completed }} / {{ build.quantity }}</td>
|
||||
</tr>
|
||||
{% if build.batch %}
|
||||
<tr>
|
||||
<td><span class='fas fa-layer-group'></span></td>
|
||||
<td>{% trans "Batch" %}</td>
|
||||
<td>{{ build.batch }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.parent %}
|
||||
<tr>
|
||||
<td><span class='fas fa-sitemap'></span></td>
|
||||
<td>{% trans "Parent Build" %}</td>
|
||||
<td><a href="{% url 'build-detail' build.parent.id %}">{{ build.parent }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.sales_order %}
|
||||
<tr>
|
||||
<td><span class='fas fa-dolly'></span></td>
|
||||
<td>{% trans "Sales Order" %}</td>
|
||||
<td><a href="{% url 'so-detail' build.sales_order.id %}">{{ build.sales_order }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.link %}
|
||||
<tr>
|
||||
<td><span class='fas fa-link'></span></td>
|
||||
<td>{% trans "External Link" %}</td>
|
||||
<td><a href="{{ build.link }}">{{ build.link }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.issued_by %}
|
||||
<tr>
|
||||
<td><span class='fas fa-user'></span></td>
|
||||
<td>{% trans "Issued By" %}</td>
|
||||
<td>{{ build.issued_by }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.responsible %}
|
||||
<tr>
|
||||
<td><span class='fas fa-users'></span></td>
|
||||
<td>{% trans "Responsible" %}</td>
|
||||
<td>{{ build.responsible }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-details'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Build Details" %}</h4>
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
<table class='table table-striped'>
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Created" %}</td>
|
||||
<td>{{ build.creation_date }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Target Date" %}</td>
|
||||
{% if build.target_date %}
|
||||
<td>
|
||||
{{ build.target_date }}{% if build.is_overdue %} <span class='fas fa-calendar-times icon-red'></span>{% endif %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td><i>{% trans "No target date set" %}</i></td>
|
||||
<div class='panel-content'>
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<table class='table table-striped'>
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-info'></span></td>
|
||||
<td>{% trans "Description" %}</td>
|
||||
<td>{{ build.title }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>{% trans "Part" %}</td>
|
||||
<td><a href="{% url 'part-detail' build.part.id %}?display=build-orders">{{ build.part.full_name }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans "Quantity" %}</td><td>{{ build.quantity }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-map-marker-alt'></span></td>
|
||||
<td>{% trans "Stock Source" %}</td>
|
||||
<td>
|
||||
{% if build.take_from %}
|
||||
<a href="{% url 'stock-location-detail' build.take_from.id %}">{{ build.take_from }}</a>{% include "clip.html"%}
|
||||
{% else %}
|
||||
<i>{% trans "Stock can be taken from any available location." %}</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-map-marker-alt'></span></td>
|
||||
<td>{% trans "Destination" %}</td>
|
||||
<td>
|
||||
{% if build.destination %}
|
||||
<a href="{% url 'stock-location-detail' build.destination.id %}">
|
||||
{{ build.destination }}
|
||||
</a>{% include "clip.html"%}
|
||||
{% else %}
|
||||
<i>{% trans "Destination location not specified" %}</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-info'></span></td>
|
||||
<td>{% trans "Status" %}</td>
|
||||
<td>{% build_status_label build.status %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-spinner'></span></td>
|
||||
<td>{% trans "Progress" %}</td>
|
||||
<td>{{ build.completed }} / {{ build.quantity }}</td>
|
||||
</tr>
|
||||
{% if build.batch %}
|
||||
<tr>
|
||||
<td><span class='fas fa-layer-group'></span></td>
|
||||
<td>{% trans "Batch" %}</td>
|
||||
<td>{{ build.batch }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Completed" %}</td>
|
||||
{% if build.completion_date %}
|
||||
<td>{{ build.completion_date }}{% if build.completed_by %}<span class='badge'>{{ build.completed_by }}</span>{% endif %}</td>
|
||||
{% else %}
|
||||
<td><i>{% trans "Build not complete" %}</i></td>
|
||||
{% if build.parent %}
|
||||
<tr>
|
||||
<td><span class='fas fa-sitemap'></span></td>
|
||||
<td>{% trans "Parent Build" %}</td>
|
||||
<td><a href="{% url 'build-detail' build.parent.id %}">{{ build.parent }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</table>
|
||||
{% if build.sales_order %}
|
||||
<tr>
|
||||
<td><span class='fas fa-dolly'></span></td>
|
||||
<td>{% trans "Sales Order" %}</td>
|
||||
<td><a href="{% url 'so-detail' build.sales_order.id %}">{{ build.sales_order }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.link %}
|
||||
<tr>
|
||||
<td><span class='fas fa-link'></span></td>
|
||||
<td>{% trans "External Link" %}</td>
|
||||
<td><a href="{{ build.link }}">{{ build.link }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.issued_by %}
|
||||
<tr>
|
||||
<td><span class='fas fa-user'></span></td>
|
||||
<td>{% trans "Issued By" %}</td>
|
||||
<td>{{ build.issued_by }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if build.responsible %}
|
||||
<tr>
|
||||
<td><span class='fas fa-users'></span></td>
|
||||
<td>{% trans "Responsible" %}</td>
|
||||
<td>{{ build.responsible }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
<table class='table table-striped'>
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Created" %}</td>
|
||||
<td>{{ build.creation_date }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Target Date" %}</td>
|
||||
{% if build.target_date %}
|
||||
<td>
|
||||
{{ build.target_date }}{% if build.is_overdue %} <span class='fas fa-calendar-times icon-red'></span>{% endif %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td><i>{% trans "No target date set" %}</i></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Completed" %}</td>
|
||||
{% if build.completion_date %}
|
||||
<td>{{ build.completion_date }}{% if build.completed_by %}<span class='badge'>{{ build.completed_by }}</span>{% endif %}</td>
|
||||
{% else %}
|
||||
<td><i>{% trans "Build not complete" %}</i></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-children'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Child Build Orders" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='child-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid float-right'>
|
||||
<div class='filter-list' id='filter-list-sub-build'>
|
||||
<!-- Empty div for filters -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class='table table-striped table-condensed' id='sub-build-table' data-toolbar='#child-button-toolbar'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-allocate'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Allocate Stock to Build" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if build.has_untracked_bom_items %}
|
||||
{% if build.active %}
|
||||
<div class='btn-group' role='group'>
|
||||
<button class='btn btn-success' type='button' id='btn-auto-allocate' title='{% trans "Allocate stock to build" %}'>
|
||||
<span class='fas fa-magic'></span> {% trans "Auto Allocate" %}
|
||||
</button>
|
||||
<button class='btn btn-danger' type='button' id='btn-unallocate' title='{% trans "Unallocate stock" %}'>
|
||||
<span class='fas fa-minus-circle'></span> {% trans "Unallocate Stock" %}
|
||||
</button>
|
||||
<!--
|
||||
<button class='btn btn-primary' type='button' id='btn-order-parts' title='{% trans "Order required parts" %}'>
|
||||
<span class='fas fa-shopping-cart'></span> {% trans "Order Parts" %}
|
||||
</button>
|
||||
-->
|
||||
</div>
|
||||
{% if build.areUntrackedPartsFullyAllocated %}
|
||||
<div class='alert alert-block alert-success'>
|
||||
{% trans "Untracked stock has been fully allocated for this Build Order" %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "Untracked stock has not been fully allocated for this Build Order" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<table class='table table-striped table-condensed' id='allocation-table-untracked'></table>
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "This Build Order does not have any associated untracked BOM items" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-outputs'>
|
||||
{% if not build.is_complete %}
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Incomplete Build Outputs" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div class='btn-group' role='group'>
|
||||
{% if build.active %}
|
||||
<button class='btn btn-primary' type='button' id='btn-create-output' title='{% trans "Create new build output" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Create New Output" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if build.incomplete_outputs %}
|
||||
<div class="panel-group" id="build-output-accordion" role="tablist" aria-multiselectable="true">
|
||||
{% for item in build.incomplete_outputs %}
|
||||
{% include "build/allocation_card.html" with item=item tracked_items=build.has_tracked_bom_items %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
<b>{% trans "Create a new build output" %}</b><br>
|
||||
{% trans "No incomplete build outputs remain." %}<br>
|
||||
{% trans "Create a new build output using the button above" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
{% trans "Completed Build Outputs" %}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'>
|
||||
{% include "stock_table.html" with read_only=True prefix="build-" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-attachments'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Attachments" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% include "attachment_table.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-notes'>
|
||||
<div class='panel-heading'>
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<h4>{% trans "Build Notes" %}</h4>
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
<div class='btn-group float-right'>
|
||||
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn btn-small btn-default'>
|
||||
<span class='fas fa-edit'>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if build.notes %}
|
||||
{{ build.notes | markdownify }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$('#btn-create-output').click(function() {
|
||||
launchModalForm('{% url "build-output-create" build.id %}',
|
||||
{
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
loadStockTable($("#build-stock-table"), {
|
||||
params: {
|
||||
location_detail: true,
|
||||
part_detail: true,
|
||||
build: {{ build.id }},
|
||||
},
|
||||
groupByField: 'location',
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
|
||||
var buildInfo = {
|
||||
pk: {{ build.pk }},
|
||||
quantity: {{ build.quantity }},
|
||||
completed: {{ build.completed }},
|
||||
part: {{ build.part.pk }},
|
||||
};
|
||||
|
||||
{% for item in build.incomplete_outputs %}
|
||||
// Get the build output as a javascript object
|
||||
inventreeGet('{% url 'api-stock-detail' item.pk %}', {},
|
||||
{
|
||||
success: function(response) {
|
||||
loadBuildOutputAllocationTable(buildInfo, response);
|
||||
}
|
||||
}
|
||||
);
|
||||
{% endfor %}
|
||||
|
||||
loadBuildTable($('#sub-build-table'), {
|
||||
url: '{% url "api-build-list" %}',
|
||||
filterTarget: "#filter-list-sub-build",
|
||||
params: {
|
||||
ancestor: {{ build.pk }},
|
||||
}
|
||||
});
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-build-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
build: {{ build.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Callback for creating a new attachment
|
||||
$('#new-attachment').click(function() {
|
||||
|
||||
constructForm('{% url "api-build-attachment-list" %}', {
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
build: {
|
||||
value: {{ build.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
method: 'POST',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
});
|
||||
});
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-build-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
build: {{ build.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/build/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
|
||||
constructForm(`/api/build/attachment/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('#edit-notes').click(function() {
|
||||
constructForm('{% url "api-build-detail" build.pk %}', {
|
||||
fields: {
|
||||
notes: {
|
||||
multiline: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Edit Notes" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
var buildInfo = {
|
||||
pk: {{ build.pk }},
|
||||
quantity: {{ build.quantity }},
|
||||
completed: {{ build.completed }},
|
||||
part: {{ build.part.pk }},
|
||||
};
|
||||
|
||||
{% if build.has_untracked_bom_items %}
|
||||
// Load allocation table for un-tracked parts
|
||||
loadBuildOutputAllocationTable(buildInfo, null);
|
||||
{% endif %}
|
||||
|
||||
function reloadTable() {
|
||||
$('#allocation-table-untracked').bootstrapTable('refresh');
|
||||
}
|
||||
|
||||
{% if build.active %}
|
||||
$("#btn-auto-allocate").on('click', function() {
|
||||
launchModalForm(
|
||||
"{% url 'build-auto-allocate' build.id %}",
|
||||
{
|
||||
success: reloadTable,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#btn-unallocate').on('click', function() {
|
||||
launchModalForm(
|
||||
"{% url 'build-unallocate' build.id %}",
|
||||
{
|
||||
success: reloadTable,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$("#btn-order-parts").click(function() {
|
||||
launchModalForm("/order/purchase-order/order-parts/", {
|
||||
data: {
|
||||
build: {{ build.id }},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -9,46 +9,45 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "details" %}active{% endif %}' title='{% trans "Build Order Details" %}'>
|
||||
<a href='{% url "build-detail" build.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Build Order Details" %}'>
|
||||
<a href='#' id='select-details' class='nav-toggle'>
|
||||
<span class='fas fa-info-circle sidebar-icon'></span>
|
||||
{% trans "Details" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if build.active %}
|
||||
|
||||
<li class='list-group-item {% if tab == "allocate" %}active{% endif %}' title='{% trans "Allocate Stock" %}'>
|
||||
<a href='{% url "build-allocate" build.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Allocate Stock" %}'>
|
||||
<a href='#' id='select-allocate' class='nav-toggle'>
|
||||
<span class='fas fa-tools sidebar-icon'></span>
|
||||
{% trans "Allocate Stock" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class='list-group-item {% if tab == "output" %}active{% endif %}' title='{% trans "Build Outputs" %}'>
|
||||
<a href='{% url "build-output" build.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Build Outputs" %}'>
|
||||
<a href='#' id='select-outputs' class='nav-toggle'>
|
||||
<span class='fas fa-box sidebar-icon'></span>
|
||||
{% trans "Build Outputs" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "children" %}active{% endif %}' title='{% trans "Child Build Orders" %}'>
|
||||
<a href='{% url "build-children" build.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Child Build Orders" %}'>
|
||||
<a href='#' id='select-children' class='nav-toggle'>
|
||||
<span class='fas fa-sitemap sidebar-icon'></span>
|
||||
{% trans "Child Builds" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "attachments" %}active{% endif %}' title='{% trans "Attachments" %}'>
|
||||
<a href='{% url "build-attachments" build.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Attachments" %}'>
|
||||
<a href='#' id='select-attachments' class='nav-toggle'>
|
||||
<span class='fas fa-paperclip sidebar-icon'></span>
|
||||
{% trans "Attachments" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "notes" %}active{% endif %}' title='{% trans "Build Order Notes" %}'>
|
||||
<a href='{% url "build-notes" build.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Build Order Notes" %}'>
|
||||
<a href='#' id='select-notes' class='nav-toggle'>
|
||||
<span class='fas fa-clipboard sidebar-icon'></span>
|
||||
{% trans "Notes" %}
|
||||
</a>
|
||||
|
@ -1,51 +0,0 @@
|
||||
{% extends "build/build_base.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "build/navbar.html" with tab='notes' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Build Notes" %}
|
||||
{% if roles.build.change and not editing %}
|
||||
<button title='{% trans "Edit notes" %}' class='btn btn-default' id='edit-notes'><span class='fas fa-edit'></span></button>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% if editing %}
|
||||
<hr>
|
||||
<form method='POST'>
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form }}
|
||||
<hr>
|
||||
<button type="submit" class='btn btn-default'>{% trans "Save" %}</button>
|
||||
|
||||
</form>
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
{% else %}
|
||||
|
||||
{% if build.notes %}
|
||||
{{ build.notes | markdownify }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if editing %}
|
||||
{% else %}
|
||||
$("#edit-notes").click(function() {
|
||||
location.href = "{% url 'build-notes' build.id %}?edit=1";
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -7,30 +7,23 @@ from django.conf.urls import url, include
|
||||
from . import views
|
||||
|
||||
build_detail_urls = [
|
||||
url(r'^allocate/', views.BuildAllocate.as_view(), name='build-allocate'),
|
||||
url(r'^cancel/', views.BuildCancel.as_view(), name='build-cancel'),
|
||||
url(r'^delete/', views.BuildDelete.as_view(), name='build-delete'),
|
||||
url(r'^create-output/', views.BuildOutputCreate.as_view(), name='build-output-create'),
|
||||
url(r'^delete-output/', views.BuildOutputDelete.as_view(), name='build-output-delete'),
|
||||
url(r'^complete-output/?', views.BuildOutputComplete.as_view(), name='build-output-complete'),
|
||||
url(r'^auto-allocate/?', views.BuildAutoAllocate.as_view(), name='build-auto-allocate'),
|
||||
url(r'^complete-output/', views.BuildOutputComplete.as_view(), name='build-output-complete'),
|
||||
url(r'^auto-allocate/', views.BuildAutoAllocate.as_view(), name='build-auto-allocate'),
|
||||
url(r'^unallocate/', views.BuildUnallocate.as_view(), name='build-unallocate'),
|
||||
url(r'^complete/', views.BuildComplete.as_view(), name='build-complete'),
|
||||
|
||||
url(r'^notes/', views.BuildNotes.as_view(), name='build-notes'),
|
||||
|
||||
url(r'^children/', views.BuildDetail.as_view(template_name='build/build_children.html'), name='build-children'),
|
||||
url(r'^attachments/', views.BuildDetail.as_view(template_name='build/attachments.html'), name='build-attachments'),
|
||||
url(r'^output/', views.BuildDetail.as_view(template_name='build/build_output.html'), name='build-output'),
|
||||
|
||||
url(r'^.*$', views.BuildDetail.as_view(), name='build-detail'),
|
||||
]
|
||||
|
||||
build_urls = [
|
||||
url(r'item/', include([
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url('^edit/?', views.BuildItemEdit.as_view(), name='build-item-edit'),
|
||||
url('^delete/?', views.BuildItemDelete.as_view(), name='build-item-delete'),
|
||||
url('^edit/', views.BuildItemEdit.as_view(), name='build-item-edit'),
|
||||
url('^delete/', views.BuildItemDelete.as_view(), name='build-item-delete'),
|
||||
])),
|
||||
url('^new/', views.BuildItemCreate.as_view(), name='build-item-create'),
|
||||
])),
|
||||
|
@ -593,31 +593,6 @@ class BuildOutputComplete(AjaxUpdateView):
|
||||
}
|
||||
|
||||
|
||||
class BuildNotes(InvenTreeRoleMixin, UpdateView):
|
||||
""" View for editing the 'notes' field of a Build object.
|
||||
"""
|
||||
|
||||
context_object_name = 'build'
|
||||
template_name = 'build/notes.html'
|
||||
model = Build
|
||||
|
||||
# Override the default permission role for this View
|
||||
role_required = 'build.view'
|
||||
|
||||
fields = ['notes']
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('build-notes', kwargs={'pk': self.get_object().id})
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
|
||||
ctx['editing'] = str2bool(self.request.GET.get('edit', ''))
|
||||
|
||||
return ctx
|
||||
|
||||
|
||||
class BuildDetail(InvenTreeRoleMixin, DetailView):
|
||||
""" Detail view of a single Build object. """
|
||||
|
||||
@ -635,36 +610,15 @@ class BuildDetail(InvenTreeRoleMixin, DetailView):
|
||||
ctx['BuildStatus'] = BuildStatus
|
||||
ctx['sub_build_count'] = build.sub_build_count()
|
||||
|
||||
return ctx
|
||||
|
||||
|
||||
class BuildAllocate(InvenTreeRoleMixin, DetailView):
|
||||
""" View for allocating parts to a Build """
|
||||
model = Build
|
||||
context_object_name = 'build'
|
||||
template_name = 'build/allocate.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
""" Provide extra context information for the Build allocation page """
|
||||
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
|
||||
build = self.get_object()
|
||||
part = build.part
|
||||
bom_items = build.bom_items
|
||||
|
||||
context['part'] = part
|
||||
context['bom_items'] = bom_items
|
||||
context['has_tracked_bom_items'] = build.has_tracked_bom_items()
|
||||
context['has_untracked_bom_items'] = build.has_untracked_bom_items()
|
||||
context['BuildStatus'] = BuildStatus
|
||||
ctx['part'] = part
|
||||
ctx['bom_items'] = bom_items
|
||||
ctx['has_tracked_bom_items'] = build.has_tracked_bom_items()
|
||||
ctx['has_untracked_bom_items'] = build.has_untracked_bom_items()
|
||||
|
||||
context['bom_price'] = build.part.get_price_info(build.quantity, buy=False)
|
||||
|
||||
if str2bool(self.request.GET.get('edit', None)):
|
||||
context['editing'] = True
|
||||
|
||||
return context
|
||||
return ctx
|
||||
|
||||
|
||||
class BuildDelete(AjaxDeleteView):
|
||||
|
@ -20,7 +20,6 @@ function attachNavCallbacks(options={}) {
|
||||
activatePanel(panelName, options);
|
||||
});
|
||||
|
||||
|
||||
var panelClass = options.name || 'unknown';
|
||||
|
||||
/* Look for a default panel to initialize
|
||||
|
Loading…
Reference in New Issue
Block a user