Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters 2020-04-28 10:51:55 +10:00
commit 351e825ba8
46 changed files with 3000 additions and 1688 deletions

View File

@ -384,6 +384,10 @@
padding-bottom: 2px; padding-bottom: 2px;
} }
.action-button {
font-size: 125%;
}
.action-buttons .btn { .action-buttons .btn {
font-size: 175%; font-size: 175%;
align-content: center; align-content: center;

View File

@ -237,11 +237,11 @@ function loadBomTable(table, options) {
cols.push({ cols.push({
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
var bValidate = "<button title='Validate BOM Item' class='bom-validate-button btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-check'/></button>"; var bValidate = "<button title='Validate BOM Item' class='bom-validate-button btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='fas fa-check-circle icon-blue'/></button>";
var bValid = "<span class='glyphicon glyphicon-ok'/>"; var bValid = "<span title='This line has been validated' class='fas fa-check-double icon-green'/>";
var bEdit = "<button title='Edit BOM Item' class='bom-edit-button btn btn-default btn-glyph' type='button' url='/part/bom/" + row.pk + "/edit'><span class='glyphicon glyphicon-edit'/></button>"; var bEdit = "<button title='Edit BOM Item' class='bom-edit-button btn btn-default btn-glyph' type='button' url='/part/bom/" + row.pk + "/edit'><span class='fas fa-edit'/></button>";
var bDelt = "<button title='Delete BOM Item' class='bom-delete-button btn btn-default btn-glyph' type='button' url='/part/bom/" + row.pk + "/delete'><span class='glyphicon glyphicon-trash'/></button>"; var bDelt = "<button title='Delete BOM Item' class='bom-delete-button btn btn-default btn-glyph' type='button' url='/part/bom/" + row.pk + "/delete'><span class='fas fa-trash-alt icon-red'/></button>";
var html = "<div class='btn-group' role='group'>"; var html = "<div class='btn-group' role='group'>";

View File

@ -119,8 +119,8 @@ function loadAllocationTable(table, part_id, part, url, required, button) {
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
var html = parseFloat(value); var html = parseFloat(value);
var bEdit = "<button class='btn item-edit-button btn-sm' type='button' title='Edit stock allocation' url='/build/item/" + row.pk + "/edit/'><span class='glyphicon glyphicon-small glyphicon-edit'></span></button>"; var bEdit = "<button class='btn item-edit-button btn-sm' type='button' title='Edit stock allocation' url='/build/item/" + row.pk + "/edit/'><span class='fas fa-edit'></span></button>";
var bDel = "<button class='btn item-del-button btn-sm' type='button' title='Delete stock allocation' url='/build/item/" + row.pk + "/delete/'><span class='glyphicon glyphicon-small glyphicon-trash'></span></button>"; var bDel = "<button class='btn item-del-button btn-sm' type='button' title='Delete stock allocation' url='/build/item/" + row.pk + "/delete/'><span class='fas fa-trash-alt icon-red'></span></button>";
html += "<div class='btn-group' style='float: right;'>" + bEdit + bDel + "</div>"; html += "<div class='btn-group' style='float: right;'>" + bEdit + bDel + "</div>";

View File

@ -148,7 +148,7 @@ function loadSupplierPartTable(table, url, options) {
field: 'SKU', field: 'SKU',
title: "Supplier Part", title: "Supplier Part",
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
return renderLink(value, row.url); return renderLink(value, `/supplier-part/${row.pk}/`);
} }
}, },
{ {

View File

@ -475,8 +475,8 @@ function loadStockTrackingTable(table, options) {
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
// Manually created entries can be edited or deleted // Manually created entries can be edited or deleted
if (!row.system) { if (!row.system) {
var bEdit = "<button title='Edit tracking entry' class='btn btn-entry-edit btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/edit/'><span class='glyphicon glyphicon-edit'/></button>"; var bEdit = "<button title='Edit tracking entry' class='btn btn-entry-edit btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/edit/'><span class='fas fa-edit'/></button>";
var bDel = "<button title='Delete tracking entry' class='btn btn-entry-delete btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/delete/'><span class='glyphicon glyphicon-trash'/></button>"; var bDel = "<button title='Delete tracking entry' class='btn btn-entry-delete btn-default btn-glyph' type='button' url='/stock/track/" + row.pk + "/delete/'><span class='fas fa-trash-alt icon-red'/></button>";
return "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>"; return "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";
} else { } else {

View File

@ -25,8 +25,8 @@ from InvenTree.status_codes import BuildStatus, StockStatus
from InvenTree.fields import InvenTreeURLField from InvenTree.fields import InvenTreeURLField
from InvenTree.helpers import decimal2string from InvenTree.helpers import decimal2string
from stock.models import StockItem from stock import models as StockModels
from part.models import Part, BomItem from part import models as PartModels
class Build(MPTTModel): class Build(MPTTModel):
@ -189,7 +189,11 @@ class Build(MPTTModel):
# How many parts required for this build? # How many parts required for this build?
q_required = item.quantity * self.quantity q_required = item.quantity * self.quantity
stock = StockItem.objects.filter(part=item.sub_part) # Grab a list of StockItem objects which are "in stock"
stock = StockModels.StockItem.objects.filter(StockModels.StockItem.IN_STOCK_FILTER)
# Filter by part reference
stock = stock.filter(part=item.sub_part)
# Ensure that the available stock items are in the correct location # Ensure that the available stock items are in the correct location
if self.take_from is not None: if self.take_from is not None:
@ -278,7 +282,7 @@ class Build(MPTTModel):
if self.part.trackable and serial_numbers: if self.part.trackable and serial_numbers:
# Add new serial numbers # Add new serial numbers
for serial in serial_numbers: for serial in serial_numbers:
item = StockItem.objects.create( item = StockModels.StockItem.objects.create(
part=self.part, part=self.part,
build=self, build=self,
location=location, location=location,
@ -292,7 +296,7 @@ class Build(MPTTModel):
else: else:
# Add stock of the newly created item # Add stock of the newly created item
item = StockItem.objects.create( item = StockModels.StockItem.objects.create(
part=self.part, part=self.part,
build=self, build=self,
location=location, location=location,
@ -338,9 +342,9 @@ class Build(MPTTModel):
""" """
try: try:
item = BomItem.objects.get(part=self.part.id, sub_part=part.id) item = PartModels.BomItem.objects.get(part=self.part.id, sub_part=part.id)
q = item.quantity q = item.quantity
except BomItem.DoesNotExist: except PartModels.BomItem.DoesNotExist:
q = 0 q = 0
return q * self.quantity return q * self.quantity
@ -461,7 +465,7 @@ class BuildItem(models.Model):
if self.stock_item.serial and not self.quantity == 1: if self.stock_item.serial and not self.quantity == 1:
errors['quantity'] = _('Quantity must be 1 for serialized stock') errors['quantity'] = _('Quantity must be 1 for serialized stock')
except (StockItem.DoesNotExist, Part.DoesNotExist): except (StockModels.StockItem.DoesNotExist, PartModels.Part.DoesNotExist):
pass pass
if len(errors) > 0: if len(errors) > 0:

View File

@ -1,8 +1,9 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load static %} {% load static %}
{% load i18n %}
{% block page_title %} {% block page_title %}
InvenTree | Build List InvenTree | {% trans "Build Orders" %}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@ -10,7 +11,7 @@ InvenTree | Build List
<div class='row'> <div class='row'>
<div class='col-sm-6'> <div class='col-sm-6'>
<h3>Part Builds</h3> <h3>{% trans "Build Orders" %}</h3>
</div> </div>
<div class='col-sm-6'> <div class='col-sm-6'>
@ -20,7 +21,7 @@ InvenTree | Build List
<div id='button-toolbar'> <div id='button-toolbar'>
<div class='button-toolbar container-fluid' style='float: right;'> <div class='button-toolbar container-fluid' style='float: right;'>
<button type='button' class="btn btn-success" id='new-build'>Start New Build</button> <button type='button' class="btn btn-success" id='new-build'>{% trans "New Build Order" %}</button>
<div class='filter-list' id='filter-list-build'> <div class='filter-list' id='filter-list-build'>
<!-- An empty div in which the filter list will be constructed --> <!-- An empty div in which the filter list will be constructed -->
</div> </div>

View File

@ -30,7 +30,7 @@
<h4>{% trans "Build Notes" %}</h4> <h4>{% trans "Build Notes" %}</h4>
</div> </div>
<div class='col-sm-6'> <div class='col-sm-6'>
<button title='{% trans "Edit notes" %}' class='btn btn-default btn-glyph float-right' id='edit-notes'><span class='glyphicon glyphicon-edit'></span></button> <button title='{% trans "Edit notes" %}' class='btn btn-default action-button float-right' id='edit-notes'><span class='fas fa-edit'></span></button>
</div> </div>
</div> </div>
<hr> <hr>

View File

@ -11,6 +11,6 @@
<a href="{% url 'build-output' build.id %}">{% trans "Build Outputs" %}{% if build.output_count > 0%}<span class='badge'>{{ build.output_count }}</span>{% endif %}</a> <a href="{% url 'build-output' build.id %}">{% trans "Build Outputs" %}{% if build.output_count > 0%}<span class='badge'>{{ build.output_count }}</span>{% endif %}</a>
</li> </li>
<li{% if tab == 'notes' %} class='active'{% endif %}> <li{% if tab == 'notes' %} class='active'{% endif %}>
<a href="{% url 'build-notes' build.id %}">{% trans "Notes" %}{% if build.notes %} <span class='glyphicon glyphicon-small glyphicon-info-sign'></span>{% endif %}</a> <a href="{% url 'build-notes' build.id %}">{% trans "Notes" %}{% if build.notes %} <span class='fas fa-info-circle'></span>{% endif %}</a>
</li> </li>
</ul> </ul>

View File

@ -141,10 +141,6 @@ class TestBuildViews(TestCase):
response = self.client.get(reverse('build-index')) response = self.client.get(reverse('build-index'))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
content = str(response.content)
self.assertIn("Part Builds", content)
def test_build_detail(self): def test_build_detail(self):
""" Test the detail view for a Build object """ """ Test the detail view for a Build object """

View File

@ -27,7 +27,7 @@
<h4>{% trans "Company Notes" %}</h4> <h4>{% trans "Company Notes" %}</h4>
</div> </div>
<div class='col-sm-6'> <div class='col-sm-6'>
<button title='{% trans "Edit notes" %}' class='btn btn-default btn-glyph float-right' id='edit-notes'><span class='glyphicon glyphicon-edit'></span></button> <button title='{% trans "Edit notes" %}' class='btn btn-default action-button float-right' id='edit-notes'><span class='fas fa-edit'></span></button>
</div> </div>
</div> </div>
<hr> <hr>

View File

@ -19,12 +19,12 @@ src="{% static 'img/blank_image.png' %}"
<h3>{% trans "Supplier Part" %}</h3> <h3>{% trans "Supplier Part" %}</h3>
<p>{{ part.supplier.name }} - {{ part.SKU }}</p> <p>{{ part.supplier.name }} - {{ part.SKU }}</p>
<div class='btn-row'> <div class='btn-row'>
<div class='btn-group'> <div class='btn-group action-buttons' role='group'>
<button type='button' class='btn btn-default btn-glyph' id='edit-part' title='Edit supplier part'> <button type='button' class='btn btn-default btn-glyph' id='edit-part' title='{% trans "Edit supplier part" %}'>
<span class='glyphicon glyphicon-edit'/> <span class='fas fa-edit icon-green'/>
</button> </button>
<button type='button' class='btn btn-default btn-glyph' id='delete-part' title='Delete supplier part'> <button type='button' class='btn btn-default btn-glyph' id='delete-part' title='{% trans "Delete supplier part" %}'>
<span class='glyphicon glyphicon-trash'/> <span class='fas fa-trash-alt icon-red'/>
</button> </button>
</div> </div>
</div> </div>

View File

@ -36,8 +36,8 @@
{% decimal pb.cost %} {% decimal pb.cost %}
{% if pb.currency %}{{ pb.currency.suffix }}{% endif %} {% if pb.currency %}{{ pb.currency.suffix }}{% endif %}
<div class='btn-group' style='float: right;'> <div class='btn-group' style='float: right;'>
<button title='Edit Price Break' class='btn btn-default btn-sm pb-edit-button' type='button' url="{% url 'price-break-edit' pb.id %}"><span class='glyphicon glyphicon-edit'></span></button> <button title='Edit Price Break' class='btn btn-default btn-sm pb-edit-button' type='button' url="{% url 'price-break-edit' pb.id %}"><span class='fas fa-edit icon-green'></span></button>
<button title='Delete Price Break' class='btn btn-default btn-sm pb-delete-button' type='button' url="{% url 'price-break-delete' pb.id %}"><span class='glyphicon glyphicon-trash'></span></button> <button title='Delete Price Break' class='btn btn-default btn-sm pb-delete-button' type='button' url="{% url 'price-break-delete' pb.id %}"><span class='fas fa-trash-alt icon-red'></span></button>
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -23,6 +23,6 @@
</li> </li>
{% endif %} {% endif %}
<li{% if tab == 'notes' %} class='active'{% endif %}> <li{% if tab == 'notes' %} class='active'{% endif %}>
<a href="{% url 'company-notes' company.id %}">{% trans "Notes" %}{% if company.notes %} <span class='glyphicon glyphicon-small glyphicon-info-sign'></span>{% endif %}</a> <a href="{% url 'company-notes' company.id %}">{% trans "Notes" %}{% if company.notes %} <span class='fas fa-info-circle'></span>{% endif %}</a>
</li> </li>
</ul> </ul>

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

@ -29,7 +29,7 @@
<h4>{% trans "Order Notes" %}</h4> <h4>{% trans "Order Notes" %}</h4>
</div> </div>
<div class='col-sm-6'> <div class='col-sm-6'>
<button title='{% trans "Edit notes" %}' class='btn btn-default btn-glyph float-right' id='edit-notes'><span class='glyphicon glyphicon-edit'></span></button> <button title='{% trans "Edit notes" %}' class='btn btn-default action-button float-right' id='edit-notes'><span class='fas fa-edit'></span></button>
</div> </div>
</div> </div>
<hr> <hr>

View File

@ -40,7 +40,7 @@
</td> </td>
<td> <td>
<button class='btn btn-default btn-create' onClick='newSupplierPartFromOrderWizard()' id='new_supplier_part_{{ part.id }}' title='Create new supplier part for {{ part }}' type='button'> <button class='btn btn-default btn-create' onClick='newSupplierPartFromOrderWizard()' id='new_supplier_part_{{ part.id }}' title='Create new supplier part for {{ part }}' type='button'>
<span part-id='{{ part.id }}' class='glyphicon glyphicon-small glyphicon-plus'></span> <span part-id='{{ part.id }}' class='fas fa-plus-circle'></span>
</button> </button>
</td> </td>
<td> <td>
@ -67,7 +67,7 @@
</td> </td>
<td> <td>
<button class='btn btn-default btn-remove' onclick='removeOrderRowFromOrderWizard()' id='del_item_{{ part.id }}' title='Remove part' type='button'> <button class='btn btn-default btn-remove' onclick='removeOrderRowFromOrderWizard()' id='del_item_{{ part.id }}' title='Remove part' type='button'>
<span row='part_row_{{ part.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row='part_row_{{ part.id }}' class='fas fa-trash-alt icon-red'></span>
</button> </button>
</td> </td>
</tr> </tr>

View File

@ -45,7 +45,7 @@
title='Create new purchase order for {{ supplier.name }}' title='Create new purchase order for {{ supplier.name }}'
type='button' type='button'
onclick='newPurchaseOrderFromOrderWizard()'> onclick='newPurchaseOrderFromOrderWizard()'>
<span supplier-id='{{ supplier.id }}' class='glyphicon glyphicon-small glyphicon-plus'></span> <span supplier-id='{{ supplier.id }}' class='fas fa-plus-circle'></span>
</button> </button>
</td> </td>
<td> <td>

View File

@ -8,7 +8,7 @@
{% include 'order/po_tabs.html' with tab='attachments' %} {% include 'order/po_tabs.html' with tab='attachments' %}
<h4>{% trans "Purchase Order Attachments" %} <h4>{% trans "Purchase Order Attachments" %}</h4>
<hr> <hr>
@ -34,10 +34,10 @@
<td> <td>
<div class='btn-group' style='float: right;'> <div class='btn-group' style='float: right;'>
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'po-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'> <button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'po-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
<span class='glyphicon glyphicon-edit'/> <span class='fas fa-edit'/>
</button> </button>
<button type='button' class='btn btn-default btn-glyph attachment-delete-button' url="{% url 'po-attachment-delete' attachment.id %}" data-toggle='tooltip' title='{% trans "Delete attachment" %}'> <button type='button' class='btn btn-default btn-glyph attachment-delete-button' url="{% url 'po-attachment-delete' attachment.id %}" data-toggle='tooltip' title='{% trans "Delete attachment" %}'>
<span class='glyphicon glyphicon-trash'/> <span class='fas fa-trash-alt icon-red'/>
</button> </button>
</div> </div>
</td> </td>

View File

@ -12,6 +12,6 @@
</a> </a>
</li> </li>
<li{% ifequal tab 'notes' %} class='active'{% endifequal %}> <li{% ifequal tab 'notes' %} class='active'{% endifequal %}>
<a href="{% url 'po-notes' order.id %}">{% trans "Notes" %}{% if order.notes %} <span class='glyphicon glyphicon-small glyphicon-info-sign'></span>{% endif %}</a> <a href="{% url 'po-notes' order.id %}">{% trans "Notes" %}{% if order.notes %} <span class='fas fa-info-circle'></span>{% endif %}</a>
</li> </li>
</ul> </ul>

View File

@ -41,7 +41,7 @@ Receive outstanding parts for <b>{{ order }}</b> - <i>{{ order.description }}</i
</td> </td>
<td> <td>
<button class='btn btn-default btn-remove' onClick="removeOrderRowFromOrderWizard()" id='del_item_{{ line.id }}' title='Remove line' type='button'> <button class='btn btn-default btn-remove' onClick="removeOrderRowFromOrderWizard()" id='del_item_{{ line.id }}' title='Remove line' type='button'>
<span row='line_row_{{ line.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row='line_row_{{ line.id }}' class='fas fa-trash-alt icon-red'></span>
</button> </button>
</td> </td>
</tr> </tr>

View File

@ -34,7 +34,7 @@ InvenTree | {% trans "Sales Order" %}
<h4>{% trans "Order Notes" %}</h4> <h4>{% trans "Order Notes" %}</h4>
</div> </div>
<div class='col-sm-6'> <div class='col-sm-6'>
<button title='{% trans "Edit notes" %}' class='btn btn-default btn-glyph float-right' id='edit-notes'><span class='glyphicon glyphicon-edit'></span></button> <button title='{% trans "Edit notes" %}' class='btn btn-default action-button float-right' id='edit-notes'><span class='fas fa-edit'></span></button>
</div> </div>
</div> </div>
<hr> <hr>

View File

@ -34,10 +34,10 @@
<td> <td>
<div class='btn-group' style='float: right;'> <div class='btn-group' style='float: right;'>
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'so-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'> <button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'so-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
<span class='glyphicon glyphicon-edit'/> <span class='fas fa-edit'/>
</button> </button>
<button type='button' class='btn btn-default btn-glyph attachment-delete-button' url="{% url 'so-attachment-delete' attachment.id %}" data-toggle='tooltip' title='{% trans "Delete attachment" %}'> <button type='button' class='btn btn-default btn-glyph attachment-delete-button' url="{% url 'so-attachment-delete' attachment.id %}" data-toggle='tooltip' title='{% trans "Delete attachment" %}'>
<span class='glyphicon glyphicon-trash'/> <span class='fas fa-trash-alt icon-red'/>
</button> </button>
</div> </div>
</td> </td>

View File

@ -20,6 +20,6 @@
</a> </a>
</li> </li>
<li{% ifequal tab 'notes' %} class='active'{% endifequal %}> <li{% ifequal tab 'notes' %} class='active'{% endifequal %}>
<a href="{% url 'so-notes' order.id %}">{% trans "Notes" %}{% if order.notes %} <span class='glyphicon glyphicon-small glyphicon-info-sign'></span>{% endif %}</a> <a href="{% url 'so-notes' order.id %}">{% trans "Notes" %}{% if order.notes %} <span class='fas fa-info-circle'></span>{% endif %}</a>
</li> </li>
</ul> </ul>

View File

@ -234,7 +234,7 @@ class PurchaseOrderNotes(UpdateView):
def get_success_url(self): def get_success_url(self):
return reverse('purchase-order-notes', kwargs={'pk': self.get_object().id}) return reverse('po-notes', kwargs={'pk': self.get_object().id})
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

View File

@ -13,7 +13,7 @@ from django.urls import reverse
from django.db import models, transaction from django.db import models, transaction
from django.db.models import Sum from django.db.models import Sum
from django.db.models import prefetch_related_objects from django.db.models.functions import Coalesce
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -41,6 +41,8 @@ from InvenTree.helpers import decimal2string, normalize
from InvenTree.status_codes import BuildStatus, StockStatus, PurchaseOrderStatus from InvenTree.status_codes import BuildStatus, StockStatus, PurchaseOrderStatus
from build import models as BuildModels
from order import models as OrderModels
from company.models import SupplierPart from company.models import SupplierPart
from stock import models as StockModels from stock import models as StockModels
@ -502,8 +504,7 @@ class Part(models.Model):
""" """
total = self.total_stock total = self.total_stock
total -= self.allocation_count()
total -= self.allocation_count
return max(total, 0) return max(total, 0)
@ -594,46 +595,47 @@ class Part(models.Model):
return quantity return quantity
@property def build_order_allocations(self):
def build_allocation(self): """
""" Return list of builds to which this part is allocated Return all 'BuildItem' objects which allocate this part to Build objects
""" """
builds = [] return BuildModels.BuildItem.objects.filter(stock_item__part__id=self.id)
for item in self.used_in.all().prefetch_related('part__builds'): def build_order_allocation_count(self):
"""
active = item.part.active_builds Return the total amount of this part allocated to build orders
for build in active:
b = {}
b['build'] = build
b['quantity'] = item.quantity * build.quantity
builds.append(b)
prefetch_related_objects(builds, 'build_items')
return builds
@property
def allocated_build_count(self):
""" Return the total number of this part that are allocated for builds
""" """
return sum([a['quantity'] for a in self.build_allocation]) query = self.build_order_allocations().aggregate(total=Coalesce(Sum('quantity'), 0))
return query['total']
def sales_order_allocations(self):
"""
Return all sales-order-allocation objects which allocate this part to a SalesOrder
"""
return OrderModels.SalesOrderAllocation.objects.filter(item__part__id=self.id)
def sales_order_allocation_count(self):
"""
Return the tutal quantity of this part allocated to sales orders
"""
query = self.sales_order_allocations().aggregate(total=Coalesce(Sum('quantity'), 0))
return query['total']
@property
def allocation_count(self): def allocation_count(self):
""" Return true if any of this part is allocated: """
Return the total quantity of stock allocated for this part,
- To another build against both build orders and sales orders.
- To a customer order
""" """
return sum([ return sum([
self.allocated_build_count, self.build_order_allocation_count(),
self.sales_order_allocation_count(),
]) ])
@property @property
@ -645,7 +647,7 @@ class Part(models.Model):
- belongs_to is None - belongs_to is None
""" """
return self.stock_items.filter(StockModels.StockItem.IN_STOCK_FILTER).exclude(status__in=StockStatus.UNAVAILABLE_CODES) return self.stock_items.filter(StockModels.StockItem.IN_STOCK_FILTER)
@property @property
def total_stock(self): def total_stock(self):

View File

@ -1,24 +1,32 @@
{% extends "part/part_base.html" %} {% extends "part/part_base.html" %}
{% block details %}
{% load status_codes %} {% load status_codes %}
{% load i18n %}
{% load inventree_extras %}
{% block details %}
{% include "part/tabs.html" with tab="allocation" %} {% include "part/tabs.html" with tab="allocation" %}
<h4>Part Allocation</h4> <h4>{% trans "Part Stock Allocations" %}</h4>
<table class='table table-striped table-condensed' id='build-table'> <table class='table table-striped table-condensed' id='build-table'>
<tr> <tr>
<th>Build</th> <th>{% trans "Order" %}</th>
<th>Making</th> <th>{% trans "Stock Item" %}</th>
<th>Allocated</th> <th>{% trans "Quantity" %}</th>
<th>Status</th>
</tr> </tr>
{% for allocation in part.build_allocation %} {% for allocation in part.build_order_allocations %}
<tr> <tr>
<td><a href="{% url 'build-detail' allocation.build.id %}">{{ allocation.build.title }}</a></td> <td><a href="{% url 'build-detail' allocation.build.id %}">{% trans "Build Order" %}: {{ allocation.build.pk }}</a></td>
<td>{{ allocation.build.quantity }} &times <a href="{% url 'part-detail' allocation.build.part.id %}">{{ allocation.build.part.full_name }}</a></td> <td><a href="{% url 'stock-item-detail' allocation.stock_item.id %}">{% trans "Stock Item" %}: {{ allocation.stock_item.id }}</a></td>
<td>{{ allocation.quantity }}</td> <td>{% decimal allocation.quantity %}</td>
<td>{% build_status_label allocation.build.status %}</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>{% decimal allocation.quantity %}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
@ -30,23 +38,16 @@
$("#build-table").inventreeTable({ $("#build-table").inventreeTable({
columns: [ columns: [
{ {
title: 'Build', title: '{% trans "Order" %}',
sortable: true, sortable: true,
}, },
{ {
title: 'Making', title: '{% trans "Stock Item" %}',
sortable: true, sortable: true,
}, },
{ {
title: 'Allocated', title: '{% trans "Quantity" %}',
sortable: false, sortable: true,
formatter: function(value, row, index, field) {
return parseFloat(value);
},
},
{
title: 'Status',
sortable: false,
} }
] ]
}); });

View File

@ -32,10 +32,10 @@
<td> <td>
<div class='btn-group' style='float: right;'> <div class='btn-group' style='float: right;'>
<button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'part-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'> <button type='button' class='btn btn-default btn-glyph attachment-edit-button' url="{% url 'part-attachment-edit' attachment.id %}" data-toggle='tooltip' title='{% trans "Edit attachment" %}'>
<span class='glyphicon glyphicon-edit'/> <span class='fas fa-edit'/>
</button> </button>
<button type='button' class='btn btn-default btn-glyph attachment-delete-button' url="{% url 'part-attachment-delete' attachment.id %}" data-toggle='tooltip' title='{% trans "Delete attachment" %}'> <button type='button' class='btn btn-default btn-glyph attachment-delete-button' url="{% url 'part-attachment-delete' attachment.id %}" data-toggle='tooltip' title='{% trans "Delete attachment" %}'>
<span class='glyphicon glyphicon-trash'/> <span class='fas fa-trash-alt icon-red'/>
</button> </button>
</div> </div>
</td> </td>

View File

@ -1,5 +1,6 @@
{% extends "part/part_base.html" %} {% extends "part/part_base.html" %}
{% load static %} {% load static %}
{% load i18n %}
{% block css %} {% block css %}
@ -9,7 +10,7 @@
{% include 'part/tabs.html' with tab='bom' %} {% include 'part/tabs.html' with tab='bom' %}
<h3>Bill of Materials</h3> <h3>{% trans "Bill of Materials" %}</h3>
{% if part.has_complete_bom_pricing == False %} {% if part.has_complete_bom_pricing == False %}
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
@ -33,18 +34,16 @@
<div id='button-toolbar' class="btn-group" role="group" aria-label="..."> <div id='button-toolbar' class="btn-group" role="group" aria-label="...">
{% if editing_enabled %} {% if editing_enabled %}
<button class='btn btn-default' type='button' title='Remove selected BOM items' id='bom-item-delete'><span class='glyphicon glyphicon-trash'></span></button> <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>
<a href="{% url 'upload-bom' part.id %}"> <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' type='button' title='Import BOM data' id='bom-upload'><span class='glyphicon glyphicon-open-file'></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>
</a> <button class='btn btn-default action-button' type='button' title='{% trans "Finish Editing" %}' id='editing-finished'><span class='fas fa-check-circle'></span></button>
<button class='btn btn-default' type='button' title='New BOM Item' id='bom-item-new'><span class='glyphicon glyphicon-plus'></span></button>
<button class='btn btn-default' type='button' title='Finish Editing' id='editing-finished'><span class='glyphicon glyphicon-ok'></span></button>
{% elif part.active %} {% elif part.active %}
<button class='btn btn-default' type='button' title='Edit BOM' id='edit-bom'><span class='glyphicon glyphicon-edit'></span></button> <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 %} {% if part.is_bom_valid == False %}
<button class='btn btn-default' id='validate-bom' type='button'><span class='glyphicon glyphicon-check'></span></button> <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='Export BOM' class='btn btn-default' id='download-bom' type='button'><span class='glyphicon glyphicon-download-alt'></span></button> <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 %} {% endif %}
</div> </div>
@ -76,6 +75,10 @@
location.href = "{% url 'part-bom' part.id %}"; location.href = "{% url 'part-bom' part.id %}";
}); });
$('#bom-upload').click(function() {
location.href = "{% url 'upload-bom' part.id %}";
});
$("#bom-item-new").click(function () { $("#bom-item-new").click(function () {
launchModalForm( launchModalForm(
"{% url 'bom-item-create' %}?parent={{ part.id }}", "{% url 'bom-item-create' %}?parent={{ part.id }}",

View File

@ -38,7 +38,7 @@
<input type='hidden' name='col_name_{{ forloop.counter0 }}' value='{{ col.name }}'/> <input type='hidden' name='col_name_{{ forloop.counter0 }}' value='{{ col.name }}'/>
{{ col.name }} {{ col.name }}
<button class='btn btn-default btn-remove' onClick='removeColFromBomWizard()' id='del_col_{{ forloop.counter0 }}' style='display: inline; float: right;' title='Remove column'> <button class='btn btn-default btn-remove' onClick='removeColFromBomWizard()' id='del_col_{{ forloop.counter0 }}' style='display: inline; float: right;' title='Remove column'>
<span col_id='{{ forloop.counter0 }}' class='glyphicon glyphicon-small glyphicon-remove'></span> <span col_id='{{ forloop.counter0 }}' class='fas fa-trash-alt icon-red'></span>
</button> </button>
</div> </div>
</th> </th>
@ -67,7 +67,7 @@
<tr> <tr>
<td> <td>
<button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'> <button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'>
<span row_id='{{ forloop.counter }}' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row_id='{{ forloop.counter }}' class='fas fa-trash-alt icon-red'></span>
</button> </button>
</td> </td>
<td>{{ forloop.counter }}</td> <td>{{ forloop.counter }}</td>

View File

@ -48,7 +48,7 @@
<tr {% if row.errors %} style='background: #ffeaea;'{% endif %} part-name='{{ row.part_name }}' part-description='{{ row.description }}' part-select='#select_part_{{ row.index }}'> <tr {% if row.errors %} style='background: #ffeaea;'{% endif %} part-name='{{ row.part_name }}' part-description='{{ row.description }}' part-select='#select_part_{{ row.index }}'>
<td> <td>
<button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'> <button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'>
<span row_id='{{ forloop.counter }}' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row_id='{{ forloop.counter }}' class='fas fa-trash-alt icon-red'></span>
</button> </button>
</td> </td>
<td> <td>
@ -58,7 +58,7 @@
<td> <td>
{% if item.column.guess == 'Part' %} {% if item.column.guess == 'Part' %}
<button class='btn btn-default btn-create' onClick='newPartFromBomWizard()' id='new_part_row_{{ row.index }}' title='Create new part' type='button'> <button class='btn btn-default btn-create' onClick='newPartFromBomWizard()' id='new_part_row_{{ row.index }}' title='Create new part' type='button'>
<span row_id='{{ row.index }}' class='glyphicon glyphicon-small glyphicon-plus'/> <span row_id='{{ row.index }}' class='fas fa-trash-alt icon-red'/>
</button> </button>
<select class='select bomselect' id='select_part_{{ row.index }}' name='part_{{ row.index }}'> <select class='select bomselect' id='select_part_{{ row.index }}' name='part_{{ row.index }}'>

View File

@ -29,7 +29,7 @@
<h4>{% trans "Part Notes" %}</h4> <h4>{% trans "Part Notes" %}</h4>
</div> </div>
<div class='col-sm-6'> <div class='col-sm-6'>
<button title='{% trans "Edit notes" %}' class='btn btn-default btn-glyph float-right' id='edit-notes'><span class='glyphicon glyphicon-edit'></span></button> <button title='{% trans "Edit notes" %}' class='btn btn-default action-button float-right' id='edit-notes'><span class='fas fa-edit'></span></button>
</div> </div>
</div> </div>
<hr> <hr>

View File

@ -1,24 +1,25 @@
{% extends "part/part_base.html" %} {% extends "part/part_base.html" %}
{% load static %} {% load static %}
{% load i18n %}
{% block details %} {% block details %}
{% include "part/tabs.html" with tab='params' %} {% include "part/tabs.html" with tab='params' %}
<h4>Part Parameters</h4> <h4>{% trans "Part Parameters" %}</h4>
<hr> <hr>
<div id='button-toolbar'> <div id='button-toolbar'>
<div class='button-toolbar container-fluid' style='float: right;'> <div class='button-toolbar container-fluid' style='float: right;'>
<button class='btn btn-success' id='param-create'>New Parameter</button> <button title='{% trans "Add new parameter" %}' class='btn btn-success' id='param-create'>{% trans "New Parameter" %}</button>
</div> </div>
</div> </div>
<table id='param-table' class='table table-condensed table-striped' data-toolbar='#button-toolbar'> <table id='param-table' class='table table-condensed table-striped' data-toolbar='#button-toolbar'>
<thead> <thead>
<tr> <tr>
<th data-field='name' data-serachable='true'>Name</th> <th data-field='name' data-serachable='true'>{% trans "Name" %}</th>
<th data-field='value' data-searchable='true'>Value</th> <th data-field='value' data-searchable='true'>{% trans "Value" %}</th>
<th data-field='units' data-searchable='true'>Units</th> <th data-field='units' data-searchable='true'>{% trans "Units" %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -29,8 +30,8 @@
<td> <td>
{{ param.template.units }} {{ param.template.units }}
<div class='btn-group' style='float: right;'> <div class='btn-group' style='float: right;'>
<button title='Edit' class='btn btn-default btn-glyph param-edit' url="{% url 'part-param-edit' param.id %}" type='button'><span class='glyphicon glyphicon-edit'/></button> <button title='{% trans "Edit" %}' class='btn btn-default btn-glyph param-edit' url="{% url 'part-param-edit' param.id %}" type='button'><span class='fas fa-edit'/></button>
<button title='Delete' class='btn btn-default btn-glyph param-delete' url="{% url 'part-param-delete' param.id %}" type='button'><span class='glyphicon glyphicon-trash'/></button> <button title='{% trans "Delete" %}' class='btn btn-default btn-glyph param-delete' url="{% url 'part-param-delete' param.id %}" type='button'><span class='fas fa-trash-alt icon-red'/></button>
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -13,8 +13,8 @@
</div> </div>
<div class='btn-row part-thumb-overlay'> <div class='btn-row part-thumb-overlay'>
<div class='btn-group'> <div class='btn-group'>
<button type='button' class='btn btn-default btn-glyph' title="{% trans 'Select from existing images' %}" id='part-image-select'><span class='glyphicon glyphicon-th'></span></button> <button type='button' class='btn btn-default btn-glyph' title="{% trans 'Select from existing images' %}" id='part-image-select'><span class='fas fa-th'></span></button>
<button type='button' class='btn btn-default btn-glyph' title="{% trans 'Upload new image' %}" id='part-image-upload'><span class='glyphicon glyphicon-upload'></span></button> <button type='button' class='btn btn-default btn-glyph' title="{% trans 'Upload new image' %}" id='part-image-upload'><span class='fas fa-file-image'></span></button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,17 +1,18 @@
{% extends "modal_form.html" %} {% extends "modal_form.html" %}
{% load i18n %}
{% block form %} {% block form %}
<form method="post" action='' class='js-modal-form' enctype="multipart/form-data"> <form method="post" action='' class='js-modal-form' enctype="multipart/form-data">
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
<label class='control-label'>Parts</label> <label class='control-label'>Parts</label>
<p class='help-block'>Set category for the following parts</p> <p class='help-block'>{% trans "Set category for the following parts" %}</p>
<table class='table table-striped'> <table class='table table-striped'>
<tr> <tr>
<th>Part</th> <th>{% trans "Part" %}</th>
<th>Description</th> <th>{% trans "Description" %}</th>
<th>Category</th> <th>{% trans "Category" %}</th>
<th> <th>
</tr> </tr>
{% for part in parts %} {% for part in parts %}
@ -28,8 +29,8 @@
{{ part.category.pathstring }} {{ part.category.pathstring }}
</td> </td>
<td> <td>
<button class='btn btn-default btn-remove' onClick='removeRowFromModalForm()' title='Remove part' type='button'> <button class='btn btn-default btn-remove' onClick='removeRowFromModalForm()' title='{% trans "Remove part" %}' type='button'>
<span row='part_row_{{ part.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row='part_row_{{ part.id }}' class='fas fa-trash-alt icon-red'></span>
</button> </button>
</td> </td>
</tr> </tr>

View File

@ -31,7 +31,6 @@ from InvenTree.models import InvenTreeTree
from InvenTree.fields import InvenTreeURLField from InvenTree.fields import InvenTreeURLField
from part import models as PartModels from part import models as PartModels
from order.models import PurchaseOrder, SalesOrder
class StockLocation(InvenTreeTree): class StockLocation(InvenTreeTree):
@ -134,7 +133,12 @@ class StockItem(MPTTModel):
""" """
# A Query filter which will be re-used in multiple places to determine if a StockItem is actually "in stock" # A Query filter which will be re-used in multiple places to determine if a StockItem is actually "in stock"
IN_STOCK_FILTER = Q(sales_order=None, build_order=None, belongs_to=None) IN_STOCK_FILTER = Q(
sales_order=None,
build_order=None,
belongs_to=None,
status__in=StockStatus.AVAILABLE_CODES
)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.pk: if not self.pk:
@ -393,7 +397,7 @@ class StockItem(MPTTModel):
) )
purchase_order = models.ForeignKey( purchase_order = models.ForeignKey(
PurchaseOrder, 'order.PurchaseOrder',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
verbose_name=_('Source Purchase Order'), verbose_name=_('Source Purchase Order'),
related_name='stock_items', related_name='stock_items',
@ -402,7 +406,7 @@ class StockItem(MPTTModel):
) )
sales_order = models.ForeignKey( sales_order = models.ForeignKey(
SalesOrder, 'order.SalesOrder',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
verbose_name=_("Destination Sales Order"), verbose_name=_("Destination Sales Order"),
related_name='stock_items', related_name='stock_items',

View File

@ -29,7 +29,7 @@
<h4>{% trans "Stock Item Notes" %}</h4> <h4>{% trans "Stock Item Notes" %}</h4>
</div> </div>
<div class='col-sm-6'> <div class='col-sm-6'>
<button title='{% trans "Edit notes" %}' class='btn btn-default btn-glyph float-right' id='edit-notes'><span class='glyphicon glyphicon-edit'></span></button> <button title='{% trans "Edit notes" %}' class='btn btn-default action-button float-right' id='edit-notes'><span class='fas fa-edit'></span></button>
</div> </div>
</div> </div>
<hr> <hr>

View File

@ -9,24 +9,24 @@
<h3>{{ location.name }}</h3> <h3>{{ location.name }}</h3>
<p>{{ location.description }}</p> <p>{{ location.description }}</p>
{% else %} {% else %}
<h3>Stock</h3> <h3>{% trans "Stock" %}</h3>
<p>All stock items</p> <p>{% trans "All stock items" %}</p>
{% endif %} {% endif %}
<p> <p>
<div class='btn-group action-buttons'> <div class='btn-group action-buttons'>
<button class='btn btn-default' id='location-create' title='Create new stock location'> <button class='btn btn-default' id='location-create' title='{% trans "Create new stock location" %}'>
<span class='fas fa-plus-circle icon-green'/> <span class='fas fa-plus-circle icon-green'/>
</button> </button>
{% if location %} {% if location %}
{% include "qr_button.html" %} {% include "qr_button.html" %}
<button class='btn btn-default' id='location-count' title='Count stock items'> <button class='btn btn-default' id='location-count' title='{% trans "Count stock items" %}'>
<span class='fas fa-clipboard-list'/> <span class='fas fa-clipboard-list'/>
</button> </button>
<button class='btn btn-default btn-glyph' id='location-edit' title='Edit stock location'> <button class='btn btn-default btn-glyph' id='location-edit' title='{% trans "Edit stock location" %}'>
<span class='fas fa-edit icon-blue'/> <span class='fas fa-edit icon-blue'/>
</button> </button>
<button class='btn btn-default btn-glyph' id='location-delete' title='Delete stock location'> <button class='btn btn-default btn-glyph' id='location-delete' title='{% trans "Delete stock location" %}'>
<span class='glyphicon glyphicon-trash icon-red'/> <span class='fas fa-trash-alt icon-red'/>
</button> </button>
{% endif %} {% endif %}
</div> </div>

View File

@ -40,7 +40,7 @@
<input type='hidden' name='stock-id-{{ item.id }}' value='{{ item.new_quantity }}'/> <input type='hidden' name='stock-id-{{ item.id }}' value='{{ item.new_quantity }}'/>
{% endif %} {% endif %}
</td> </td>
<td><button class='btn btn-default btn-remove' onclick='removeStockRow()' id='del-{{ item.id }}' title='Remove item' type='button'><span row='stock-row-{{ item.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span></button></td> <td><button class='btn btn-default btn-remove' onclick='removeStockRow()' id='del-{{ item.id }}' title='Remove item' type='button'><span row='stock-row-{{ item.id }}' class='fas fa-trash-alt icon-red'></span></button></td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -14,6 +14,6 @@
</li> </li>
{% endif %} {% endif %}
<li{% ifequal tab 'notes' %} class='active'{% endifequal %}> <li{% ifequal tab 'notes' %} class='active'{% endifequal %}>
<a href="{% url 'stock-item-notes' item.id %}">{% trans "Notes" %}{% if item.notes %} <span class='glyphicon glyphicon-small glyphicon-info-sign'></span>{% endif %}</a> <a href="{% url 'stock-item-notes' item.id %}">{% trans "Notes" %}{% if item.notes %} <span class='fas fa-info-circle'></span>{% endif %}</a>
</li> </li>
</ul> </ul>

View File

@ -67,8 +67,8 @@
{ {
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
var bEdit = "<button title='Edit Currency' class='cur-edit btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-edit'></span></button>"; var bEdit = "<button title='Edit Currency' class='cur-edit btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='fas fa-edit'></span></button>";
var bDel = "<button title='Delete Currency' class='cur-delete btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-trash'></span></button>"; var bDel = "<button title='Delete Currency' class='cur-delete btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='fas fa-trash-alt icon-red'></span></button>";
var html = "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>"; var html = "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";

View File

@ -1,14 +1,15 @@
{% extends "InvenTree/settings/settings.html" %} {% extends "InvenTree/settings/settings.html" %}
{% load i18n %}
{% block tabs %} {% block tabs %}
{% include "InvenTree/settings/tabs.html" with tab='part' %} {% include "InvenTree/settings/tabs.html" with tab='part' %}
{% endblock %} {% endblock %}
{% block settings %} {% block settings %}
<h4>Part Parameter Templates</h4> <h4>{% transa "Part Parameter Templates" %}</h4>
<div id='param-buttons'> <div id='param-buttons'>
<button class='btn btn-success' id='new-param'>New Parameter</button> <button class='btn btn-success' id='new-param'>{% trans "New Parameter" %}</button>
</div> </div>
<table class='table table-striped table-condensed' id='param-table' data-toolbar='#param-buttons'> <table class='table table-striped table-condensed' id='param-table' data-toolbar='#param-buttons'>
@ -24,7 +25,7 @@
queryParams: { queryParams: {
ordering: 'name', ordering: 'name',
}, },
formatNoMatches: function() { return "No part parameter templates found"; }, formatNoMatches: function() { return '{% trans "No part parameter templates found" %}'; },
columns: [ columns: [
{ {
field: 'pk', field: 'pk',
@ -43,8 +44,8 @@
}, },
{ {
formatter: function(value, row, index, field) { formatter: function(value, row, index, field) {
var bEdit = "<button title='Edit Template' class='template-edit btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-edit'></span></button>"; var bEdit = "<button title='{% trans "Edit Template" %}' class='template-edit btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='fas fa-edit'></span></button>";
var bDel = "<button title='Delete Template' class='template-delete btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-trash'></span></button>"; var bDel = "<button title='{% trans "Delete Template" %}' class='template-delete btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='fas fa-trash-alt icon-red'></span></button>";
var html = "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>"; var html = "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";

View File

@ -1,16 +1,16 @@
<ul class='nav nav-pills nav-stacked'> <ul class='nav nav-pills nav-stacked'>
<li{% ifequal tab 'user' %} class='active'{% endifequal %}> <li{% ifequal tab 'user' %} class='active'{% endifequal %}>
<a href="{% url 'settings-user' %}"><span class='glyphicon glyphicon-user'></span> User</a> <a href="{% url 'settings-user' %}"><span class='fas fa-user'></span> User</a>
</li> </li>
<li{% ifequal tab 'currency' %} class='active'{% endifequal %}> <li{% ifequal tab 'currency' %} class='active'{% endifequal %}>
<a href="{% url 'settings-currency' %}"><span class='glyphicon glyphicon-usd'></span> Currency</a> <a href="{% url 'settings-currency' %}"><span class='fas fa-dollar-sign'></span> Currency</a>
</li> </li>
<li{% ifequal tab 'part' %} class='active'{% endifequal %}> <li{% ifequal tab 'part' %} class='active'{% endifequal %}>
<a href="{% url 'settings-part' %}"><span class='glyphicon glyphicon-briefcase'></span> Part</a> <a href="{% url 'settings-part' %}"><span class='fas fa-shapes'></span> Part</a>
</li> </li>
{% if user.is_staff %} {% if user.is_staff %}
<li{% ifequal tab 'other' %} class='active'{% endifequal %}> <li{% ifequal tab 'other' %} class='active'{% endifequal %}>
<a href="{% url 'settings-other' %}"><span class='glyphicon glyphicon-cog'></span>Other</a> <a href="{% url 'settings-other' %}"><span class='fas fa-cogs'></span> Other</a>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>