mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #1811 from SchrodingersGat/spa
Dynamically switch between navbar selections on pages
This commit is contained in:
commit
bb60eed897
@ -781,7 +781,7 @@ input[type="submit"] {
|
||||
}
|
||||
|
||||
.sidenav .list-group-item.active {
|
||||
background-color: #ddd;
|
||||
background-color: #b3a997;
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
@ -912,6 +912,10 @@ input[type="submit"] {
|
||||
box-shadow: 1px 1px #DDD;
|
||||
}
|
||||
|
||||
.panel-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
@ -4678,7 +4678,7 @@ input[type="submit"].btn.btn-mini {
|
||||
|
||||
.navbar .btn-navbar:active,
|
||||
.navbar .btn-navbar.active {
|
||||
background-color: #cccccc \9;
|
||||
background-color: #ba8;
|
||||
}
|
||||
|
||||
.navbar .btn-navbar .icon-bar {
|
||||
|
@ -104,22 +104,23 @@ settings_urls = [
|
||||
dynamic_javascript_urls = [
|
||||
url(r'^api.js', DynamicJsView.as_view(template_name='js/api.js'), name='api.js'),
|
||||
url(r'^attachment.js', DynamicJsView.as_view(template_name='js/attachment.js'), name='attachment.js'),
|
||||
url(r'^forms.js', DynamicJsView.as_view(template_name='js/forms.js'), name='forms.js'),
|
||||
url(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/model_renderers.js'), name='model_renderers.js'),
|
||||
url(r'^modals.js', DynamicJsView.as_view(template_name='js/modals.js'), name='modals.js'),
|
||||
url(r'^barcode.js', DynamicJsView.as_view(template_name='js/barcode.js'), name='barcode.js'),
|
||||
url(r'^bom.js', DynamicJsView.as_view(template_name='js/bom.js'), name='bom.js'),
|
||||
url(r'^build.js', DynamicJsView.as_view(template_name='js/build.js'), name='build.js'),
|
||||
url(r'^calendar.js', DynamicJsView.as_view(template_name='js/calendar.js'), name='calendar.js'),
|
||||
url(r'^company.js', DynamicJsView.as_view(template_name='js/company.js'), name='company.js'),
|
||||
url(r'^filters.js', DynamicJsView.as_view(template_name='js/filters.js'), name='filters.js'),
|
||||
url(r'^forms.js', DynamicJsView.as_view(template_name='js/forms.js'), name='forms.js'),
|
||||
url(r'^label.js', DynamicJsView.as_view(template_name='js/label.js'), name='label.js'),
|
||||
url(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/model_renderers.js'), name='model_renderers.js'),
|
||||
url(r'^modals.js', DynamicJsView.as_view(template_name='js/modals.js'), name='modals.js'),
|
||||
url(r'^nav.js', DynamicJsView.as_view(template_name='js/nav.js'), name='nav.js'),
|
||||
url(r'^order.js', DynamicJsView.as_view(template_name='js/order.js'), name='order.js'),
|
||||
url(r'^part.js', DynamicJsView.as_view(template_name='js/part.js'), name='part.js'),
|
||||
url(r'^label.js', DynamicJsView.as_view(template_name='js/label.js'), name='label.js'),
|
||||
url(r'^report.js', DynamicJsView.as_view(template_name='js/report.js'), name='report.js'),
|
||||
url(r'^stock.js', DynamicJsView.as_view(template_name='js/stock.js'), name='stock.js'),
|
||||
url(r'^tables.js', DynamicJsView.as_view(template_name='js/tables.js'), name='tables.js'),
|
||||
url(r'^table_filters.js', DynamicJsView.as_view(template_name='js/table_filters.js'), name='table_filters.js'),
|
||||
url(r'^filters.js', DynamicJsView.as_view(template_name='js/filters.js'), name='filters.js'),
|
||||
]
|
||||
|
||||
urlpatterns = [
|
||||
|
@ -68,10 +68,6 @@ class BuildList(generics.ListCreateAPIView):
|
||||
filters.OrderingFilter,
|
||||
]
|
||||
|
||||
filter_fields = [
|
||||
'sales_order',
|
||||
]
|
||||
|
||||
ordering_fields = [
|
||||
'reference',
|
||||
'part__name',
|
||||
@ -114,6 +110,12 @@ class BuildList(generics.ListCreateAPIView):
|
||||
if parent is not None:
|
||||
queryset = queryset.filter(parent=parent)
|
||||
|
||||
# Filter by sales_order
|
||||
sales_order = params.get('sales_order', None)
|
||||
|
||||
if sales_order is not None:
|
||||
queryset = queryset.filter(sales_order=sales_order)
|
||||
|
||||
# Filter by "ancestor" builds
|
||||
ancestor = params.get('ancestor', None)
|
||||
|
||||
|
@ -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 %}
|
@ -126,7 +126,7 @@ src="{% static 'img/blank_image.png' %}"
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>{% trans "Part" %}</td>
|
||||
<td><a href="{% url 'part-detail' build.part.id %}">{{ build.part.full_name }}</a></td>
|
||||
<td><a href="{% url 'part-detail' build.part.id %}?display=build-orders">{{ build.part.full_name }}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
@ -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-build' build.part.id %}">{{ 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,49 +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 %}
|
||||
|
||||
{{ build.notes | markdownify }}
|
||||
{% 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 %}
|
@ -252,19 +252,6 @@ class TestBuildViews(TestCase):
|
||||
|
||||
self.assertIn(build.title, content)
|
||||
|
||||
def test_build_allocate(self):
|
||||
""" Test the part allocation view for a Build """
|
||||
|
||||
url = reverse('build-allocate', args=(1,))
|
||||
|
||||
# Get the page normally
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Get the page in editing mode
|
||||
response = self.client.get(url, {'edit': 1})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_build_item_create(self):
|
||||
""" Test the BuildItem creation view (ajax form) """
|
||||
|
||||
|
@ -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'),
|
||||
])),
|
||||
|
@ -7,9 +7,8 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.views.generic import DetailView, ListView, UpdateView
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.forms import HiddenInput
|
||||
from django.urls import reverse
|
||||
|
||||
from part.models import Part
|
||||
from .models import Build, BuildItem
|
||||
@ -593,31 +592,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 +609,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):
|
||||
|
@ -99,13 +99,18 @@ class FileManager:
|
||||
self.update_headers()
|
||||
|
||||
def guess_header(self, header, threshold=80):
|
||||
""" Try to match a header (from the file) to a list of known headers
|
||||
"""
|
||||
Try to match a header (from the file) to a list of known headers
|
||||
|
||||
Args:
|
||||
header - Header name to look for
|
||||
threshold - Match threshold for fuzzy search
|
||||
"""
|
||||
|
||||
# Replace null values with empty string
|
||||
if header is None:
|
||||
header = ''
|
||||
|
||||
# Try for an exact match
|
||||
for h in self.HEADERS:
|
||||
if h == header:
|
||||
|
@ -1,38 +0,0 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/navbar.html" with tab="assigned" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Assigned Stock" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<div id='button-toolbar'>
|
||||
<div class='filter-list' id='filter-list-stock'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='stock-table' data-toolbar='#button-toolbar'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
customer: {{ company.id }},
|
||||
part_detail: true,
|
||||
location_detail: true,
|
||||
},
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
filterKey: "customerstock",
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -71,6 +71,17 @@
|
||||
<td><a href="{{ company.website }}">{{ company.website }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-dollar-sign'></span></td>
|
||||
<td>{% trans "Currency" %}</td>
|
||||
<td>
|
||||
{% if company.currency %}
|
||||
{{ company.currency }}
|
||||
{% else %}
|
||||
<i>{% trans "Uses default currency" %}</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if company.address %}
|
||||
<tr>
|
||||
<td><span class='fas fa-map-marked-alt'></span></td>
|
||||
@ -99,6 +110,22 @@
|
||||
<td>{{ company.contact }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
<tr>
|
||||
<td><span class='fas fa-industry'></span></td>
|
||||
<td>{%trans "Manufacturer" %}</td>
|
||||
<td>{% include "yesnolabel.html" with value=company.is_manufacturer %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-building'></span></td>
|
||||
<td>{% trans "Supplier" %}</td>
|
||||
<td>{% include 'yesnolabel.html' with value=company.is_supplier %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-user-tie'></span></td>
|
||||
<td>{% trans "Customer" %}</td>
|
||||
<td>{% include 'yesnolabel.html' with value=company.is_customer %}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
@ -1,79 +1,432 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'company/navbar.html' with tab='details' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Company Details" %}
|
||||
{% endblock %}
|
||||
{% block page_content %}
|
||||
|
||||
{% block details %}
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<table class='table table-striped'>
|
||||
<col width='25'>
|
||||
<col>
|
||||
<tr>
|
||||
<td><span class='fas fa-font'></span></td>
|
||||
<td>{% trans "Company Name" %}</td>
|
||||
<td>{{ company.name }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% if company.description %}
|
||||
<tr>
|
||||
<td><span class='fas fa-info'></span></td>
|
||||
<td>{% trans "Description" %}</td>
|
||||
<td>{{ company.description }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-globe'></span></td>
|
||||
<td>{% trans "Website" %}</td>
|
||||
<td>
|
||||
{% if company.website %}<a href='{{ company.website }}'>{{ company.website }}</a>{% include "clip.html"%}
|
||||
{% else %}<i>{% trans "No website specified" %}</i>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-supplier-parts'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Supplier Parts" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if roles.purchase_order.change %}
|
||||
<div id='supplier-part-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid'>
|
||||
<div class='btn-group' role='group'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<button class="btn btn-success" id='supplier-part-create' title='{% trans "Create new supplier part" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Supplier Part" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-dollar-sign'></span></td>
|
||||
<td>{% trans "Currency" %}</td>
|
||||
<td>
|
||||
{% if company.currency %}{{ company.currency }}
|
||||
{% else %}<i>{% trans "Uses default currency" %}</i>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<div class='btn-group'>
|
||||
<div class="dropdown" style="float: right;">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% if roles.purchase_order.add %}
|
||||
<li><a href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li>
|
||||
{% endif %}
|
||||
{% if roles.purchase_order.delete %}
|
||||
<li><a href='#' id='multi-part-delete' title='{% trans "Delete parts" %}'>{% trans "Delete Parts" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-supplier-part'>
|
||||
<!-- Empty div (will be filled out with available BOM filters) -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed' id='supplier-part-table' data-toolbar='#supplier-part-button-toolbar'>
|
||||
</table>
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
<table class='table table-striped'>
|
||||
<col width='25'>
|
||||
<col>
|
||||
<tr>
|
||||
<td><span class='fas fa-industry'></span></td>
|
||||
<td>{% trans "Manufacturer" %}</td>
|
||||
<td>{% include "yesnolabel.html" with value=company.is_manufacturer %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-building'></span></td>
|
||||
<td>{% trans "Supplier" %}</td>
|
||||
<td>{% include 'yesnolabel.html' with value=company.is_supplier %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-user-tie'></span></td>
|
||||
<td>{% trans "Customer" %}</td>
|
||||
<td>{% include 'yesnolabel.html' with value=company.is_customer %}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-manufacturer-parts'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Manufacturer Parts" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if roles.purchase_order.change %}
|
||||
<div id='manufacturer-part-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid'>
|
||||
<div class='btn-group role='group'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<button class="btn btn-success" id='manufacturer-part-create' title='{% trans "Create new manufacturer part" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Manufacturer Part" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<div class='btn-group'>
|
||||
<div class="dropdown" style="float: right;">
|
||||
<button class="btn btn-primary dropdown-toggle" id='table-options', type="button" data-toggle="dropdown">{% trans "Options" %}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% if roles.purchase_order.add %}
|
||||
<li><a href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li>
|
||||
{% endif %}
|
||||
{% if roles.purchase_order.delete %}
|
||||
<li><a href='#' id='multi-part-delete' title='{% trans "Delete parts" %}'>{% trans "Delete Parts" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-supplier-part'>
|
||||
<!-- Empty div (will be filled out with available BOM filters) -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class='table table-striped table-condensed' id='part-table' data-toolbar='#manufacturer-part-button-toolbar'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-company-stock'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Supplier Stock" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% include "stock_table.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-purchase-orders'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Purchase Orders" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<div id='po-button-bar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
<button class='btn btn-primary' type='button' id='company-order2' title='{% trans "Create new purchase order" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Purchase Order" %}</button>
|
||||
<div class='filter-list' id='filter-list-purchaseorder'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed po-table' id='purchase-order-table' data-toolbar='#po-button-bar'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-sales-orders'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sales Orders" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if roles.sales_order.add %}
|
||||
<div id='so-button-bar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
<button class='btn btn-primary' type='button' id='new-sales-order' title='{% trans "Create new sales order" %}'>
|
||||
<div class='fas fa-plus-circle'></div> {% trans "New Sales Order" %}
|
||||
</button>
|
||||
<div class='filter-list' id='filter-list-salesorder'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed po-table' id='sales-order-table' data-toolbar='#so-button-bar'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-assigned-stock'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Assigned Stock" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='assigned-stock-button-toolbar'>
|
||||
<div class='filter-list' id='filter-list-stock'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='assigned-stock-table' data-toolbar='#bassigned-stock-utton-toolbar'></table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-company-notes'>
|
||||
<div class='panel-heading'>
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<h4>{% trans "Company 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 company.notes %}
|
||||
{{ company.notes | markdownify }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$('#edit-notes').click(function() {
|
||||
constructForm('{% url "api-company-detail" company.pk %}', {
|
||||
fields: {
|
||||
notes: {
|
||||
multiline: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Edit Notes" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
loadStockTable($("#assigned-stock-table"), {
|
||||
params: {
|
||||
customer: {{ company.id }},
|
||||
part_detail: true,
|
||||
location_detail: true,
|
||||
},
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
filterKey: "customerstock",
|
||||
});
|
||||
|
||||
{% if company.is_customer %}
|
||||
loadSalesOrderTable("#sales-order-table", {
|
||||
url: "{% url 'api-so-list' %}",
|
||||
params: {
|
||||
customer: {{ company.id }},
|
||||
}
|
||||
});
|
||||
|
||||
$("#new-sales-order").click(function() {
|
||||
|
||||
createSalesOrder({
|
||||
customer: {{ company.pk }},
|
||||
});
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% if company.is_supplier %}
|
||||
loadPurchaseOrderTable("#purchase-order-table", {
|
||||
url: "{% url 'api-po-list' %}",
|
||||
params: {
|
||||
supplier: {{ company.id }},
|
||||
}
|
||||
});
|
||||
|
||||
function newOrder() {
|
||||
createPurchaseOrder({
|
||||
supplier: {{ company.pk }},
|
||||
});
|
||||
}
|
||||
|
||||
$("#company-order").click(function() {
|
||||
newOrder();
|
||||
});
|
||||
|
||||
$("#company-order2").click(function() {
|
||||
newOrder();
|
||||
});
|
||||
|
||||
{% endif %}
|
||||
|
||||
loadStockTable($('#stock-table'), {
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
params: {
|
||||
company: {{ company.id }},
|
||||
part_detail: true,
|
||||
supplier_part_detail: true,
|
||||
location_detail: true,
|
||||
},
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
filterKey: "companystock",
|
||||
});
|
||||
|
||||
$("#stock-export").click(function() {
|
||||
launchModalForm("{% url 'stock-export-options' %}", {
|
||||
submit_text: '{% trans "Export" %}',
|
||||
success: function(response) {
|
||||
var url = "{% url 'stock-export' %}";
|
||||
|
||||
url += "?format=" + response.format;
|
||||
url += "&supplier={{ company.id }}";
|
||||
|
||||
location.href = url;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% if company.is_manufacturer %}
|
||||
|
||||
$("#manufacturer-part-create").click(function () {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-list" %}', {
|
||||
fields: {
|
||||
part: {},
|
||||
manufacturer: {
|
||||
value: {{ company.pk }},
|
||||
},
|
||||
MPN: {
|
||||
icon: 'fa-hashtag',
|
||||
},
|
||||
description: {},
|
||||
link: {
|
||||
icon: 'fa-link',
|
||||
},
|
||||
},
|
||||
method: 'POST',
|
||||
title: '{% trans "Add Manufacturer Part" %}',
|
||||
onSuccess: function() {
|
||||
$("#part-table").bootstrapTable("refresh");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
loadManufacturerPartTable(
|
||||
"#part-table",
|
||||
"{% url 'api-manufacturer-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part_detail: true,
|
||||
manufacturer_detail: true,
|
||||
manufacturer: {{ company.id }},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
linkButtonsToSelection($("#manufacturer-table"), ['#table-options']);
|
||||
|
||||
$("#multi-part-delete").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
deleteManufacturerParts(selections, {
|
||||
onSuccess: function() {
|
||||
$("#part-table").bootstrapTable("refresh");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#multi-part-order").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.part);
|
||||
});
|
||||
|
||||
launchModalForm("/order/purchase-order/order-parts/", {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if company.is_supplier %}
|
||||
|
||||
$("#supplier-part-create").click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-create' %}",
|
||||
{
|
||||
data: {
|
||||
supplier: {{ company.id }},
|
||||
},
|
||||
reload: true,
|
||||
secondary: [
|
||||
{
|
||||
field: 'part',
|
||||
label: '{% trans "New Part" %}',
|
||||
title: '{% trans "Create new Part" %}',
|
||||
url: "{% url 'part-create' %}"
|
||||
},
|
||||
{
|
||||
field: 'supplier',
|
||||
label: "{% trans 'New Supplier' %}",
|
||||
title: "{% trans 'Create new Supplier' %}",
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
loadSupplierPartTable(
|
||||
"#supplier-part-table",
|
||||
"{% url 'api-supplier-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part_detail: true,
|
||||
supplier_detail: true,
|
||||
manufacturer_detail: true,
|
||||
supplier: {{ company.id }},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
{% endif %}
|
||||
|
||||
$("#multi-part-delete").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.pk);
|
||||
});
|
||||
|
||||
var url = "{% url 'supplier-part-delete' %}"
|
||||
|
||||
launchModalForm(url, {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$("#multi-part-order").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.part);
|
||||
});
|
||||
|
||||
launchModalForm("/order/purchase-order/order-parts/", {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'company',
|
||||
default: 'company-stock'
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,119 +0,0 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'company/navbar.html' with tab='manufacturer_parts' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Manufacturer Parts" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% if roles.purchase_order.change %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid'>
|
||||
<div class='btn-group role='group'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<button class="btn btn-success" id='manufacturer-part-create' title='{% trans "Create new manufacturer part" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Manufacturer Part" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<div class='btn-group'>
|
||||
<div class="dropdown" style="float: right;">
|
||||
<button class="btn btn-primary dropdown-toggle" id='table-options', type="button" data-toggle="dropdown">{% trans "Options" %}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% if roles.purchase_order.add %}
|
||||
<li><a href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li>
|
||||
{% endif %}
|
||||
{% if roles.purchase_order.delete %}
|
||||
<li><a href='#' id='multi-part-delete' title='{% trans "Delete parts" %}'>{% trans "Delete Parts" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-supplier-part'>
|
||||
<!-- Empty div (will be filled out with available BOM filters) -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class='table table-striped table-condensed' id='part-table' data-toolbar='#button-toolbar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$("#manufacturer-part-create").click(function () {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-list" %}', {
|
||||
fields: {
|
||||
part: {},
|
||||
manufacturer: {
|
||||
value: {{ company.pk }},
|
||||
},
|
||||
MPN: {
|
||||
icon: 'fa-hashtag',
|
||||
},
|
||||
description: {},
|
||||
link: {
|
||||
icon: 'fa-link',
|
||||
},
|
||||
},
|
||||
method: 'POST',
|
||||
title: '{% trans "Add Manufacturer Part" %}',
|
||||
onSuccess: function() {
|
||||
$("#part-table").bootstrapTable("refresh");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
loadManufacturerPartTable(
|
||||
"#part-table",
|
||||
"{% url 'api-manufacturer-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part_detail: true,
|
||||
manufacturer_detail: true,
|
||||
manufacturer: {{ company.id }},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
linkButtonsToSelection($("#manufacturer-table"), ['#table-options']);
|
||||
|
||||
$("#multi-part-delete").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
deleteManufacturerParts(selections, {
|
||||
onSuccess: function() {
|
||||
$("#part-table").bootstrapTable("refresh");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#multi-part-order").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.part);
|
||||
});
|
||||
|
||||
launchModalForm("/order/purchase-order/order-parts/", {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,49 +0,0 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/navbar.html" with tab='stock' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Supplier Stock" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% include "stock_table.html" %}
|
||||
|
||||
{% endblock %}
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadStockTable($('#stock-table'), {
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
params: {
|
||||
company: {{ company.id }},
|
||||
part_detail: true,
|
||||
supplier_part_detail: true,
|
||||
location_detail: true,
|
||||
},
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
filterKey: "companystock",
|
||||
});
|
||||
|
||||
$("#stock-export").click(function() {
|
||||
launchModalForm("{% url 'stock-export-options' %}", {
|
||||
submit_text: '{% trans "Export" %}',
|
||||
success: function(response) {
|
||||
var url = "{% url 'stock-export' %}";
|
||||
|
||||
url += "?format=" + response.format;
|
||||
url += "&supplier={{ company.id }}";
|
||||
|
||||
location.href = url;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,127 +0,0 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'company/navbar.html' with tab='supplier_parts' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Supplier Parts" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block details %}
|
||||
{% if roles.purchase_order.change %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid'>
|
||||
<div class='btn-group' role='group'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<button class="btn btn-success" id='supplier-part-create' title='{% trans "Create new supplier part" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Supplier Part" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<div class='btn-group'>
|
||||
<div class="dropdown" style="float: right;">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% if roles.purchase_order.add %}
|
||||
<li><a href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li>
|
||||
{% endif %}
|
||||
{% if roles.purchase_order.delete %}
|
||||
<li><a href='#' id='multi-part-delete' title='{% trans "Delete parts" %}'>{% trans "Delete Parts" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-supplier-part'>
|
||||
<!-- Empty div (will be filled out with available BOM filters) -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed' id='part-table' data-toolbar='#button-toolbar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$("#supplier-part-create").click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-create' %}",
|
||||
{
|
||||
data: {
|
||||
supplier: {{ company.id }},
|
||||
},
|
||||
reload: true,
|
||||
secondary: [
|
||||
{
|
||||
field: 'part',
|
||||
label: '{% trans "New Part" %}',
|
||||
title: '{% trans "Create new Part" %}',
|
||||
url: "{% url 'part-create' %}"
|
||||
},
|
||||
{
|
||||
field: 'supplier',
|
||||
label: "{% trans 'New Supplier' %}",
|
||||
title: "{% trans 'Create new Supplier' %}",
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
loadSupplierPartTable(
|
||||
"#part-table",
|
||||
"{% url 'api-supplier-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part_detail: true,
|
||||
supplier_detail: true,
|
||||
manufacturer_detail: true,
|
||||
supplier: {{ company.id }},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
$("#multi-part-delete").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.pk);
|
||||
});
|
||||
|
||||
var url = "{% url 'supplier-part-delete' %}"
|
||||
|
||||
launchModalForm(url, {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$("#multi-part-order").click(function() {
|
||||
var selections = $("#part-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.part);
|
||||
});
|
||||
|
||||
launchModalForm("/order/purchase-order/order-parts/", {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
330
InvenTree/company/templates/company/manufacturer_part.html
Normal file
330
InvenTree/company/templates/company/manufacturer_part.html
Normal file
@ -0,0 +1,330 @@
|
||||
{% extends "two_column.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}
|
||||
InvenTree | {% trans "Manufacturer Part" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/manufacturer_part_navbar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block thumbnail %}
|
||||
<img class='part-thumb'
|
||||
{% if part.part.image %}
|
||||
src='{{ part.part.image.url }}'
|
||||
{% else %}
|
||||
src="{% static 'img/blank_image.png' %}"
|
||||
{% endif %}/>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_data %}
|
||||
<h3>{% trans "Manufacturer Part" %}</h3>
|
||||
<hr>
|
||||
<h4>
|
||||
{{ part.part.full_name }}
|
||||
{% if user.is_staff and perms.company.change_company %}
|
||||
<a href="{% url 'admin:company_supplierpart_change' part.pk %}">
|
||||
<span title='{% trans "Admin view" %}' class='fas fa-user-shield'></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h4>
|
||||
<p>{{ part.manufacturer.name }} - {{ part.MPN }}</p>
|
||||
|
||||
{% if roles.purchase_order.change %}
|
||||
<div class='btn-row'>
|
||||
<div class='btn-group action-buttons' role='group'>
|
||||
{% comment "for later" %}
|
||||
{% if roles.purchase_order.add %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='order-part' title='{% trans "Order part" %}'>
|
||||
<span class='fas fa-shopping-cart'></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endcomment %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='edit-part' title='{% trans "Edit manufacturer part" %}'>
|
||||
<span class='fas fa-edit icon-green'/>
|
||||
</button>
|
||||
{% if roles.purchase_order.delete %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='delete-part' title='{% trans "Delete manufacturer part" %}'>
|
||||
<span class='fas fa-trash-alt icon-red'/>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block page_details %}
|
||||
|
||||
<h4>{% trans "Manufacturer Part Details" %}</h4>
|
||||
<table class="table table-striped table-condensed">
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>{% trans "Internal Part" %}</td>
|
||||
<td>
|
||||
{% if part.part %}
|
||||
<a href="{% url 'part-detail' part.part.id %}?display=part-suppliers">{{ part.part.full_name }}</a>{% include "clip.html"%}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if part.description %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans "Description" %}</td>
|
||||
<td>{{ part.description }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.link %}
|
||||
<tr>
|
||||
<td><span class='fas fa-link'></span></td>
|
||||
<td>{% trans "External Link" %}</td>
|
||||
<td><a href="{{ part.link }}">{{ part.link }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-industry'></span></td>
|
||||
<td>{% trans "Manufacturer" %}</td>
|
||||
<td><a href="{% url 'company-detail' part.manufacturer.id %}">{{ part.manufacturer.name }}</a>{% include "clip.html"%}</td></tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "MPN" %}</td>
|
||||
<td>{{ part.MPN }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-supplier-parts'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Suppliers" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='supplier-button-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class="btn btn-success" id='supplier-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Supplier Part" %}
|
||||
</button>
|
||||
<div id='opt-dropdown' class="btn-group">
|
||||
<button id='supplier-part-options' class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href='#' id='supplier-part-delete' title='{% trans "Delete supplier parts" %}'>{% trans "Delete" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-condensed" id='supplier-table' data-toolbar='#supplier-button-toolbar'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-parameters'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Parameters" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='parameter-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-success' id='parameter-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Parameter" %}
|
||||
</button>
|
||||
<div id='opt-dropdown' class="btn-group">
|
||||
<button id='parameter-options' class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href='#' id='multi-parameter-delete' title='{% trans "Delete parameters" %}'>{% trans "Delete" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='parameter-table' data-toolbar='#parameter-toolbar'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableNavbar({
|
||||
label: 'manufacturer-part',
|
||||
toggleId: '#manufacturer-part-menu-toggle'
|
||||
});
|
||||
|
||||
function reloadParameters() {
|
||||
$("#parameter-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
$('#parameter-create').click(function() {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-parameter-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
name: {},
|
||||
value: {},
|
||||
units: {},
|
||||
manufacturer_part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Add Parameter" %}',
|
||||
onSuccess: reloadParameters
|
||||
});
|
||||
});
|
||||
|
||||
$('#supplier-create').click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-create' %}",
|
||||
{
|
||||
reload: true,
|
||||
data: {
|
||||
manufacturer_part: {{ part.id }}
|
||||
},
|
||||
secondary: [
|
||||
{
|
||||
field: 'supplier',
|
||||
label: '{% trans "New Supplier" %}',
|
||||
title: '{% trans "Create new supplier" %}',
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
$("#supplier-part-delete").click(function() {
|
||||
|
||||
var selections = $("#supplier-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.pk);
|
||||
});
|
||||
|
||||
launchModalForm("{% url 'supplier-part-delete' %}", {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$("#multi-parameter-delete").click(function() {
|
||||
|
||||
var selections = $("#parameter-table").bootstrapTable("getSelections");
|
||||
|
||||
var text = `
|
||||
<div class ='alert alert-block alert-danger'>
|
||||
<p>{% trans "Selected parameters will be deleted" %}:</p>
|
||||
<ul>`;
|
||||
|
||||
selections.forEach(function(item) {
|
||||
text += `<li>${item.name} - <i>${item.value}</i></li>`;
|
||||
});
|
||||
|
||||
text += `
|
||||
</ul>
|
||||
</div>`;
|
||||
|
||||
showQuestionDialog(
|
||||
'{% trans "Delete Parameters" %}',
|
||||
text,
|
||||
{
|
||||
accept_text: '{% trans "Delete" %}',
|
||||
accept: function() {
|
||||
// Delete each parameter via the API
|
||||
var requests = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
var url = `/api/company/part/manufacturer/parameter/${item.pk}/`;
|
||||
|
||||
requests.push(inventreeDelete(url));
|
||||
});
|
||||
|
||||
$.when.apply($, requests).then(function() {
|
||||
$('#parameter-table').bootstrapTable('refresh');
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
loadSupplierPartTable(
|
||||
"#supplier-table",
|
||||
"{% url 'api-supplier-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part: {{ part.part.id }},
|
||||
manufacturer_part: {{ part.id }},
|
||||
part_detail: false,
|
||||
supplier_detail: true,
|
||||
manufacturer_detail: false,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
loadManufacturerPartParameterTable(
|
||||
"#parameter-table",
|
||||
"{% url 'api-manufacturer-part-parameter-list' %}",
|
||||
{
|
||||
params: {
|
||||
manufacturer_part: {{ part.id }},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
linkButtonsToSelection($("#supplier-table"), ['#supplier-part-options']);
|
||||
|
||||
linkButtonsToSelection($("#parameter-table"), ['#parameter-options']);
|
||||
|
||||
$('#order-part, #order-part2').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'order-parts' %}",
|
||||
{
|
||||
data: {
|
||||
part: {{ part.part.id }},
|
||||
},
|
||||
reload: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
$('#edit-part').click(function () {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-detail" part.pk %}', {
|
||||
fields: {
|
||||
part: {},
|
||||
manufacturer: {},
|
||||
MPN: {
|
||||
icon: 'fa-hashtag',
|
||||
},
|
||||
description: {},
|
||||
link: {
|
||||
icon: 'fa-link',
|
||||
},
|
||||
},
|
||||
title: '{% trans "Edit Manufacturer Part" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$('#delete-part').click(function() {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-detail" part.pk %}', {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Manufacturer Part" %}',
|
||||
redirect: "{% url 'company-detail' part.manufacturer.id %}",
|
||||
});
|
||||
});
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'manufacturerpart',
|
||||
default: 'parameters'
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,143 +0,0 @@
|
||||
{% extends "two_column.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}
|
||||
InvenTree | {% trans "Manufacturer Part" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block thumbnail %}
|
||||
<img class='part-thumb'
|
||||
{% if part.part.image %}
|
||||
src='{{ part.part.image.url }}'
|
||||
{% else %}
|
||||
src="{% static 'img/blank_image.png' %}"
|
||||
{% endif %}/>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_data %}
|
||||
<h3>{% trans "Manufacturer Part" %}</h3>
|
||||
<hr>
|
||||
<h4>
|
||||
{{ part.part.full_name }}
|
||||
{% if user.is_staff and perms.company.change_company %}
|
||||
<a href="{% url 'admin:company_supplierpart_change' part.pk %}">
|
||||
<span title='{% trans "Admin view" %}' class='fas fa-user-shield'></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h4>
|
||||
<p>{{ part.manufacturer.name }} - {{ part.MPN }}</p>
|
||||
|
||||
{% if roles.purchase_order.change %}
|
||||
<div class='btn-row'>
|
||||
<div class='btn-group action-buttons' role='group'>
|
||||
{% comment "for later" %}
|
||||
{% if roles.purchase_order.add %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='order-part' title='{% trans "Order part" %}'>
|
||||
<span class='fas fa-shopping-cart'></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endcomment %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='edit-part' title='{% trans "Edit manufacturer part" %}'>
|
||||
<span class='fas fa-edit icon-green'/>
|
||||
</button>
|
||||
{% if roles.purchase_order.delete %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='delete-part' title='{% trans "Delete manufacturer part" %}'>
|
||||
<span class='fas fa-trash-alt icon-red'/>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block page_details %}
|
||||
|
||||
<h4>{% trans "Manufacturer Part Details" %}</h4>
|
||||
<table class="table table-striped table-condensed">
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>{% trans "Internal Part" %}</td>
|
||||
<td>
|
||||
{% if part.part %}
|
||||
<a href="{% url 'part-suppliers' part.part.id %}">{{ part.part.full_name }}</a>{% include "clip.html"%}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if part.description %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans "Description" %}</td>
|
||||
<td>{{ part.description }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.link %}
|
||||
<tr>
|
||||
<td><span class='fas fa-link'></span></td>
|
||||
<td>{% trans "External Link" %}</td>
|
||||
<td><a href="{{ part.link }}">{{ part.link }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-industry'></span></td>
|
||||
<td>{% trans "Manufacturer" %}</td>
|
||||
<td><a href="{% url 'company-detail-manufacturer-parts' part.manufacturer.id %}">{{ part.manufacturer.name }}</a>{% include "clip.html"%}</td></tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "MPN" %}</td>
|
||||
<td>{{ part.MPN }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableNavbar({
|
||||
label: 'manufacturer-part',
|
||||
toggleId: '#manufacturer-part-menu-toggle'
|
||||
})
|
||||
|
||||
$('#order-part, #order-part2').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'order-parts' %}",
|
||||
{
|
||||
data: {
|
||||
part: {{ part.part.id }},
|
||||
},
|
||||
reload: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
$('#edit-part').click(function () {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-detail" part.pk %}', {
|
||||
fields: {
|
||||
part: {},
|
||||
manufacturer: {},
|
||||
MPN: {
|
||||
icon: 'fa-hashtag',
|
||||
},
|
||||
description: {},
|
||||
link: {
|
||||
icon: 'fa-link',
|
||||
},
|
||||
},
|
||||
title: '{% trans "Edit Manufacturer Part" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$('#delete-part').click(function() {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-detail" part.pk %}', {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Manufacturer Part" %}',
|
||||
redirect: "{% url 'company-detail-manufacturer-parts' part.manufacturer.id %}",
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,17 +0,0 @@
|
||||
{% extends "modal_form.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if part %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% include "hover_image.html" with image=part.image %}
|
||||
{{ part.full_name}}
|
||||
<br>
|
||||
<i>{{ part.description }}</i>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -1,38 +0,0 @@
|
||||
{% extends "company/manufacturer_part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/manufacturer_part_navbar.html" with tab='details' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Manufacturer Part Details" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block details %}
|
||||
|
||||
<table class="table table-striped table-condensed">
|
||||
<tr>
|
||||
<td>{% trans "Internal Part" %}</td>
|
||||
<td>
|
||||
{% if part.part %}
|
||||
<a href="{% url 'part-suppliers' part.part.id %}">{{ part.part.full_name }}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td>{% trans "Manufacturer" %}</td><td><a href="{% url 'company-detail-manufacturer-parts' part.manufacturer.id %}">{{ part.manufacturer.name }}</a></td></tr>
|
||||
<tr><td>{% trans "MPN" %}</td><td>{{ part.MPN }}</tr></tr>
|
||||
{% if part.link %}
|
||||
<tr><td>{% trans "External Link" %}</td><td><a href="{{ part.link }}">{{ part.link }}</a></td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
|
||||
{% endblock %}
|
@ -8,8 +8,15 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "suppliers" %}active{% endif %}' title='{% trans "Supplier Parts" %}'>
|
||||
<a href='{% url "manufacturer-part-suppliers" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Parameters" %}'>
|
||||
<a href='#' id='select-parameters' class='nav-toggle'>
|
||||
<span class='fas fa-th-list sidebar-icon'></span>
|
||||
{% trans "Parameters" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item' title='{% trans "Supplier Parts" %}'>
|
||||
<a href='#' id='select-supplier-parts' class='nav-toggle'>
|
||||
<span class='fas fa-building sidebar-icon'></span>
|
||||
{% trans "Suppliers" %}
|
||||
</a>
|
||||
@ -22,7 +29,7 @@
|
||||
{% trans "Stock" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li class='list-group-item {% if tab == "orders" %}active{% endif %}' title='{% trans "Manufacturer Part Orders" %}'>
|
||||
<a href='{% url "manufacturer-part-orders" part.id %}'>
|
||||
<span class='fas fa-shopping-cart sidebar-icon'></span>
|
||||
|
@ -1,187 +0,0 @@
|
||||
{% extends "company/manufacturer_part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/manufacturer_part_navbar.html" with tab='suppliers' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Suppliers" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class="btn btn-success" id='supplier-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Supplier Part" %}
|
||||
</button>
|
||||
<div id='opt-dropdown' class="btn-group">
|
||||
<button id='supplier-part-options' class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href='#' id='supplier-part-delete' title='{% trans "Delete supplier parts" %}'>{% trans "Delete" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-condensed" id='supplier-table' data-toolbar='#button-toolbar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block post_content_panels %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Parameters" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='parameter-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-success' id='parameter-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Parameter" %}
|
||||
</button>
|
||||
<div id='opt-dropdown' class="btn-group">
|
||||
<button id='parameter-options' class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href='#' id='multi-parameter-delete' title='{% trans "Delete parameters" %}'>{% trans "Delete" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='parameter-table' data-toolbar='#parameter-toolbar'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
function reloadParameters() {
|
||||
$("#parameter-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
$('#parameter-create').click(function() {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-parameter-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
name: {},
|
||||
value: {},
|
||||
units: {},
|
||||
manufacturer_part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Add Parameter" %}',
|
||||
onSuccess: reloadParameters
|
||||
});
|
||||
});
|
||||
|
||||
$('#supplier-create').click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-create' %}",
|
||||
{
|
||||
reload: true,
|
||||
data: {
|
||||
manufacturer_part: {{ part.id }}
|
||||
},
|
||||
secondary: [
|
||||
{
|
||||
field: 'supplier',
|
||||
label: '{% trans "New Supplier" %}',
|
||||
title: '{% trans "Create new supplier" %}',
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
$("#supplier-part-delete").click(function() {
|
||||
|
||||
var selections = $("#supplier-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.pk);
|
||||
});
|
||||
|
||||
launchModalForm("{% url 'supplier-part-delete' %}", {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$("#multi-parameter-delete").click(function() {
|
||||
|
||||
var selections = $("#parameter-table").bootstrapTable("getSelections");
|
||||
|
||||
var text = `
|
||||
<div class ='alert alert-block alert-danger'>
|
||||
<p>{% trans "Selected parameters will be deleted" %}:</p>
|
||||
<ul>`;
|
||||
|
||||
selections.forEach(function(item) {
|
||||
text += `<li>${item.name} - <i>${item.value}</i></li>`;
|
||||
});
|
||||
|
||||
text += `
|
||||
</ul>
|
||||
</div>`;
|
||||
|
||||
showQuestionDialog(
|
||||
'{% trans "Delete Parameters" %}',
|
||||
text,
|
||||
{
|
||||
accept_text: '{% trans "Delete" %}',
|
||||
accept: function() {
|
||||
// Delete each parameter via the API
|
||||
var requests = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
var url = `/api/company/part/manufacturer/parameter/${item.pk}/`;
|
||||
|
||||
requests.push(inventreeDelete(url));
|
||||
});
|
||||
|
||||
$.when.apply($, requests).then(function() {
|
||||
$('#parameter-table').bootstrapTable('refresh');
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
loadSupplierPartTable(
|
||||
"#supplier-table",
|
||||
"{% url 'api-supplier-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part: {{ part.part.id }},
|
||||
manufacturer_part: {{ part.id }},
|
||||
part_detail: false,
|
||||
supplier_detail: true,
|
||||
manufacturer_detail: false,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
loadManufacturerPartParameterTable(
|
||||
"#parameter-table",
|
||||
"{% url 'api-manufacturer-part-parameter-list' %}",
|
||||
{
|
||||
params: {
|
||||
manufacturer_part: {{ part.id }},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
linkButtonsToSelection($("#supplier-table"), ['#supplier-part-options'])
|
||||
linkButtonsToSelection($("#parameter-table"), ['#parameter-options'])
|
||||
{% endblock %}
|
@ -9,16 +9,9 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "details" %}active{% endif %}' title='{% trans "Company Details" %}'>
|
||||
<a href='{% url "company-detail" company.id %}'>
|
||||
<span class='fas fa-info-circle sidebar-icon'></span>
|
||||
{% trans "Details" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if company.is_manufacturer %}
|
||||
<li class='list-group-item {% if tab == "manufacturer_parts" %}active{% endif %}' title='{% trans "Manufactured Parts" %}'>
|
||||
<a href='{% url "company-detail-manufacturer-parts" company.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Manufactured Parts" %}'>
|
||||
<a href='#' id='select-manufacturer-parts' class='nav-toggle'>
|
||||
<span class='fas fa-industry sidebar-icon'></span>
|
||||
{% trans "Manufactured Parts" %}
|
||||
</a>
|
||||
@ -26,8 +19,8 @@
|
||||
{% endif %}
|
||||
|
||||
{% if company.is_supplier or company.is_manufacturer %}
|
||||
<li class='list-group-item {% if tab == "supplier_parts" %}active{% endif %}' title='{% trans "Supplied Parts" %}'>
|
||||
<a href='{% url "company-detail-supplier-parts" company.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Supplied Parts" %}'>
|
||||
<a href='#' id='select-supplier-parts' class='nav-toggle'>
|
||||
<span class='fas fa-building sidebar-icon'></span>
|
||||
{% trans "Supplied Parts" %}
|
||||
</a>
|
||||
@ -35,8 +28,8 @@
|
||||
{% endif %}
|
||||
|
||||
{% if company.is_manufacturer or company.is_supplier %}
|
||||
<li class='list-group-item {% if tab == "stock" %}active{% endif %}' title='{% trans "Stock Items" %}'>
|
||||
<a href='{% url "company-detail-stock" company.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Stock Items" %}'>
|
||||
<a href='#' id='select-company-stock' class='nav-toggle'>
|
||||
<span class='fas fa-boxes sidebar-icon'></span>
|
||||
{% trans "Stock" %}
|
||||
</a>
|
||||
@ -44,8 +37,8 @@
|
||||
{% endif %}
|
||||
|
||||
{% if company.is_supplier %}
|
||||
<li class='list-group-item {% if tab == "po" %}active{% endif %}' title='{% trans "Sales Orders" %}'>
|
||||
<a href='{% url "company-detail-purchase-orders" company.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Purchase Orders" %}'>
|
||||
<a href='#' id='select-purchase-orders' class='nav-toggle'>
|
||||
<span class='fas fa-shopping-cart sidebar-icon'></span>
|
||||
{% trans "Purchase Orders" %}
|
||||
</a>
|
||||
@ -53,22 +46,22 @@
|
||||
{% endif %}
|
||||
|
||||
{% if company.is_customer %}
|
||||
<li class='list-group-item {% if tab == "so" %}active{% endif %}' title='{% trans "Sales Orders" %}'>
|
||||
<a href='{% url "company-detail-sales-orders" company.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Sales Orders" %}'>
|
||||
<a href='#' id='select-sales-orders' class='nav-toggle'>
|
||||
<span class='fas fa-truck sidebar-icon'></span>
|
||||
{% trans "Sales Orders" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item {% if tab == "assigned" %}active{% endif %}' title='{% trans "Assigned Stock" %}'>
|
||||
<a href='{% url "company-detail-assigned-stock" company.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Assigned Stock" %}'>
|
||||
<a href='#' id='select-assigned-stock' class='nav-toggle'>
|
||||
<span class='fas fa-sign-out-alt sidebar-icon'></span>
|
||||
{% trans "Assigned Stock" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class='list-group-item {% if tab == "notes" %}active{% endif %}' titl='{% trans "Notes" %}'>
|
||||
<a href='{% url "company-notes" company.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Notes" %}'>
|
||||
<a href='#' id='select-company-notes' class='nav-toggle'>
|
||||
<span class='fas fa-clipboard sidebar-icon'></span>
|
||||
{% trans "Notes" %}
|
||||
</a>
|
||||
|
@ -1,47 +0,0 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'company/navbar.html' with tab='notes' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Company Notes" %}
|
||||
{% if 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 %}
|
||||
<form method='POST'>
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form }}
|
||||
<hr>
|
||||
<button type="submit" class='btn btn-default'>{% trans "Save" %}</button>
|
||||
|
||||
</form>
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
{% else %}
|
||||
|
||||
{{ company.notes | markdownify }}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if editing %}
|
||||
{% else %}
|
||||
$("#edit-notes").click(function() {
|
||||
location.href = "{% url 'company-notes' company.id %}?edit=1";
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -1,56 +0,0 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'company/navbar.html' with tab='po' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Purchase Orders" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% if roles.purchase_order.add %}
|
||||
<div id='button-bar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
<button class='btn btn-primary' type='button' id='company-order2' title='{% trans "Create new purchase order" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Purchase Order" %}</button>
|
||||
<div class='filter-list' id='filter-list-purchaseorder'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed po-table' id='purchase-order-table' data-toolbar='#button-bar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadPurchaseOrderTable("#purchase-order-table", {
|
||||
url: "{% url 'api-po-list' %}",
|
||||
params: {
|
||||
supplier: {{ company.id }},
|
||||
}
|
||||
});
|
||||
|
||||
function newOrder() {
|
||||
createPurchaseOrder({
|
||||
supplier: {{ company.pk }},
|
||||
});
|
||||
}
|
||||
|
||||
$("#company-order").click(function() {
|
||||
newOrder();
|
||||
});
|
||||
|
||||
$("#company-order2").click(function() {
|
||||
newOrder();
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,51 +0,0 @@
|
||||
{% extends "company/company_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'company/navbar.html' with tab='so' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Sales Orders" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% if roles.sales_order.add %}
|
||||
<div id='button-bar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
<button class='btn btn-primary' type='button' id='new-sales-order' title='{% trans "Create new sales order" %}'>
|
||||
<div class='fas fa-plus-circle'></div> {% trans "New Sales Order" %}
|
||||
</button>
|
||||
<div class='filter-list' id='filter-list-salesorder'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed po-table' id='sales-order-table' data-toolbar='#button-bar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadSalesOrderTable("#sales-order-table", {
|
||||
url: "{% url 'api-so-list' %}",
|
||||
params: {
|
||||
customer: {{ company.id }},
|
||||
}
|
||||
});
|
||||
|
||||
$("#new-sales-order").click(function() {
|
||||
|
||||
createSalesOrder({
|
||||
customer: {{ company.pk }},
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
352
InvenTree/company/templates/company/supplier_part.html
Normal file
352
InvenTree/company/templates/company/supplier_part.html
Normal file
@ -0,0 +1,352 @@
|
||||
{% extends "two_column.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block page_title %}
|
||||
{% inventree_title %} | {% trans "Supplier Part" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/supplier_part_navbar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block thumbnail %}
|
||||
<img class='part-thumb'
|
||||
{% if part.part.image %}
|
||||
src='{{ part.part.image.url }}'
|
||||
{% else %}
|
||||
src="{% static 'img/blank_image.png' %}"
|
||||
{% endif %}/>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_data %}
|
||||
<h3>{% trans "Supplier Part" %}</h3>
|
||||
<hr>
|
||||
<h4>
|
||||
{{ part.part.full_name }}
|
||||
{% if user.is_staff and perms.company.change_company %}
|
||||
<a href="{% url 'admin:company_supplierpart_change' part.pk %}">
|
||||
<span title='{% trans "Admin view" %}' class='fas fa-user-shield'></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h4>
|
||||
<p>{{ part.supplier.name }} - {{ part.SKU }}</p>
|
||||
|
||||
{% if roles.purchase_order.change %}
|
||||
<div class='btn-row'>
|
||||
<div class='btn-group action-buttons' role='group'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='order-part' title='{% trans "Order part" %}'>
|
||||
<span class='fas fa-shopping-cart'></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='edit-part' title='{% trans "Edit supplier part" %}'>
|
||||
<span class='fas fa-edit icon-green'/>
|
||||
</button>
|
||||
{% if roles.purchase_order.delete %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='delete-part' title='{% trans "Delete supplier part" %}'>
|
||||
<span class='fas fa-trash-alt icon-red'/>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block page_details %}
|
||||
|
||||
<h4>{% trans "Supplier Part Details" %}</h4>
|
||||
<table class="table table-striped table-condensed">
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>{% trans "Internal Part" %}</td>
|
||||
<td>
|
||||
{% if part.part %}
|
||||
<a href="{% url 'part-detail' part.part.id %}?display=part-suppliers">{{ part.part.full_name }}</a>{% include "clip.html"%}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if part.description %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans "Description" %}</td>
|
||||
<td>{{ part.description }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.link %}
|
||||
<tr>
|
||||
<td><span class='fas fa-link'></span></td>
|
||||
<td>{% trans "External Link" %}</td>
|
||||
<td><a href="{{ part.link }}">{{ part.link }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-building'></span></td>
|
||||
<td>{% trans "Supplier" %}</td>
|
||||
<td><a href="{% url 'company-detail' part.supplier.id %}">{{ part.supplier.name }}</a>{% include "clip.html"%}</td></tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "SKU" %}</td>
|
||||
<td>{{ part.SKU }}{% include "clip.html"%}</tr>
|
||||
</tr>
|
||||
{% if part.manufacturer_part.manufacturer %}
|
||||
<tr>
|
||||
<td><span class='fas fa-industry'></span></td>
|
||||
<td>{% trans "Manufacturer" %}</td>
|
||||
<td><a href="{% url 'company-detail' part.manufacturer_part.manufacturer.id %}">
|
||||
{{ part.manufacturer_part.manufacturer.name }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.manufacturer_part.MPN %}
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "MPN" %}</td>
|
||||
<td><a href="{% url 'manufacturer-part-detail' part.manufacturer_part.id %}">{{ part.manufacturer_part.MPN }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.packaging %}
|
||||
<tr>
|
||||
<td><span class='fas fa-cube'></span></td>
|
||||
<td>{% trans "Packaging" %}</td>
|
||||
<td>{{ part.packaging }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.note %}
|
||||
<tr>
|
||||
<td><span class='fas fa-sticky-note'></span></td>
|
||||
<td>{% trans "Note" %}</td>
|
||||
<td>{{ part.note }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-stock'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Supplier Part Stock" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% include "stock_table.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-purchase-orders'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Supplier Part Orders" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<div id='button-bar'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-primary' type='button' id='order-part2' title='{% trans "Order part" %}'>
|
||||
<span class='fas fa-shopping-cart'></span> {% trans "Order Part" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class='table table-striped table-condensed po-table' id='purchase-order-table' data-toolbar='#button-bar'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-pricing'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Pricing Information" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<div id='price-break-toolbar' class='btn-group'>
|
||||
<button class='btn btn-primary' id='new-price-break' type='button'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Price Break" %}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed' id='price-break-table' data-toolbar='#price-break-toolbar'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
function reloadPriceBreaks() {
|
||||
$("#price-break-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
$('#price-break-table').inventreeTable({
|
||||
name: 'buypricebreaks',
|
||||
formatNoMatches: function() { return "{% trans "No price break information found" %}"; },
|
||||
queryParams: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
url: "{% url 'api-part-supplier-price-list' %}",
|
||||
onPostBody: function() {
|
||||
var table = $('#price-break-table');
|
||||
|
||||
table.find('.button-price-break-delete').click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
constructForm(`/api/company/price-break/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
onSuccess: reloadPriceBreaks,
|
||||
title: '{% trans "Delete Price Break" %}',
|
||||
});
|
||||
});
|
||||
|
||||
table.find('.button-price-break-edit').click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
constructForm(`/api/company/price-break/${pk}/`, {
|
||||
fields: {
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
onSuccess: reloadPriceBreaks,
|
||||
title: '{% trans "Edit Price Break" %}',
|
||||
});
|
||||
});
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'pk',
|
||||
title: 'ID',
|
||||
visible: false,
|
||||
switchable: false,
|
||||
},
|
||||
{
|
||||
field: 'quantity',
|
||||
title: '{% trans "Quantity" %}',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'price',
|
||||
title: '{% trans "Price" %}',
|
||||
sortable: true,
|
||||
formatter: function(value, row, index) {
|
||||
var html = value;
|
||||
|
||||
html += `<div class='btn-group float-right' role='group'>`
|
||||
|
||||
html += makeIconButton('fa-edit icon-blue', 'button-price-break-edit', row.pk, '{% trans "Edit price break" %}');
|
||||
html += makeIconButton('fa-trash-alt icon-red', 'button-price-break-delete', row.pk, '{% trans "Delete price break" %}');
|
||||
|
||||
html += `</div>`;
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
$('#new-price-break').click(function() {
|
||||
|
||||
constructForm(
|
||||
'{% url "api-part-supplier-price-list" %}',
|
||||
{
|
||||
method: 'POST',
|
||||
fields: {
|
||||
quantity: {},
|
||||
part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
},
|
||||
price: {},
|
||||
price_currency: {
|
||||
},
|
||||
},
|
||||
title: '{% trans "Add Price Break" %}',
|
||||
onSuccess: reloadPriceBreaks,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
loadPurchaseOrderTable($("#purchase-order-table"), {
|
||||
url: "{% url 'api-po-list' %}?supplier_part={{ part.id }}",
|
||||
});
|
||||
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
supplier_part: {{ part.id }},
|
||||
location_detail: true,
|
||||
part_detail: false,
|
||||
},
|
||||
groupByField: 'location',
|
||||
buttons: ['#stock-options'],
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
|
||||
$("#stock-export").click(function() {
|
||||
launchModalForm("{% url 'stock-export-options' %}", {
|
||||
submit_text: '{% trans "Export" %}',
|
||||
success: function(response) {
|
||||
var url = "{% url 'stock-export' %}";
|
||||
|
||||
url += "?format=" + response.format;
|
||||
url += "&cascade=" + response.cascade;
|
||||
url += "&supplier_part={{ part.id }}";
|
||||
|
||||
location.href = url;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$("#item-create").click(function() {
|
||||
createNewStockItem({
|
||||
data: {
|
||||
part: {{ part.part.id }},
|
||||
supplier_part: {{ part.id }},
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
enableNavbar({
|
||||
label: 'supplier-part',
|
||||
toggleId: '#supplier-part-menu-toggle'
|
||||
})
|
||||
|
||||
$('#order-part, #order-part2').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'order-parts' %}",
|
||||
{
|
||||
data: {
|
||||
part: {{ part.part.id }},
|
||||
},
|
||||
reload: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
$('#edit-part').click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-edit' part.id %}",
|
||||
{
|
||||
reload: true
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#delete-part').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-delete' %}?part={{ part.id }}",
|
||||
{
|
||||
redirect: "{% url 'company-detail' part.supplier.id %}"
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'supplierpart',
|
||||
default: 'stock'
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,161 +0,0 @@
|
||||
{% extends "two_column.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block page_title %}
|
||||
{% inventree_title %} | {% trans "Supplier Part" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block thumbnail %}
|
||||
<img class='part-thumb'
|
||||
{% if part.part.image %}
|
||||
src='{{ part.part.image.url }}'
|
||||
{% else %}
|
||||
src="{% static 'img/blank_image.png' %}"
|
||||
{% endif %}/>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_data %}
|
||||
<h3>{% trans "Supplier Part" %}</h3>
|
||||
<hr>
|
||||
<h4>
|
||||
{{ part.part.full_name }}
|
||||
{% if user.is_staff and perms.company.change_company %}
|
||||
<a href="{% url 'admin:company_supplierpart_change' part.pk %}">
|
||||
<span title='{% trans "Admin view" %}' class='fas fa-user-shield'></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</h4>
|
||||
<p>{{ part.supplier.name }} - {{ part.SKU }}</p>
|
||||
|
||||
{% if roles.purchase_order.change %}
|
||||
<div class='btn-row'>
|
||||
<div class='btn-group action-buttons' role='group'>
|
||||
{% if roles.purchase_order.add %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='order-part' title='{% trans "Order part" %}'>
|
||||
<span class='fas fa-shopping-cart'></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='edit-part' title='{% trans "Edit supplier part" %}'>
|
||||
<span class='fas fa-edit icon-green'/>
|
||||
</button>
|
||||
{% if roles.purchase_order.delete %}
|
||||
<button type='button' class='btn btn-default btn-glyph' id='delete-part' title='{% trans "Delete supplier part" %}'>
|
||||
<span class='fas fa-trash-alt icon-red'/>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block page_details %}
|
||||
|
||||
<h4>{% trans "Supplier Part Details" %}</h4>
|
||||
<table class="table table-striped table-condensed">
|
||||
<col width='25'>
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>{% trans "Internal Part" %}</td>
|
||||
<td>
|
||||
{% if part.part %}
|
||||
<a href="{% url 'part-suppliers' part.part.id %}">{{ part.part.full_name }}</a>{% include "clip.html"%}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if part.description %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans "Description" %}</td>
|
||||
<td>{{ part.description }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.link %}
|
||||
<tr>
|
||||
<td><span class='fas fa-link'></span></td>
|
||||
<td>{% trans "External Link" %}</td>
|
||||
<td><a href="{{ part.link }}">{{ part.link }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-building'></span></td>
|
||||
<td>{% trans "Supplier" %}</td>
|
||||
<td><a href="{% url 'company-detail-supplier-parts' part.supplier.id %}">{{ part.supplier.name }}</a>{% include "clip.html"%}</td></tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "SKU" %}</td>
|
||||
<td>{{ part.SKU }}{% include "clip.html"%}</tr>
|
||||
</tr>
|
||||
{% if part.manufacturer_part.manufacturer %}
|
||||
<tr>
|
||||
<td><span class='fas fa-industry'></span></td>
|
||||
<td>{% trans "Manufacturer" %}</td>
|
||||
<td><a href="{% url 'company-detail-manufacturer-parts' part.manufacturer_part.manufacturer.id %}">
|
||||
{{ part.manufacturer_part.manufacturer.name }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.manufacturer_part.MPN %}
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "MPN" %}</td>
|
||||
<td><a href="{% url 'manufacturer-part-detail' part.manufacturer_part.id %}">{{ part.manufacturer_part.MPN }}</a>{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.packaging %}
|
||||
<tr>
|
||||
<td><span class='fas fa-cube'></span></td>
|
||||
<td>{% trans "Packaging" %}</td>
|
||||
<td>{{ part.packaging }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.note %}
|
||||
<tr>
|
||||
<td><span class='fas fa-sticky-note'></span></td>
|
||||
<td>{% trans "Note" %}</td>
|
||||
<td>{{ part.note }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableNavbar({
|
||||
label: 'supplier-part',
|
||||
toggleId: '#supplier-part-menu-toggle'
|
||||
})
|
||||
|
||||
$('#order-part, #order-part2').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'order-parts' %}",
|
||||
{
|
||||
data: {
|
||||
part: {{ part.part.id }},
|
||||
},
|
||||
reload: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
$('#edit-part').click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-edit' part.id %}",
|
||||
{
|
||||
reload: true
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#delete-part').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-delete' %}?part={{ part.id }}",
|
||||
{
|
||||
redirect: "{% url 'company-detail-supplier-parts' part.supplier.id %}"
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,48 +0,0 @@
|
||||
{% extends "company/supplier_part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/supplier_part_navbar.html" with tab='details' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Supplier Part Details" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block details %}
|
||||
|
||||
<table class="table table-striped table-condensed">
|
||||
<tr>
|
||||
<td>{% trans "Internal Part" %}</td>
|
||||
<td>
|
||||
{% if part.part %}
|
||||
<a href="{% url 'part-suppliers' part.part.id %}">{{ part.part.full_name }}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td>{% trans "Supplier" %}</td><td><a href="{% url 'company-detail-supplier-parts' part.supplier.id %}">{{ part.supplier.name }}</a></td></tr>
|
||||
<tr><td>{% trans "SKU" %}</td><td>{{ part.SKU }}</tr></tr>
|
||||
{% if part.link %}
|
||||
<tr><td>{% trans "External Link" %}</td><td><a href="{{ part.link }}">{{ part.link }}</a></td></tr>
|
||||
{% endif %}
|
||||
{% if part.description %}
|
||||
<tr><td>{% trans "Description" %}</td><td>{{ part.description }}{% include "clip.html"%}</td></tr>
|
||||
{% endif %}
|
||||
{% if part.manufacturer %}
|
||||
<tr><td>{% trans "Manufacturer" %}</td><td>{{ part.manufacturer }}{% include "clip.html"%}</td></tr>
|
||||
<tr><td>{% trans "MPN" %}</td><td>{{ part.MPN }}{% include "clip.html"%}</td></tr>
|
||||
{% endif %}
|
||||
{% if part.note %}
|
||||
<tr><td>{% trans "Note" %}</td><td>{{ part.note }}{% include "clip.html"%}</td></tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
|
||||
{% endblock %}
|
@ -9,22 +9,22 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "stock" %}active{% endif %}' title='{% trans "Supplier Part Stock" %}'>
|
||||
<a href='{% url "supplier-part-stock" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Supplier Part Stock" %}'>
|
||||
<a href='#' id='select-stock' class='nav-toggle'>
|
||||
<span class='fas fa-boxes sidebar-icon'></span>
|
||||
{% trans "Stock" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "orders" %}active{% endif %}' title='{% trans "Supplier Part Orders" %}'>
|
||||
<a href='{% url "supplier-part-orders" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Supplier Part Orders" %}'>
|
||||
<a href='#' id='select-purchase-orders' class='nav-toggle'>
|
||||
<span class='fas fa-shopping-cart sidebar-icon'></span>
|
||||
{% trans "Orders" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "pricing" %}active{% endif %}' title='{% trans "Supplier Part Pricing" %}'>
|
||||
<a href='{% url "supplier-part-pricing" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Supplier Part Pricing" %}'>
|
||||
<a href='#' id='select-pricing' class='nav-toggle'>
|
||||
<span class='fas fa-dollar-sign sidebar-icon'></span>
|
||||
{% trans "Pricing" %}
|
||||
</a>
|
||||
|
@ -1,35 +0,0 @@
|
||||
{% extends "company/supplier_part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/supplier_part_navbar.html" with tab='orders' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Supplier Part Orders" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% if roles.purchase_order.add %}
|
||||
<div id='button-bar'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-primary' type='button' id='order-part2' title='{% trans "Order part" %}'>
|
||||
<span class='fas fa-shopping-cart'></span> {% trans "Order Part" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed po-table' id='purchase-order-table' data-toolbar='#button-bar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadPurchaseOrderTable($("#purchase-order-table"), {
|
||||
url: "{% url 'api-po-list' %}?supplier_part={{ part.id }}",
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,124 +0,0 @@
|
||||
{% extends "company/supplier_part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/supplier_part_navbar.html" with tab='pricing' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Pricing Information" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% if roles.purchase_order.add %}
|
||||
<div id='price-break-toolbar' class='btn-group'>
|
||||
<button class='btn btn-primary' id='new-price-break' type='button'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Price Break" %}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed' id='price-break-table' data-toolbar='#price-break-toolbar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
function reloadPriceBreaks() {
|
||||
$("#price-break-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
$('#price-break-table').inventreeTable({
|
||||
name: 'buypricebreaks',
|
||||
formatNoMatches: function() { return "{% trans "No price break information found" %}"; },
|
||||
queryParams: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
url: "{% url 'api-part-supplier-price-list' %}",
|
||||
onPostBody: function() {
|
||||
var table = $('#price-break-table');
|
||||
|
||||
table.find('.button-price-break-delete').click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
constructForm(`/api/company/price-break/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
onSuccess: reloadPriceBreaks,
|
||||
title: '{% trans "Delete Price Break" %}',
|
||||
});
|
||||
});
|
||||
|
||||
table.find('.button-price-break-edit').click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
constructForm(`/api/company/price-break/${pk}/`, {
|
||||
fields: {
|
||||
quantity: {},
|
||||
price: {},
|
||||
price_currency: {},
|
||||
},
|
||||
onSuccess: reloadPriceBreaks,
|
||||
title: '{% trans "Edit Price Break" %}',
|
||||
});
|
||||
});
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'pk',
|
||||
title: 'ID',
|
||||
visible: false,
|
||||
switchable: false,
|
||||
},
|
||||
{
|
||||
field: 'quantity',
|
||||
title: '{% trans "Quantity" %}',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'price',
|
||||
title: '{% trans "Price" %}',
|
||||
sortable: true,
|
||||
formatter: function(value, row, index) {
|
||||
var html = value;
|
||||
|
||||
html += `<div class='btn-group float-right' role='group'>`
|
||||
|
||||
html += makeIconButton('fa-edit icon-blue', 'button-price-break-edit', row.pk, '{% trans "Edit price break" %}');
|
||||
html += makeIconButton('fa-trash-alt icon-red', 'button-price-break-delete', row.pk, '{% trans "Delete price break" %}');
|
||||
|
||||
html += `</div>`;
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
$('#new-price-break').click(function() {
|
||||
|
||||
constructForm(
|
||||
'{% url "api-part-supplier-price-list" %}',
|
||||
{
|
||||
method: 'POST',
|
||||
fields: {
|
||||
quantity: {},
|
||||
part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
},
|
||||
price: {},
|
||||
price_currency: {
|
||||
},
|
||||
},
|
||||
title: '{% trans "Add Price Break" %}',
|
||||
onSuccess: reloadPriceBreaks,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,58 +0,0 @@
|
||||
{% extends "company/supplier_part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "company/supplier_part_navbar.html" with tab='stock' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Supplier Part Stock" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% include "stock_table.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
supplier_part: {{ part.id }},
|
||||
location_detail: true,
|
||||
part_detail: false,
|
||||
},
|
||||
groupByField: 'location',
|
||||
buttons: ['#stock-options'],
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
|
||||
$("#stock-export").click(function() {
|
||||
launchModalForm("{% url 'stock-export-options' %}", {
|
||||
submit_text: '{% trans "Export" %}',
|
||||
success: function(response) {
|
||||
var url = "{% url 'stock-export' %}";
|
||||
|
||||
url += "?format=" + response.format;
|
||||
url += "&cascade=" + response.cascade;
|
||||
url += "&supplier_part={{ part.id }}";
|
||||
|
||||
location.href = url;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$("#item-create").click(function() {
|
||||
createNewStockItem({
|
||||
data: {
|
||||
part: {{ part.part.id }},
|
||||
supplier_part: {{ part.id }},
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
{% endblock %}
|
@ -8,15 +8,6 @@ from . import views
|
||||
|
||||
|
||||
company_detail_urls = [
|
||||
# url(r'orders/?', views.CompanyDetail.as_view(template_name='company/orders.html'), name='company-detail-orders'),
|
||||
|
||||
url(r'^supplier-parts/', views.CompanyDetail.as_view(template_name='company/detail_supplier_part.html'), name='company-detail-supplier-parts'),
|
||||
url(r'^manufacturer-parts/', views.CompanyDetail.as_view(template_name='company/detail_manufacturer_part.html'), name='company-detail-manufacturer-parts'),
|
||||
url(r'^stock/', views.CompanyDetail.as_view(template_name='company/detail_stock.html'), name='company-detail-stock'),
|
||||
url(r'^purchase-orders/', views.CompanyDetail.as_view(template_name='company/purchase_orders.html'), name='company-detail-purchase-orders'),
|
||||
url(r'^assigned-stock/', views.CompanyDetail.as_view(template_name='company/assigned_stock.html'), name='company-detail-assigned-stock'),
|
||||
url(r'^sales-orders/', views.CompanyDetail.as_view(template_name='company/sales_orders.html'), name='company-detail-sales-orders'),
|
||||
url(r'^notes/', views.CompanyNotes.as_view(), name='company-notes'),
|
||||
|
||||
url(r'^thumb-download/', views.CompanyImageDownloadFromURL.as_view(), name='company-image-download'),
|
||||
|
||||
@ -40,20 +31,14 @@ company_urls = [
|
||||
manufacturer_part_urls = [
|
||||
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^suppliers/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part_suppliers.html'), name='manufacturer-part-suppliers'),
|
||||
url('^.*$', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part_suppliers.html'), name='manufacturer-part-detail'),
|
||||
url('^.*$', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part.html'), name='manufacturer-part-detail'),
|
||||
])),
|
||||
]
|
||||
|
||||
supplier_part_detail_urls = [
|
||||
url(r'^edit/?', views.SupplierPartEdit.as_view(), name='supplier-part-edit'),
|
||||
|
||||
url(r'^manufacturers/', views.SupplierPartDetail.as_view(template_name='company/supplier_part_manufacturers.html'), name='supplier-part-manufacturers'),
|
||||
url(r'^pricing/', views.SupplierPartDetail.as_view(template_name='company/supplier_part_pricing.html'), name='supplier-part-pricing'),
|
||||
url(r'^orders/', views.SupplierPartDetail.as_view(template_name='company/supplier_part_orders.html'), name='supplier-part-orders'),
|
||||
url(r'^stock/', views.SupplierPartDetail.as_view(template_name='company/supplier_part_stock.html'), name='supplier-part-stock'),
|
||||
|
||||
url('^.*$', views.SupplierPartDetail.as_view(template_name='company/supplier_part_pricing.html'), name='supplier-part-detail'),
|
||||
url('^.*$', views.SupplierPartDetail.as_view(template_name='company/supplier_part.html'), name='supplier-part-detail'),
|
||||
]
|
||||
|
||||
supplier_part_urls = [
|
||||
|
@ -7,7 +7,7 @@ Django views for interacting with Company app
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView, UpdateView
|
||||
from django.views.generic import DetailView, ListView
|
||||
|
||||
from django.urls import reverse
|
||||
from django.forms import HiddenInput
|
||||
@ -113,28 +113,6 @@ class CompanyIndex(InvenTreeRoleMixin, ListView):
|
||||
return queryset
|
||||
|
||||
|
||||
class CompanyNotes(UpdateView):
|
||||
""" View for editing the 'notes' field of a Company object.
|
||||
"""
|
||||
|
||||
context_object_name = 'company'
|
||||
template_name = 'company/notes.html'
|
||||
model = Company
|
||||
fields = ['notes']
|
||||
permission_required = 'company.view_company'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('company-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 CompanyDetail(DetailView):
|
||||
""" Detail view for Company object """
|
||||
context_obect_name = 'company'
|
||||
|
@ -145,10 +145,6 @@ src="{% static 'img/blank_image.png' %}"
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableNavbar({
|
||||
label: 'po',
|
||||
toggleId: '#po-menu-toggle',
|
||||
});
|
||||
|
||||
{% if order.status == PurchaseOrderStatus.PENDING and order.lines.count > 0 %}
|
||||
$("#place-order").click(function() {
|
||||
|
@ -1,54 +0,0 @@
|
||||
{% extends "order/order_base.html" %}
|
||||
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/po_navbar.html' with tab='notes' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Order Notes" %}
|
||||
{% if roles.purchase_order.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 %}
|
||||
<form method='POST'>
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form }}
|
||||
<hr>
|
||||
<button type="submit" class='btn btn-default'>{% trans "Save" %}</button>
|
||||
</form>
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
{% else %}
|
||||
|
||||
<div class='panel panel-default'>
|
||||
<div class='panel-content'>
|
||||
{{ order.notes | markdownify }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
{% if editing %}
|
||||
{% else %}
|
||||
$("#edit-notes").click(function() {
|
||||
location.href = "{% url 'po-notes' order.id %}?edit=1";
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -3,10 +3,6 @@
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/po_navbar.html' with tab='upload' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Upload File for Purchase Order" %}
|
||||
{{ wizard.form.media }}
|
||||
|
@ -1,83 +0,0 @@
|
||||
{% extends "order/order_base.html" %}
|
||||
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/po_navbar.html' with tab='attachments' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Purchase Order Attachments" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% include "attachment_table.html" with attachments=order.attachments.all %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-po-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
order: {{ order.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-po-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
order: {{ order.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/order/po/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
|
||||
constructForm(`/api/order/po/attachment/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm('{% url "api-po-attachment-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
order: {
|
||||
value: {{ order.pk }},
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
reload: true,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -9,34 +9,34 @@
|
||||
<span class='menu-tab-icon fas fa-expand-arrows-alt'></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item {% if tab == "details" %}active{% endif %}' title='{% trans "Purchase Order Details" %}'>
|
||||
<a href='{% url "po-detail" order.id %}'>
|
||||
<span class='fas fa-info-circle side-icon'></span>
|
||||
{% trans "Details" %}
|
||||
<li class='list-group-item' title='{% trans "Purchase Order Line Items" %}'>
|
||||
<a href='#' id='select-order-items' class='nav-toggle'>
|
||||
<span class='fas fa-list-ol side-icon'></span>
|
||||
{% trans "Order Items" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.change %}
|
||||
<li class='list-group-item {% if tab == "upload" %}active{% endif %}' title='{% trans "Upload File" %}'>
|
||||
<li class='list-group-item' title='{% trans "Upload File" %}'>
|
||||
<a href='{% url "po-upload" order.id %}'>
|
||||
<span class='fas fa-file-upload side-icon'></span>
|
||||
{% trans "Upload File" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class='list-group-item {% if tab == "received" %}active{% endif %}' title='{% trans "Received Stock Items" %}'>
|
||||
<a href='{% url "po-received" order.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Received Stock Items" %}'>
|
||||
<a href='#' id='select-received-items' class='nav-toggle'>
|
||||
<span class='fas fa-sign-in-alt side-icon'></span>
|
||||
{% trans "Received Items" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item {% if tab == "attachments" %}active{% endif %}' title='{% trans "Purchase Order Attachments" %}'>
|
||||
<a href='{% url "po-attachments" order.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Purchase Order Attachments" %}'>
|
||||
<a href='#' id='select-order-attachments' class='nav-toggle'>
|
||||
<span class='fas fa-paperclip side-icon'></span>
|
||||
{% trans "Attachments" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item {% if tab == "notes" %}active{% endif %}' title='{% trans "Notes" %}'>
|
||||
<a href='{% url "po-notes" order.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Notes" %}'>
|
||||
<a href='#' id='select-order-notes' class='nav-toggle'>
|
||||
<span class='fas fa-clipboard side-icon'></span>
|
||||
{% trans "Notes" %}
|
||||
</a>
|
||||
|
@ -1,37 +0,0 @@
|
||||
{% extends "order/order_base.html" %}
|
||||
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/po_navbar.html' with tab='received' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Received Items" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% include "stock_table.html" with read_only=True %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
purchase_order: {{ order.id }},
|
||||
part_detail: true,
|
||||
supplier_part_detail: true,
|
||||
location_detail: true,
|
||||
},
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
filterkey: "postock"
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -4,31 +4,72 @@
|
||||
{% load status_codes %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/po_navbar.html' with tab='details' %}
|
||||
|
||||
{% include 'order/po_navbar.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Purchase Order Items" %}
|
||||
{% endblock %}
|
||||
{% block page_content %}
|
||||
|
||||
|
||||
{% block details %}
|
||||
|
||||
|
||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||
{% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.change %}
|
||||
<button type='button' class='btn btn-primary' id='new-po-line'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Line Item" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-order-items'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Purchase Order Items" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||
{% if order.status == PurchaseOrderStatus.PENDING and roles.purchase_order.change %}
|
||||
<button type='button' class='btn btn-primary' id='new-po-line'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Line Item" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='po-table' data-toolbar='#order-toolbar-buttons'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-received-items'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Received Items" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% include "stock_table.html" with read_only=True %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='po-table' data-toolbar='#order-toolbar-buttons'>
|
||||
</table>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-order-attachments'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Purchase Order Attachments" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% include "attachment_table.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-order-notes'>
|
||||
<div class='panel-heading'>
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<h4>{% trans "Order 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 order.notes %}
|
||||
{{ order.notes | markdownify }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@ -36,6 +77,96 @@
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
enableNavbar({
|
||||
label: 'po',
|
||||
toggleId: '#po-menu-toggle',
|
||||
});
|
||||
|
||||
$('#edit-notes').click(function() {
|
||||
constructForm('{% url "api-po-detail" order.pk %}', {
|
||||
fields: {
|
||||
notes: {
|
||||
multiline: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Edit Notes" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-po-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
order: {{ order.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-po-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
order: {{ order.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/order/po/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
|
||||
constructForm(`/api/order/po/attachment/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm('{% url "api-po-attachment-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
order: {
|
||||
value: {{ order.pk }},
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
reload: true,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
});
|
||||
});
|
||||
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
purchase_order: {{ order.id }},
|
||||
part_detail: true,
|
||||
supplier_part_detail: true,
|
||||
location_detail: true,
|
||||
},
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
filterkey: "postock"
|
||||
});
|
||||
|
||||
{% if order.status == PurchaseOrderStatus.PENDING %}
|
||||
$('#new-po-line').click(function() {
|
||||
|
||||
@ -301,4 +432,9 @@ $("#po-table").inventreeTable({
|
||||
]
|
||||
});
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'purchase-order',
|
||||
default: 'order-items'
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -4,38 +4,158 @@
|
||||
{% load status_codes %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "order/so_navbar.html" with tab='details' %}
|
||||
{% include "order/so_navbar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Sales Order Items" %}
|
||||
{% endblock %}
|
||||
{% block page_content %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
|
||||
{% if roles.sales_order.change %}
|
||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||
<button type='button' class='btn btn-success' id='new-so-line'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Line Item" %}
|
||||
</button>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-order-items'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sales Order Items" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if roles.sales_order.change %}
|
||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||
<button type='button' class='btn btn-success' id='new-so-line'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Line Item" %}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class='table table-striped table-condensed' id='so-lines-table' data-toolbar='#order-toolbar-buttons'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class='table table-striped table-condensed' id='so-lines-table' data-toolbar='#order-toolbar-buttons'>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-order-builds'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Build Orders" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<table class='table table-striped table-condensed' id='builds-table'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</table>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-order-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-order-notes'>
|
||||
<div class='panel-heading'>
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<h4>{% trans "Order 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 order.notes %}
|
||||
{{ order.notes | markdownify }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
function reloadTable() {
|
||||
$("#so-lines-table").bootstrapTable("refresh");
|
||||
}
|
||||
$('#edit-notes').click(function() {
|
||||
constructForm('{% url "api-so-detail" order.pk %}', {
|
||||
fields: {
|
||||
notes: {
|
||||
multiline: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Edit Notes" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-so-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
order: {{ order.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-so-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
order: {{ order.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/order/so/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
constructForm(`/api/order/so/attachment/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm('{% url "api-so-attachment-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
order: {
|
||||
value: {{ order.pk }},
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Add Attachment" %}'
|
||||
});
|
||||
});
|
||||
|
||||
loadBuildTable($("#builds-table"), {
|
||||
url: "{% url 'api-build-list' %}",
|
||||
params: {
|
||||
sales_order: {{ order.id }},
|
||||
},
|
||||
});
|
||||
|
||||
function reloadTable() {
|
||||
$("#so-lines-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
$("#new-so-line").click(function() {
|
||||
|
||||
@ -493,6 +613,11 @@ function setupCallbacks() {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'sales-order',
|
||||
default: 'order-items'
|
||||
});
|
||||
}
|
||||
|
||||
{% endblock %}
|
@ -1,56 +0,0 @@
|
||||
{% extends "order/sales_order_base.html" %}
|
||||
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load markdownify %}
|
||||
{% load status_codes %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/so_navbar.html' with tab='notes' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Sales Order Notes" %}
|
||||
{% if roles.sales_order.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 %}
|
||||
|
||||
<form method='POST'>
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form }}
|
||||
<hr>
|
||||
<button type="submit" class='btn btn-default'>{% trans "Save" %}</button>
|
||||
</form>
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
{% else %}
|
||||
<div class='panel panel-default'>
|
||||
<div class='panel-content'>
|
||||
{{ order.notes | markdownify }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
{% if editing %}
|
||||
{% else %}
|
||||
$("#edit-notes").click(function() {
|
||||
location.href = "{% url 'so-notes' order.id %}?edit=1";
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -1,83 +0,0 @@
|
||||
{% extends "order/sales_order_base.html" %}
|
||||
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/so_navbar.html' with tab='attachments' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Sales Order Attachments" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% include "attachment_table.html" with attachments=order.attachments.all %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-so-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
order: {{ order.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-so-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
order: {{ order.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/order/so/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
constructForm(`/api/order/so/attachment/${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm('{% url "api-so-attachment-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
order: {
|
||||
value: {{ order.pk }},
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Add Attachment" %}'
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,33 +0,0 @@
|
||||
{% extends "order/sales_order_base.html" %}
|
||||
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'order/so_navbar.html' with tab='builds' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Build Orders" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
|
||||
<table class='table table-striped table-condensed' id='builds-table'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
loadBuildTable($("#builds-table"), {
|
||||
url: "{% url 'api-build-list' %}",
|
||||
params: {
|
||||
sales_order: {{ order.id }},
|
||||
},
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -9,29 +9,29 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "details" %}active{% endif %}' title='{% trans "Sales Order Details" %}'>
|
||||
<a href='{% url "so-detail" order.id %}'>
|
||||
<span class='fas fa-info-circle sidebar-icon'></span>
|
||||
{% trans "Details" %}
|
||||
<li class='list-group-item' title='{% trans "Sales Order Line Items" %}'>
|
||||
<a href='#' id='select-order-items' class='nav-toggle'>
|
||||
<span class='fas fa-list-ol sidebar-icon'></span>
|
||||
{% trans "Order Items" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "builds" %}active{% endif %}' title='{% trans "Build Orders" %}'>
|
||||
<a href='{% url "so-builds" order.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Build Orders" %}'>
|
||||
<a href='#' id='select-order-builds' class='nav-toggle'>
|
||||
<span class='fas fa-tools sidebar-icon'></span>
|
||||
{% trans "Build Orders" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "attachments" %}active{% endif %}' title='{% trans "Sales Order Attachments" %}'>
|
||||
<a href='{% url "so-attachments" order.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Sales Order Attachments" %}'>
|
||||
<a href='#' id='select-order-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 "Notes" %}'>
|
||||
<a href='{% url "so-notes" order.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Notes" %}'>
|
||||
<a href='#' id='select-order-notes' class='nav-toggle'>
|
||||
<span class='fas fa-clipboard sidebar-icon'></span>
|
||||
{% trans "Notes" %}
|
||||
</a>
|
||||
|
@ -19,10 +19,6 @@ purchase_order_detail_urls = [
|
||||
url(r'^upload/', views.PurchaseOrderUpload.as_view(), name='po-upload'),
|
||||
url(r'^export/', views.PurchaseOrderExport.as_view(), name='po-export'),
|
||||
|
||||
url(r'^notes/', views.PurchaseOrderNotes.as_view(), name='po-notes'),
|
||||
|
||||
url(r'^received/', views.PurchaseOrderDetail.as_view(template_name='order/po_received_items.html'), name='po-received'),
|
||||
url(r'^attachments/', views.PurchaseOrderDetail.as_view(template_name='order/po_attachments.html'), name='po-attachments'),
|
||||
url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'),
|
||||
]
|
||||
|
||||
@ -42,10 +38,6 @@ sales_order_detail_urls = [
|
||||
url(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'),
|
||||
url(r'^ship/', views.SalesOrderShip.as_view(), name='so-ship'),
|
||||
|
||||
url(r'^builds/', views.SalesOrderDetail.as_view(template_name='order/so_builds.html'), name='so-builds'),
|
||||
url(r'^attachments/', views.SalesOrderDetail.as_view(template_name='order/so_attachments.html'), name='so-attachments'),
|
||||
url(r'^notes/', views.SalesOrderNotes.as_view(), name='so-notes'),
|
||||
|
||||
url(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'),
|
||||
]
|
||||
|
||||
|
@ -13,7 +13,7 @@ from django.core.exceptions import ValidationError
|
||||
from django.urls import reverse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView, UpdateView
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.views.generic.edit import FormMixin
|
||||
from django.forms import HiddenInput, IntegerField
|
||||
|
||||
@ -97,53 +97,6 @@ class SalesOrderDetail(InvenTreeRoleMixin, DetailView):
|
||||
template_name = 'order/sales_order_detail.html'
|
||||
|
||||
|
||||
class PurchaseOrderNotes(InvenTreeRoleMixin, UpdateView):
|
||||
""" View for updating the 'notes' field of a PurchaseOrder """
|
||||
|
||||
context_object_name = 'order'
|
||||
template_name = 'order/order_notes.html'
|
||||
model = PurchaseOrder
|
||||
|
||||
# Override the default permission roles
|
||||
role_required = 'purchase_order.view'
|
||||
|
||||
fields = ['notes']
|
||||
|
||||
def get_success_url(self):
|
||||
|
||||
return reverse('po-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', False))
|
||||
|
||||
return ctx
|
||||
|
||||
|
||||
class SalesOrderNotes(InvenTreeRoleMixin, UpdateView):
|
||||
""" View for editing the 'notes' field of a SalesORder """
|
||||
|
||||
context_object_name = 'order'
|
||||
template_name = 'order/sales_order_notes.html'
|
||||
model = SalesOrder
|
||||
role_required = 'sales_order.view'
|
||||
|
||||
fields = ['notes']
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('so-notes', kwargs={'pk': self.get_object().pk})
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
|
||||
ctx['editing'] = str2bool(self.request.GET.get('edit', False))
|
||||
|
||||
return ctx
|
||||
|
||||
|
||||
class PurchaseOrderCancel(AjaxUpdateView):
|
||||
""" View for cancelling a purchase order """
|
||||
|
||||
|
@ -1104,7 +1104,7 @@ part_api_urls = [
|
||||
url(r'^(?P<pk>\d+)/?', PartThumbsUpdate.as_view(), name='api-part-thumbs-update'),
|
||||
])),
|
||||
|
||||
url(r'^(?P<pk>\d+)/?', PartDetail.as_view(), name='api-part-detail'),
|
||||
url(r'^(?P<pk>\d+)/', PartDetail.as_view(), name='api-part-detail'),
|
||||
|
||||
url(r'^.*$', PartList.as_view(), name='api-part-list'),
|
||||
]
|
||||
|
@ -1,50 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load status_codes %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "part/navbar.html" with tab="allocation" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Build Order Allocations" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<table class='table table-striped table-condensed' id='build-order-table'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block pre_content_panel %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sales Order Allocations" %}</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'>
|
||||
<table class='table table-striped table-condensed' id='sales-order-table'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadSalesOrderAllocationTable("#sales-order-table", {
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
}
|
||||
});
|
||||
|
||||
loadBuildOrderAllocationTable("#build-order-table", {
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
}
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,16 +1,5 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='bom' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Bill of Materials" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% if roles.part.change != True and editing_enabled %}
|
||||
<div class='alert alert-danger alert-block'>
|
||||
@ -32,7 +21,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id='button-toolbar'>
|
||||
<div id='bom-button-toolbar'>
|
||||
<div class="btn-group" role="group" aria-label="...">
|
||||
{% if editing_enabled %}
|
||||
<button class='btn btn-default' type='button' title='{% trans "Remove selected BOM items" %}' id='bom-item-delete'>
|
||||
@ -76,131 +65,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-bom table-condensed' data-toolbar="#button-toolbar" id='bom-table'>
|
||||
<table class='table table-bom table-condensed' data-toolbar="#bom-button-toolbar" id='bom-table'>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
// Load the BOM table data
|
||||
loadBomTable($("#bom-table"), {
|
||||
editable: {{ editing_enabled }},
|
||||
bom_url: "{% url 'api-bom-list' %}",
|
||||
part_url: "{% url 'api-part-list' %}",
|
||||
parent_id: {{ part.id }} ,
|
||||
sub_part_detail: true,
|
||||
});
|
||||
|
||||
linkButtonsToSelection($("#bom-table"),
|
||||
[
|
||||
"#bom-item-delete",
|
||||
]
|
||||
);
|
||||
|
||||
{% if editing_enabled %}
|
||||
$("#editing-finished").click(function() {
|
||||
location.href = "{% url 'part-bom' part.id %}";
|
||||
});
|
||||
|
||||
$('#bom-item-delete').click(function() {
|
||||
|
||||
// Get a list of the selected BOM items
|
||||
var rows = $("#bom-table").bootstrapTable('getSelections');
|
||||
|
||||
// TODO - In the future, display (in the dialog) which items are going to be deleted
|
||||
|
||||
showQuestionDialog(
|
||||
'{% trans "Delete selected BOM items?" %}',
|
||||
'{% trans "All selected BOM items will be deleted" %}',
|
||||
{
|
||||
accept: function() {
|
||||
|
||||
// Keep track of each DELETE request
|
||||
var requests = [];
|
||||
|
||||
rows.forEach(function(row) {
|
||||
requests.push(
|
||||
inventreeDelete(
|
||||
`/api/bom/${row.pk}/`,
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
// Wait for *all* the requests to complete
|
||||
$.when.apply($, requests).then(function() {
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#bom-upload').click(function() {
|
||||
location.href = "{% url 'upload-bom' part.id %}";
|
||||
});
|
||||
|
||||
$('#bom-duplicate').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'duplicate-bom' part.id %}",
|
||||
{
|
||||
success: function() {
|
||||
$('#bom-table').bootstrapTable('refresh');
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$("#bom-item-new").click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'bom-item-create' %}?parent={{ part.id }}",
|
||||
{
|
||||
success: function() {
|
||||
$("#bom-table").bootstrapTable('refresh');
|
||||
},
|
||||
secondary: [
|
||||
{
|
||||
field: 'sub_part',
|
||||
label: '{% trans "New Part" %}',
|
||||
title: '{% trans "Create New Part" %}',
|
||||
url: "{% url 'part-create' %}",
|
||||
},
|
||||
]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% else %}
|
||||
|
||||
$("#validate-bom").click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'bom-validate' part.id %}",
|
||||
{
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$("#edit-bom").click(function () {
|
||||
location.href = "{% url 'part-bom' part.id %}?edit=1";
|
||||
});
|
||||
|
||||
$("#download-bom").click(function () {
|
||||
launchModalForm("{% url 'bom-export' part.id %}",
|
||||
{
|
||||
success: function(response) {
|
||||
location.href = response.url;
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% endif %}
|
||||
|
||||
$("#print-bom-report").click(function() {
|
||||
printBomReports([{{ part.pk }}]);
|
||||
});
|
||||
|
||||
{% endblock %}
|
||||
{% endif %}
|
@ -3,15 +3,13 @@
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "part/navbar.html" with tab='bom' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Upload BOM File" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% block page_content %}
|
||||
|
||||
<h4>{% trans "Upload Bill of Materials" %}</h4>
|
||||
|
||||
{% block form_alert %}
|
||||
<div class='alert alert-info alert-block'>
|
||||
|
@ -1,48 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='build' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Builds" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right';>
|
||||
{% if part.active %}
|
||||
{% if roles.build.add %}
|
||||
<button class="btn btn-success" id='start-build'><span class='fas fa-tools'></span> {% trans "Start New Build" %}</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div class='filter-list' id='filter-list-build'>
|
||||
<!-- Empty div for filters -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='build-table'>
|
||||
</table>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
$("#start-build").click(function() {
|
||||
newBuildOrder({
|
||||
part: {{ part.pk }},
|
||||
});
|
||||
});
|
||||
|
||||
loadBuildTable($("#build-table"), {
|
||||
url: "{% url 'api-build-list' %}",
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
}
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -3,7 +3,7 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/category_navbar.html' with tab='parts' %}
|
||||
{% include 'part/category_navbar.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
@ -115,63 +115,81 @@
|
||||
|
||||
</div>
|
||||
|
||||
{% block category_content %}
|
||||
{% block page_content %}
|
||||
|
||||
<div id='button-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-default' id='part-export' title='{% trans "Export Part Data" %}'>
|
||||
<span class='fas fa-file-download'></span> {% trans "Export" %}
|
||||
</button>
|
||||
{% if roles.part.add %}
|
||||
<button class='btn btn-success' id='part-create' title='{% trans "Create new part" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Part" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-parts'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Parts" %}</h4>
|
||||
</div>
|
||||
<div id='part-button-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button id='part-options' class='btn btn-primary dropdown-toggle' type='button' data-toggle="dropdown">{% trans "Options" %}<span class='caret'></span></button>
|
||||
<ul class='dropdown-menu'>
|
||||
{% if roles.part.change %}
|
||||
<li><a href='#' id='multi-part-category' title='{% trans "Set category" %}'>{% trans "Set Category" %}</a></li>
|
||||
{% endif %}
|
||||
<li><a href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li>
|
||||
<li><a href='#' id='multi-part-export' title='{% trans "Export" %}'>{% trans "Export Data" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Buttons to toggle between grid and table view -->
|
||||
<button id='view-list' class='btn btn-default' type='button' title='{% trans "View list display" %}'>
|
||||
<span class='fas fa-th-list'></span>
|
||||
</button>
|
||||
<button id='view-grid' class='btn btn-default' type='button' title='{% trans "View grid display" %}'>
|
||||
<span class='fas fa-th'></span>
|
||||
</button>
|
||||
<div class='filter-list' id='filter-list-parts'>
|
||||
<!-- Empty div -->
|
||||
<button class='btn btn-default' id='part-export' title='{% trans "Export Part Data" %}'>
|
||||
<span class='fas fa-file-download'></span> {% trans "Export" %}
|
||||
</button>
|
||||
{% if roles.part.add %}
|
||||
<button class='btn btn-success' id='part-create' title='{% trans "Create new part" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Part" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<div class='btn-group'>
|
||||
<button id='part-options' class='btn btn-primary dropdown-toggle' type='button' data-toggle="dropdown">{% trans "Options" %}<span class='caret'></span></button>
|
||||
<ul class='dropdown-menu'>
|
||||
{% if roles.part.change %}
|
||||
<li><a href='#' id='multi-part-category' title='{% trans "Set category" %}'>{% trans "Set Category" %}</a></li>
|
||||
{% endif %}
|
||||
<li><a href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li>
|
||||
<li><a href='#' id='multi-part-export' title='{% trans "Export" %}'>{% trans "Export Data" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Buttons to toggle between grid and table view -->
|
||||
<button id='view-list' class='btn btn-default' type='button' title='{% trans "View list display" %}'>
|
||||
<span class='fas fa-th-list'></span>
|
||||
</button>
|
||||
<button id='view-grid' class='btn btn-default' type='button' title='{% trans "View grid display" %}'>
|
||||
<span class='fas fa-th'></span>
|
||||
</button>
|
||||
<div class='filter-list' id='filter-list-parts'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<table class='table table-striped table-condensed' data-toolbar='#part-button-toolbar' id='part-table'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-parameters'>
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
{% block heading %}
|
||||
{% trans "Parts" %}
|
||||
{% endblock %}
|
||||
</h4>
|
||||
<h4>{% trans "Part Parameters" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% block details %}
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='part-table'>
|
||||
</table>
|
||||
{% endblock %}
|
||||
<div class='panel-content'>
|
||||
<table class='table table-striped table-condensed' data-toolbar='#param-button-toolbar' id='parametric-part-table'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-subcategories'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Subcategories" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='subcategory-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
|
||||
<div class='filter-list' id='filter-list-category'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='subcategory-table' data-toolbar='#subcategory-button-toolbar'></table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block category_tables %}
|
||||
{% endblock category_tables %}
|
||||
|
||||
{% endblock %}
|
||||
{% block js_load %}
|
||||
{{ block.super }}
|
||||
@ -180,6 +198,26 @@
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadPartCategoryTable($('#subcategory-table'), {
|
||||
params: {
|
||||
{% if category %}
|
||||
parent: {{ category.pk }}
|
||||
{% else %}
|
||||
parent: 'null'
|
||||
{% endif %}
|
||||
}
|
||||
});
|
||||
|
||||
{% if category %}
|
||||
loadParametricPartTable(
|
||||
"#parametric-part-table",
|
||||
{
|
||||
headers: {{ headers|safe }},
|
||||
data: {{ parameters|safe }},
|
||||
}
|
||||
);
|
||||
{% endif %}
|
||||
|
||||
enableNavbar({
|
||||
label: 'category',
|
||||
toggleId: '#category-menu-toggle',
|
||||
@ -206,11 +244,11 @@
|
||||
"{% url 'category-create' %}",
|
||||
{
|
||||
follow: true,
|
||||
{% if category %}
|
||||
data: {
|
||||
{% if category %}
|
||||
category: {{ category.id }}
|
||||
{% endif %}
|
||||
},
|
||||
{% endif %}
|
||||
secondary: [
|
||||
{
|
||||
field: 'default_location',
|
||||
@ -328,4 +366,9 @@
|
||||
$('#view-list').hide();
|
||||
}
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'partcategory',
|
||||
default: 'part-stock'
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -11,30 +11,22 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "subcategories" %}active{% endif %}' title='{% trans "Subcategories" %}'>
|
||||
{% if category %}
|
||||
<a href='{% url "category-subcategory" category.id %}'>
|
||||
{% else %}
|
||||
<a href='{% url "category-index-subcategory" %}'>
|
||||
{% endif %}
|
||||
<li class='list-group-item' title='{% trans "Subcategories" %}'>
|
||||
<a href='#' id='select-subcategories' class='nav-toggle'>
|
||||
<span class='fas fa-sitemap sidebar-icon'></span>
|
||||
{% trans "Subcategories" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "parts" %}active{% endif %}' title='{% trans "Parts" %}'>
|
||||
{% if category %}
|
||||
<a href='{% url "category-detail" category.id %}'>
|
||||
{% else %}
|
||||
<a href='{% url "part-index" %}'>
|
||||
{% endif %}
|
||||
<li class='list-group-item' title='{% trans "Parts" %}'>
|
||||
<a href='#' id='select-parts' class='nav-toggle'>
|
||||
<span class='fas fa-shapes sidebar-icon'></span>
|
||||
{% trans "Parts" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if show_import and user.is_staff and roles.part.add %}
|
||||
<li class='list-group-item {% if tab == "import" %}active{% endif %}' title='{% trans "Import Parts" %}'>
|
||||
<li class='list-group-item' title='{% trans "Import Parts" %}'>
|
||||
<a href='{% url "part-import" %}'>
|
||||
<span class='fas fa-file-upload sidebar-icon'></span>
|
||||
{% trans "Import Parts" %}
|
||||
@ -43,8 +35,8 @@
|
||||
{% endif %}
|
||||
|
||||
{% if category %}
|
||||
<li class='list-group-item {% if tab == "parameters" %}active{% endif %}' title='{% trans "Parameters" %}'>
|
||||
<a href='{% url "category-parametric" category.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Parameters" %}'>
|
||||
<a href='#' id='select-parameters' class='nav-toggle'>
|
||||
<span class='fas fa-tasks sidebar-icon'></span>
|
||||
{% trans "Parameters" %}
|
||||
</a>
|
||||
|
@ -1,37 +0,0 @@
|
||||
{% extends "part/category.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/category_navbar.html' with tab='parameters' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Parameters" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='parametric-part-table'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
/* Hide Button Toolbar */
|
||||
window.onload = function hideButtonToolbar() {
|
||||
var toolbar = document.getElementById("button-toolbar");
|
||||
toolbar.style.display = "none";
|
||||
};
|
||||
|
||||
loadParametricPartTable(
|
||||
"#parametric-part-table",
|
||||
{
|
||||
headers: {{ headers|safe }},
|
||||
data: {{ parameters|safe }},
|
||||
}
|
||||
);
|
||||
|
||||
{% endblock %}
|
@ -1,16 +0,0 @@
|
||||
{% extends "part/category.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/category_navbar.html' with tab='parts' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Parts" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='part-table'>
|
||||
</table>
|
||||
{% endblock %}
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,9 @@
|
||||
{% extends "part/category.html" %}
|
||||
{% extends "base.html" %}
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/category_navbar.html' with tab='import' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block category_content %}
|
||||
{% block content %}
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
|
@ -11,46 +11,36 @@
|
||||
<span class='menu-tab-icon fas fa-expand-arrows-alt'></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item {% if tab == "details" %}active{% endif %}' title='{% trans "Part Details" %}'>
|
||||
<a href='{% url "part-detail" part.id %}'>
|
||||
<span class='menu-tab-icon fas fa-info-circle sidebar-icon'></span>
|
||||
<span class='tab-text'>
|
||||
{% trans "Details" %}
|
||||
</span>
|
||||
<li class='list-group-item' title='{% trans "Parameters" %}'>
|
||||
<a href='#' id='select-part-parameters' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-th-list sidebar-icon'></span>
|
||||
{% trans "Parameters" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if part.is_template %}
|
||||
<li class='list-group-item {% if tab == "variants" %}active{% endif %}' title='{% trans "Part Variants" %}'>
|
||||
<a href='{% url "part-variants" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Part Variants" %}'>
|
||||
<a href='#' id='select-variants' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-shapes sidebar-icon'></span>
|
||||
{% trans "Variants" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class='list-group-item {% if tab == "stock" %}active{% endif %}' title='{% trans "Stock Items" %}'>
|
||||
<a href='{% url "part-stock" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Stock Items" %}'>
|
||||
<a href='#' id='select-part-stock' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-boxes sidebar-icon'></span>
|
||||
{% trans "Stock" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if part.component or part.salable %}
|
||||
<li class='list-group-item {% if tab == "allocation" %}active{% endif %}' title='{% trans "Allocated Stock" %}'>
|
||||
<a href='{% url "part-allocation" part.id %}'>
|
||||
<span class='menu-tab-icon fas fa-sign-out-alt sidebar-icon'></span>
|
||||
{% trans "Allocations" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if part.assembly %}
|
||||
<li class='list-group-item {% if tab == "bom" %}active{% endif %}' title='{% trans "Bill of Materials" %}'>
|
||||
<a href='{% url "part-bom" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Bill of Materials" %}'>
|
||||
<a href='#' id='select-bom' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-list sidebar-icon'></span>
|
||||
{% trans "Bill of Materials" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if roles.build.view %}
|
||||
<li class='list-group-item {% if tab == "build" %}active{% endif %}' title='{% trans "Build Orders" %}'>
|
||||
<a href='{% url "part-build" part.id %}'>
|
||||
<li class='list-group-item ' title='{% trans "Build Orders" %}'>
|
||||
<a href='#' id='select-build-orders' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-tools sidebar-icon'></span>
|
||||
{% trans "Build Orders" %}
|
||||
</a>
|
||||
@ -58,55 +48,73 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if part.component %}
|
||||
<li class='list-group-item {% if tab == "used" %}active{% endif %}' title='{% trans "Used In" %}'>
|
||||
<a href='{% url "part-used-in" part.id %}'>
|
||||
<li class='list-group-item ' title='{% trans "Used In" %}'>
|
||||
<a href='#' id='select-used-in' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-layer-group sidebar-icon'></span>
|
||||
{% trans "Used In" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class='list-group-item {% if tab == "prices" %}active{% endif %}' title='{% trans "Pricing Information" %}'>
|
||||
<a href='{% url "part-prices" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Pricing Information" %}'>
|
||||
<a href='#' id='select-pricing' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-dollar-sign sidebar-icon'></span>
|
||||
{% trans "Prices" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if part.purchaseable and roles.purchase_order.view %}
|
||||
<li class='list-group-item {% if tab == "suppliers" %}active{% endif %}' title='{% trans "Suppliers" %}'>
|
||||
<a href='{% url "part-suppliers" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Suppliers" %}'>
|
||||
<a href='#' id='select-part-suppliers' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-building sidebar-icon'></span>
|
||||
{% trans "Suppliers" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item {% if tab == "orders" %}active{% endif %}' title='{% trans "Purchase Orders" %}'>
|
||||
<a href='{% url "part-orders" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Manufacturers" %}'>
|
||||
<a href='#' id='select-part-manufacturers' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-tools sidebar-icon'></span>
|
||||
{% trans "Manufacturers" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item' title='{% trans "Purchase Orders" %}'>
|
||||
<a href='#' id='select-purchase-orders' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-shopping-cart sidebar-icon'></span>
|
||||
{% trans "Purchase Orders" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if roles.sales_order.view %}
|
||||
<li class='list-group-item {% if tab == "sales-orders" %}active{% endif %}' title='{% trans "Sales Orders" %}'>
|
||||
<a href='{% url "part-sales-orders" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Sales Orders" %}'>
|
||||
<a href='#' id='select-sales-orders' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-truck sidebar-icon'></span>
|
||||
{% trans "Sales Orders" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if part.trackable %}
|
||||
<li class='list-group-item {% if tab == "tests" %}active{% endif %}' title='{% trans "Part Test Templates" %}'>
|
||||
<a href='{% url "part-test-templates" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Part Test Templates" %}'>
|
||||
<a href='#' id='select-test-templates' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-vial sidebar-icon'></span>
|
||||
{% trans "Test Templates" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if show_related %}
|
||||
<li class='list-group-item {% if tab == "related" %}active{% endif %}' title='{% trans "Related Parts" %}'>
|
||||
<a href='{% url "part-related" part.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Related Parts" %}'>
|
||||
<a href='#' id='select-related-parts' class='nav-toggle'>
|
||||
<span class='menu-tab-icon fas fa-random sidebar-icon'></span>
|
||||
{% trans "Related Parts" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class='list-group-item' title='{% trans "Attachments" %}'>
|
||||
<a href='#' id='select-part-attachments' class='nav-toggle'>
|
||||
<span class='fas fa-paperclip side-icon'></span>
|
||||
{% trans "Attachments" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item' title='{% trans "Notes" %}'>
|
||||
<a href='#' id='select-part-notes' class='nav-toggle'>
|
||||
<span class='fas fa-clipboard side-icon'></span>
|
||||
{% trans "Notes" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -1,51 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='orders' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Purchase Orders" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<div id='button-bar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
<button class='btn btn-primary' type='button' id='part-order2' title='{% trans "Order part" %}'>
|
||||
<span class='fas fa-shopping-cart'></span> {% trans "Order Part" %}
|
||||
</button>
|
||||
<div class='filter-list' id='filter-list-purchaseorder'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed po-table' id='purchase-order-table' data-toolbar='#button-bar'>
|
||||
</table>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadPurchaseOrderTable($("#purchase-order-table"), {
|
||||
url: "{% url 'api-po-list' %}",
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
});
|
||||
|
||||
$("#part-order2").click(function() {
|
||||
launchModalForm("{% url 'order-parts' %}", {
|
||||
data: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -27,7 +27,34 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% if part.description %}
|
||||
<p><em>{{ part.description }}</em></p>
|
||||
{% endif %}
|
||||
<p>
|
||||
<div id='part-properties' class='btn-group' role='group'>
|
||||
{% if part.virtual %}
|
||||
<span class='fas fa-ghost' title='{% trans "Part is virtual (not a physical part)" %}'></span>
|
||||
{% endif %}
|
||||
{% if part.is_template %}
|
||||
<span class='fas fa-clone' title='{% trans "Part is a template part (variants can be made from this part)" %}'></span>
|
||||
{% endif %}
|
||||
{% if part.assembly %}
|
||||
<span class='fas fa-tools' title='{% trans "Part can be assembled from other parts" %}'></span>
|
||||
{% endif %}
|
||||
{% if part.component %}
|
||||
<span class='fas fa-th' title='{% trans "Part can be used in assemblies" %}'></span>
|
||||
{% endif %}
|
||||
{% if part.trackable %}
|
||||
<span class='fas fa-directions' title='{% trans "Part stock is tracked by serial number" %}'></span>
|
||||
{% endif %}
|
||||
{% if part.purchaseable %}
|
||||
<span class='fas fa-shopping-cart' title='{% trans "Part can be purchased from external suppliers" %}'></span>
|
||||
{% endif %}
|
||||
{% if part.salable %}
|
||||
<span class='fas fa-dollar-sign' title='{% trans "Part can be sold to customers" %}'></span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<div class='btn-group action-buttons' role='group'>
|
||||
<button type='button' class='btn btn-default' id='toggle-starred' title='{% trans "Star this part" %}'>
|
||||
@ -97,11 +124,11 @@
|
||||
</div>
|
||||
<table class='table table-condensed'>
|
||||
<col width='25'>
|
||||
{% if part.IPN %}
|
||||
{% if part.keywords %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans "IPN" %}</td>
|
||||
<td>{{ part.IPN }}</td>
|
||||
<td><span class='fas fa-key'></span></td>
|
||||
<td>{% trans "Keywords" %}</td>
|
||||
<td>{{ part.keywords }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.link %}
|
||||
@ -112,7 +139,22 @@
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-calendar-alt'></span></td>
|
||||
<td>{% trans "Creation Date" %}</td>
|
||||
<td>
|
||||
{{ part.creation_date }}
|
||||
{% if part.creation_user %}
|
||||
<span class='badge'>{{ part.creation_user }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if part.trackable and part.getLatestSerialNumber %}
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "Latest Serial Number" %}</td>
|
||||
<td>{{ part.getLatestSerialNumber }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -125,7 +167,7 @@
|
||||
{% endif %}
|
||||
{% if part.variant_of %}
|
||||
<div class='alert alert-info alert-block'>
|
||||
{% object_link 'part-variants' part.variant_of.id part.variant_of.full_name as link %}
|
||||
{% object_link 'part-detail' part.variant_of.id part.variant_of.full_name as link %}
|
||||
{% blocktrans %}This part is a variant of {{link}}{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@ -197,44 +239,13 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if part.trackable and part.getLatestSerialNumber %}
|
||||
<tr><td colspan="3"></td></tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-hashtag'></span></td>
|
||||
<td>{% trans "Latest Serial Number" %}</td>
|
||||
<td>{{ part.getLatestSerialNumber }}{% include "clip.html"%}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% block pre_content_panel %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
|
||||
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
{% block heading %}
|
||||
<!-- Heading goes here -->
|
||||
{% endblock %}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'>
|
||||
{% block details %}
|
||||
<!-- Specific part details go here... -->
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% block post_content_panel %}
|
||||
|
||||
{% block page_content %}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
@ -242,11 +253,6 @@
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableNavbar({
|
||||
label: 'part',
|
||||
toggleId: '#part-menu-toggle',
|
||||
});
|
||||
|
||||
{% if part.image %}
|
||||
$('#part-thumb').click(function() {
|
||||
showModalImage('{{ part.image.url }}');
|
||||
@ -410,80 +416,7 @@
|
||||
|
||||
$("#part-edit").click(function() {
|
||||
|
||||
constructForm('{% url "api-part-detail" part.id %}', {
|
||||
focus: 'name',
|
||||
fields: {
|
||||
category: {
|
||||
secondary: {
|
||||
label: '{% trans "New Category" %}',
|
||||
title: '{% trans "Create New Part Category" %}',
|
||||
api_url: '{% url "api-part-category-list" %}',
|
||||
method: 'POST',
|
||||
fields: {
|
||||
name: {},
|
||||
description: {},
|
||||
parent: {
|
||||
secondary: {
|
||||
title: '{% trans "New Parent" %}',
|
||||
api_url: '{% url "api-part-category-list" %}',
|
||||
method: 'POST',
|
||||
fields: {
|
||||
name: {},
|
||||
description: {},
|
||||
parent: {},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
name: {
|
||||
placeholder: 'part name',
|
||||
},
|
||||
IPN: {},
|
||||
description: {},
|
||||
revision: {},
|
||||
keywords: {
|
||||
icon: 'fa-key',
|
||||
},
|
||||
variant_of: {},
|
||||
link: {
|
||||
icon: 'fa-link',
|
||||
},
|
||||
default_location: {
|
||||
secondary: {
|
||||
label: '{% trans "New Location" %}',
|
||||
title: '{% trans "Create new stock location" %}',
|
||||
|
||||
},
|
||||
},
|
||||
default_supplier: {
|
||||
filters: {
|
||||
part: {{ part.pk }},
|
||||
part_detail: true,
|
||||
manufacturer_detail: true,
|
||||
supplier_detail: true,
|
||||
},
|
||||
secondary: {
|
||||
label: '{% trans "New Supplier Part" %}',
|
||||
title: '{% trans "Create new supplier part" %}',
|
||||
}
|
||||
},
|
||||
units: {},
|
||||
minimum_stock: {},
|
||||
},
|
||||
title: '{% trans "Edit Part" %}',
|
||||
reload: true,
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
launchModalForm(
|
||||
"{% url 'part-edit' part.id %}",
|
||||
{
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
editPart({{ part.pk }});
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
|
@ -1,96 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='tests' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Test Templates" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style="float: right;">
|
||||
<div class='btn-group' role='group'>
|
||||
<button type='button' class='btn btn-success' id='add-test-template'>{% trans "Add Test Template" %}</button>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-parttests'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='test-template-table'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadPartTestTemplateTable(
|
||||
$("#test-template-table"),
|
||||
{
|
||||
part: {{ part.pk }},
|
||||
params: {
|
||||
part: {{ part.pk }},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function reloadTable() {
|
||||
$("#test-template-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
$("#add-test-template").click(function() {
|
||||
|
||||
constructForm('{% url "api-part-test-template-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
test_name: {},
|
||||
description: {},
|
||||
required: {},
|
||||
requires_value: {},
|
||||
requires_attachment: {},
|
||||
part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Add Test Result Template" %}',
|
||||
onSuccess: reloadTable
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-template-table").on('click', '.button-test-edit', function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
var url = `/api/part/test-template/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
test_name: {},
|
||||
description: {},
|
||||
required: {},
|
||||
requires_value: {},
|
||||
requires_attachment: {},
|
||||
},
|
||||
title: '{% trans "Edit Test Result Template" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-template-table").on('click', '.button-test-delete', function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
var url = `/api/part/test-template/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Test Result Template" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,176 +1,168 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='prices' %}
|
||||
{% endblock %}
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Pricing Information" %}</h4>
|
||||
</div>
|
||||
|
||||
{% block heading %}
|
||||
{% trans "General Price Information" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block details %}
|
||||
{% default_currency as currency %}
|
||||
<div class='panel-content'>
|
||||
|
||||
<div class="row">
|
||||
<a class="anchor" id="overview"></a>
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Pricing ranges" %}</h4>
|
||||
<table class='table table-striped table-condensed'>
|
||||
{% if part.supplier_count > 0 %}
|
||||
{% if min_total_buy_price %}
|
||||
<tr>
|
||||
<td><b>{% trans 'Supplier Pricing' %}</b>
|
||||
<a href="#supplier-cost" title='{% trans "Show supplier cost" %}'><span class="fas fa-search-dollar"></span></a>
|
||||
<a href="#purchase-price" title='{% trans "Show purchase price" %}'><span class="fas fa-chart-bar"></span></a>
|
||||
</td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_unit_buy_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_unit_buy_price %}</td>
|
||||
</tr>
|
||||
{% if quantity > 1 %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans 'Total Cost' %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_total_buy_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_total_buy_price %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan='4'>
|
||||
<span class='warning-msg'><i>{% trans 'No supplier pricing available' %}</i></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if part.bom_count > 0 %}
|
||||
{% if min_total_bom_price %}
|
||||
<tr>
|
||||
<td><b>{% trans 'BOM Pricing' %}</b>
|
||||
<a href="#bom-cost" title='{% trans "Show BOM cost" %}'><span class="fas fa-search-dollar"></span></a>
|
||||
</td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_unit_bom_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_unit_bom_price %}</td>
|
||||
</tr>
|
||||
{% if quantity > 1 %}
|
||||
<div class="row">
|
||||
<a class="anchor" id="overview"></a>
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Pricing ranges" %}</h4>
|
||||
<table class='table table-striped table-condensed'>
|
||||
{% if part.supplier_count > 0 %}
|
||||
{% if min_total_buy_price %}
|
||||
<tr>
|
||||
<td><b>{% trans 'Supplier Pricing' %}</b>
|
||||
<a href="#supplier-cost" title='{% trans "Show supplier cost" %}'><span class="fas fa-search-dollar"></span></a>
|
||||
<a href="#purchase-price" title='{% trans "Show purchase price" %}'><span class="fas fa-chart-bar"></span></a>
|
||||
</td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_unit_buy_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_unit_buy_price %}</td>
|
||||
</tr>
|
||||
{% if quantity > 1 %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans 'Total Cost' %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_total_bom_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_total_bom_price %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_total_buy_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_total_buy_price %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.has_complete_bom_pricing == False %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan='4'>
|
||||
<span class='warning-msg'><i>{% trans 'Note: BOM pricing is incomplete for this part' %}</i></span>
|
||||
<span class='warning-msg'><i>{% trans 'No supplier pricing available' %}</i></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% endif %}
|
||||
|
||||
{% if part.bom_count > 0 %}
|
||||
{% if min_total_bom_price %}
|
||||
<tr>
|
||||
<td><b>{% trans 'BOM Pricing' %}</b>
|
||||
<a href="#bom-cost" title='{% trans "Show BOM cost" %}'><span class="fas fa-search-dollar"></span></a>
|
||||
</td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_unit_bom_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_unit_bom_price %}</td>
|
||||
</tr>
|
||||
{% if quantity > 1 %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans 'Total Cost' %}</td>
|
||||
<td>Min: {% include "price.html" with price=min_total_bom_price %}</td>
|
||||
<td>Max: {% include "price.html" with price=max_total_bom_price %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if part.has_complete_bom_pricing == False %}
|
||||
<tr>
|
||||
<td colspan='4'>
|
||||
<span class='warning-msg'><i>{% trans 'Note: BOM pricing is incomplete for this part' %}</i></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan='4'>
|
||||
<span class='warning-msg'><i>{% trans 'No BOM pricing available' %}</i></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if show_internal_price and roles.sales_order.view %}
|
||||
{% if total_internal_part_price %}
|
||||
<tr>
|
||||
<td colspan='4'>
|
||||
<span class='warning-msg'><i>{% trans 'No BOM pricing available' %}</i></span>
|
||||
</td>
|
||||
<td><b>{% trans 'Internal Price' %}</b></td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=unit_internal_part_price %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans 'Total Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=total_internal_part_price %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if show_internal_price and roles.sales_order.view %}
|
||||
{% if total_internal_part_price %}
|
||||
<tr>
|
||||
<td><b>{% trans 'Internal Price' %}</b></td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=unit_internal_part_price %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans 'Total Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=total_internal_part_price %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if total_part_price %}
|
||||
<tr>
|
||||
<td><b>{% trans 'Sale Price' %}</b>
|
||||
<a href="#sale-cost" title='{% trans "Show sale cost" %}'><span class="fas fa-search-dollar"></span></a>
|
||||
<a href="#sale-price" title='{% trans "Show sale price" %}'><span class="fas fa-chart-bar"></span></a>
|
||||
</td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=unit_part_price %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans 'Total Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=total_part_price %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if total_part_price %}
|
||||
<tr>
|
||||
<td><b>{% trans 'Sale Price' %}</b>
|
||||
<a href="#sale-cost" title='{% trans "Show sale cost" %}'><span class="fas fa-search-dollar"></span></a>
|
||||
<a href="#sale-price" title='{% trans "Show sale price" %}'><span class="fas fa-chart-bar"></span></a>
|
||||
</td>
|
||||
<td>{% trans 'Unit Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=unit_part_price %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{% trans 'Total Cost' %}</td>
|
||||
<td colspan='2'>{% include "price.html" with price=total_part_price %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
{% if min_unit_buy_price or min_unit_bom_price %}
|
||||
{% else %}
|
||||
<div class='alert alert-danger alert-block'>
|
||||
{% trans 'No pricing information is available for this part.' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if min_unit_buy_price or min_unit_bom_price %}
|
||||
{% else %}
|
||||
<div class='alert alert-danger alert-block'>
|
||||
{% trans 'No pricing information is available for this part.' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Calculation parameters" %}</h4>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<input type="submit" value="{% trans 'Calculate' %}" class="btn btn-primary btn-block">
|
||||
</form>
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Calculation parameters" %}</h4>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<input type="submit" value="{% trans 'Calculate' %}" class="btn btn-primary btn-block">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block post_content_panel %}
|
||||
{% default_currency as currency %}
|
||||
{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %}
|
||||
|
||||
|
||||
{% if part.purchaseable and roles.purchase_order.view %}
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<a class="anchor" id="supplier-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Supplier Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<a class="anchor" id="supplier-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Supplier Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'><div class="row">
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Suppliers" %}</h4>
|
||||
<table class="table table-striped table-condensed" id='supplier-table' data-toolbar='#button-toolbar'></table>
|
||||
</div>
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Manufacturers" %}</h4>
|
||||
<table class="table table-striped table-condensed" id='manufacturer-table' data-toolbar='#button-toolbar'></table>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class='panel-content'>
|
||||
<div class="row">
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Suppliers" %}</h4>
|
||||
<table class="table table-striped table-condensed" id='supplier-table' data-toolbar='#button-toolbar'></table>
|
||||
</div>
|
||||
<div class="col col-md-6">
|
||||
<h4>{% trans "Manufacturers" %}</h4>
|
||||
<table class="table table-striped table-condensed" id='manufacturer-table' data-toolbar='#button-toolbar'></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<a class="anchor" id="purchase-price"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Purchase Price" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
{% if price_history %}
|
||||
<h4>{% trans 'Stock Pricing' %}<i class="fas fa-info-circle" title="Shows the purchase prices of stock for this part.
|
||||
The part single price is the current purchase price for that supplier part."></i></h4>
|
||||
{% if price_history %}
|
||||
<a class="anchor" id="purchase-price"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Purchase Price" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<h4>{% trans 'Stock Pricing' %}
|
||||
<i class="fas fa-info-circle" title="Shows the purchase prices of stock for this part.
|
||||
The part single price is the current purchase price for that supplier part."></i>
|
||||
</h4>
|
||||
{% if price_history|length > 0 %}
|
||||
<div style="max-width: 99%; min-height: 300px">
|
||||
<canvas id="StockPriceChart"></canvas>
|
||||
@ -180,52 +172,50 @@
|
||||
{% trans 'No stock pricing history is available for this part.' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_internal_price and roles.sales_order.view %}
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<a class="anchor" id="internal-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Internal Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<a class="anchor" id="internal-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Internal Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'><div class="row full-height">
|
||||
<div class="col col-md-8">
|
||||
<div style="max-width: 99%; height: 100%;">
|
||||
<canvas id="InternalPriceBreakChart"></canvas>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div class="row full-height">
|
||||
<div class="col col-md-8">
|
||||
<div style="max-width: 99%; height: 100%;">
|
||||
<canvas id="InternalPriceBreakChart"></canvas>
|
||||
</div>
|
||||
<div class="col col-md-4">
|
||||
<div id='internal-price-break-toolbar' class='btn-group'>
|
||||
<button class='btn btn-primary' id='new-internal-price-break' type='button'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Internal Price Break" %}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='internal-price-break-table' data-toolbar='#internal-price-break-toolbar'
|
||||
data-sort-name="quantity" data-sort-order="asc">
|
||||
</table>
|
||||
</div>
|
||||
<div class="col col-md-4">
|
||||
<div id='internal-price-break-toolbar' class='btn-group'>
|
||||
<button class='btn btn-primary' id='new-internal-price-break' type='button'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Internal Price Break" %}
|
||||
</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='internal-price-break-table' data-toolbar='#internal-price-break-toolbar'
|
||||
data-sort-name="quantity" data-sort-order="asc">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if part.has_bom and roles.sales_order.view %}
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<a class="anchor" id="bom-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "BOM Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<a class="anchor" id="bom-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "BOM Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'><div class="row">
|
||||
<div class='panel-content'>
|
||||
<div class="row">
|
||||
<div class="col col-md-6">
|
||||
<table class='table table-bom table-condensed' data-toolbar="#button-toolbar" id='bom-table'></table>
|
||||
</div>
|
||||
@ -238,251 +228,55 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if part.salable and roles.sales_order.view %}
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<a class="anchor" id="sale-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sale Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<a class="anchor" id="sale-cost"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sale Cost" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'><div class="row full-height">
|
||||
<div class="col col-md-8">
|
||||
<div style="max-width: 99%; height: 100%;">
|
||||
<canvas id="SalePriceBreakChart"></canvas>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div class="row full-height">
|
||||
<div class="col col-md-8">
|
||||
<div style="max-width: 99%; height: 100%;">
|
||||
<canvas id="SalePriceBreakChart"></canvas>
|
||||
</div>
|
||||
<div class="col col-md-4">
|
||||
<div id='price-break-toolbar' class='btn-group'>
|
||||
<button class='btn btn-primary' id='new-price-break' type='button'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Price Break" %}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='price-break-table' data-toolbar='#price-break-toolbar'
|
||||
data-sort-name="quantity" data-sort-order="asc">
|
||||
</table>
|
||||
</div>
|
||||
<div class="col col-md-4">
|
||||
<div id='price-break-toolbar' class='btn-group'>
|
||||
<button class='btn btn-primary' id='new-price-break' type='button'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Price Break" %}
|
||||
</button>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='price-break-table' data-toolbar='#price-break-toolbar'
|
||||
data-sort-name="quantity" data-sort-order="asc">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<a class="anchor" id="sale-price"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sale Price" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<a class="anchor" id="sale-price"></a>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sale Price" %}
|
||||
<a href="#overview" title='{% trans "Jump to overview" %}'><span class="fas fa-level-up-alt"></span></a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'>
|
||||
{% if sale_history|length > 0 %}
|
||||
<div style="max-width: 99%; min-height: 300px">
|
||||
<canvas id="SalePriceChart"></canvas>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='alert alert-danger alert-block'>
|
||||
{% trans 'No sale pice history available for this part.' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class='panel-content'>
|
||||
{% if sale_history|length > 0 %}
|
||||
<div style="max-width: 99%; min-height: 300px">
|
||||
<canvas id="SalePriceChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class='alert alert-danger alert-block'>
|
||||
{% trans 'No sale pice history available for this part.' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
{% default_currency as currency %}
|
||||
|
||||
|
||||
loadSupplierPartTable(
|
||||
"#supplier-table",
|
||||
"{% url 'api-supplier-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
part_detail: false,
|
||||
supplier_detail: true,
|
||||
manufacturer_detail: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
loadManufacturerPartTable(
|
||||
"#manufacturer-table",
|
||||
"{% url 'api-manufacturer-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
part_detail: false,
|
||||
manufacturer_detail: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// history graphs
|
||||
{% if price_history %}
|
||||
var purchasepricedata = {
|
||||
labels: [
|
||||
{% for line in price_history %}'{{ line.date }}',{% endfor %}
|
||||
],
|
||||
datasets: [{
|
||||
label: '{% blocktrans %}Single Price - {{currency}}{% endblocktrans %}',
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
||||
borderColor: 'rgb(255, 99, 132)',
|
||||
yAxisID: 'y',
|
||||
data: [
|
||||
{% for line in price_history %}{{ line.price|stringformat:".2f" }},{% endfor %}
|
||||
],
|
||||
borderWidth: 1,
|
||||
type: 'line'
|
||||
},
|
||||
{% if 'price_diff' in price_history.0 %}
|
||||
{
|
||||
label: '{% blocktrans %}Single Price Difference - {{currency}}{% endblocktrans %}',
|
||||
backgroundColor: 'rgba(68, 157, 68, 0.2)',
|
||||
borderColor: 'rgb(68, 157, 68)',
|
||||
yAxisID: 'y2',
|
||||
data: [
|
||||
{% for line in price_history %}{{ line.price_diff|stringformat:".2f" }},{% endfor %}
|
||||
],
|
||||
borderWidth: 1,
|
||||
type: 'line',
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
label: '{% blocktrans %}Part Single Price - {{currency}}{% endblocktrans %}',
|
||||
backgroundColor: 'rgba(70, 127, 155, 0.2)',
|
||||
borderColor: 'rgb(70, 127, 155)',
|
||||
yAxisID: 'y',
|
||||
data: [
|
||||
{% for line in price_history %}{{ line.price_part|stringformat:".2f" }},{% endfor %}
|
||||
],
|
||||
borderWidth: 1,
|
||||
type: 'line',
|
||||
hidden: true,
|
||||
},
|
||||
{% endif %}
|
||||
{
|
||||
label: '{% trans "Quantity" %}',
|
||||
backgroundColor: 'rgba(255, 206, 86, 0.2)',
|
||||
borderColor: 'rgb(255, 206, 86)',
|
||||
yAxisID: 'y1',
|
||||
data: [
|
||||
{% for line in price_history %}{{ line.qty|stringformat:"f" }},{% endfor %}
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
}
|
||||
var StockPriceChart = loadStockPricingChart($('#StockPriceChart'), purchasepricedata)
|
||||
{% endif %}
|
||||
|
||||
{% if bom_parts %}
|
||||
var bom_colors = randomColor({hue: 'green', count: {{ bom_parts|length }} })
|
||||
var bomdata = {
|
||||
labels: [{% for line in bom_parts %}'{{ line.name }}',{% endfor %}],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Price',
|
||||
data: [{% for line in bom_parts %}{{ line.min_price }},{% endfor %}],
|
||||
backgroundColor: bom_colors,
|
||||
},
|
||||
{% if bom_pie_max %}
|
||||
{
|
||||
label: 'Max Price',
|
||||
data: [{% for line in bom_parts %}{{ line.max_price }},{% endfor %}],
|
||||
backgroundColor: bom_colors,
|
||||
},
|
||||
{% endif %}
|
||||
]
|
||||
};
|
||||
var BomChart = loadBomChart(document.getElementById('BomChart'), bomdata)
|
||||
{% endif %}
|
||||
|
||||
|
||||
// Internal pricebreaks
|
||||
{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %}
|
||||
{% if show_internal_price and roles.sales_order.view %}
|
||||
initPriceBreakSet(
|
||||
$('#internal-price-break-table'),
|
||||
{
|
||||
part_id: {{part.id}},
|
||||
pb_human_name: 'internal price break',
|
||||
pb_url_slug: 'internal-price',
|
||||
pb_url: '{% url 'api-part-internal-price-list' %}',
|
||||
pb_new_btn: $('#new-internal-price-break'),
|
||||
pb_new_url: '{% url 'internal-price-break-create' %}',
|
||||
linkedGraph: $('#InternalPriceBreakChart'),
|
||||
},
|
||||
);
|
||||
{% endif %}
|
||||
|
||||
|
||||
// Load the BOM table data
|
||||
loadBomTable($("#bom-table"), {
|
||||
editable: {{ editing_enabled }},
|
||||
bom_url: "{% url 'api-bom-list' %}",
|
||||
part_url: "{% url 'api-part-list' %}",
|
||||
parent_id: {{ part.id }} ,
|
||||
sub_part_detail: true,
|
||||
});
|
||||
|
||||
|
||||
// Sales pricebreaks
|
||||
{% if part.salable and roles.sales_order.view %}
|
||||
initPriceBreakSet(
|
||||
$('#price-break-table'),
|
||||
{
|
||||
part_id: {{part.id}},
|
||||
pb_human_name: 'sale price break',
|
||||
pb_url_slug: 'sale-price',
|
||||
pb_url: "{% url 'api-part-sale-price-list' %}",
|
||||
pb_new_btn: $('#new-price-break'),
|
||||
pb_new_url: '{% url 'sale-price-break-create' %}',
|
||||
linkedGraph: $('#SalePriceBreakChart'),
|
||||
},
|
||||
);
|
||||
{% endif %}
|
||||
|
||||
// Sale price history
|
||||
{% if sale_history %}
|
||||
var salepricedata = {
|
||||
labels: [
|
||||
{% for line in sale_history %}'{{ line.date }}',{% endfor %}
|
||||
],
|
||||
datasets: [{
|
||||
label: '{% blocktrans %}Unit Price - {{currency}}{% endblocktrans %}',
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
||||
borderColor: 'rgb(255, 99, 132)',
|
||||
yAxisID: 'y',
|
||||
data: [
|
||||
{% for line in sale_history %}{{ line.price|stringformat:".2f" }},{% endfor %}
|
||||
],
|
||||
borderWidth: 1,
|
||||
},
|
||||
{
|
||||
label: '{% trans "Quantity" %}',
|
||||
backgroundColor: 'rgba(255, 206, 86, 0.2)',
|
||||
borderColor: 'rgb(255, 206, 86)',
|
||||
yAxisID: 'y1',
|
||||
data: [
|
||||
{% for line in sale_history %}{{ line.qty|stringformat:"f" }},{% endfor %}
|
||||
],
|
||||
borderWidth: 1,
|
||||
type: 'bar',
|
||||
}]
|
||||
}
|
||||
var SalePriceChart = loadSellPricingChart($('#SalePriceChart'), salepricedata)
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,80 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='related' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Related Parts" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<div id='button-bar'>
|
||||
<div class='button-toolbar container-fluid' style='float: left;'>
|
||||
{% if roles.part.change %}
|
||||
<button class='btn btn-primary' type='button' id='add-related-part' title='{% trans "Add Related" %}'>{% trans "Add Related" %}</button>
|
||||
<div class='filter-list' id='filter-list-related'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id='table-related-part' class='table table-condensed table-striped' data-toolbar='#button-toolbar'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-field='part' data-serachable='true'>{% trans "Part" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in part.get_related_parts %}
|
||||
{% with part_related=item.0 part=item.1 %}
|
||||
<tr>
|
||||
<td>
|
||||
<a class='hover-icon'>
|
||||
<img class='hover-img-thumb' src='{{ part.get_thumbnail_url }}'>
|
||||
<img class='hover-img-large' src='{{ part.get_thumbnail_url }}'>
|
||||
</a>
|
||||
<a href='/part/{{ part.id }}/'>{{ part }}</a>
|
||||
<div class='btn-group' style='float: right;'>
|
||||
{% if roles.part.change %}
|
||||
<button title='{% trans "Delete" %}' class='btn btn-default btn-glyph delete-related-part' url="{% url 'part-related-delete' part_related.id %}" type='button'><span class='fas fa-trash-alt icon-red'/></button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$('#table-related-part').inventreeTable({
|
||||
});
|
||||
|
||||
$("#add-related-part").click(function() {
|
||||
launchModalForm("{% url 'part-related-create' %}", {
|
||||
data: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$('.delete-related-part').click(function() {
|
||||
var button = $(this);
|
||||
|
||||
launchModalForm(button.attr('url'), {
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,41 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='sales-orders' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Sales Orders" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<div id='button-bar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
{% if 0 %}
|
||||
<button class='btn btn-primary' type='button' id='part-order2' title='{% trans "New sales order" %}'>{% trans "New Order" %}</button>
|
||||
{% endif %}
|
||||
<div class='filter-list' id='filter-list-salesorder'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed po-table' id='sales-order-table' data-toolbar='#button-bar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadSalesOrderTable($("#sales-order-table"), {
|
||||
url: "{% url 'api-so-list' %}",
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,77 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='stock' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Stock" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% if part.is_template %}
|
||||
<div class='alert alert-info alert-block'>
|
||||
{% blocktrans with full_name=part.full_name%}Showing stock for all variants of <i>{{full_name}}</i>{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% include "stock_table.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_load %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$('#add-stock-item').click(function () {
|
||||
createNewStockItem({
|
||||
reload: true,
|
||||
data: {
|
||||
part: {{ part.id }},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
location_detail: true,
|
||||
part_detail: true,
|
||||
supplier_part_detail: true,
|
||||
},
|
||||
groupByField: 'location',
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
|
||||
$("#stock-export").click(function() {
|
||||
launchModalForm("{% url 'stock-export-options' %}", {
|
||||
submit_text: "{% trans 'Export' %}",
|
||||
success: function(response) {
|
||||
var url = "{% url 'stock-export' %}";
|
||||
|
||||
url += "?format=" + response.format;
|
||||
url += "&cascade=" + response.cascade;
|
||||
url += "&part={{ part.id }}";
|
||||
|
||||
location.href = url;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$('#item-create').click(function () {
|
||||
createNewStockItem({
|
||||
reload: true,
|
||||
data: {
|
||||
part: {{ part.id }},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,51 +0,0 @@
|
||||
{% extends "part/category.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
{% load static %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/category_navbar.html' with tab='subcategories' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block category_content %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Subcategories" %}</h4>
|
||||
</div>
|
||||
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
|
||||
<div class='filter-list' id='filter-list-category'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='subcategory-table' data-toolbar='#button-toolbar'></table>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableNavbar({
|
||||
label: 'category',
|
||||
toggleId: '#category-menu-toggle',
|
||||
});
|
||||
|
||||
loadPartCategoryTable($('#subcategory-table'), {
|
||||
params: {
|
||||
{% if category %}
|
||||
parent: {{ category.pk }}
|
||||
{% else %}
|
||||
parent: 'null'
|
||||
{% endif %}
|
||||
}
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,171 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='suppliers' %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Suppliers" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<div id='supplier-button-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class="btn btn-success" id='supplier-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Supplier Part" %}
|
||||
</button>
|
||||
<div id='opt-dropdown' class="btn-group">
|
||||
<button id='supplier-part-options' class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href='#' id='supplier-part-delete' title='{% trans "Delete supplier parts" %}'>{% trans "Delete" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-condensed" id='supplier-table' data-toolbar='#supplier-button-toolbar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block post_content_panel %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
{% trans "Part Manufacturers" %}
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class='panel-content'>
|
||||
<div id='manufacturer-button-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class="btn btn-success" id='manufacturer-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Manufacturer Part" %}
|
||||
</button>
|
||||
<div id='opt-dropdown' class="btn-group">
|
||||
<button id='manufacturer-part-options' class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">{% trans "Options" %}<span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href='#' id='manufacturer-part-delete' title='{% trans "Delete manufacturer parts" %}'>{% trans "Delete" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class='table table-condensed table-striped' id='manufacturer-table' data-toolbar='#manufacturer-button-toolbar'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_load %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$('#supplier-create').click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'supplier-part-create' %}",
|
||||
{
|
||||
reload: true,
|
||||
data: {
|
||||
part: {{ part.id }}
|
||||
},
|
||||
secondary: [
|
||||
{
|
||||
field: 'supplier',
|
||||
label: '{% trans "New Supplier" %}',
|
||||
title: '{% trans "Create new supplier" %}',
|
||||
},
|
||||
{
|
||||
field: 'manufacturer',
|
||||
label: '{% trans "New Manufacturer" %}',
|
||||
title: '{% trans "Create new manufacturer" %}',
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
$("#supplier-part-delete").click(function() {
|
||||
|
||||
var selections = $("#supplier-table").bootstrapTable("getSelections");
|
||||
|
||||
var parts = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
parts.push(item.pk);
|
||||
});
|
||||
|
||||
launchModalForm("{% url 'supplier-part-delete' %}", {
|
||||
data: {
|
||||
parts: parts,
|
||||
},
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
loadSupplierPartTable(
|
||||
"#supplier-table",
|
||||
"{% url 'api-supplier-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
part_detail: false,
|
||||
supplier_detail: true,
|
||||
manufacturer_detail: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
linkButtonsToSelection($("#supplier-table"), ['#supplier-part-options']);
|
||||
|
||||
loadManufacturerPartTable(
|
||||
'#manufacturer-table',
|
||||
"{% url 'api-manufacturer-part-list' %}",
|
||||
{
|
||||
params: {
|
||||
part: {{ part.id }},
|
||||
part_detail: true,
|
||||
manufacturer_detail: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
linkButtonsToSelection($("#manufacturer-table"), ['#manufacturer-part-options']);
|
||||
|
||||
$("#manufacturer-part-delete").click(function() {
|
||||
|
||||
var selections = $("#manufacturer-table").bootstrapTable("getSelections");
|
||||
|
||||
deleteManufacturerParts(selections, {
|
||||
onSuccess: function() {
|
||||
$("#manufacturer-table").bootstrapTable("refresh");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#manufacturer-create').click(function () {
|
||||
|
||||
constructForm('{% url "api-manufacturer-part-list" %}', {
|
||||
fields: {
|
||||
part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
},
|
||||
manufacturer: {},
|
||||
MPN: {},
|
||||
description: {},
|
||||
link: {},
|
||||
},
|
||||
method: 'POST',
|
||||
title: '{% trans "Add Manufacturer Part" %}',
|
||||
onSuccess: function() {
|
||||
$("#manufacturer-table").bootstrapTable("refresh");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,14 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='track' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Tracking" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% endblock %}
|
@ -1,39 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='used' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Assemblies" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<div id='button-toolbar'>
|
||||
<div class='filter-list' id='filter-list-usedin'>
|
||||
<!-- Empty div (will be filled out with avilable BOM filters) -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-condensed" id='used-table' data-toolbar='#button-toolbar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadPartTable('#used-table',
|
||||
'{% url "api-part-list" %}',
|
||||
{
|
||||
params: {
|
||||
uses: {{ part.pk }},
|
||||
},
|
||||
filterTarget: '#filter-list-usedin',
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
{% endblock %}
|
@ -1,49 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "part/navbar.html" with tab='variants' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Variants" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid'>
|
||||
<div class='btn-group' role='group'>
|
||||
{% if part.is_template and part.active %}
|
||||
<button class='btn btn-success' id='new-variant' title='{% trans "Create new variant" %}'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Variant" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-variants'>
|
||||
<!-- Empty div (will be filled out with available BOM filters) -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='variants-table' data-toolbar='#button-toolbar'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadPartVariantTable($('#variants-table'), {{ part.pk }});
|
||||
|
||||
$('#new-variant').click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'make-part-variant' part.id %}",
|
||||
{
|
||||
follow: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -158,21 +158,6 @@ class PartDetailTest(PartViewTestCase):
|
||||
class PartTests(PartViewTestCase):
|
||||
""" Tests for Part forms """
|
||||
|
||||
def test_part_edit(self):
|
||||
|
||||
response = self.client.get(reverse('part-edit', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
|
||||
keys = response.context.keys()
|
||||
data = str(response.content)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertIn('part', keys)
|
||||
self.assertIn('csrf_token', keys)
|
||||
|
||||
self.assertIn('html_form', data)
|
||||
self.assertIn('"title":', data)
|
||||
|
||||
def test_part_create(self):
|
||||
""" Launch form to create a new part """
|
||||
response = self.client.get(reverse('part-create'), {'category': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
|
@ -36,7 +36,6 @@ part_parameter_urls = [
|
||||
]
|
||||
|
||||
part_detail_urls = [
|
||||
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
|
||||
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
||||
url(r'^bom-export/?', views.BomExport.as_view(), name='bom-export'),
|
||||
url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'),
|
||||
@ -48,20 +47,6 @@ part_detail_urls = [
|
||||
url(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'),
|
||||
url(r'^bom-duplicate/?', views.BomDuplicate.as_view(), name='duplicate-bom'),
|
||||
|
||||
url(r'^variants/?', views.PartDetail.as_view(template_name='part/variants.html'), name='part-variants'),
|
||||
url(r'^stock/?', views.PartDetail.as_view(template_name='part/stock.html'), name='part-stock'),
|
||||
url(r'^allocation/?', views.PartDetail.as_view(template_name='part/allocation.html'), name='part-allocation'),
|
||||
url(r'^bom/?', views.PartDetail.as_view(template_name='part/bom.html'), name='part-bom'),
|
||||
url(r'^build/?', views.PartDetail.as_view(template_name='part/build.html'), name='part-build'),
|
||||
url(r'^used/?', views.PartDetail.as_view(template_name='part/used_in.html'), name='part-used-in'),
|
||||
url(r'^prices/', views.PartPricingView.as_view(template_name='part/prices.html'), name='part-prices'),
|
||||
url(r'^suppliers/?', views.PartDetail.as_view(template_name='part/supplier.html'), name='part-suppliers'),
|
||||
url(r'^orders/?', views.PartDetail.as_view(template_name='part/orders.html'), name='part-orders'),
|
||||
url(r'^sales-orders/', views.PartDetail.as_view(template_name='part/sales_orders.html'), name='part-sales-orders'),
|
||||
url(r'^tests/', views.PartDetail.as_view(template_name='part/part_tests.html'), name='part-test-templates'),
|
||||
url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'),
|
||||
url(r'^related-parts/?', views.PartDetail.as_view(template_name='part/related.html'), name='part-related'),
|
||||
|
||||
url(r'^qr_code/?', views.PartQRCode.as_view(), name='part-qr'),
|
||||
|
||||
# Normal thumbnail with form
|
||||
@ -91,9 +76,6 @@ category_urls = [
|
||||
url(r'^delete/', views.CategoryDelete.as_view(), name='category-delete'),
|
||||
url(r'^parameters/', include(category_parameter_urls)),
|
||||
|
||||
url(r'^subcategory/', views.CategoryDetail.as_view(template_name='part/subcategory.html'), name='category-subcategory'),
|
||||
url(r'^parametric/', views.CategoryParametric.as_view(), name='category-parametric'),
|
||||
|
||||
# Anything else
|
||||
url(r'^.*$', views.CategoryDetail.as_view(), name='category-detail'),
|
||||
]))
|
||||
|
@ -754,6 +754,7 @@ class PartDetail(InvenTreeRoleMixin, DetailView):
|
||||
context_object_name = 'part'
|
||||
queryset = Part.objects.all().select_related('category')
|
||||
template_name = 'part/detail.html'
|
||||
form_class = part_forms.PartPriceForm
|
||||
|
||||
# Add in some extra context information based on query params
|
||||
def get_context_data(self, **kwargs):
|
||||
@ -774,25 +775,12 @@ class PartDetail(InvenTreeRoleMixin, DetailView):
|
||||
ctx = part.get_context_data(self.request)
|
||||
context.update(**ctx)
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class PartPricingView(PartDetail):
|
||||
""" Detail view for Part object
|
||||
"""
|
||||
context_object_name = 'part'
|
||||
template_name = 'part/order_prices.html'
|
||||
form_class = part_forms.PartPriceForm
|
||||
|
||||
# Add in some extra context information based on query params
|
||||
def get_context_data(self, **kwargs):
|
||||
""" Provide extra context data to template """
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
# Pricing information
|
||||
ctx = self.get_pricing(self.get_quantity())
|
||||
ctx['form'] = self.form_class(initial=self.get_initials())
|
||||
|
||||
context.update(ctx)
|
||||
|
||||
return context
|
||||
|
||||
def get_quantity(self):
|
||||
@ -1084,40 +1072,6 @@ class PartImageSelect(AjaxUpdateView):
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
|
||||
|
||||
class PartEdit(AjaxUpdateView):
|
||||
""" View for editing Part object """
|
||||
|
||||
model = Part
|
||||
form_class = part_forms.EditPartForm
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Part Properties')
|
||||
context_object_name = 'part'
|
||||
|
||||
def get_form(self):
|
||||
""" Create form for Part editing.
|
||||
Overrides default get_form() method to limit the choices
|
||||
for the 'default_supplier' field to SupplierParts that reference this part
|
||||
"""
|
||||
|
||||
form = super(AjaxUpdateView, self).get_form()
|
||||
|
||||
# Hide the "default expiry" field if the feature is not enabled
|
||||
if not inventree_settings.stock_expiry_enabled():
|
||||
form.fields['default_expiry'].widget = HiddenInput()
|
||||
|
||||
part = self.get_object()
|
||||
|
||||
form.fields['default_supplier'].queryset = SupplierPart.objects.filter(part=part)
|
||||
|
||||
# Check if IPN can be edited
|
||||
ipn_edit_enable = InvenTreeSetting.get_setting('PART_ALLOW_EDIT_IPN')
|
||||
if not ipn_edit_enable and not self.request.user.is_superuser:
|
||||
# Admin can still change IPN
|
||||
form.fields['IPN'].disabled = True
|
||||
|
||||
return form
|
||||
|
||||
|
||||
class BomDuplicate(AjaxUpdateView):
|
||||
"""
|
||||
View for duplicating BOM from a parent item.
|
||||
@ -1475,7 +1429,7 @@ class BomUpload(InvenTreeRoleMixin, FileManagementFormView):
|
||||
# BomItem already exists
|
||||
pass
|
||||
|
||||
return HttpResponseRedirect(reverse('part-bom', kwargs={'pk': self.kwargs['pk']}))
|
||||
return HttpResponseRedirect(reverse('part-detail', kwargs={'pk': self.kwargs['pk']}))
|
||||
|
||||
|
||||
class PartExport(AjaxView):
|
||||
@ -1852,7 +1806,7 @@ class CategoryDetail(InvenTreeRoleMixin, DetailView):
|
||||
model = PartCategory
|
||||
context_object_name = 'category'
|
||||
queryset = PartCategory.objects.all().prefetch_related('children')
|
||||
template_name = 'part/category_partlist.html'
|
||||
template_name = 'part/category.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
@ -1863,18 +1817,6 @@ class CategoryDetail(InvenTreeRoleMixin, DetailView):
|
||||
except KeyError:
|
||||
context['part_count'] = 0
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class CategoryParametric(CategoryDetail):
|
||||
""" Parametric view for PartCategory """
|
||||
|
||||
template_name = 'part/category_parametric.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
context = super(CategoryParametric, self).get_context_data(**kwargs).copy()
|
||||
|
||||
# Get current category
|
||||
category = kwargs.get('object', None)
|
||||
|
||||
|
@ -3,44 +3,360 @@
|
||||
{% load static %}
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/navbar.html" with tab="tracking" %}
|
||||
{% include "stock/navbar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Stock Tracking Information" %}
|
||||
{% endblock %}
|
||||
{% block page_content %}
|
||||
|
||||
{% block details %}
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-history'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Stock Tracking Information" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %}
|
||||
{% if owner_control.value == "True" %}
|
||||
{% authorized_owners item.owner as owners %}
|
||||
{% endif %}
|
||||
<!-- Check permissions and owner -->
|
||||
{% if owner_control.value == "False" or owner_control.value == "True" and user in owners %}
|
||||
{% if roles.stock.change and not item.is_building %}
|
||||
<div id='table-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-success' type='button' title='New tracking entry' id='new-entry'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Entry" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<table class='table table-condensed table-striped' id='track-table' data-toolbar='#table-toolbar'>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %}
|
||||
{% if owner_control.value == "True" %}
|
||||
{% authorized_owners item.owner as owners %}
|
||||
{% endif %}
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-children'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Child Stock Items" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% if item.child_count > 0 %}
|
||||
{% include "stock_table.html" with prefix="childs-" %}
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "This stock item does not have any child items" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-test-data'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Test Data" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='test-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style="float: right;">
|
||||
<div class='btn-group' role='group'>
|
||||
{% if user.is_staff %}
|
||||
<button type='button' class='btn btn-danger' id='delete-test-results'>
|
||||
<span class='fas fa-trash-alt'></span> {% trans "Delete Test Data" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type='button' class='btn btn-success' id='add-test-result'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Test Data" %}
|
||||
</button>
|
||||
<button type='button' class='btn btn-default' id='test-report'>
|
||||
<span class='fas fa-tasks'></span> {% trans "Test Report" %}
|
||||
</button>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-stocktests'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#test-button-toolbar' id='test-result-table'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Check permissions and owner -->
|
||||
{% if owner_control.value == "False" or owner_control.value == "True" and user in owners %}
|
||||
{% if roles.stock.change and not item.is_building %}
|
||||
<div id='table-toolbar'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-success' type='button' title='New tracking entry' id='new-entry'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Entry" %}
|
||||
</button>
|
||||
<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 "Stock Item 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>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<table class='table table-condensed table-striped' id='track-table' data-toolbar='#table-toolbar'>
|
||||
</table>
|
||||
<div class='panel-content'>
|
||||
{% if item.notes %}
|
||||
{{ item.notes | markdownify }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-installed-items'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Installed Stock Items" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<table class='table table-striped table-condensed' id='installed-table'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadInstalledInTable(
|
||||
$('#installed-table'),
|
||||
{
|
||||
stock_item: {{ item.pk }},
|
||||
part: {{ item.part.pk }},
|
||||
quantity: {{ item.quantity }},
|
||||
}
|
||||
);
|
||||
|
||||
$('#multi-item-uninstall').click(function() {
|
||||
|
||||
var selections = $('#installed-table').bootstrapTable('getSelections');
|
||||
|
||||
var items = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
items.push(item.pk);
|
||||
});
|
||||
|
||||
launchModalForm(
|
||||
"{% url 'stock-item-uninstall' %}",
|
||||
{
|
||||
data: {
|
||||
'items[]': items,
|
||||
},
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#edit-notes').click(function() {
|
||||
constructForm('{% url "api-stock-detail" item.pk %}', {
|
||||
fields: {
|
||||
notes: {
|
||||
multiline: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Edit Notes" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
"{% url 'api-stock-attachment-list' %}",
|
||||
{
|
||||
data: {
|
||||
stock_item: {{ item.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
reloadAttachmentTable();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-stock-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
stock_item: {{ item.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/stock/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
var url = `/api/stock/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm(
|
||||
'{% url "api-stock-attachment-list" %}',
|
||||
{
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
stock_item: {
|
||||
value: {{ item.pk }},
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
reload: true,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
loadStockTestResultsTable(
|
||||
$("#test-result-table"), {
|
||||
part: {{ item.part.id }},
|
||||
stock_item: {{ item.id }},
|
||||
}
|
||||
);
|
||||
|
||||
function reloadTable() {
|
||||
$("#test-result-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
{% if item.has_test_reports %}
|
||||
$("#test-report").click(function() {
|
||||
printTestReports([{{ item.pk }}]);
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_staff %}
|
||||
$("#delete-test-results").click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'stock-item-delete-test-data' item.id %}",
|
||||
{
|
||||
success: reloadTable,
|
||||
}
|
||||
);
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
$("#add-test-result").click(function() {
|
||||
|
||||
constructForm('{% url "api-stock-test-result-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
test: {},
|
||||
result: {},
|
||||
value: {},
|
||||
attachment: {},
|
||||
notes: {},
|
||||
stock_item: {
|
||||
value: {{ item.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Add Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-add', function() {
|
||||
var button = $(this);
|
||||
|
||||
var test_name = button.attr('pk');
|
||||
|
||||
constructForm('{% url "api-stock-test-result-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
test: {
|
||||
value: test_name,
|
||||
},
|
||||
result: {},
|
||||
value: {},
|
||||
attachment: {},
|
||||
notes: {},
|
||||
stock_item: {
|
||||
value: {{ item.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Add Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-edit', function() {
|
||||
var button = $(this);
|
||||
|
||||
var pk = button.attr('pk');
|
||||
|
||||
var url = `/api/stock/test/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
test: {},
|
||||
result: {},
|
||||
value: {},
|
||||
attachment: {},
|
||||
notes: {},
|
||||
},
|
||||
title: '{% trans "Edit Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-delete', function() {
|
||||
var button = $(this);
|
||||
|
||||
var pk = button.attr('pk');
|
||||
|
||||
var url = `/api/stock/test/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
{% if item.child_count > 0 %}
|
||||
loadStockTable($("#childs-stock-table"), {
|
||||
params: {
|
||||
location_detail: true,
|
||||
part_detail: false,
|
||||
ancestor: {{ item.id }},
|
||||
},
|
||||
name: 'item-childs',
|
||||
groupByField: 'location',
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
$("#new-entry").click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'stock-tracking-create' item.id %}",
|
||||
|
@ -1,86 +0,0 @@
|
||||
{% extends "stock/item_base.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/navbar.html" with tab='attachments' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Stock Item Attachments" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% include "attachment_table.html" with attachments=item.attachments.all %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
"{% url 'api-stock-attachment-list' %}",
|
||||
{
|
||||
data: {
|
||||
stock_item: {{ item.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
reloadAttachmentTable();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-stock-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
stock_item: {{ item.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/stock/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
var url = `/api/stock/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm(
|
||||
'{% url "api-stock-attachment-list" %}',
|
||||
{
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
stock_item: {
|
||||
value: {{ item.pk }},
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
reload: true,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -235,7 +235,7 @@
|
||||
<td>{% trans "Base Part" %}</td>
|
||||
<td>
|
||||
{% if roles.part.view %}
|
||||
<a href="{% url 'part-stock' item.part.id %}">
|
||||
<a href="{% url 'part-detail' item.part.id %}">
|
||||
{% endif %}
|
||||
{{ item.part.full_name }}
|
||||
{% if roles.part.view %}
|
||||
@ -428,6 +428,7 @@
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
@ -561,7 +562,7 @@ $("#stock-delete").click(function () {
|
||||
launchModalForm(
|
||||
"{% url 'stock-item-delete' item.id %}",
|
||||
{
|
||||
redirect: "{% url 'part-stock' item.part.id %}"
|
||||
redirect: "{% url 'part-detail' item.part.id %}"
|
||||
}
|
||||
);
|
||||
});
|
||||
@ -610,4 +611,9 @@ $("#stock-return-from-customer").click(function() {
|
||||
|
||||
{% endif %}
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'stockitem',
|
||||
default: 'history'
|
||||
});
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,45 +0,0 @@
|
||||
{% extends "stock/item_base.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/navbar.html" with tab='children' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Child Stock Items" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
{% if item.child_count > 0 %}
|
||||
{% include "stock_table.html" %}
|
||||
{% else %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "This stock item does not have any child items" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if item.child_count > 0 %}
|
||||
loadStockTable($("#stock-table"), {
|
||||
params: {
|
||||
location_detail: true,
|
||||
part_detail: false,
|
||||
ancestor: {{ item.id }},
|
||||
},
|
||||
name: 'item-childs',
|
||||
groupByField: 'location',
|
||||
buttons: [
|
||||
'#stock-options',
|
||||
],
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -1,53 +0,0 @@
|
||||
{% extends "stock/item_base.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/navbar.html" with tab='installed' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Installed Stock Items" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<table class='table table-striped table-condensed' id='installed-table'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
loadInstalledInTable(
|
||||
$('#installed-table'),
|
||||
{
|
||||
stock_item: {{ item.pk }},
|
||||
part: {{ item.part.pk }},
|
||||
quantity: {{ item.quantity }},
|
||||
}
|
||||
);
|
||||
|
||||
$('#multi-item-uninstall').click(function() {
|
||||
|
||||
var selections = $('#installed-table').bootstrapTable('getSelections');
|
||||
|
||||
var items = [];
|
||||
|
||||
selections.forEach(function(item) {
|
||||
items.push(item.pk);
|
||||
});
|
||||
|
||||
launchModalForm(
|
||||
"{% url 'stock-item-uninstall' %}",
|
||||
{
|
||||
data: {
|
||||
'items[]': items,
|
||||
},
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,51 +0,0 @@
|
||||
{% extends "stock/item_base.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load inventree_extras %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/navbar.html" with tab="notes" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Stock Item Notes" %}
|
||||
{% if roles.stock.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 %}
|
||||
<form method='POST'>
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form }}
|
||||
<hr>
|
||||
<button type="submit" class='btn btn-default'>{% trans "Save" %}</button>
|
||||
</form>
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
{% else %}
|
||||
{% if item.notes %}
|
||||
{{ item.notes | markdownify }}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
|
||||
{{ block.super }}
|
||||
|
||||
{% if editing %}
|
||||
{% else %}
|
||||
$("#edit-notes").click(function() {
|
||||
location.href = "{% url 'stock-item-notes' item.id %}?edit=1";
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -1,150 +0,0 @@
|
||||
{% extends "stock/item_base.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/navbar.html" with tab='tests' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Test Data" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style="float: right;">
|
||||
<div class='btn-group' role='group'>
|
||||
{% if user.is_staff %}
|
||||
<button type='button' class='btn btn-danger' id='delete-test-results'>
|
||||
<span class='fas fa-trash-alt'></span> {% trans "Delete Test Data" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type='button' class='btn btn-success' id='add-test-result'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "Add Test Data" %}
|
||||
</button>
|
||||
<button type='button' class='btn btn-default' id='test-report'>
|
||||
<span class='fas fa-tasks'></span> {% trans "Test Report" %}
|
||||
</button>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-stocktests'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='test-result-table'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadStockTestResultsTable(
|
||||
$("#test-result-table"), {
|
||||
part: {{ item.part.id }},
|
||||
stock_item: {{ item.id }},
|
||||
}
|
||||
);
|
||||
|
||||
function reloadTable() {
|
||||
$("#test-result-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
{% if item.has_test_reports %}
|
||||
$("#test-report").click(function() {
|
||||
printTestReports([{{ item.pk }}]);
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_staff %}
|
||||
$("#delete-test-results").click(function() {
|
||||
launchModalForm(
|
||||
"{% url 'stock-item-delete-test-data' item.id %}",
|
||||
{
|
||||
success: reloadTable,
|
||||
}
|
||||
);
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
$("#add-test-result").click(function() {
|
||||
|
||||
constructForm('{% url "api-stock-test-result-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
test: {},
|
||||
result: {},
|
||||
value: {},
|
||||
attachment: {},
|
||||
notes: {},
|
||||
stock_item: {
|
||||
value: {{ item.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Add Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-add', function() {
|
||||
var button = $(this);
|
||||
|
||||
var test_name = button.attr('pk');
|
||||
|
||||
constructForm('{% url "api-stock-test-result-list" %}', {
|
||||
method: 'POST',
|
||||
fields: {
|
||||
test: {
|
||||
value: test_name,
|
||||
},
|
||||
result: {},
|
||||
value: {},
|
||||
attachment: {},
|
||||
notes: {},
|
||||
stock_item: {
|
||||
value: {{ item.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Add Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-edit', function() {
|
||||
var button = $(this);
|
||||
|
||||
var pk = button.attr('pk');
|
||||
|
||||
var url = `/api/stock/test/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
test: {},
|
||||
result: {},
|
||||
value: {},
|
||||
attachment: {},
|
||||
notes: {},
|
||||
},
|
||||
title: '{% trans "Edit Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-delete', function() {
|
||||
var button = $(this);
|
||||
|
||||
var pk = button.attr('pk');
|
||||
|
||||
var url = `/api/stock/test/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Test Result" %}',
|
||||
onSuccess: reloadTable,
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -4,7 +4,7 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/location_navbar.html" with tab="stock" %}
|
||||
{% include "stock/location_navbar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
@ -143,13 +143,39 @@
|
||||
|
||||
{% block location_content %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-stock'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Stock Items" %}</h4>
|
||||
</div>
|
||||
{% include "stock_table.html" %}
|
||||
</div>
|
||||
|
||||
<div class='panel panel-default panel-inventree panel-hidden' id='panel-sublocations'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sublocations" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='sublocation-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
<!-- Printing actions menu -->
|
||||
<div class='btn-group'>
|
||||
<button id='location-print-options' class='btn btn-primary dropdown-toggle' type='button' data-toggle="dropdown" title='{% trans "Printing Actions" %}'>
|
||||
<span class='fas fa-print'></span> <span class='caret'></span>
|
||||
</button>
|
||||
<ul class='dropdown-menu'>
|
||||
<li><a href='#' id='multi-location-print-label' title='{% trans "Print labels" %}'><span class='fas fa-tags'></span> {% trans "Print labels" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-location'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#sublocation-button-toolbar' id='sublocation-table'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
@ -164,6 +190,36 @@
|
||||
toggleId: '#location-menu-toggle'
|
||||
});
|
||||
|
||||
loadStockLocationTable($('#sublocation-table'), {
|
||||
params: {
|
||||
{% if location %}
|
||||
parent: {{ location.pk }},
|
||||
{% else %}
|
||||
parent: 'null',
|
||||
{% endif %}
|
||||
}
|
||||
});
|
||||
|
||||
linkButtonsToSelection(
|
||||
$('#sublocation-table'),
|
||||
[
|
||||
'#location-print-options',
|
||||
]
|
||||
);
|
||||
|
||||
$('#multi-location-print-label').click(function() {
|
||||
|
||||
var selections = $('#sublocation-table').bootstrapTable('getSelections');
|
||||
|
||||
var locations = [];
|
||||
|
||||
selections.forEach(function(loc) {
|
||||
locations.push(loc.pk);
|
||||
});
|
||||
|
||||
printStockLocationLabels(locations);
|
||||
});
|
||||
|
||||
{% if location %}
|
||||
$("#barcode-check-in").click(function() {
|
||||
barcodeCheckIn({{ location.id }});
|
||||
@ -301,4 +357,10 @@
|
||||
},
|
||||
url: "{% url 'api-stock-list' %}",
|
||||
});
|
||||
|
||||
attachNavCallbacks({
|
||||
name: 'stocklocation',
|
||||
default: 'stock'
|
||||
});
|
||||
|
||||
{% endblock %}
|
||||
|
@ -8,23 +8,15 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "sublocations" %}active{% endif %}' title='{% trans "Sublocations" %}'>
|
||||
{% if location %}
|
||||
<a href='{% url "stock-location-sublocation" location.id %}'>
|
||||
{% else %}
|
||||
<a href='{% url "stock-sublocations" %}'>
|
||||
{% endif %}
|
||||
<li class='list-group-item' title='{% trans "Sublocations" %}'>
|
||||
<a href='#' id='select-sublocations' class='nav-toggle'>
|
||||
<span class='fas fa-sitemap sidebar-icon'></span>
|
||||
{% trans "Sublocations" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "stock" %}active{% endif %}' title='{% trans "Stock Items" %}'>
|
||||
{% if location %}
|
||||
<a href='{% url "stock-location-detail" location.id %}'>
|
||||
{% else %}
|
||||
<a href='{% url "stock-index" %}'>
|
||||
{% endif %}
|
||||
<a href='#' id='select-stock' class='nav-toggle'>
|
||||
<span class='fas fa-boxes sidebar-icon'></span>
|
||||
{% trans "Stock Items" %}
|
||||
</a>
|
||||
|
@ -8,24 +8,24 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class='list-group-item {% if tab == "tracking" %}active{% endif %}' title='{% trans "Stock Item Tracking" %}'>
|
||||
<a href='{% url "stock-item-detail" item.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Stock Item Tracking" %}'>
|
||||
<a href='#' id='select-history' class='nav-toggle'>
|
||||
<span class='fas fa-history sidebar-icon'></span>
|
||||
{% trans "History" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if item.part.trackable %}
|
||||
<li class='list-group-item {% if tab == "tests" %}active{% endif %}' title='{% trans "Test Data" %}'>
|
||||
<a href='{% url "stock-item-test-results" item.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Test Data" %}'>
|
||||
<a href='#' id='select-test-data' class='nav-toggle'>
|
||||
<span class='fas fa-vial sidebar-icon'></span>
|
||||
{% trans "Test Data" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if item.part.assembly %}
|
||||
<li class='list-group-item {% if tab == "installed" %}active{% endif %}' title='{% trans "Installed Stock Items" %}'>
|
||||
<a href='{% url "stock-item-installed" item.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Installed Stock Items" %}'>
|
||||
<a href='#' id='select-installed-items' class='nav-toggle'>
|
||||
<span class='fas fa-sign-in-alt sidebar-icon'></span>
|
||||
{% trans "Installed Items" %}
|
||||
</a>
|
||||
@ -35,8 +35,8 @@
|
||||
{% endif %}
|
||||
|
||||
{% if item.child_count > 0 %}
|
||||
<li class='list-group-item {% if tab == "children" %}active{% endif %}' title='{% trans "Child Items" %}'>
|
||||
<a href='{% url "stock-item-children" item.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Child Items" %}'>
|
||||
<a href='#' id='select-children' class='nav-toggle'>
|
||||
<span class='fas fa-sitemap sidebar-icon'></span>
|
||||
{% trans "Children" %}
|
||||
</a>
|
||||
@ -44,15 +44,15 @@
|
||||
{% endif %}
|
||||
|
||||
|
||||
<li class='list-group-item {% if tab == "attachments" %}active{% endif %}' title='{% trans "Attachments" %}'>
|
||||
<a href='{% url "stock-item-attachments" item.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 "Stock Item Notes" %}'>
|
||||
<a href='{% url "stock-item-notes" item.id %}'>
|
||||
<li class='list-group-item' title='{% trans "Stock Item Notes" %}'>
|
||||
<a href='#' id='select-notes' class='nav-toggle'>
|
||||
<span class='fas fa-clipboard sidebar-icon'></span>
|
||||
{% trans "Notes" %}
|
||||
</a>
|
||||
|
@ -1,74 +0,0 @@
|
||||
{% extends "stock/location.html" %}
|
||||
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load inventree_extras %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include "stock/location_navbar.html" with tab="sublocations" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block location_content %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Sublocations" %}</h4>
|
||||
</div>
|
||||
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
<!-- Printing actions menu -->
|
||||
<div class='btn-group'>
|
||||
<button id='location-print-options' class='btn btn-primary dropdown-toggle' type='button' data-toggle="dropdown" title='{% trans "Printing Actions" %}'>
|
||||
<span class='fas fa-print'></span> <span class='caret'></span>
|
||||
</button>
|
||||
<ul class='dropdown-menu'>
|
||||
<li><a href='#' id='multi-location-print-label' title='{% trans "Print labels" %}'><span class='fas fa-tags'></span> {% trans "Print labels" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-location'>
|
||||
<!-- An empty div in which the filter list will be constructed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='sublocation-table'></table>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadStockLocationTable($('#sublocation-table'), {
|
||||
params: {
|
||||
{% if location %}
|
||||
parent: {{ location.pk }},
|
||||
{% else %}
|
||||
parent: 'null',
|
||||
{% endif %}
|
||||
}
|
||||
});
|
||||
|
||||
linkButtonsToSelection(
|
||||
$('#sublocation-table'),
|
||||
[
|
||||
'#location-print-options',
|
||||
]
|
||||
);
|
||||
|
||||
$('#multi-location-print-label').click(function() {
|
||||
|
||||
var selections = $('#sublocation-table').bootstrapTable('getSelections');
|
||||
|
||||
var locations = [];
|
||||
|
||||
selections.forEach(function(loc) {
|
||||
locations.push(loc.pk);
|
||||
});
|
||||
|
||||
printStockLocationLabels(locations);
|
||||
})
|
||||
|
||||
{% endblock %}
|
@ -14,9 +14,7 @@ location_urls = [
|
||||
url(r'^edit/?', views.StockLocationEdit.as_view(), name='stock-location-edit'),
|
||||
url(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'),
|
||||
url(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'),
|
||||
|
||||
url(r'sublocation/', views.StockLocationDetail.as_view(template_name='stock/sublocation.html'), name='stock-location-sublocation'),
|
||||
|
||||
|
||||
# Anything else
|
||||
url('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'),
|
||||
])),
|
||||
@ -36,12 +34,6 @@ stock_item_detail_urls = [
|
||||
|
||||
url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'),
|
||||
|
||||
url(r'^test/', views.StockItemDetail.as_view(template_name='stock/item_tests.html'), name='stock-item-test-results'),
|
||||
url(r'^children/', views.StockItemDetail.as_view(template_name='stock/item_childs.html'), name='stock-item-children'),
|
||||
url(r'^attachments/', views.StockItemDetail.as_view(template_name='stock/item_attachments.html'), name='stock-item-attachments'),
|
||||
url(r'^installed/', views.StockItemDetail.as_view(template_name='stock/item_installed.html'), name='stock-item-installed'),
|
||||
url(r'^notes/', views.StockItemNotes.as_view(), name='stock-item-notes'),
|
||||
|
||||
url('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'),
|
||||
]
|
||||
|
||||
|
@ -149,22 +149,23 @@
|
||||
<!-- translated -->
|
||||
<script type='text/javascript' src="{% i18n_static 'api.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'attachment.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'forms.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'model_renderers.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'barcode.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'bom.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'build.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'calendar.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'company.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'part.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'modals.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'filters.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'forms.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'label.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'nav.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'modals.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'model_renderers.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'order.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'part.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'report.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'stock.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'build.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'order.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'calendar.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'tables.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'table_filters.js' %}"></script>
|
||||
<script type='text/javascript' src="{% i18n_static 'filters.js' %}"></script>
|
||||
|
||||
<script type='text/javascript' src="{% static 'fontawesome/js/solid.js' %}"></script>
|
||||
<script type='text/javascript' src="{% static 'fontawesome/js/brands.js' %}"></script>
|
||||
|
@ -3,6 +3,14 @@
|
||||
|
||||
var jQuery = window.$;
|
||||
|
||||
$.urlParam = function(name){
|
||||
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
|
||||
if (results==null) {
|
||||
return null;
|
||||
}
|
||||
return decodeURI(results[1]) || 0;
|
||||
}
|
||||
|
||||
// using jQuery
|
||||
function getCookie(name) {
|
||||
var cookieValue = null;
|
||||
|
@ -921,7 +921,7 @@ function loadBuildTable(table, options) {
|
||||
}
|
||||
else
|
||||
{
|
||||
return '{% trans "No user information" %}';
|
||||
return `<i>{% trans "No user information" %}</i>`;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
84
InvenTree/templates/js/nav.js
Normal file
84
InvenTree/templates/js/nav.js
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
/*
|
||||
* Attach callbacks to navigation bar elements.
|
||||
*
|
||||
* Searches for elements with the class 'nav-toggle'.
|
||||
* A callback is added to each element,
|
||||
* to display the matching panel.
|
||||
*
|
||||
* The 'id' of the .nav-toggle element should be of the form "select-<x>",
|
||||
* and point to a matching "panel-<x>"
|
||||
*/
|
||||
function attachNavCallbacks(options={}) {
|
||||
|
||||
$('.nav-toggle').click(function() {
|
||||
var el = $(this);
|
||||
|
||||
// Find the matching "panel" element
|
||||
var panelName = el.attr('id').replace('select-', '');
|
||||
|
||||
activatePanel(panelName, options);
|
||||
});
|
||||
|
||||
var panelClass = options.name || 'unknown';
|
||||
|
||||
/* Look for a default panel to initialize
|
||||
* First preference = URL parameter e.g. ?display=part-stock
|
||||
* Second preference = localStorage
|
||||
* Third preference = default
|
||||
*/
|
||||
var defaultPanel = $.urlParam('display') || localStorage.getItem(`inventree-selected-panel-${panelClass}`) || options.default;
|
||||
|
||||
if (defaultPanel) {
|
||||
activatePanel(defaultPanel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function activatePanel(panelName, options={}) {
|
||||
|
||||
var panelClass = options.name || 'unknown';
|
||||
|
||||
// First, cause any other panels to "fade out"
|
||||
$('.panel-visible').hide();
|
||||
$('.panel-visible').removeClass('panel-visible');
|
||||
|
||||
// Find the target panel
|
||||
var panel = `#panel-${panelName}`;
|
||||
var select = `#select-${panelName}`;
|
||||
|
||||
// Check that the selected panel (and select) exist
|
||||
if ($(panel).length && $(select).length) {
|
||||
// Yep, both are displayed
|
||||
} else {
|
||||
// Either the select or the panel are not displayed!
|
||||
// Iterate through the available 'select' elements until one matches
|
||||
panelName = null;
|
||||
|
||||
$('.nav-toggle').each(function(item) {
|
||||
var panel_name = $(this).attr('id').replace('select-', '');
|
||||
|
||||
if ($(`#panel-${panel_name}`).length && (panelName == null)) {
|
||||
panelName = panel_name;
|
||||
}
|
||||
|
||||
panel = `#panel-${panelName}`;
|
||||
select = `#select-${panelName}`;
|
||||
});
|
||||
}
|
||||
|
||||
// Save the selected panel
|
||||
localStorage.setItem(`inventree-selected-panel-${panelClass}`, panelName);
|
||||
|
||||
// Display the panel
|
||||
$(panel).addClass('panel-visible');
|
||||
$(panel).fadeIn(100);
|
||||
|
||||
// Un-select all selectors
|
||||
$('.list-group-item').removeClass('active');
|
||||
|
||||
// Find the associated selector
|
||||
var select = `#select-${panelName}`;
|
||||
|
||||
$(select).parent('.list-group-item').addClass('active');
|
||||
}
|
@ -13,6 +13,94 @@ function yesNoLabel(value) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function editPart(pk, options={}) {
|
||||
|
||||
var url = `/api/part/${pk}/`;
|
||||
|
||||
var fields = {
|
||||
category: {
|
||||
/*
|
||||
secondary: {
|
||||
label: '{% trans "New Category" %}',
|
||||
title: '{% trans "Create New Part Category" %}',
|
||||
api_url: '{% url "api-part-category-list" %}',
|
||||
method: 'POST',
|
||||
fields: {
|
||||
name: {},
|
||||
description: {},
|
||||
parent: {
|
||||
secondary: {
|
||||
title: '{% trans "New Parent" %}',
|
||||
api_url: '{% url "api-part-category-list" %}',
|
||||
method: 'POST',
|
||||
fields: {
|
||||
name: {},
|
||||
description: {},
|
||||
parent: {},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
*/
|
||||
},
|
||||
name: {
|
||||
placeholder: 'part name',
|
||||
},
|
||||
IPN: {},
|
||||
description: {},
|
||||
revision: {},
|
||||
keywords: {
|
||||
icon: 'fa-key',
|
||||
},
|
||||
variant_of: {},
|
||||
link: {
|
||||
icon: 'fa-link',
|
||||
},
|
||||
default_location: {
|
||||
/*
|
||||
secondary: {
|
||||
label: '{% trans "New Location" %}',
|
||||
title: '{% trans "Create new stock location" %}',
|
||||
},
|
||||
*/
|
||||
},
|
||||
default_supplier: {
|
||||
filters: {
|
||||
part: pk,
|
||||
part_detail: true,
|
||||
manufacturer_detail: true,
|
||||
supplier_detail: true,
|
||||
},
|
||||
/*
|
||||
secondary: {
|
||||
label: '{% trans "New Supplier Part" %}',
|
||||
title: '{% trans "Create new supplier part" %}',
|
||||
}
|
||||
*/
|
||||
},
|
||||
units: {},
|
||||
minimum_stock: {},
|
||||
virtual: {},
|
||||
is_template: {},
|
||||
assembly: {},
|
||||
component: {},
|
||||
trackable: {},
|
||||
purchaseable: {},
|
||||
salable: {},
|
||||
active: {},
|
||||
};
|
||||
|
||||
constructForm(url, {
|
||||
fields: fields,
|
||||
title: '{% trans "Edit Part" %}',
|
||||
reload: true,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function toggleStar(options) {
|
||||
/* Toggle the 'starred' status of a part.
|
||||
* Performs AJAX queries and updates the display on the button.
|
||||
@ -626,7 +714,7 @@ function loadPartTable(table, url, options={}) {
|
||||
|
||||
var html = '';
|
||||
|
||||
html = `<div class='row'>`;
|
||||
html = `<div class='row full-height'>`;
|
||||
|
||||
data.forEach(function(row, index) {
|
||||
|
||||
|
@ -1495,7 +1495,7 @@ function loadStockTrackingTable(table, options) {
|
||||
}
|
||||
else
|
||||
{
|
||||
return '{% trans "No user information" %}';
|
||||
return `<i>{% trans "No user information" %}</i>`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user