2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-21 06:16:29 +00:00

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

# Conflicts:
#	InvenTree/InvenTree/urls.py
#	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/part/templates/part/bom.html
#	InvenTree/templates/js/build.js
#	InvenTree/templates/js/table_filters.js
#	InvenTree/templates/stock_table.html
#	tasks.py
This commit is contained in:
Oliver Walters
2020-10-28 22:24:09 +11:00
27 changed files with 1520 additions and 1298 deletions

View File

@ -761,12 +761,26 @@ class BomList(generics.ListCreateAPIView):
if sub_part is not None:
queryset = queryset.filter(sub_part=sub_part)
# Filter by "trackable" status of the sub-part
trackable = params.get('trackable', None)
# Filter by "active" status of the part
part_active = params.get('part_active', None)
if trackable is not None:
trackable = str2bool(trackable)
queryset = queryset.filter(sub_part__trackable=trackable)
if part_active is not None:
part_active = str2bool(part_active)
queryset = queryset.filter(part__active=part_active)
# Filter by "trackable" status of the part
part_trackable = params.get('part_trackable', None)
if part_trackable is not None:
part_trackable = str2bool(part_trackable)
queryset = queryset.filter(part__trackable=part_trackable)
# Filter by "trackable" status of the sub-part
sub_part_trackable = params.get('sub_part_trackable', None)
if sub_part_trackable is not None:
sub_part_trackable = str2bool(sub_part_trackable)
queryset = queryset.filter(sub_part__trackable=sub_part_trackable)
# Filter by whether the BOM line has been validated
validated = params.get('validated', None)

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.7 on 2020-10-27 04:57
import InvenTree.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('part', '0051_bomitem_optional'),
]
operations = [
migrations.AlterField(
model_name='part',
name='link',
field=InvenTree.fields.InvenTreeURLField(blank=True, help_text='Link to external URL', null=True),
),
]

View File

@ -576,7 +576,7 @@ class Part(MPTTModel):
revision = models.CharField(max_length=100, blank=True, null=True, help_text=_('Part revision or version number'))
link = InvenTreeURLField(blank=True, null=True, help_text=_('Link to extenal URL'))
link = InvenTreeURLField(blank=True, null=True, help_text=_('Link to external URL'))
image = StdImageField(
upload_to=rename_part_image,

View File

@ -17,15 +17,15 @@
</tr>
{% for allocation in part.build_order_allocations %}
<tr>
<td><a href="{% url 'build-detail' allocation.build.id %}">{% trans "Build Order" %}: {{ allocation.build.pk }}</a></td>
<td><a href="{% url 'stock-item-detail' allocation.stock_item.id %}">{% trans "Stock Item" %}: {{ allocation.stock_item.id }}</a></td>
<td><a href="{% url 'build-detail' allocation.build.id %}">{% trans "Build Order" %}: {{ allocation.build }}</a></td>
<td><a href="{% url 'stock-item-detail' allocation.stock_item.id %}">{% trans "Stock Item" %}: {{ allocation.stock_item }}</a></td>
<td>{% decimal allocation.quantity %}</td>
</tr>
{% endfor %}
{% for allocation in part.sales_order_allocations %}
<tr>
<td><a href="{% url 'so-detail' allocation.line.order.id %}">{% trans "Sales Order" %}: {{ allocation.line.order.pk }}</a></td>
<td><a href="{% url 'stock-item-detail' allocation.item.id %}">{% trans "Stock Item" %}: {{ allocation.item.id }}</a></td>
<td><a href="{% url 'so-detail' allocation.line.order.id %}">{% trans "Sales Order" %}: {{ allocation.line.order }}</a></td>
<td><a href="{% url 'stock-item-detail' allocation.item.id %}">{% trans "Stock Item" %}: {{ allocation.item }}</a></td>
<td>{% decimal allocation.quantity %}</td>
</tr>
{% endfor %}

View File

@ -32,21 +32,37 @@
</div>
{% endif %}
<div id='button-toolbar' class="btn-group" role="group" aria-label="...">
{% if editing_enabled %}
<button class='btn btn-default action-button' type='button' title='{% trans "Remove selected BOM items" %}' id='bom-item-delete'><span class='fas fa-trash-alt'></span></button>
<button class='btn btn-default action-button' type='button' title='{% trans "Import BOM data" %}' id='bom-upload'><span class='fas fa-file-upload'></span></button>
<button class='btn btn-default action-button' type='button' title='{% trans "New BOM Item" %}' id='bom-item-new'><span class='fas fa-plus-circle'></span></button>
<button class='btn btn-default action-button' type='button' title='{% trans "Finish Editing" %}' id='editing-finished'><span class='fas fa-check-circle'></span></button>
{% elif part.active %}
{% if roles.part.change %}
<button class='btn btn-default action-button' type='button' title='{% trans "Edit BOM" %}' id='edit-bom'><span class='fas fa-edit'></span></button>
{% if part.is_bom_valid == False %}
<button class='btn btn-default action-button' id='validate-bom' title='{% trans "Validate Bill of Materials" %}' type='button'><span class='fas fa-clipboard-check'></span></button>
{% endif %}
{% endif %}
<button title='{% trans "Export Bill of Materials" %}' class='btn btn-default action-button' id='download-bom' type='button'><span class='fas fa-file-download'></span></button>
{% endif %}
<div id='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'>
<span class='fas fa-trash-alt'></span>
</button>
<button class='btn btn-primary' type='button' title='{% trans "Import BOM data" %}' id='bom-upload'>
<span class='fas fa-file-upload'></span> {% trans "Upload" %}
</button>
<button class='btn btn-default' type='button' title='{% trans "New BOM Item" %}' id='bom-item-new'>
<span class='fas fa-plus-circle'></span> {% trans "Add Item" %}
</button>
<button class='btn btn-success' type='button' title='{% trans "Finish Editing" %}' id='editing-finished'>
<span class='fas fa-check-circle'></span> {% trans "Finished" %}
</button>
{% elif part.active %}
{% if roles.part.change %}
<button class='btn btn-primary' type='button' title='{% trans "Edit BOM" %}' id='edit-bom'>
<span class='fas fa-edit'></span> {% trans "Edit" %}
</button>
{% if part.is_bom_valid == False %}
<button class='btn btn-success' id='validate-bom' title='{% trans "Validate Bill of Materials" %}' type='button'>
<span class='fas fa-clipboard-check'></span> {% trans "Validate" %}
</button>
{% endif %}
{% endif %}
<button title='{% trans "Export Bill of Materials" %}' class='btn btn-default' id='download-bom' type='button'>
<span class='fas fa-file-download'></span> {% trans "Export" %}
</button>
{% endif %}
</div>
<div class='filter-list' id='filter-list-bom'>
<!-- Empty div (will be filled out with avilable BOM filters) -->
</div>
@ -187,4 +203,4 @@
{% endif %}
{% endblock %}
{% endblock %}

View File

@ -107,22 +107,24 @@
<hr>
<div id='button-toolbar'>
<div class='button-toolbar container-fluid' style="float: right;">
<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='btn-group'>
<button class='btn btn-default' id='part-export' title='{% trans "Export Part Data" %}'>{% trans "Export" %}</button>
{% if roles.part.add %}
<button class='btn btn-success' id='part-create' title='{% trans "Create new part" %}'>{% 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>
<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>
</div>
<div class='filter-list' id='filter-list-parts'>

View File

@ -11,7 +11,9 @@
<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" %}'>{% trans "Order Part" %}</button>
<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>

View File

@ -11,7 +11,9 @@
<div id='button-toolbar'>
<div class='button-toolbar container-fluid' style='float: right;'>
{% if roles.part.add %}
<button title='{% trans "Add new parameter" %}' class='btn btn-success' id='param-create'>{% trans "New Parameter" %}</button>
<button title='{% trans "Add new parameter" %}' class='btn btn-success' id='param-create'>
<span class='fas fa-plus-circle'></span> {% trans "New Parameter" %}
</button>
{% endif %}
</div>
</div>

View File

@ -10,7 +10,9 @@
<div id='button-toolbar'>
<div class='btn-group'>
<button class="btn btn-success" id='supplier-create'>{% trans "New Supplier Part" %}</button>
<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">

View File

@ -8,7 +8,13 @@
<hr>
<table class="table table-striped table-condensed" id='used-table'>
<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 %}
@ -16,52 +22,10 @@
{% block js_ready %}
{{ block.super }}
$("#used-table").inventreeTable({
formatNoMatches: function() { return "{{ part.full_name }} is not used to make any other parts"; },
queryParams: function(p) {
return {
sub_part: {{ part.id }},
part_detail: true,
}
},
columns: [
{
field: 'pk',
title: 'ID',
visible: false,
switchable: false,
},
{
field: 'part_detail',
title: 'Part',
sortable: true,
formatter: function(value, row, index, field) {
var link = `/part/${value.pk}/bom/`;
var html = imageHoverIcon(row.part_detail.thumbnail) + renderLink(value.full_name, link);
loadUsedInTable('#used-table', {
part_detail: true,
part_id: {{ part.pk }}
});
if (!row.part_detail.active) {
html += "<span class='label label-warning' style='float: right;'>{% trans "INACTIVE" %}</span>";
}
return html;
}
},
{
field: 'part_detail.description',
title: 'Description',
sortable: true,
},
{
sortable: true,
field: 'quantity',
title: 'Uses',
formatter: function(value, row, index, field) {
return parseFloat(value);
},
}
],
url: "{% url 'api-bom-list' %}"
})
{% endblock %}

View File

@ -510,7 +510,7 @@ class PartCreate(AjaxCreateView):
model = Part
form_class = part_forms.EditPartForm
ajax_form_title = _('Create new part')
ajax_form_title = _('Create New Part')
ajax_template_name = 'part/create_part.html'
role_required = 'part.add'