Merge remote-tracking branch 'inventree/master' into build-fixes

# Conflicts:
#	InvenTree/locale/de/LC_MESSAGES/django.mo
#	InvenTree/locale/de/LC_MESSAGES/django.po
#	InvenTree/locale/en/LC_MESSAGES/django.po
#	InvenTree/locale/es/LC_MESSAGES/django.po
#	InvenTree/templates/js/bom.js
This commit is contained in:
Oliver Walters 2020-10-29 15:23:51 +11:00
commit 90cfb3496a
15 changed files with 1001 additions and 732 deletions

View File

@ -131,6 +131,13 @@ class SupplierPartList(generics.ListCreateAPIView):
if part is not None:
queryset = queryset.filter(part=part)
# Filter by 'active' status of the part?
active = params.get('active', None)
if active is not None:
active = str2bool(active)
queryset = queryset.filter(part__active=active)
return queryset
def get_serializer(self, *args, **kwargs):

View File

@ -34,6 +34,9 @@
</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 %}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -461,8 +461,8 @@ class PartList(generics.ListCreateAPIView):
else:
queryset = queryset.exclude(pk__in=starred_parts)
# Cascade?
cascade = str2bool(params.get('cascade', None))
# Cascade? (Default = True)
cascade = str2bool(params.get('cascade', True))
# Does the user wish to filter by category?
cat_id = params.get('category', None)

View File

@ -15,7 +15,7 @@
<table class='table table-striped'>
<col width='25'>
<tr>
<td></td>
<td><span class='fas fa-font'></span></td>
<td><b>{% trans "Part name" %}</b></td>
<td>{{ part.name }}</td>
</tr>
@ -28,7 +28,7 @@
{% endif %}
{% if part.revision %}
<tr>
<td></td>
<td><span class='fas fa-code-branch'></span></td>
<td><b>{% trans "Revision" %}</b></td>
<td>{{ part.revision }}</td>
</tr>
@ -132,7 +132,9 @@
</div>
<div class='col-sm-6'>
<table class='table table-striped'>
<col width='25'>
<tr>
<td><span class='fas fa-ghost'%></span></td>
<td><b>{% trans "Virtual" %}</b></td>
<td>{% include "slide.html" with state=part.virtual field='virtual' %}</td>
{% if part.virtual %}
@ -142,6 +144,7 @@
{% endif %}
</tr>
<tr>
<td><span class='fas fa-clone'></span></td>
<td><b>{% trans "Template" %}</b></td>
<td>{% include "slide.html" with state=part.is_template field='is_template' %}</td>
{% if part.is_template %}
@ -151,6 +154,7 @@
{% endif %}
</tr>
<tr>
<td><span class='fas fa-tools'></span></td>
<td><b>{% trans "Assembly" %}</b></td>
<td>{% include "slide.html" with state=part.assembly field='assembly' %}</td>
{% if part.assembly %}
@ -160,6 +164,7 @@
{% endif %}
</tr>
<tr>
<td><span class='fas fa-th'></span></td>
<td><b>{% trans "Component" %}</b></td>
<td>{% include "slide.html" with state=part.component field='component' %}</td>
{% if part.component %}
@ -169,6 +174,7 @@
{% endif %}
</tr>
<tr>
<td><span class='fas fa-directions'></span></td>
<td><b>{% trans "Trackable" %}</b></td>
<td>{% include "slide.html" with state=part.trackable field='trackable' %}</td>
{% if part.trackable %}
@ -178,6 +184,7 @@
{% endif %}
</tr>
<tr>
<td><span class='fas fa-shopping-cart'></span></td>
<td><b>{% trans "Purchaseable" %}</b></td>
<td>{% include "slide.html" with state=part.purchaseable field='purchaseable' %}</td>
{% if part.purchaseable %}
@ -187,6 +194,7 @@
{% endif %}
</tr>
<tr>
<td><span class='fas fa-dollar-sign'></span></td>
<td><b>{% trans "Salable" %}</b></td>
<td>{% include "slide.html" with state=part.salable field='salable' %}</td>
{% if part.salable %}
@ -196,6 +204,13 @@
{% endif %}
</tr>
<tr>
<td>
{% if part.active %}
<span class='fas fa-check-square'></span>
{% else %}
<span class='fas fa-times-square'></span>
{% endif %}
</td>
<td><b>{% trans "Active" %}</b></td>
<td>{% include "slide.html" with state=part.active field='active' disabled=False %}</td>
{% if part.active %}

View File

@ -16,10 +16,17 @@
<hr>
<div id='button-toolbar'>
<div class='btn-group'>
{% if part.is_template and part.active %}
<button class='btn btn-success' id='new-variant' title='{% trans "Create new variant" %}'>{% trans "New Variant" %}</button>
{% endif %}
<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>

View File

@ -2099,7 +2099,7 @@ class BomItemCreate(AjaxCreateView):
model = BomItem
form_class = part_forms.EditBomItemForm
ajax_template_name = 'modal_form.html'
ajax_form_title = _('Create BOM item')
ajax_form_title = _('Create BOM Item')
role_required = 'part.add'

View File

@ -247,7 +247,7 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}
{% endif %}
{% if item.batch %}
<tr>
<td></td>
<td><span class='fas fa-layer-group'></span></td>
<td>{% trans "Batch" %}</td>
<td>{{ item.batch }}</td>
</tr>
@ -261,7 +261,7 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}
{% endif %}
{% if item.purchase_order %}
<tr>
<td></td>
<td><span class='fas fa-shopping-cart'></span></td>
<td>{% trans "Purchase Order" %}</td>
<td><a href="{% url 'po-detail' item.purchase_order.id %}">{{ item.purchase_order }}</a></td>
</tr>

View File

@ -150,17 +150,31 @@ function loadBomTable(table, options) {
var url = `/part/${row.sub_part}/`;
var html = imageHoverIcon(row.sub_part_detail.thumbnail) + renderLink(row.sub_part_detail.full_name, url);
if (row.sub_part_detail.trackable) {
html += `<span title='{% trans "Trackable part" %}' class='fas fa-directions label-right'></span>`;
var sub_part = row.sub_part_detail;
if (sub_part.trackable) {
html += makeIconBadge('fa-directions', '{% trans "Trackable part" %}');
}
if (sub_part.virtual) {
html += makeIconBadge('fa-ghost', '{% trans "Virtual part" %}');
}
if (sub_part.is_template) {
html += makeIconBadge('fa-clone', '{% trans "Templat part" %}');
}
// Display an extra icon if this part is an assembly
if (row.sub_part_detail.assembly) {
if (sub_part.assembly) {
var text = `<span title='{% trans "Open subassembly" %}' class='fas fa-stream label-right'></span>`;
html += renderLink(text, `/part/${row.sub_part}/bom/`);
}
if (!sub_part.active) {
html += `<span class='label label-warning label-right'>{% trans "Inactive" %}</span>`;
}
return html;
}
}

View File

@ -110,7 +110,7 @@ function loadSupplierPartTable(table, url, options) {
// Query parameters
var params = options.params || {};
// Load 'user' filters
// Load filters
var filters = loadTableFilters("supplier-part");
for (var key in params) {
@ -122,6 +122,7 @@ function loadSupplierPartTable(table, url, options) {
$(table).inventreeTable({
url: url,
method: 'get',
original: params,
queryParams: filters,
name: 'supplierparts',
groupBy: false,
@ -135,6 +136,7 @@ function loadSupplierPartTable(table, url, options) {
sortable: true,
field: 'part_detail.full_name',
title: '{% trans "Part" %}',
switchable: false,
formatter: function(value, row, index, field) {
var url = `/part/${row.part}/`;

View File

@ -61,13 +61,22 @@ function toggleStar(options) {
}
function loadPartVariantTable(table, partId, options) {
function loadPartVariantTable(table, partId, options={}) {
/* Load part variant table
*/
var params = {
ancestor: partId,
};
var params = options.params || {};
params.ancestor = partId;
// Load filters
var filters = loadTableFilters("variants");
for (var key in params) {
filters[key] = params[key];
}
setupFilterList("variants", $(table));
var cols = [
{
@ -104,16 +113,36 @@ function loadPartVariantTable(table, partId, options) {
html += imageHoverIcon(row.thumbnail);
html += renderLink(name, `/part/${row.pk}/`);
if (row.trackable) {
html += makeIconBadge('fa-directions', '{% trans "Trackable part" %}');
}
if (row.virtual) {
html += makeIconBadge('fa-ghost', '{% trans "Virtual part" %}');
}
if (row.is_template) {
html += makeIconBadge('fa-clone', '{% trans "Template part" %}');
}
if (row.assembly) {
html += makeIconBadge('fa-tools', '{% trans "Assembled part" %}');
}
if (!row.active) {
html += `<span class='label label-warning label-right'>{% trans "Inactive" %}</span>`;
}
return html;
},
},
{
field: 'IPN',
title: '{% trans 'IPN' %}',
title: '{% trans "IPN" %}',
},
{
field: 'revision',
title: '{% trans 'Revision' %}',
title: '{% trans "Revision" %}',
},
{
field: 'description',
@ -133,7 +162,7 @@ function loadPartVariantTable(table, partId, options) {
name: 'partvariants',
showColumns: true,
original: params,
queryParams: params,
queryParams: filters,
formatNoMatches: function() { return "{% trans "No variants found" %}"; },
columns: cols,
treeEnable: true,
@ -272,7 +301,7 @@ function loadPartTable(table, url, options={}) {
if (options.checkbox) {
columns.push({
checkbox: true,
title: '{% trans 'Select' %}',
title: '{% trans "Select" %}',
searchable: false,
switchable: false,
});
@ -286,8 +315,9 @@ function loadPartTable(table, url, options={}) {
columns.push({
field: 'name',
title: '{% trans 'Part' %}',
title: '{% trans "Part" %}',
sortable: true,
switchable: false,
formatter: function(value, row, index, field) {
var name = '';
@ -310,20 +340,29 @@ function loadPartTable(table, url, options={}) {
var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/');
if (row.trackable) {
display += makeIconBadge('fa-directions', '{% trans "Trackable part" %}');
}
if (row.virtual) {
display += makeIconBadge('fa-ghost', '{% trans "Virtual part" %}');
}
if (row.is_template) {
display += `<span class='fas fa-clone label-right' title='{% trans "Template part" %}'></span>`;
display += makeIconBadge('fa-clone', '{% trans "Template part" %}');
}
if (row.assembly) {
display += `<span class='fas fa-tools label-right' title='{% trans "Assembled part" %}'></span>`;
display += makeIconBadge('fa-tools', '{% trans "Assembled part" %}');
}
if (row.starred) {
display += `<span class='fas fa-star label-right' title='{% trans "Starred part" %}'></span>`;
display += makeIconBadge('fa-star', '{% trans "Starred part" %}');
}
if (row.salable) {
display += `<span class='fas fa-dollar-sign label-right' title='{% trans "Salable part" %}'></span>`;
display += makeIconBadge('fa-dollar-sign', title='{% trans "Salable part" %}');
}
/*
@ -342,7 +381,7 @@ function loadPartTable(table, url, options={}) {
columns.push({
sortable: true,
field: 'description',
title: '{% trans 'Description' %}',
title: '{% trans "Description" %}',
formatter: function(value, row, index, field) {
if (row.is_template) {
@ -356,7 +395,7 @@ function loadPartTable(table, url, options={}) {
columns.push({
sortable: true,
field: 'category_detail',
title: '{% trans 'Category' %}',
title: '{% trans "Category" %}',
formatter: function(value, row, index, field) {
if (row.category) {
return renderLink(value.pathstring, "/part/category/" + row.category + "/");

View File

@ -11,6 +11,28 @@ function getAvailableTableFilters(tableKey) {
tableKey = tableKey.toLowerCase();
// Filters for "variant" table
if (tableKey == "variants") {
return {
active: {
type: 'bool',
title: '{% trans "Active" %}',
},
template: {
type: 'bool',
title: '{% trans "Template" %}',
},
virtual: {
type: 'bool',
title: '{% trans "Virtual" %}',
},
trackable: {
type: 'bool',
title: '{% trans "Trackable" %}',
},
};
}
// Filters for Bill of Materials table
if (tableKey == "bom") {
return {
@ -194,6 +216,15 @@ function getAvailableTableFilters(tableKey) {
};
}
if (tableKey == 'supplier-part') {
return {
active: {
type: 'bool',
title: '{% trans "Active parts" %}',
}
};
}
// Filters for the "Parts" table
if (tableKey == "parts") {
return {