diff --git a/InvenTree/InvenTree/static/script/inventree/build.js b/InvenTree/InvenTree/static/script/inventree/build.js
index 0a9250ebb2..aa938ecd53 100644
--- a/InvenTree/InvenTree/static/script/inventree/build.js
+++ b/InvenTree/InvenTree/static/script/inventree/build.js
@@ -1,5 +1,6 @@
function updateAllocationTotal(id, count, required) {
+ count = parseFloat(count);
$('#allocation-total-'+id).html(count);
@@ -27,21 +28,24 @@ function loadAllocationTable(table, part_id, part, url, required, button) {
field: 'stock_item_detail',
title: 'Stock Item',
formatter: function(value, row, index, field) {
- return '' + value.quantity + ' x ' + value.part_name + ' @ ' + value.location_name;
+ return '' + parseFloat(value.quantity) + ' x ' + value.part_name + ' @ ' + value.location_name;
}
},
{
field: 'stock_item_detail.quantity',
title: 'Available',
+ formatter: function(value, row, index, field) {
+ return parseFloat(value);
+ }
},
{
field: 'quantity',
title: 'Allocated',
formatter: function(value, row, index, field) {
- var html = value;
+ var html = parseFloat(value);
- var bEdit = "";
- var bDel = "";
+ var bEdit = "";
+ var bDel = "";
html += "
{% multiply build.quantity item.quantity %}
diff --git a/InvenTree/build/templates/build/delete_build_item.html b/InvenTree/build/templates/build/delete_build_item.html
index 37ed0dfa32..f9c41b9eb5 100644
--- a/InvenTree/build/templates/build/delete_build_item.html
+++ b/InvenTree/build/templates/build/delete_build_item.html
@@ -1,7 +1,9 @@
{% extends "modal_delete_form.html" %}
+{% load i18n %}
+{% load inventree_extras %}
{% block pre_form_content %}
-Are you sure you want to unallocate these parts?
+{% trans "Are you sure you want to unallocate these parts?" %}
-This will remove {{ item.quantity }} parts from build '{{ item.build.title }}'.
+This will remove {% decimal item.quantity %} parts from build '{{ item.build.title }}'.
{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/build/templates/build/unallocate.html b/InvenTree/build/templates/build/unallocate.html
index 503bc354f6..f6543b3732 100644
--- a/InvenTree/build/templates/build/unallocate.html
+++ b/InvenTree/build/templates/build/unallocate.html
@@ -1,9 +1,10 @@
{% extends "modal_form.html" %}
-
+{% load i18n %}
+{% load inventree_extras %}
{% block pre_form_content %}
{{ block.super }}
-Are you sure you wish to unallocate all stock for this build?
+{% trans "Are you sure you wish to unallocate all stock for this build?" %}
{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/build/views.py b/InvenTree/build/views.py
index 6a09a3234e..feda6ee9eb 100644
--- a/InvenTree/build/views.py
+++ b/InvenTree/build/views.py
@@ -53,7 +53,7 @@ class BuildCancel(AjaxUpdateView):
model = Build
ajax_template_name = 'build/cancel.html'
- ajax_form_title = 'Cancel Build'
+ ajax_form_title = _('Cancel Build')
context_object_name = 'build'
form_class = forms.CancelBuildForm
@@ -71,12 +71,12 @@ class BuildCancel(AjaxUpdateView):
if confirm:
build.cancelBuild(request.user)
else:
- form.errors['confirm_cancel'] = ['Confirm build cancellation']
+ form.errors['confirm_cancel'] = [_('Confirm build cancellation')]
valid = False
data = {
'form_valid': valid,
- 'danger': 'Build was cancelled'
+ 'danger': _('Build was cancelled')
}
return self.renderJsonResponse(request, form, data=data)
@@ -92,7 +92,7 @@ class BuildAutoAllocate(AjaxUpdateView):
model = Build
form_class = forms.ConfirmBuildForm
context_object_name = 'build'
- ajax_form_title = 'Allocate Stock'
+ ajax_form_title = _('Allocate Stock')
ajax_template_name = 'build/auto_allocate.html'
def get_context_data(self, *args, **kwargs):
@@ -105,7 +105,7 @@ class BuildAutoAllocate(AjaxUpdateView):
context['build'] = build
context['allocations'] = build.getAutoAllocations()
except Build.DoesNotExist:
- context['error'] = 'No matching build found'
+ context['error'] = _('No matching build found')
return context
@@ -124,8 +124,8 @@ class BuildAutoAllocate(AjaxUpdateView):
valid = False
if confirm is False:
- form.errors['confirm'] = ['Confirm stock allocation']
- form.non_field_errors = 'Check the confirmation box at the bottom of the list'
+ form.errors['confirm'] = [_('Confirm stock allocation')]
+ form.non_field_errors = _('Check the confirmation box at the bottom of the list')
else:
build.autoAllocate()
valid = True
@@ -145,7 +145,7 @@ class BuildUnallocate(AjaxUpdateView):
model = Build
form_class = forms.ConfirmBuildForm
- ajax_form_title = "Unallocate Stock"
+ ajax_form_title = _("Unallocate Stock")
ajax_template_name = "build/unallocate.html"
def post(self, request, *args, **kwargs):
@@ -158,8 +158,8 @@ class BuildUnallocate(AjaxUpdateView):
valid = False
if confirm is False:
- form.errors['confirm'] = ['Confirm unallocation of build stock']
- form.non_field_errors = 'Check the confirmation box'
+ form.errors['confirm'] = [_('Confirm unallocation of build stock')]
+ form.non_field_errors = _('Check the confirmation box')
else:
build.unallocateStock()
valid = True
@@ -182,7 +182,7 @@ class BuildComplete(AjaxUpdateView):
model = Build
form_class = forms.CompleteBuildForm
context_object_name = "build"
- ajax_form_title = "Complete Build"
+ ajax_form_title = _("Complete Build")
ajax_template_name = "build/complete.html"
def get_form(self):
@@ -255,14 +255,14 @@ class BuildComplete(AjaxUpdateView):
if confirm is False:
form.errors['confirm'] = [
- 'Confirm completion of build',
+ _('Confirm completion of build'),
]
else:
try:
location = StockLocation.objects.get(id=loc_id)
valid = True
except StockLocation.DoesNotExist:
- form.errors['location'] = ['Invalid location selected']
+ form.errors['location'] = [_('Invalid location selected')]
serials = []
@@ -306,7 +306,7 @@ class BuildComplete(AjaxUpdateView):
def get_data(self):
""" Provide feedback data back to the form """
return {
- 'info': 'Build marked as COMPLETE'
+ 'info': _('Build marked as COMPLETE')
}
@@ -382,7 +382,7 @@ class BuildCreate(AjaxCreateView):
model = Build
context_object_name = 'build'
form_class = forms.EditBuildForm
- ajax_form_title = 'Start new Build'
+ ajax_form_title = _('Start new Build')
ajax_template_name = 'modal_form.html'
def get_initial(self):
@@ -405,7 +405,7 @@ class BuildCreate(AjaxCreateView):
def get_data(self):
return {
- 'success': 'Created new build',
+ 'success': _('Created new build'),
}
@@ -415,12 +415,12 @@ class BuildUpdate(AjaxUpdateView):
model = Build
form_class = forms.EditBuildForm
context_object_name = 'build'
- ajax_form_title = 'Edit Build Details'
+ ajax_form_title = _('Edit Build Details')
ajax_template_name = 'modal_form.html'
def get_data(self):
return {
- 'info': 'Edited build',
+ 'info': _('Edited build'),
}
@@ -429,7 +429,7 @@ class BuildDelete(AjaxDeleteView):
model = Build
ajax_template_name = 'build/delete_build.html'
- ajax_form_title = 'Delete Build'
+ ajax_form_title = _('Delete Build')
class BuildItemDelete(AjaxDeleteView):
@@ -439,12 +439,12 @@ class BuildItemDelete(AjaxDeleteView):
model = BuildItem
ajax_template_name = 'build/delete_build_item.html'
- ajax_form_title = 'Unallocate Stock'
+ ajax_form_title = _('Unallocate Stock')
context_object_name = 'item'
def get_data(self):
return {
- 'danger': 'Removed parts from build allocation'
+ 'danger': _('Removed parts from build allocation')
}
@@ -454,7 +454,7 @@ class BuildItemCreate(AjaxCreateView):
model = BuildItem
form_class = forms.EditBuildItemForm
ajax_template_name = 'build/create_build_item.html'
- ajax_form_title = 'Allocate new Part'
+ ajax_form_title = _('Allocate new Part')
part = None
available_stock = None
@@ -570,11 +570,11 @@ class BuildItemEdit(AjaxUpdateView):
model = BuildItem
ajax_template_name = 'modal_form.html'
form_class = forms.EditBuildItemForm
- ajax_form_title = 'Edit Stock Allocation'
+ ajax_form_title = _('Edit Stock Allocation')
def get_data(self):
return {
- 'info': 'Updated Build Item',
+ 'info': _('Updated Build Item'),
}
def get_form(self):
diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py
index 9e72818a36..5da634c6d3 100644
--- a/InvenTree/common/views.py
+++ b/InvenTree/common/views.py
@@ -5,6 +5,8 @@ Django views for interacting with common models
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+from django.utils.translation import ugettext as _
+
from InvenTree.views import AjaxCreateView, AjaxUpdateView, AjaxDeleteView
from . import models
@@ -16,7 +18,7 @@ class CurrencyCreate(AjaxCreateView):
model = models.Currency
form_class = forms.CurrencyEditForm
- ajax_form_title = 'Create new Currency'
+ ajax_form_title = _('Create new Currency')
class CurrencyEdit(AjaxUpdateView):
@@ -24,12 +26,12 @@ class CurrencyEdit(AjaxUpdateView):
model = models.Currency
form_class = forms.CurrencyEditForm
- ajax_form_title = 'Edit Currency'
+ ajax_form_title = _('Edit Currency')
class CurrencyDelete(AjaxDeleteView):
""" View for deleting an existing Currency object """
model = models.Currency
- ajax_form_title = 'Delete Currency'
+ ajax_form_title = _('Delete Currency')
ajax_template_name = "common/delete_currency.html"
diff --git a/InvenTree/company/templates/company/partdetail.html b/InvenTree/company/templates/company/partdetail.html
deleted file mode 100644
index 1b101ec48e..0000000000
--- a/InvenTree/company/templates/company/partdetail.html
+++ /dev/null
@@ -1,172 +0,0 @@
-{% extends "base.html" %}
-{% load static %}
-{% load i18n %}
-
-{% block page_title %}
-InvenTree | {{ company.name }} - {% trans "Parts" %}
-{% endblock %}
-
-{% block content %}
-
-
-
-
{% trans "Supplier Part" %}
-
-
-
-
-
-
-
-
-
-
{% trans "Supplier Part Details" %}
-
-
- {% trans "Internal Part" %} |
-
- {% if part.part %}
- {{ part.part.full_name }}
- {% endif %}
- |
-
- {% trans "Supplier" %} | {{ part.supplier.name }} |
- {% trans "SKU" %} | {{ part.SKU }} |
- {% if part.URL %}
- {% trans "URL" %} | {{ part.URL }} |
- {% endif %}
- {% if part.description %}
- {% trans "Description" %} | {{ part.description }} |
- {% endif %}
- {% if part.manufacturer %}
- {% trans "Manufacturer" %} | {{ part.manufacturer }} |
- {% trans "MPN" %} | {{ part.MPN }} |
- {% endif %}
- {% if part.note %}
- {% trans "Note" %} | {{ part.note }} |
- {% endif %}
-
-
-
-
-
{% trans "Pricing Information" %}
-
- {% trans "Order Multiple" %} | {{ part.multiple }} |
- {% if part.base_cost > 0 %}
- {% trans "Base Price (Flat Fee)" %} | {{ part.base_cost }} |
- {% endif %}
-
- {% trans "Price Breaks" %} |
-
-
-
-
- |
-
-
- {% trans "Quantity" %} |
- {% trans "Price" %} |
-
- {% if part.price_breaks.all %}
- {% for pb in part.price_breaks.all %}
-
- {{ pb.quantity }} |
-
- {% if pb.currency %}{{ pb.currency.symbol }}{% endif %}
- {{ pb.cost }}
- {% if pb.currency %}{{ pb.currency.suffix }}{% endif %}
-
-
-
-
- |
-
- {% endfor %}
- {% else %}
-
-
- {% trans "No price breaks have been added for this part" %}
- |
-
- {% endif %}
-
-
-
-
-
-
-
{% trans "Purchase Orders" %}
-{% include "order/po_table.html" with orders=part.purchase_orders %}
-
-{% endblock %}
-
-{% block js_ready %}
-{{ block.super }}
- $('#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-parts' part.supplier.id %}"
- }
- );
- });
-
- $('#new-price-break').click(function() {
- launchModalForm("{% url 'price-break-create' %}",
- {
- reload: true,
- data: {
- part: {{ part.id }},
- }
- }
- );
- });
-
- $('.pb-edit-button').click(function() {
- var button = $(this);
-
- launchModalForm(button.attr('url'),
- {
- reload: true,
- }
- );
- });
-
- $('.pb-delete-button').click(function() {
- var button = $(this);
-
- launchModalForm(button.attr('url'),
- {
- reload: true,
- }
- );
- });
-
-{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/supplier_part_base.html b/InvenTree/company/templates/company/supplier_part_base.html
new file mode 100644
index 0000000000..f7e6ce88cc
--- /dev/null
+++ b/InvenTree/company/templates/company/supplier_part_base.html
@@ -0,0 +1,68 @@
+{% extends "base.html" %}
+{% load static %}
+{% load i18n %}
+
+{% block page_title %}
+InvenTree | {% trans "Supplier Part" %}
+{% endblock %}
+
+{% block content %}
+
+
+
+
{% trans "Supplier Part" %}
+
+
+
+
+
+
+
+
+ {% block details %}
+
+ {% endblock %}
+
+
+{% endblock %}
+
+{% block js_ready %}
+{{ block.super }}
+
+$('#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-parts' part.supplier.id %}"
+ }
+ );
+});
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/supplier_part_detail.html b/InvenTree/company/templates/company/supplier_part_detail.html
new file mode 100644
index 0000000000..bb0dee177a
--- /dev/null
+++ b/InvenTree/company/templates/company/supplier_part_detail.html
@@ -0,0 +1,44 @@
+{% extends "company/supplier_part_base.html" %}
+{% load static %}
+{% load i18n %}
+
+{% block details %}
+
+{% include "company/supplier_part_tabs.html" with tab='details' %}
+
+
+
+
{% trans "Supplier Part Details" %}
+
+
+ {% trans "Internal Part" %} |
+
+ {% if part.part %}
+ {{ part.part.full_name }}
+ {% endif %}
+ |
+
+ {% trans "Supplier" %} | {{ part.supplier.name }} |
+ {% trans "SKU" %} | {{ part.SKU }} |
+{% if part.URL %}
+ {% trans "URL" %} | {{ part.URL }} |
+{% endif %}
+{% if part.description %}
+ {% trans "Description" %} | {{ part.description }} |
+{% endif %}
+{% if part.manufacturer %}
+ {% trans "Manufacturer" %} | {{ part.manufacturer }} |
+ {% trans "MPN" %} | {{ part.MPN }} |
+{% endif %}
+{% if part.note %}
+ {% trans "Note" %} | {{ part.note }} |
+{% endif %}
+
+
+{% endblock %}
+
+{% block js_ready %}
+{{ block.super }}
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/supplier_part_orders.html b/InvenTree/company/templates/company/supplier_part_orders.html
new file mode 100644
index 0000000000..381a2941e9
--- /dev/null
+++ b/InvenTree/company/templates/company/supplier_part_orders.html
@@ -0,0 +1,31 @@
+{% extends "company/supplier_part_base.html" %}
+{% load static %}
+{% load i18n %}
+
+{% block details %}
+
+{% include "company/supplier_part_tabs.html" with tab='orders' %}
+
+
+
+
{% trans "Supplier Part Orders" %}
+
+
+
+
+
+{% endblock %}
+
+{% block js_ready %}
+{{ block.super }}
+
+loadPurchaseOrderTable($("#purchase-order-table"), {
+ url: "{% url 'api-po-list' %}?supplier_part={{ part.id }}",
+});
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/supplier_part_pricing.html b/InvenTree/company/templates/company/supplier_part_pricing.html
new file mode 100644
index 0000000000..bed8d9ed35
--- /dev/null
+++ b/InvenTree/company/templates/company/supplier_part_pricing.html
@@ -0,0 +1,92 @@
+{% extends "company/supplier_part_base.html" %}
+{% load static %}
+{% load i18n %}
+{% load inventree_extras %}
+
+{% block details %}
+
+{% include "company/supplier_part_tabs.html" with tab='pricing' %}
+
+
+
+
{% trans "Pricing Information" %}
+
+ {% trans "Order Multiple" %} | {{ part.multiple }} |
+ {% if part.base_cost > 0 %}
+ {% trans "Base Price (Flat Fee)" %} | {{ part.base_cost }} |
+ {% endif %}
+
+ {% trans "Price Breaks" %} |
+
+
+
+
+ |
+
+
+ {% trans "Quantity" %} |
+ {% trans "Price" %} |
+
+ {% if part.price_breaks.all %}
+ {% for pb in part.price_breaks.all %}
+
+ {% decimal pb.quantity %} |
+
+ {% if pb.currency %}{{ pb.currency.symbol }}{% endif %}
+ {% decimal pb.cost %}
+ {% if pb.currency %}{{ pb.currency.suffix }}{% endif %}
+
+
+
+
+ |
+
+ {% endfor %}
+ {% else %}
+
+
+ {% trans "No price breaks have been added for this part" %}
+ |
+
+ {% endif %}
+
+
+{% endblock %}
+
+{% block js_ready %}
+{{ block.super }}
+
+
+
+$('#new-price-break').click(function() {
+ launchModalForm("{% url 'price-break-create' %}",
+ {
+ reload: true,
+ data: {
+ part: {{ part.id }},
+ }
+ }
+ );
+});
+
+$('.pb-edit-button').click(function() {
+ var button = $(this);
+
+ launchModalForm(button.attr('url'),
+ {
+ reload: true,
+ }
+ );
+});
+
+$('.pb-delete-button').click(function() {
+ var button = $(this);
+
+ launchModalForm(button.attr('url'),
+ {
+ reload: true,
+ }
+ );
+});
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/supplier_part_stock.html b/InvenTree/company/templates/company/supplier_part_stock.html
new file mode 100644
index 0000000000..9f3157c0b5
--- /dev/null
+++ b/InvenTree/company/templates/company/supplier_part_stock.html
@@ -0,0 +1,72 @@
+{% extends "company/supplier_part_base.html" %}
+{% load static %}
+{% load i18n %}
+
+{% block details %}
+
+{% include "company/supplier_part_tabs.html" with tab='stock' %}
+
+
+
+
{% trans "Supplier Part Stock" %}
+
+{% include "stock_table.html" %}
+
+{% endblock %}
+
+{% block js_load %}
+{{ block.super }}
+
+{% endblock %}
+
+{% block js_ready %}
+{{ block.super }}
+
+ loadStockTable($("#stock-table"), {
+ params: {
+ supplier_part: {{ part.id }},
+ location_detail: true,
+ 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 += "&supplier_part={{ part.id }}";
+
+ location.href = url;
+ },
+ });
+ });
+
+ $("#item-create").click(function() {
+ launchModalForm("{% url 'stock-item-create' %}", {
+ reload: true,
+ data: {
+ part: {{ part.part.id }},
+ supplier_part: {{ part.id }},
+ },
+ secondary: [
+ {
+ field: 'location',
+ label: '{% trans "New Location" %}',
+ title: '{% trans "Create New Location" %}',
+ url: "{% url 'stock-location-create' %}",
+ }
+ ]
+ });
+
+ return false;
+ });
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/company/templates/company/supplier_part_tabs.html b/InvenTree/company/templates/company/supplier_part_tabs.html
new file mode 100644
index 0000000000..0bcd8aa4fa
--- /dev/null
+++ b/InvenTree/company/templates/company/supplier_part_tabs.html
@@ -0,0 +1,16 @@
+{% load i18n %}
+
+
\ No newline at end of file
diff --git a/InvenTree/company/urls.py b/InvenTree/company/urls.py
index a7683b7bbc..66cc0b9cd8 100644
--- a/InvenTree/company/urls.py
+++ b/InvenTree/company/urls.py
@@ -47,7 +47,11 @@ price_break_urls = [
]
supplier_part_detail_urls = [
- url(r'edit/?', views.SupplierPartEdit.as_view(), name='supplier-part-edit'),
+ url(r'^edit/?', views.SupplierPartEdit.as_view(), name='supplier-part-edit'),
+
+ 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(), name='supplier-part-detail'),
]
diff --git a/InvenTree/company/views.py b/InvenTree/company/views.py
index 0fa7a2c712..d37b72e707 100644
--- a/InvenTree/company/views.py
+++ b/InvenTree/company/views.py
@@ -6,6 +6,7 @@ Django views for interacting with Company app
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+from django.utils.translation import ugettext as _
from django.views.generic import DetailView, ListView, UpdateView
from django.urls import reverse
@@ -93,12 +94,12 @@ class CompanyImage(AjaxUpdateView):
""" View for uploading an image for the Company """
model = Company
ajax_template_name = 'modal_form.html'
- ajax_form_title = 'Update Company Image'
+ ajax_form_title = _('Update Company Image')
form_class = CompanyImageForm
def get_data(self):
return {
- 'success': 'Updated company image',
+ 'success': _('Updated company image'),
}
@@ -108,11 +109,11 @@ class CompanyEdit(AjaxUpdateView):
form_class = EditCompanyForm
context_object_name = 'company'
ajax_template_name = 'modal_form.html'
- ajax_form_title = 'Edit Company'
+ ajax_form_title = _('Edit Company')
def get_data(self):
return {
- 'info': 'Edited company information',
+ 'info': _('Edited company information'),
}
@@ -122,11 +123,11 @@ class CompanyCreate(AjaxCreateView):
context_object_name = 'company'
form_class = EditCompanyForm
ajax_template_name = 'modal_form.html'
- ajax_form_title = "Create new Company"
+ ajax_form_title = _("Create new Company")
def get_data(self):
return {
- 'success': "Created new company",
+ 'success': _("Created new company"),
}
@@ -136,19 +137,19 @@ class CompanyDelete(AjaxDeleteView):
model = Company
success_url = '/company/'
ajax_template_name = 'company/delete.html'
- ajax_form_title = 'Delete Company'
+ ajax_form_title = _('Delete Company')
context_object_name = 'company'
def get_data(self):
return {
- 'danger': 'Company was deleted',
+ 'danger': _('Company was deleted'),
}
class SupplierPartDetail(DetailView):
""" Detail view for SupplierPart """
model = SupplierPart
- template_name = 'company/partdetail.html'
+ template_name = 'company/supplier_part_detail.html'
context_object_name = 'part'
queryset = SupplierPart.objects.all()
@@ -166,7 +167,7 @@ class SupplierPartEdit(AjaxUpdateView):
context_object_name = 'part'
form_class = EditSupplierPartForm
ajax_template_name = 'modal_form.html'
- ajax_form_title = 'Edit Supplier Part'
+ ajax_form_title = _('Edit Supplier Part')
class SupplierPartCreate(AjaxCreateView):
@@ -175,7 +176,7 @@ class SupplierPartCreate(AjaxCreateView):
model = SupplierPart
form_class = EditSupplierPartForm
ajax_template_name = 'modal_form.html'
- ajax_form_title = 'Create new Supplier Part'
+ ajax_form_title = _('Create new Supplier Part')
context_object_name = 'part'
def get_form(self):
@@ -232,7 +233,7 @@ class SupplierPartDelete(AjaxDeleteView):
success_url = '/supplier/'
ajax_template_name = 'company/partdelete.html'
- ajax_form_title = 'Delete Supplier Part'
+ ajax_form_title = _('Delete Supplier Part')
parts = []
@@ -302,7 +303,7 @@ class PriceBreakCreate(AjaxCreateView):
model = SupplierPriceBreak
form_class = EditPriceBreakForm
- ajax_form_title = 'Add Price Break'
+ ajax_form_title = _('Add Price Break')
ajax_template_name = 'modal_form.html'
def get_data(self):
@@ -337,7 +338,7 @@ class PriceBreakEdit(AjaxUpdateView):
model = SupplierPriceBreak
form_class = EditPriceBreakForm
- ajax_form_title = 'Edit Price Break'
+ ajax_form_title = _('Edit Price Break')
ajax_template_name = 'modal_form.html'
def get_form(self):
@@ -352,5 +353,5 @@ class PriceBreakDelete(AjaxDeleteView):
""" View for deleting a supplier price break """
model = SupplierPriceBreak
- ajax_form_title = "Delete Price Break"
+ ajax_form_title = _("Delete Price Break")
ajax_template_name = 'modal_delete_form.html'
diff --git a/InvenTree/locale/de/LC_MESSAGES/django.po b/InvenTree/locale/de/LC_MESSAGES/django.po
index fc53b0aed0..06afa0b14d 100644
--- a/InvenTree/locale/de/LC_MESSAGES/django.po
+++ b/InvenTree/locale/de/LC_MESSAGES/django.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-02-10 11:09+0000\n"
+"POT-Creation-Date: 2020-02-12 00:31+0000\n"
"PO-Revision-Date: 2020-02-02 08:07+0100\n"
"Last-Translator: Christian Schlüter
\n"
"Language-Team: C \n"
@@ -105,7 +105,7 @@ msgstr "Zerstört"
#: InvenTree/status_codes.py:92 build/templates/build/allocate_edit.html:28
#: build/templates/build/allocate_view.html:21
-#: part/templates/part/part_base.html:116 part/templates/part/tabs.html:21
+#: part/templates/part/part_base.html:106 part/templates/part/tabs.html:21
msgid "Allocated"
msgstr "Zugeordnet"
@@ -150,15 +150,15 @@ msgstr "Eindeutige Seriennummern eingeben (oder leer lassen)"
msgid "Confirm build completion"
msgstr "Bau-Fertigstellung bestätigen"
-#: build/models.py:53
+#: build/models.py:54
msgid "Brief description of the build"
msgstr "Kurze Beschreibung des Baus"
-#: build/models.py:62
+#: build/models.py:63
msgid "Select part to build"
msgstr "Teil für den Bau wählen"
-#: build/models.py:68
+#: build/models.py:69
msgid ""
"Select location to take stock from for this build (leave blank to take from "
"any stock location)"
@@ -166,46 +166,46 @@ msgstr ""
"Lager-Entnahmestandort für diesen Bau wählen (oder leer lassen für einen "
"beliebigen Lager-Standort)"
-#: build/models.py:74
+#: build/models.py:75
msgid "Number of parts to build"
msgstr "Anzahl der zu bauenden Teile"
-#: build/models.py:80
+#: build/models.py:81
msgid "Build status"
msgstr "Bau-Status"
-#: build/models.py:83
+#: build/models.py:84
msgid "Batch code for this build output"
msgstr "Chargennummer für diese Bau-Ausgabe"
-#: build/models.py:95
+#: build/models.py:96
msgid "Link to external URL"
msgstr "Link zu einer externen URL"
-#: build/models.py:97
+#: build/models.py:98
msgid "Extra build notes"
msgstr "Notizen für den Bau"
-#: build/models.py:382
+#: build/models.py:383
#, python-brace-format
msgid "Selected stock item not found in BOM for part '{p}'"
msgstr "Ausgewähltes Lagerobjekt nicht in BOM für Teil '{p}' gefunden"
-#: build/models.py:385
+#: build/models.py:386
#, python-brace-format
msgid "Allocated quantity ({n}) must not exceed available quantity ({q})"
msgstr ""
"zugewiesene Anzahl ({n}) darf nicht die verfügbare ({q}) Anzahl überschreiten"
-#: build/models.py:403
+#: build/models.py:404
msgid "Build to allocate parts"
msgstr "Bau starten um Teile zuzuweisen"
-#: build/models.py:410
+#: build/models.py:411
msgid "Stock Item to allocate to build"
msgstr "Lagerobjekt dem Bau zuweisen"
-#: build/models.py:418
+#: build/models.py:419
msgid "Stock quantity to allocate to build"
msgstr "Lagerobjekt-Anzahl dem Bau zuweisen"
@@ -248,23 +248,30 @@ msgid "Allocate"
msgstr "zuweisen"
#: build/templates/build/allocate_view.html:10
-#: company/templates/company/detail_part.html:18
+#: company/templates/company/detail_part.html:18 order/views.py:448
msgid "Order Parts"
msgstr "Teile bestellen"
#: build/templates/build/allocate_view.html:18
#: company/templates/company/index.html:54
-#: company/templates/company/partdetail.html:57
+#: company/templates/company/supplier_part_detail.html:27
#: order/templates/order/purchase_order_detail.html:26
#: part/templates/part/detail.html:33
msgid "Description"
msgstr "Beschreibung"
#: build/templates/build/allocate_view.html:22
-#: part/templates/part/part_base.html:122
+#: part/templates/part/part_base.html:112
msgid "On Order"
msgstr "bestellt"
+#: build/templates/build/delete_build_item.html:6
+#, fuzzy
+#| msgid "Are you sure you want to delete the following Supplier Parts?"
+msgid "Are you sure you want to unallocate these parts?"
+msgstr ""
+"Sind Sie sicher, dass sie die folgenden Zulieferer-Teile löschen möchten?"
+
#: build/templates/build/detail.html:8
msgid "Build Details"
msgstr "Bau-Status"
@@ -274,7 +281,7 @@ msgid "Title"
msgstr "Titel"
#: build/templates/build/detail.html:20
-#: company/templates/company/partdetail.html:85
+#: company/templates/company/supplier_part_pricing.html:27
#: order/templates/order/purchase_order_detail.html:29
#: stock/templates/stock/item_base.html:90
#: stock/templates/stock/stock_adjust.html:18
@@ -301,8 +308,8 @@ msgstr "Los"
#: build/templates/build/detail.html:42
#: company/templates/company/detail_part.html:90
-#: company/templates/company/partdetail.html:54
-#: part/templates/part/detail.html:50 part/templates/part/part_base.html:91
+#: company/templates/company/supplier_part_detail.html:24
+#: part/templates/part/detail.html:50 part/templates/part/part_base.html:81
#: stock/templates/stock/item_base.html:120
msgid "URL"
msgstr "URL"
@@ -344,8 +351,9 @@ msgstr "Speichern"
msgid "Edit notes"
msgstr "Bermerkungen bearbeiten"
-#: build/templates/build/tabs.html:5 company/templates/company/tabs.html:5
-#: part/templates/part/tabs.html:6
+#: build/templates/build/tabs.html:5
+#: company/templates/company/supplier_part_tabs.html:5
+#: company/templates/company/tabs.html:5 part/templates/part/tabs.html:6
msgid "Details"
msgstr "Details"
@@ -359,11 +367,135 @@ msgstr "Notizen"
msgid "Assign Parts"
msgstr "Teile zuweisen"
-#: build/views.py:290 stock/views.py:884
+#: build/templates/build/unallocate.html:8
+msgid "Are you sure you wish to unallocate all stock for this build?"
+msgstr ""
+
+#: build/views.py:56
+#, fuzzy
+#| msgid "Can Build"
+msgid "Cancel Build"
+msgstr "Herstellbar?"
+
+#: build/views.py:74
+#, fuzzy
+#| msgid "Confirm order cancellation"
+msgid "Confirm build cancellation"
+msgstr "Bestell-Stornierung bestätigen"
+
+#: build/views.py:79
+msgid "Build was cancelled"
+msgstr ""
+
+#: build/views.py:95
+#, fuzzy
+#| msgid "Allocate Stock to Build"
+msgid "Allocate Stock"
+msgstr "Lagerbestand dem Bau zuweisen"
+
+#: build/views.py:108
+msgid "No matching build found"
+msgstr ""
+
+#: build/views.py:127
+#, fuzzy
+#| msgid "Confirm order cancellation"
+msgid "Confirm stock allocation"
+msgstr "Bestell-Stornierung bestätigen"
+
+#: build/views.py:128
+msgid "Check the confirmation box at the bottom of the list"
+msgstr ""
+
+#: build/views.py:148 build/views.py:442
+#, fuzzy
+#| msgid "Unallocate"
+msgid "Unallocate Stock"
+msgstr "Zuweisung aufheben"
+
+#: build/views.py:161
+msgid "Confirm unallocation of build stock"
+msgstr ""
+
+#: build/views.py:162
+msgid "Check the confirmation box"
+msgstr ""
+
+#: build/views.py:185
+#, fuzzy
+#| msgid "Completed"
+msgid "Complete Build"
+msgstr "Fertig"
+
+#: build/views.py:258
+#, fuzzy
+#| msgid "Confirm build completion"
+msgid "Confirm completion of build"
+msgstr "Bau-Fertigstellung bestätigen"
+
+#: build/views.py:265
+#, fuzzy
+#| msgid "Invalid part selection"
+msgid "Invalid location selected"
+msgstr "Ungültige Teileauswahl"
+
+#: build/views.py:290 stock/views.py:916
#, python-brace-format
msgid "The following serial numbers already exist: ({sn})"
msgstr "Die folgende Seriennummer existiert bereits: ({sn})"
+#: build/views.py:309
+msgid "Build marked as COMPLETE"
+msgstr ""
+
+#: build/views.py:385
+#, fuzzy
+#| msgid "Can Build"
+msgid "Start new Build"
+msgstr "Herstellbar?"
+
+#: build/views.py:408
+#, fuzzy
+#| msgid "Created new stock item"
+msgid "Created new build"
+msgstr "Neues Lagerobjekt erstellt"
+
+#: build/views.py:418
+#, fuzzy
+#| msgid "Build Details"
+msgid "Edit Build Details"
+msgstr "Bau-Status"
+
+#: build/views.py:423
+msgid "Edited build"
+msgstr ""
+
+#: build/views.py:432
+msgid "Delete Build"
+msgstr ""
+
+#: build/views.py:447
+#, fuzzy
+#| msgid "Receive parts to this location"
+msgid "Removed parts from build allocation"
+msgstr "Teile in diesen Ort empfangen"
+
+#: build/views.py:457
+#, fuzzy
+#| msgid "Create new Stock Item"
+msgid "Allocate new Part"
+msgstr "Neues Lagerobjekt hinzufügen"
+
+#: build/views.py:573
+#, fuzzy
+#| msgid "Edit Stock Location"
+msgid "Edit Stock Allocation"
+msgstr "Lagerobjekt-Standort bearbeiten"
+
+#: build/views.py:577
+msgid "Updated Build Item"
+msgstr ""
+
#: common/models.py:69
msgid "Settings key (must be unique - case insensitive"
msgstr ""
@@ -402,6 +534,20 @@ msgstr "Währungs-Wert"
msgid "Use this currency as the base currency"
msgstr "Benutze diese Währung als Basis-Währung"
+#: common/views.py:21
+#, fuzzy
+#| msgid "Create new Stock Item"
+msgid "Create new Currency"
+msgstr "Neues Lagerobjekt hinzufügen"
+
+#: common/views.py:29
+msgid "Edit Currency"
+msgstr ""
+
+#: common/views.py:36
+msgid "Delete Currency"
+msgstr ""
+
#: company/models.py:74
msgid "Company name"
msgstr "Firmenname"
@@ -455,7 +601,7 @@ msgid "Supplier stock keeping unit"
msgstr "Stock Keeping Units (SKU) des Zulieferers"
#: company/models.py:240 company/templates/company/detail_part.html:81
-#: company/templates/company/partdetail.html:60
+#: company/templates/company/supplier_part_detail.html:30
msgid "Manufacturer"
msgstr "Hersteller"
@@ -517,7 +663,7 @@ msgstr "Kunde"
#: company/templates/company/detail.html:17
#: company/templates/company/index.html:46
-#: company/templates/company/partdetail.html:51
+#: company/templates/company/supplier_part_detail.html:21
#: order/templates/order/order_base.html:67
#: stock/templates/stock/item_base.html:126
msgid "Supplier"
@@ -529,12 +675,13 @@ msgid "Supplier Parts"
msgstr "Zulieferer-Teile"
#: company/templates/company/detail_part.html:13
+#: part/templates/part/stock.html:81
#, fuzzy
#| msgid "Supplier Part"
msgid "New Supplier Part"
msgstr "Zulieferer-Teil"
-#: company/templates/company/detail_part.html:15
+#: company/templates/company/detail_part.html:15 templates/stock_table.html:10
msgid "Options"
msgstr ""
@@ -545,12 +692,11 @@ msgid "Delete Parts"
msgstr "Anhang löschen"
#: company/templates/company/detail_part.html:73
-#: company/templates/company/partdetail.html:52
+#: company/templates/company/supplier_part_detail.html:22
msgid "SKU"
msgstr ""
#: company/templates/company/detail_purchase_orders.html:8
-#: company/templates/company/partdetail.html:116
#: company/templates/company/tabs.html:15 part/templates/part/tabs.html:43
msgid "Purchase Orders"
msgstr "Bestellungen"
@@ -568,6 +714,8 @@ msgid "Supplier Stock"
msgstr "Zulieferer-Teil"
#: company/templates/company/detail_stock.html:33
+#: company/templates/company/supplier_part_stock.html:38
+#: part/templates/part/stock.html:53 templates/stock_table.html:5
msgid "Export"
msgstr ""
@@ -588,10 +736,8 @@ msgstr "Zulieferer"
msgid "ID"
msgstr ""
-#: company/templates/company/index.html:69
-#: company/templates/company/partdetail.html:6
-#: part/templates/part/category.html:73 templates/navbar.html:10
-#: templates/stats.html:7 templates/stats.html:10
+#: company/templates/company/index.html:69 part/templates/part/category.html:73
+#: templates/navbar.html:10 templates/stats.html:7 templates/stats.html:10
msgid "Parts"
msgstr "Teile"
@@ -605,75 +751,194 @@ msgid "Are you sure you want to delete the following Supplier Parts?"
msgstr ""
"Sind Sie sicher, dass sie die folgenden Zulieferer-Teile löschen möchten?"
-#: company/templates/company/partdetail.html:13
+#: company/templates/company/supplier_part_base.html:6
+#: company/templates/company/supplier_part_base.html:13
#: stock/templates/stock/item_base.html:130
msgid "Supplier Part"
msgstr "Zulieferer-Teil"
-#: company/templates/company/partdetail.html:41
+#: company/templates/company/supplier_part_detail.html:11
#, fuzzy
#| msgid "Supplier Parts"
msgid "Supplier Part Details"
msgstr "Zulieferer-Teile"
-#: company/templates/company/partdetail.html:44
+#: company/templates/company/supplier_part_detail.html:14
#, fuzzy
#| msgid "Internal Part Number"
msgid "Internal Part"
msgstr "Interne Teilenummer"
-#: company/templates/company/partdetail.html:61
+#: company/templates/company/supplier_part_detail.html:31
#, fuzzy
#| msgid "IPN"
msgid "MPN"
msgstr "IPN (Interne Produktnummer)"
-#: company/templates/company/partdetail.html:64
+#: company/templates/company/supplier_part_detail.html:34
#: order/templates/order/purchase_order_detail.html:33
msgid "Note"
msgstr "Notiz"
-#: company/templates/company/partdetail.html:70
+#: company/templates/company/supplier_part_orders.html:11
+#, fuzzy
+#| msgid "Supplier Parts"
+msgid "Supplier Part Orders"
+msgstr "Zulieferer-Teile"
+
+#: company/templates/company/supplier_part_pricing.html:12
#, fuzzy
#| msgid "Show pricing information"
msgid "Pricing Information"
msgstr "Kosteninformationen ansehen"
-#: company/templates/company/partdetail.html:72
+#: company/templates/company/supplier_part_pricing.html:14
#, fuzzy
#| msgid "Order notes"
msgid "Order Multiple"
msgstr "Bestell-Notizen"
-#: company/templates/company/partdetail.html:74
+#: company/templates/company/supplier_part_pricing.html:16
msgid "Base Price (Flat Fee)"
msgstr ""
-#: company/templates/company/partdetail.html:77
+#: company/templates/company/supplier_part_pricing.html:19
msgid "Price Breaks"
msgstr ""
-#: company/templates/company/partdetail.html:80
+#: company/templates/company/supplier_part_pricing.html:22
msgid "New Price Break"
msgstr ""
-#: company/templates/company/partdetail.html:86
+#: company/templates/company/supplier_part_pricing.html:28
msgid "Price"
msgstr ""
-#: company/templates/company/partdetail.html:106
+#: company/templates/company/supplier_part_pricing.html:48
msgid "No price breaks have been added for this part"
msgstr ""
+#: company/templates/company/supplier_part_stock.html:11
+#, fuzzy
+#| msgid "Supplier part"
+msgid "Supplier Part Stock"
+msgstr "Zulieferer-Teil"
+
+#: company/templates/company/supplier_part_stock.html:61
+#: part/templates/part/stock.html:90
+#, fuzzy
+#| msgid "Location"
+msgid "New Location"
+msgstr "Standort"
+
+#: company/templates/company/supplier_part_stock.html:62
+#: part/templates/part/stock.html:91
+#, fuzzy
+#| msgid "Create new Stock Location"
+msgid "Create New Location"
+msgstr "Neuen Lager-Standort erstellen"
+
+#: company/templates/company/supplier_part_tabs.html:8
+#, fuzzy
+#| msgid "Part packaging"
+msgid "Pricing"
+msgstr "Teile-Packaging"
+
+#: company/templates/company/supplier_part_tabs.html:11
#: company/templates/company/tabs.html:12 part/templates/part/tabs.html:17
#: templates/navbar.html:11
msgid "Stock"
msgstr "Lagerbestand"
+#: company/templates/company/supplier_part_tabs.html:14
+#: templates/navbar.html:14
+#, fuzzy
+#| msgid "On Order"
+msgid "Orders"
+msgstr "bestellt"
+
#: company/templates/company/tabs.html:21
msgid "Sales Orders"
msgstr "Bestellungen"
+#: company/views.py:97
+#, fuzzy
+#| msgid "Company name"
+msgid "Update Company Image"
+msgstr "Firmenname"
+
+#: company/views.py:102
+msgid "Updated company image"
+msgstr ""
+
+#: company/views.py:112
+#, fuzzy
+#| msgid "Company"
+msgid "Edit Company"
+msgstr "Firma"
+
+#: company/views.py:116
+#, fuzzy
+#| msgid "Link to external company information"
+msgid "Edited company information"
+msgstr "Link auf externe Firmeninformation"
+
+#: company/views.py:126
+#, fuzzy
+#| msgid "Create new Stock Item"
+msgid "Create new Company"
+msgstr "Neues Lagerobjekt hinzufügen"
+
+#: company/views.py:130
+#, fuzzy
+#| msgid "Created new stock item"
+msgid "Created new company"
+msgstr "Neues Lagerobjekt erstellt"
+
+#: company/views.py:140
+#, fuzzy
+#| msgid "Company"
+msgid "Delete Company"
+msgstr "Firma"
+
+#: company/views.py:145
+#, fuzzy
+#| msgid "Company address"
+msgid "Company was deleted"
+msgstr "Firmenadresse"
+
+#: company/views.py:170
+#, fuzzy
+#| msgid "Supplier Part"
+msgid "Edit Supplier Part"
+msgstr "Zulieferer-Teil"
+
+#: company/views.py:179 part/templates/part/stock.html:82
+#, fuzzy
+#| msgid "Supplier Part"
+msgid "Create new Supplier Part"
+msgstr "Zulieferer-Teil"
+
+#: company/views.py:236
+#, fuzzy
+#| msgid "Supplier Part"
+msgid "Delete Supplier Part"
+msgstr "Zulieferer-Teil"
+
+#: company/views.py:306
+msgid "Add Price Break"
+msgstr ""
+
+#: company/views.py:341
+msgid "Edit Price Break"
+msgstr ""
+
+#: company/views.py:356
+#, fuzzy
+#| msgid "Delete attachment"
+msgid "Delete Price Break"
+msgstr "Anhang löschen"
+
#: order/forms.py:21
msgid "Place order"
msgstr "Bestellung aufgeben"
@@ -706,7 +971,7 @@ msgstr "Link auf externe Seite"
msgid "Order notes"
msgstr "Bestell-Notizen"
-#: order/models.py:159 order/models.py:210 part/views.py:1080
+#: order/models.py:159 order/models.py:210 part/views.py:1109
#: stock/models.py:440
msgid "Quantity must be greater than zero"
msgstr "Anzahl muss größer Null sein"
@@ -761,7 +1026,7 @@ msgstr "Empfangen"
msgid "Order Notes"
msgstr "Bestellungsbemerkungen"
-#: order/templates/order/purchase_order_detail.html:15
+#: order/templates/order/purchase_order_detail.html:15 order/views.py:747
msgid "Add Line Item"
msgstr "Position hinzufügen"
@@ -785,14 +1050,50 @@ msgstr "Referenz"
msgid "Items"
msgstr "Positionen"
+#: order/views.py:99
+#, fuzzy
+#| msgid "Purchase Order"
+msgid "Create Purchase Order"
+msgstr "Kaufvertrag"
+
+#: order/views.py:129
+#, fuzzy
+#| msgid "Purchase Order"
+msgid "Edit Purchase Order"
+msgstr "Kaufvertrag"
+
+#: order/views.py:149
+#, fuzzy
+#| msgid "Cancel order"
+msgid "Cancel Order"
+msgstr "Bestellung stornieren"
+
#: order/views.py:164
msgid "Confirm order cancellation"
msgstr "Bestell-Stornierung bestätigen"
+#: order/views.py:182
+#, fuzzy
+#| msgid "Issued"
+msgid "Issue Order"
+msgstr "Aufgegeben"
+
#: order/views.py:197
msgid "Confirm order placement"
msgstr "Bestellungstätigung bestätigen"
+#: order/views.py:218
+#, fuzzy
+#| msgid "Completed"
+msgid "Complete Order"
+msgstr "Fertig"
+
+#: order/views.py:284
+#, fuzzy
+#| msgid "Required Parts"
+msgid "Receive Parts"
+msgstr "benötigte Teile"
+
#: order/views.py:351
msgid "Items received"
msgstr "Anzahl empfangener Positionen"
@@ -825,224 +1126,258 @@ msgstr "Zulieferer muss zum Teil und zur Bestellung passen"
msgid "Invalid SupplierPart selection"
msgstr "Ungültige Wahl des Zulieferer-Teils"
-#: part/bom.py:107
+#: order/views.py:862
+#, fuzzy
+#| msgid "Add Line Item"
+msgid "Edit Line Item"
+msgstr "Position hinzufügen"
+
+#: order/views.py:878
+#, fuzzy
+#| msgid "Delete Stock Item"
+msgid "Delete Line Item"
+msgstr "Lagerobjekt löschen"
+
+#: order/views.py:883
+#, fuzzy
+#| msgid "Deleted {n} stock items"
+msgid "Deleted line item"
+msgstr "{n} Teile im Lager gelöscht"
+
+#: part/bom.py:140
#, python-brace-format
msgid "Unsupported file format: {f}"
msgstr "Nicht unterstütztes Dateiformat: {f}"
-#: part/bom.py:112
+#: part/bom.py:145
msgid "Error reading BOM file (invalid data)"
msgstr "Fehler beim Lesen der Stückliste (ungültige Daten)"
-#: part/bom.py:114
+#: part/bom.py:147
msgid "Error reading BOM file (incorrect row size)"
msgstr "Fehler beim Lesen der Stückliste (ungültige Zeilengröße)"
-#: part/forms.py:37
+#: part/forms.py:37 stock/forms.py:91
+msgid "File Format"
+msgstr "Dateiformat"
+
+#: part/forms.py:37 stock/forms.py:91
+msgid "Select output file format"
+msgstr "Ausgabe-Dateiformat auswählen"
+
+#: part/forms.py:39
+msgid "Cascading"
+msgstr ""
+
+#: part/forms.py:39
+msgid "Download cascading / multi-level BOM"
+msgstr ""
+
+#: part/forms.py:58
msgid "Confirm that the BOM is correct"
msgstr "Bestätigen, dass die Stückliste korrekt ist"
-#: part/forms.py:49
+#: part/forms.py:70
msgid "Select BOM file to upload"
msgstr "Stücklisten-Datei zum Upload auswählen"
-#: part/forms.py:73
+#: part/forms.py:94
msgid "Select part category"
msgstr "Teilekategorie wählen"
-#: part/forms.py:81
+#: part/forms.py:102
msgid "Perform 'deep copy' which will duplicate all BOM data for this part"
msgstr ""
"Tiefe Kopie ausführen. Dies wird alle Daten der Stückliste für dieses Teil "
"duplizieren"
-#: part/forms.py:86
+#: part/forms.py:107
msgid "Confirm part creation"
msgstr "Erstellen des Teils bestätigen"
-#: part/forms.py:172
+#: part/forms.py:193
msgid "Input quantity for price calculation"
msgstr "Eintragsmenge zur Preisberechnung"
-#: part/forms.py:175
+#: part/forms.py:196
msgid "Select currency for price calculation"
msgstr "Währung zur Preisberechnung wählen"
-#: part/models.py:57
+#: part/models.py:59
msgid "Default location for parts in this category"
msgstr "Standard-Standort für Teile dieser Kategorie"
-#: part/models.py:60
+#: part/models.py:62
msgid "Default keywords for parts in this category"
msgstr "Standard-Stichworte für Teile dieser Kategorie"
-#: part/models.py:309
+#: part/models.py:323
msgid "Part must be unique for name, IPN and revision"
msgstr "Namen, Teile- und Revisionsnummern müssen eindeutig sein"
-#: part/models.py:323
+#: part/models.py:337
msgid "Part cannot be a template part if it is a variant of another part"
msgstr "Teil kann keine Vorlage sein wenn es Variante eines anderen Teils ist"
-#: part/models.py:324
+#: part/models.py:338
msgid "Part cannot be a variant of another part if it is already a template"
msgstr ""
"Teil kann keine Variante eines anderen Teils sein wenn es bereits eine "
"Vorlage ist"
-#: part/models.py:328 part/templates/part/detail.html:17
+#: part/models.py:342 part/templates/part/detail.html:17
msgid "Part name"
msgstr "Name des Teils"
-#: part/models.py:332
+#: part/models.py:346
msgid "Is this part a template part?"
msgstr "Ist dieses Teil eine Vorlage?"
-#: part/models.py:341
+#: part/models.py:355
msgid "Is this part a variant of another part?"
msgstr "Ist dieses Teil eine Variante eines anderen Teils?"
-#: part/models.py:343
+#: part/models.py:357
msgid "Part description"
msgstr "Beschreibung des Teils"
-#: part/models.py:345
+#: part/models.py:359
msgid "Part keywords to improve visibility in search results"
msgstr "Schlüsselworte um die Sichtbarkeit in Suchergebnissen zu verbessern"
-#: part/models.py:350
+#: part/models.py:364
msgid "Part category"
msgstr "Teile-Kategorie"
-#: part/models.py:352
+#: part/models.py:366
msgid "Internal Part Number"
msgstr "Interne Teilenummer"
-#: part/models.py:354
+#: part/models.py:368
msgid "Part revision or version number"
msgstr "Revisions- oder Versionsnummer"
-#: part/models.py:356
+#: part/models.py:370
msgid "Link to extenal URL"
msgstr "Link zu einer Externen URL"
-#: part/models.py:362
+#: part/models.py:376
msgid "Where is this item normally stored?"
msgstr "Wo wird dieses Teil normalerweise gelagert?"
-#: part/models.py:406
+#: part/models.py:420
msgid "Default supplier part"
msgstr "Standard-Zulieferer?"
-#: part/models.py:409
+#: part/models.py:423
msgid "Minimum allowed stock level"
msgstr "Minimal zulässiger Lagerbestand"
-#: part/models.py:411
+#: part/models.py:425
msgid "Stock keeping units for this part"
msgstr "Stock Keeping Units (SKU) für dieses Teil"
-#: part/models.py:413
+#: part/models.py:427
msgid "Can this part be built from other parts?"
msgstr "Kann dieses Teil aus anderen Teilen angefertigt werden?"
-#: part/models.py:415
+#: part/models.py:429
msgid "Can this part be used to build other parts?"
msgstr "Kann dieses Teil zum Bau von anderen genutzt werden?"
-#: part/models.py:417
+#: part/models.py:431
msgid "Does this part have tracking for unique items?"
msgstr "Hat dieses Teil Tracking für einzelne Objekte?"
-#: part/models.py:419
+#: part/models.py:433
msgid "Can this part be purchased from external suppliers?"
msgstr "Kann dieses Teil von externen Zulieferern gekauft werden?"
-#: part/models.py:421
+#: part/models.py:435
msgid "Can this part be sold to customers?"
msgstr "Kann dieses Teil an Kunden verkauft werden?"
-#: part/models.py:423
+#: part/models.py:437
msgid "Is this part active?"
msgstr "Ist dieses Teil aktiv?"
-#: part/models.py:425
+#: part/models.py:439
msgid "Is this a virtual part, such as a software product or license?"
msgstr "Ist dieses Teil virtuell, wie zum Beispiel eine Software oder Lizenz?"
-#: part/models.py:427
+#: part/models.py:441
msgid "Part notes - supports Markdown formatting"
msgstr "Bemerkungen - unterstüzt Markdown-Formatierung"
-#: part/models.py:429
+#: part/models.py:443
msgid "Stored BOM checksum"
msgstr "Prüfsumme der Stückliste gespeichert"
-#: part/models.py:936
+#: part/models.py:948
msgid "Select file to attach"
msgstr "Datei zum Anhängen auswählen"
-#: part/models.py:938
+#: part/models.py:950
msgid "File comment"
msgstr "Datei-Kommentar"
-#: part/models.py:993
+#: part/models.py:1005
msgid "Parameter template name must be unique"
msgstr "Vorlagen-Name des Parameters muss eindeutig sein"
-#: part/models.py:998
+#: part/models.py:1010
msgid "Parameter Name"
msgstr "Name des Parameters"
-#: part/models.py:1000
+#: part/models.py:1012
msgid "Parameter Units"
msgstr "Parameter Einheit"
-#: part/models.py:1026
+#: part/models.py:1038
msgid "Parent Part"
msgstr "Ausgangsteil"
-#: part/models.py:1028
+#: part/models.py:1040
msgid "Parameter Template"
msgstr "Parameter Vorlage"
-#: part/models.py:1030
+#: part/models.py:1042
msgid "Parameter Value"
msgstr "Parameter Wert"
-#: part/models.py:1054
+#: part/models.py:1066
msgid "Select parent part"
msgstr "Ausgangsteil auswählen"
-#: part/models.py:1062
+#: part/models.py:1074
msgid "Select part to be used in BOM"
msgstr "Teil für die Nutzung in der Stückliste auswählen"
-#: part/models.py:1068
+#: part/models.py:1080
msgid "BOM quantity for this BOM item"
msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil"
-#: part/models.py:1071
+#: part/models.py:1083
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr "Geschätzter Ausschuss (absolut oder prozentual)"
-#: part/models.py:1074
+#: part/models.py:1086
msgid "BOM item reference"
msgstr "Referenz des Objekts auf der Stückliste"
-#: part/models.py:1077
+#: part/models.py:1089
msgid "BOM item notes"
msgstr "Notizen zum Stücklisten-Objekt"
-#: part/models.py:1079
+#: part/models.py:1091
msgid "BOM line checksum"
msgstr "Prüfsumme der Stückliste"
-#: part/models.py:1142
+#: part/models.py:1154
msgid "Part cannot be added to its own Bill of Materials"
msgstr "Teil kann nicht zu seiner eigenen Stückliste hinzugefügt werden"
-#: part/models.py:1149
+#: part/models.py:1161
#, python-brace-format
msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)"
msgstr "Teil '{p1}' wird in Stückliste für Teil '{p2}' benutzt (rekursiv)"
@@ -1063,7 +1398,7 @@ msgstr "Datei"
msgid "Comment"
msgstr "Kommentar"
-#: part/templates/part/attachments.html:34
+#: part/templates/part/attachments.html:34 part/views.py:118
msgid "Edit attachment"
msgstr "Anhang bearbeiten"
@@ -1112,7 +1447,7 @@ msgstr "Teile (inklusive Unter-Kategorien)"
msgid "Part Details"
msgstr "Teile-Details"
-#: part/templates/part/detail.html:22 part/templates/part/part_base.html:85
+#: part/templates/part/detail.html:22 part/templates/part/part_base.html:75
msgid "IPN"
msgstr "IPN (Interne Produktnummer)"
@@ -1216,34 +1551,56 @@ msgstr "Teil-Bemerkungen"
msgid "This part is not active"
msgstr "Dieses Teil ist nicht aktiv"
-#: part/templates/part/part_base.html:47
+#: part/templates/part/part_base.html:37
msgid "Star this part"
msgstr "Teil favorisieren"
-#: part/templates/part/part_base.html:53
+#: part/templates/part/part_base.html:43
msgid "Show pricing information"
msgstr "Kosteninformationen ansehen"
-#: part/templates/part/part_base.html:105
+#: part/templates/part/part_base.html:95
msgid "Available Stock"
msgstr "Verfügbarer Lagerbestand"
-#: part/templates/part/part_base.html:110
+#: part/templates/part/part_base.html:100
msgid "In Stock"
msgstr "Auf Lager"
-#: part/templates/part/part_base.html:131
+#: part/templates/part/part_base.html:121
msgid "Build Status"
msgstr "Bau-Status"
-#: part/templates/part/part_base.html:135
+#: part/templates/part/part_base.html:125
msgid "Can Build"
msgstr "Herstellbar?"
-#: part/templates/part/part_base.html:140
+#: part/templates/part/part_base.html:130
msgid "Underway"
msgstr "unterwegs"
+#: part/templates/part/part_thumb.html:16
+#, fuzzy
+#| msgid "Select part"
+msgid "Select from existing images"
+msgstr "Teil auswählen"
+
+#: part/templates/part/part_thumb.html:17
+msgid "Upload new image"
+msgstr ""
+
+#: part/templates/part/stock.html:75
+#, fuzzy
+#| msgid "Part"
+msgid "New Part"
+msgstr "Teil"
+
+#: part/templates/part/stock.html:76
+#, fuzzy
+#| msgid "Create new Stock Item"
+msgid "Create New Part"
+msgstr "Neues Lagerobjekt hinzufügen"
+
#: part/templates/part/tabs.html:9
msgid "Parameters"
msgstr "Parameter"
@@ -1277,195 +1634,231 @@ msgstr "Tracking"
msgid "Attachments"
msgstr "Anhänge"
-#: part/views.py:77
+#: part/views.py:75
+#, fuzzy
+#| msgid "Add Attachment"
+msgid "Add part attachment"
+msgstr "Anhang hinzufügen"
+
+#: part/views.py:80
#, fuzzy
#| msgid "Add Attachment"
msgid "Added attachment"
msgstr "Anhang hinzufügen"
-#: part/views.py:119
+#: part/views.py:122
#, fuzzy
#| msgid "Part Attachments"
msgid "Part attachment updated"
msgstr "Anhänge"
-#: part/views.py:196
+#: part/views.py:137
+#, fuzzy
+#| msgid "Delete attachment"
+msgid "Delete Part Attachment"
+msgstr "Anhang löschen"
+
+#: part/views.py:143
+#, fuzzy
+#| msgid "Delete attachment"
+msgid "Deleted part attachment"
+msgstr "Anhang löschen"
+
+#: part/views.py:151
+#, fuzzy
+#| msgid "Select part category"
+msgid "Set Part Category"
+msgstr "Teilekategorie wählen"
+
+#: part/views.py:199
#, python-brace-format
msgid "Set category for {n} parts"
msgstr "Kategorie für {n} Teile setzen"
-#: part/views.py:306
+#: part/views.py:234
+#, fuzzy
+#| msgid "Create new Stock Item"
+msgid "Create Variant"
+msgstr "Neues Lagerobjekt hinzufügen"
+
+#: part/views.py:304
+#, fuzzy
+#| msgid "Supplier Part"
+msgid "Duplicate Part"
+msgstr "Zulieferer-Teil"
+
+#: part/views.py:309
#, fuzzy
#| msgid "Supplier part"
msgid "Copied part"
msgstr "Zulieferer-Teil"
-#: part/views.py:414
+#: part/views.py:417
#, fuzzy
#| msgid "Create new Stock Item"
msgid "Create new part"
msgstr "Neues Lagerobjekt hinzufügen"
-#: part/views.py:419
+#: part/views.py:422
#, fuzzy
#| msgid "Created new stock item"
msgid "Created new part"
msgstr "Neues Lagerobjekt erstellt"
-#: part/views.py:609
+#: part/views.py:595
+#, fuzzy
+#| msgid "Part Notes"
+msgid "Part QR Code"
+msgstr "Teil-Bemerkungen"
+
+#: part/views.py:612
msgid "Upload Part Image"
msgstr ""
-#: part/views.py:614
+#: part/views.py:617 part/views.py:652
msgid "Updated part image"
msgstr ""
-#: part/views.py:623
+#: part/views.py:626
#, fuzzy
#| msgid "Select part"
msgid "Select Part Image"
msgstr "Teil auswählen"
-#: part/views.py:627
-#, fuzzy
-#| msgid "Select part"
-msgid "Selected part image"
-msgstr "Teil auswählen"
+#: part/views.py:655
+msgid "Part image not found"
+msgstr ""
-#: part/views.py:637
+#: part/views.py:666
#, fuzzy
#| msgid "Edit notes"
msgid "Edit Part Properties"
msgstr "Bermerkungen bearbeiten"
-#: part/views.py:659
+#: part/views.py:688
msgid "Validate BOM"
msgstr ""
-#: part/views.py:821
+#: part/views.py:850
msgid "No BOM file provided"
msgstr "Keine Stückliste angegeben"
-#: part/views.py:1082
+#: part/views.py:1111
msgid "Enter a valid quantity"
msgstr "Bitte eine gültige Anzahl eingeben"
-#: part/views.py:1106 part/views.py:1109
+#: part/views.py:1135 part/views.py:1138
msgid "Select valid part"
msgstr "Bitte ein gültiges Teil auswählen"
-#: part/views.py:1115
+#: part/views.py:1144
msgid "Duplicate part selected"
msgstr "Teil doppelt ausgewählt"
-#: part/views.py:1143
+#: part/views.py:1172
msgid "Select a part"
msgstr "Teil auswählen"
-#: part/views.py:1147
+#: part/views.py:1176
msgid "Specify quantity"
msgstr "Anzahl angeben"
-#: part/views.py:1324
+#: part/views.py:1356
+msgid "Export Bill of Materials"
+msgstr ""
+
+#: part/views.py:1396
#, fuzzy
#| msgid "Confirm part creation"
msgid "Confirm Part Deletion"
msgstr "Erstellen des Teils bestätigen"
-#: part/views.py:1331
+#: part/views.py:1403
msgid "Part was deleted"
msgstr ""
-#: part/views.py:1340
+#: part/views.py:1412
#, fuzzy
#| msgid "Part packaging"
msgid "Part Pricing"
msgstr "Teile-Packaging"
-#: part/views.py:1462
+#: part/views.py:1534
#, fuzzy
#| msgid "Parameter Template"
msgid "Create Part Parameter Template"
msgstr "Parameter Vorlage"
-#: part/views.py:1470
+#: part/views.py:1542
#, fuzzy
#| msgid "Parameter Template"
msgid "Edit Part Parameter Template"
msgstr "Parameter Vorlage"
-#: part/views.py:1477
+#: part/views.py:1549
#, fuzzy
#| msgid "Parameter Template"
msgid "Delete Part Parameter Template"
msgstr "Parameter Vorlage"
-#: part/views.py:1485
+#: part/views.py:1557
msgid "Create Part Parameter"
msgstr ""
-#: part/views.py:1535
+#: part/views.py:1607
#, fuzzy
#| msgid "Edit attachment"
msgid "Edit Part Parameter"
msgstr "Anhang bearbeiten"
-#: part/views.py:1549
+#: part/views.py:1621
#, fuzzy
#| msgid "Delete attachment"
msgid "Delete Part Parameter"
msgstr "Anhang löschen"
-#: part/views.py:1565
+#: part/views.py:1637
#, fuzzy
#| msgid "Part category"
msgid "Edit Part Category"
msgstr "Teile-Kategorie"
-#: part/views.py:1600
+#: part/views.py:1672
#, fuzzy
#| msgid "Select part category"
msgid "Delete Part Category"
msgstr "Teilekategorie wählen"
-#: part/views.py:1606
+#: part/views.py:1678
#, fuzzy
#| msgid "Part category"
msgid "Part category was deleted"
msgstr "Teile-Kategorie"
-#: part/views.py:1614
+#: part/views.py:1686
#, fuzzy
#| msgid "Select part category"
msgid "Create new part category"
msgstr "Teilekategorie wählen"
-#: part/views.py:1665
+#: part/views.py:1737
#, fuzzy
#| msgid "Created new stock item"
msgid "Create BOM item"
msgstr "Neues Lagerobjekt erstellt"
-#: part/views.py:1731
+#: part/views.py:1803
#, fuzzy
#| msgid "Edit Stock Item"
msgid "Edit BOM item"
msgstr "Lagerobjekt bearbeiten"
-#: part/views.py:1779
+#: part/views.py:1851
#, fuzzy
#| msgid "Confirm build completion"
msgid "Confim BOM item deletion"
msgstr "Bau-Fertigstellung bestätigen"
-#: stock/forms.py:91
-msgid "File Format"
-msgstr "Dateiformat"
-
-#: stock/forms.py:91
-msgid "Select output file format"
-msgstr "Ausgabe-Dateiformat auswählen"
-
#: stock/forms.py:93
msgid "Include stock items in sub locations"
msgstr "Lagerobjekte in untergeordneten Lagerorten einschließen"
@@ -1702,135 +2095,135 @@ msgstr "QR-Code für diesen Standort"
msgid "Stock Export Options"
msgstr "Lagerbestandsexportoptionen"
-#: stock/views.py:264
+#: stock/views.py:278
msgid "Stock Item QR Code"
msgstr "Lagerobjekt-QR-Code"
-#: stock/views.py:287
+#: stock/views.py:301
msgid "Adjust Stock"
msgstr "Lagerbestand anpassen"
-#: stock/views.py:396
+#: stock/views.py:410
msgid "Move Stock Items"
msgstr "Lagerobjekte bewegen"
-#: stock/views.py:397
+#: stock/views.py:411
msgid "Count Stock Items"
msgstr "Lagerobjekte zählen"
-#: stock/views.py:398
+#: stock/views.py:412
msgid "Remove From Stock"
msgstr "Aus Lagerbestand entfernen"
-#: stock/views.py:399
+#: stock/views.py:413
msgid "Add Stock Items"
msgstr "Lagerobjekte hinzufügen"
-#: stock/views.py:400
+#: stock/views.py:414
msgid "Delete Stock Items"
msgstr "Lagerobjekte löschen"
-#: stock/views.py:428
+#: stock/views.py:442
msgid "Must enter integer value"
msgstr "Nur Ganzzahl eingeben"
-#: stock/views.py:433
+#: stock/views.py:447
msgid "Quantity must be positive"
msgstr "Anzahl muss positiv sein"
-#: stock/views.py:440
+#: stock/views.py:454
#, python-brace-format
msgid "Quantity must not exceed {x}"
msgstr "Anzahl darf {x} nicht überschreiten"
-#: stock/views.py:448
+#: stock/views.py:462
msgid "Confirm stock adjustment"
msgstr "Bestands-Anpassung bestätigen"
-#: stock/views.py:519
+#: stock/views.py:533
#, python-brace-format
msgid "Added stock to {n} items"
msgstr "Vorrat zu {n} Lagerobjekten hinzugefügt"
-#: stock/views.py:534
+#: stock/views.py:548
#, python-brace-format
msgid "Removed stock from {n} items"
msgstr "Vorrat von {n} Lagerobjekten entfernt"
-#: stock/views.py:547
+#: stock/views.py:561
#, python-brace-format
msgid "Counted stock for {n} items"
msgstr "Bestand für {n} Objekte erfasst"
-#: stock/views.py:575
+#: stock/views.py:589
msgid "No items were moved"
msgstr "Keine Lagerobjekte wurden bewegt"
-#: stock/views.py:578
+#: stock/views.py:592
#, python-brace-format
msgid "Moved {n} items to {dest}"
msgstr "{n} Teile nach {dest} bewegt"
-#: stock/views.py:597
+#: stock/views.py:611
#, python-brace-format
msgid "Deleted {n} stock items"
msgstr "{n} Teile im Lager gelöscht"
-#: stock/views.py:609
+#: stock/views.py:623
msgid "Edit Stock Item"
msgstr "Lagerobjekt bearbeiten"
-#: stock/views.py:645
+#: stock/views.py:659
msgid "Create new Stock Location"
msgstr "Neuen Lager-Standort erstellen"
-#: stock/views.py:666
+#: stock/views.py:680
msgid "Serialize Stock"
msgstr "Lagerbestand erfassen"
-#: stock/views.py:746
+#: stock/views.py:760
msgid "Create new Stock Item"
msgstr "Neues Lagerobjekt hinzufügen"
-#: stock/views.py:810
+#: stock/views.py:824
msgid "Copy Stock Item"
msgstr "Lagerobjekt kopieren"
-#: stock/views.py:860
+#: stock/views.py:892
msgid "Invalid quantity"
msgstr "Ungültige Menge"
-#: stock/views.py:863
+#: stock/views.py:895
msgid "Invalid part selection"
msgstr "Ungültige Teileauswahl"
-#: stock/views.py:910
+#: stock/views.py:942
#, fuzzy, python-brace-format
#| msgid "Created new stock item"
msgid "Created {n} new stock items"
msgstr "Neues Lagerobjekt erstellt"
-#: stock/views.py:927 stock/views.py:940
+#: stock/views.py:959 stock/views.py:972
msgid "Created new stock item"
msgstr "Neues Lagerobjekt erstellt"
-#: stock/views.py:957
+#: stock/views.py:989
msgid "Delete Stock Location"
msgstr "Standort löschen"
-#: stock/views.py:970
+#: stock/views.py:1002
msgid "Delete Stock Item"
msgstr "Lagerobjekt löschen"
-#: stock/views.py:981
+#: stock/views.py:1013
msgid "Delete Stock Tracking Entry"
msgstr "Lagerbestands-Tracking-Eintrag löschen"
-#: stock/views.py:998
+#: stock/views.py:1030
msgid "Edit Stock Tracking Entry"
msgstr "Lagerbestands-Tracking-Eintrag bearbeiten"
-#: stock/views.py:1007
+#: stock/views.py:1039
msgid "Add Stock Tracking Entry"
msgstr "Lagerbestands-Tracking-Eintrag hinzufügen"
@@ -1868,12 +2261,6 @@ msgstr "InvenTree-Dokumentation"
msgid "View Code on GitHub"
msgstr "Code auf GitHub ansehen"
-#: templates/navbar.html:14
-#, fuzzy
-#| msgid "On Order"
-msgid "Orders"
-msgstr "bestellt"
-
#: templates/navbar.html:23
msgid "Admin"
msgstr ""
@@ -1901,3 +2288,45 @@ msgstr ""
#| msgid "Status"
msgid "Statistics"
msgstr "Status"
+
+#: templates/stock_table.html:7
+#, fuzzy
+#| msgid "Stock Item"
+msgid "New Stock Item"
+msgstr "Lagerobjekt"
+
+#: templates/stock_table.html:12
+#, fuzzy
+#| msgid "Add Stock Items"
+msgid "Add stock"
+msgstr "Lagerobjekte hinzufügen"
+
+#: templates/stock_table.html:13
+#, fuzzy
+#| msgid "Remove From Stock"
+msgid "Remove stock"
+msgstr "Aus Lagerbestand entfernen"
+
+#: templates/stock_table.html:14
+#, fuzzy
+#| msgid "Count Stock Items"
+msgid "Count stock"
+msgstr "Lagerobjekte zählen"
+
+#: templates/stock_table.html:15
+#, fuzzy
+#| msgid "Move Stock Items"
+msgid "Move stock"
+msgstr "Lagerobjekte bewegen"
+
+#: templates/stock_table.html:16
+#, fuzzy
+#| msgid "On Order"
+msgid "Order stock"
+msgstr "bestellt"
+
+#: templates/stock_table.html:17
+#, fuzzy
+#| msgid "Delete Stock Item"
+msgid "Delete Stock"
+msgstr "Lagerobjekt löschen"
diff --git a/InvenTree/locale/en/LC_MESSAGES/django.po b/InvenTree/locale/en/LC_MESSAGES/django.po
index 930ff589f8..99c6de1be1 100644
--- a/InvenTree/locale/en/LC_MESSAGES/django.po
+++ b/InvenTree/locale/en/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-02-10 11:09+0000\n"
+"POT-Creation-Date: 2020-02-12 00:31+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -104,7 +104,7 @@ msgstr ""
#: InvenTree/status_codes.py:92 build/templates/build/allocate_edit.html:28
#: build/templates/build/allocate_view.html:21
-#: part/templates/part/part_base.html:116 part/templates/part/tabs.html:21
+#: part/templates/part/part_base.html:106 part/templates/part/tabs.html:21
msgid "Allocated"
msgstr ""
@@ -149,59 +149,59 @@ msgstr ""
msgid "Confirm build completion"
msgstr ""
-#: build/models.py:53
+#: build/models.py:54
msgid "Brief description of the build"
msgstr ""
-#: build/models.py:62
+#: build/models.py:63
msgid "Select part to build"
msgstr ""
-#: build/models.py:68
+#: build/models.py:69
msgid ""
"Select location to take stock from for this build (leave blank to take from "
"any stock location)"
msgstr ""
-#: build/models.py:74
+#: build/models.py:75
msgid "Number of parts to build"
msgstr ""
-#: build/models.py:80
+#: build/models.py:81
msgid "Build status"
msgstr ""
-#: build/models.py:83
+#: build/models.py:84
msgid "Batch code for this build output"
msgstr ""
-#: build/models.py:95
+#: build/models.py:96
msgid "Link to external URL"
msgstr ""
-#: build/models.py:97
+#: build/models.py:98
msgid "Extra build notes"
msgstr ""
-#: build/models.py:382
+#: build/models.py:383
#, python-brace-format
msgid "Selected stock item not found in BOM for part '{p}'"
msgstr ""
-#: build/models.py:385
+#: build/models.py:386
#, python-brace-format
msgid "Allocated quantity ({n}) must not exceed available quantity ({q})"
msgstr ""
-#: build/models.py:403
+#: build/models.py:404
msgid "Build to allocate parts"
msgstr ""
-#: build/models.py:410
+#: build/models.py:411
msgid "Stock Item to allocate to build"
msgstr ""
-#: build/models.py:418
+#: build/models.py:419
msgid "Stock quantity to allocate to build"
msgstr ""
@@ -244,23 +244,27 @@ msgid "Allocate"
msgstr ""
#: build/templates/build/allocate_view.html:10
-#: company/templates/company/detail_part.html:18
+#: company/templates/company/detail_part.html:18 order/views.py:448
msgid "Order Parts"
msgstr ""
#: build/templates/build/allocate_view.html:18
#: company/templates/company/index.html:54
-#: company/templates/company/partdetail.html:57
+#: company/templates/company/supplier_part_detail.html:27
#: order/templates/order/purchase_order_detail.html:26
#: part/templates/part/detail.html:33
msgid "Description"
msgstr ""
#: build/templates/build/allocate_view.html:22
-#: part/templates/part/part_base.html:122
+#: part/templates/part/part_base.html:112
msgid "On Order"
msgstr ""
+#: build/templates/build/delete_build_item.html:6
+msgid "Are you sure you want to unallocate these parts?"
+msgstr ""
+
#: build/templates/build/detail.html:8
msgid "Build Details"
msgstr ""
@@ -270,7 +274,7 @@ msgid "Title"
msgstr ""
#: build/templates/build/detail.html:20
-#: company/templates/company/partdetail.html:85
+#: company/templates/company/supplier_part_pricing.html:27
#: order/templates/order/purchase_order_detail.html:29
#: stock/templates/stock/item_base.html:90
#: stock/templates/stock/stock_adjust.html:18
@@ -297,8 +301,8 @@ msgstr ""
#: build/templates/build/detail.html:42
#: company/templates/company/detail_part.html:90
-#: company/templates/company/partdetail.html:54
-#: part/templates/part/detail.html:50 part/templates/part/part_base.html:91
+#: company/templates/company/supplier_part_detail.html:24
+#: part/templates/part/detail.html:50 part/templates/part/part_base.html:81
#: stock/templates/stock/item_base.html:120
msgid "URL"
msgstr ""
@@ -340,8 +344,9 @@ msgstr ""
msgid "Edit notes"
msgstr ""
-#: build/templates/build/tabs.html:5 company/templates/company/tabs.html:5
-#: part/templates/part/tabs.html:6
+#: build/templates/build/tabs.html:5
+#: company/templates/company/supplier_part_tabs.html:5
+#: company/templates/company/tabs.html:5 part/templates/part/tabs.html:6
msgid "Details"
msgstr ""
@@ -355,11 +360,107 @@ msgstr ""
msgid "Assign Parts"
msgstr ""
-#: build/views.py:290 stock/views.py:884
+#: build/templates/build/unallocate.html:8
+msgid "Are you sure you wish to unallocate all stock for this build?"
+msgstr ""
+
+#: build/views.py:56
+msgid "Cancel Build"
+msgstr ""
+
+#: build/views.py:74
+msgid "Confirm build cancellation"
+msgstr ""
+
+#: build/views.py:79
+msgid "Build was cancelled"
+msgstr ""
+
+#: build/views.py:95
+msgid "Allocate Stock"
+msgstr ""
+
+#: build/views.py:108
+msgid "No matching build found"
+msgstr ""
+
+#: build/views.py:127
+msgid "Confirm stock allocation"
+msgstr ""
+
+#: build/views.py:128
+msgid "Check the confirmation box at the bottom of the list"
+msgstr ""
+
+#: build/views.py:148 build/views.py:442
+msgid "Unallocate Stock"
+msgstr ""
+
+#: build/views.py:161
+msgid "Confirm unallocation of build stock"
+msgstr ""
+
+#: build/views.py:162
+msgid "Check the confirmation box"
+msgstr ""
+
+#: build/views.py:185
+msgid "Complete Build"
+msgstr ""
+
+#: build/views.py:258
+msgid "Confirm completion of build"
+msgstr ""
+
+#: build/views.py:265
+msgid "Invalid location selected"
+msgstr ""
+
+#: build/views.py:290 stock/views.py:916
#, python-brace-format
msgid "The following serial numbers already exist: ({sn})"
msgstr ""
+#: build/views.py:309
+msgid "Build marked as COMPLETE"
+msgstr ""
+
+#: build/views.py:385
+msgid "Start new Build"
+msgstr ""
+
+#: build/views.py:408
+msgid "Created new build"
+msgstr ""
+
+#: build/views.py:418
+msgid "Edit Build Details"
+msgstr ""
+
+#: build/views.py:423
+msgid "Edited build"
+msgstr ""
+
+#: build/views.py:432
+msgid "Delete Build"
+msgstr ""
+
+#: build/views.py:447
+msgid "Removed parts from build allocation"
+msgstr ""
+
+#: build/views.py:457
+msgid "Allocate new Part"
+msgstr ""
+
+#: build/views.py:573
+msgid "Edit Stock Allocation"
+msgstr ""
+
+#: build/views.py:577
+msgid "Updated Build Item"
+msgstr ""
+
#: common/models.py:69
msgid "Settings key (must be unique - case insensitive"
msgstr ""
@@ -396,6 +497,18 @@ msgstr ""
msgid "Use this currency as the base currency"
msgstr ""
+#: common/views.py:21
+msgid "Create new Currency"
+msgstr ""
+
+#: common/views.py:29
+msgid "Edit Currency"
+msgstr ""
+
+#: common/views.py:36
+msgid "Delete Currency"
+msgstr ""
+
#: company/models.py:74
msgid "Company name"
msgstr ""
@@ -449,7 +562,7 @@ msgid "Supplier stock keeping unit"
msgstr ""
#: company/models.py:240 company/templates/company/detail_part.html:81
-#: company/templates/company/partdetail.html:60
+#: company/templates/company/supplier_part_detail.html:30
msgid "Manufacturer"
msgstr ""
@@ -509,7 +622,7 @@ msgstr ""
#: company/templates/company/detail.html:17
#: company/templates/company/index.html:46
-#: company/templates/company/partdetail.html:51
+#: company/templates/company/supplier_part_detail.html:21
#: order/templates/order/order_base.html:67
#: stock/templates/stock/item_base.html:126
msgid "Supplier"
@@ -521,10 +634,11 @@ msgid "Supplier Parts"
msgstr ""
#: company/templates/company/detail_part.html:13
+#: part/templates/part/stock.html:81
msgid "New Supplier Part"
msgstr ""
-#: company/templates/company/detail_part.html:15
+#: company/templates/company/detail_part.html:15 templates/stock_table.html:10
msgid "Options"
msgstr ""
@@ -533,12 +647,11 @@ msgid "Delete Parts"
msgstr ""
#: company/templates/company/detail_part.html:73
-#: company/templates/company/partdetail.html:52
+#: company/templates/company/supplier_part_detail.html:22
msgid "SKU"
msgstr ""
#: company/templates/company/detail_purchase_orders.html:8
-#: company/templates/company/partdetail.html:116
#: company/templates/company/tabs.html:15 part/templates/part/tabs.html:43
msgid "Purchase Orders"
msgstr ""
@@ -552,6 +665,8 @@ msgid "Supplier Stock"
msgstr ""
#: company/templates/company/detail_stock.html:33
+#: company/templates/company/supplier_part_stock.html:38
+#: part/templates/part/stock.html:53 templates/stock_table.html:5
msgid "Export"
msgstr ""
@@ -568,10 +683,8 @@ msgstr ""
msgid "ID"
msgstr ""
-#: company/templates/company/index.html:69
-#: company/templates/company/partdetail.html:6
-#: part/templates/part/category.html:73 templates/navbar.html:10
-#: templates/stats.html:7 templates/stats.html:10
+#: company/templates/company/index.html:69 part/templates/part/category.html:73
+#: templates/navbar.html:10 templates/stats.html:7 templates/stats.html:10
msgid "Parts"
msgstr ""
@@ -584,65 +697,150 @@ msgstr ""
msgid "Are you sure you want to delete the following Supplier Parts?"
msgstr ""
-#: company/templates/company/partdetail.html:13
+#: company/templates/company/supplier_part_base.html:6
+#: company/templates/company/supplier_part_base.html:13
#: stock/templates/stock/item_base.html:130
msgid "Supplier Part"
msgstr ""
-#: company/templates/company/partdetail.html:41
+#: company/templates/company/supplier_part_detail.html:11
msgid "Supplier Part Details"
msgstr ""
-#: company/templates/company/partdetail.html:44
+#: company/templates/company/supplier_part_detail.html:14
msgid "Internal Part"
msgstr ""
-#: company/templates/company/partdetail.html:61
+#: company/templates/company/supplier_part_detail.html:31
msgid "MPN"
msgstr ""
-#: company/templates/company/partdetail.html:64
+#: company/templates/company/supplier_part_detail.html:34
#: order/templates/order/purchase_order_detail.html:33
msgid "Note"
msgstr ""
-#: company/templates/company/partdetail.html:70
+#: company/templates/company/supplier_part_orders.html:11
+msgid "Supplier Part Orders"
+msgstr ""
+
+#: company/templates/company/supplier_part_pricing.html:12
msgid "Pricing Information"
msgstr ""
-#: company/templates/company/partdetail.html:72
+#: company/templates/company/supplier_part_pricing.html:14
msgid "Order Multiple"
msgstr ""
-#: company/templates/company/partdetail.html:74
+#: company/templates/company/supplier_part_pricing.html:16
msgid "Base Price (Flat Fee)"
msgstr ""
-#: company/templates/company/partdetail.html:77
+#: company/templates/company/supplier_part_pricing.html:19
msgid "Price Breaks"
msgstr ""
-#: company/templates/company/partdetail.html:80
+#: company/templates/company/supplier_part_pricing.html:22
msgid "New Price Break"
msgstr ""
-#: company/templates/company/partdetail.html:86
+#: company/templates/company/supplier_part_pricing.html:28
msgid "Price"
msgstr ""
-#: company/templates/company/partdetail.html:106
+#: company/templates/company/supplier_part_pricing.html:48
msgid "No price breaks have been added for this part"
msgstr ""
+#: company/templates/company/supplier_part_stock.html:11
+msgid "Supplier Part Stock"
+msgstr ""
+
+#: company/templates/company/supplier_part_stock.html:61
+#: part/templates/part/stock.html:90
+msgid "New Location"
+msgstr ""
+
+#: company/templates/company/supplier_part_stock.html:62
+#: part/templates/part/stock.html:91
+msgid "Create New Location"
+msgstr ""
+
+#: company/templates/company/supplier_part_tabs.html:8
+msgid "Pricing"
+msgstr ""
+
+#: company/templates/company/supplier_part_tabs.html:11
#: company/templates/company/tabs.html:12 part/templates/part/tabs.html:17
#: templates/navbar.html:11
msgid "Stock"
msgstr ""
+#: company/templates/company/supplier_part_tabs.html:14
+#: templates/navbar.html:14
+msgid "Orders"
+msgstr ""
+
#: company/templates/company/tabs.html:21
msgid "Sales Orders"
msgstr ""
+#: company/views.py:97
+msgid "Update Company Image"
+msgstr ""
+
+#: company/views.py:102
+msgid "Updated company image"
+msgstr ""
+
+#: company/views.py:112
+msgid "Edit Company"
+msgstr ""
+
+#: company/views.py:116
+msgid "Edited company information"
+msgstr ""
+
+#: company/views.py:126
+msgid "Create new Company"
+msgstr ""
+
+#: company/views.py:130
+msgid "Created new company"
+msgstr ""
+
+#: company/views.py:140
+msgid "Delete Company"
+msgstr ""
+
+#: company/views.py:145
+msgid "Company was deleted"
+msgstr ""
+
+#: company/views.py:170
+msgid "Edit Supplier Part"
+msgstr ""
+
+#: company/views.py:179 part/templates/part/stock.html:82
+msgid "Create new Supplier Part"
+msgstr ""
+
+#: company/views.py:236
+msgid "Delete Supplier Part"
+msgstr ""
+
+#: company/views.py:306
+msgid "Add Price Break"
+msgstr ""
+
+#: company/views.py:341
+msgid "Edit Price Break"
+msgstr ""
+
+#: company/views.py:356
+msgid "Delete Price Break"
+msgstr ""
+
#: order/forms.py:21
msgid "Place order"
msgstr ""
@@ -675,7 +873,7 @@ msgstr ""
msgid "Order notes"
msgstr ""
-#: order/models.py:159 order/models.py:210 part/views.py:1080
+#: order/models.py:159 order/models.py:210 part/views.py:1109
#: stock/models.py:440
msgid "Quantity must be greater than zero"
msgstr ""
@@ -730,7 +928,7 @@ msgstr ""
msgid "Order Notes"
msgstr ""
-#: order/templates/order/purchase_order_detail.html:15
+#: order/templates/order/purchase_order_detail.html:15 order/views.py:747
msgid "Add Line Item"
msgstr ""
@@ -754,14 +952,38 @@ msgstr ""
msgid "Items"
msgstr ""
+#: order/views.py:99
+msgid "Create Purchase Order"
+msgstr ""
+
+#: order/views.py:129
+msgid "Edit Purchase Order"
+msgstr ""
+
+#: order/views.py:149
+msgid "Cancel Order"
+msgstr ""
+
#: order/views.py:164
msgid "Confirm order cancellation"
msgstr ""
+#: order/views.py:182
+msgid "Issue Order"
+msgstr ""
+
#: order/views.py:197
msgid "Confirm order placement"
msgstr ""
+#: order/views.py:218
+msgid "Complete Order"
+msgstr ""
+
+#: order/views.py:284
+msgid "Receive Parts"
+msgstr ""
+
#: order/views.py:351
msgid "Items received"
msgstr ""
@@ -794,220 +1016,248 @@ msgstr ""
msgid "Invalid SupplierPart selection"
msgstr ""
-#: part/bom.py:107
+#: order/views.py:862
+msgid "Edit Line Item"
+msgstr ""
+
+#: order/views.py:878
+msgid "Delete Line Item"
+msgstr ""
+
+#: order/views.py:883
+msgid "Deleted line item"
+msgstr ""
+
+#: part/bom.py:140
#, python-brace-format
msgid "Unsupported file format: {f}"
msgstr ""
-#: part/bom.py:112
+#: part/bom.py:145
msgid "Error reading BOM file (invalid data)"
msgstr ""
-#: part/bom.py:114
+#: part/bom.py:147
msgid "Error reading BOM file (incorrect row size)"
msgstr ""
-#: part/forms.py:37
+#: part/forms.py:37 stock/forms.py:91
+msgid "File Format"
+msgstr ""
+
+#: part/forms.py:37 stock/forms.py:91
+msgid "Select output file format"
+msgstr ""
+
+#: part/forms.py:39
+msgid "Cascading"
+msgstr ""
+
+#: part/forms.py:39
+msgid "Download cascading / multi-level BOM"
+msgstr ""
+
+#: part/forms.py:58
msgid "Confirm that the BOM is correct"
msgstr ""
-#: part/forms.py:49
+#: part/forms.py:70
msgid "Select BOM file to upload"
msgstr ""
-#: part/forms.py:73
+#: part/forms.py:94
msgid "Select part category"
msgstr ""
-#: part/forms.py:81
+#: part/forms.py:102
msgid "Perform 'deep copy' which will duplicate all BOM data for this part"
msgstr ""
-#: part/forms.py:86
+#: part/forms.py:107
msgid "Confirm part creation"
msgstr ""
-#: part/forms.py:172
+#: part/forms.py:193
msgid "Input quantity for price calculation"
msgstr ""
-#: part/forms.py:175
+#: part/forms.py:196
msgid "Select currency for price calculation"
msgstr ""
-#: part/models.py:57
+#: part/models.py:59
msgid "Default location for parts in this category"
msgstr ""
-#: part/models.py:60
+#: part/models.py:62
msgid "Default keywords for parts in this category"
msgstr ""
-#: part/models.py:309
+#: part/models.py:323
msgid "Part must be unique for name, IPN and revision"
msgstr ""
-#: part/models.py:323
+#: part/models.py:337
msgid "Part cannot be a template part if it is a variant of another part"
msgstr ""
-#: part/models.py:324
+#: part/models.py:338
msgid "Part cannot be a variant of another part if it is already a template"
msgstr ""
-#: part/models.py:328 part/templates/part/detail.html:17
+#: part/models.py:342 part/templates/part/detail.html:17
msgid "Part name"
msgstr ""
-#: part/models.py:332
+#: part/models.py:346
msgid "Is this part a template part?"
msgstr ""
-#: part/models.py:341
+#: part/models.py:355
msgid "Is this part a variant of another part?"
msgstr ""
-#: part/models.py:343
+#: part/models.py:357
msgid "Part description"
msgstr ""
-#: part/models.py:345
+#: part/models.py:359
msgid "Part keywords to improve visibility in search results"
msgstr ""
-#: part/models.py:350
+#: part/models.py:364
msgid "Part category"
msgstr ""
-#: part/models.py:352
+#: part/models.py:366
msgid "Internal Part Number"
msgstr ""
-#: part/models.py:354
+#: part/models.py:368
msgid "Part revision or version number"
msgstr ""
-#: part/models.py:356
+#: part/models.py:370
msgid "Link to extenal URL"
msgstr ""
-#: part/models.py:362
+#: part/models.py:376
msgid "Where is this item normally stored?"
msgstr ""
-#: part/models.py:406
+#: part/models.py:420
msgid "Default supplier part"
msgstr ""
-#: part/models.py:409
+#: part/models.py:423
msgid "Minimum allowed stock level"
msgstr ""
-#: part/models.py:411
+#: part/models.py:425
msgid "Stock keeping units for this part"
msgstr ""
-#: part/models.py:413
+#: part/models.py:427
msgid "Can this part be built from other parts?"
msgstr ""
-#: part/models.py:415
+#: part/models.py:429
msgid "Can this part be used to build other parts?"
msgstr ""
-#: part/models.py:417
+#: part/models.py:431
msgid "Does this part have tracking for unique items?"
msgstr ""
-#: part/models.py:419
+#: part/models.py:433
msgid "Can this part be purchased from external suppliers?"
msgstr ""
-#: part/models.py:421
+#: part/models.py:435
msgid "Can this part be sold to customers?"
msgstr ""
-#: part/models.py:423
+#: part/models.py:437
msgid "Is this part active?"
msgstr ""
-#: part/models.py:425
+#: part/models.py:439
msgid "Is this a virtual part, such as a software product or license?"
msgstr ""
-#: part/models.py:427
+#: part/models.py:441
msgid "Part notes - supports Markdown formatting"
msgstr ""
-#: part/models.py:429
+#: part/models.py:443
msgid "Stored BOM checksum"
msgstr ""
-#: part/models.py:936
+#: part/models.py:948
msgid "Select file to attach"
msgstr ""
-#: part/models.py:938
+#: part/models.py:950
msgid "File comment"
msgstr ""
-#: part/models.py:993
+#: part/models.py:1005
msgid "Parameter template name must be unique"
msgstr ""
-#: part/models.py:998
+#: part/models.py:1010
msgid "Parameter Name"
msgstr ""
-#: part/models.py:1000
+#: part/models.py:1012
msgid "Parameter Units"
msgstr ""
-#: part/models.py:1026
+#: part/models.py:1038
msgid "Parent Part"
msgstr ""
-#: part/models.py:1028
+#: part/models.py:1040
msgid "Parameter Template"
msgstr ""
-#: part/models.py:1030
+#: part/models.py:1042
msgid "Parameter Value"
msgstr ""
-#: part/models.py:1054
+#: part/models.py:1066
msgid "Select parent part"
msgstr ""
-#: part/models.py:1062
+#: part/models.py:1074
msgid "Select part to be used in BOM"
msgstr ""
-#: part/models.py:1068
+#: part/models.py:1080
msgid "BOM quantity for this BOM item"
msgstr ""
-#: part/models.py:1071
+#: part/models.py:1083
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr ""
-#: part/models.py:1074
+#: part/models.py:1086
msgid "BOM item reference"
msgstr ""
-#: part/models.py:1077
+#: part/models.py:1089
msgid "BOM item notes"
msgstr ""
-#: part/models.py:1079
+#: part/models.py:1091
msgid "BOM line checksum"
msgstr ""
-#: part/models.py:1142
+#: part/models.py:1154
msgid "Part cannot be added to its own Bill of Materials"
msgstr ""
-#: part/models.py:1149
+#: part/models.py:1161
#, python-brace-format
msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)"
msgstr ""
@@ -1028,7 +1278,7 @@ msgstr ""
msgid "Comment"
msgstr ""
-#: part/templates/part/attachments.html:34
+#: part/templates/part/attachments.html:34 part/views.py:118
msgid "Edit attachment"
msgstr ""
@@ -1077,7 +1327,7 @@ msgstr ""
msgid "Part Details"
msgstr ""
-#: part/templates/part/detail.html:22 part/templates/part/part_base.html:85
+#: part/templates/part/detail.html:22 part/templates/part/part_base.html:75
msgid "IPN"
msgstr ""
@@ -1181,34 +1431,50 @@ msgstr ""
msgid "This part is not active"
msgstr ""
-#: part/templates/part/part_base.html:47
+#: part/templates/part/part_base.html:37
msgid "Star this part"
msgstr ""
-#: part/templates/part/part_base.html:53
+#: part/templates/part/part_base.html:43
msgid "Show pricing information"
msgstr ""
-#: part/templates/part/part_base.html:105
+#: part/templates/part/part_base.html:95
msgid "Available Stock"
msgstr ""
-#: part/templates/part/part_base.html:110
+#: part/templates/part/part_base.html:100
msgid "In Stock"
msgstr ""
-#: part/templates/part/part_base.html:131
+#: part/templates/part/part_base.html:121
msgid "Build Status"
msgstr ""
-#: part/templates/part/part_base.html:135
+#: part/templates/part/part_base.html:125
msgid "Can Build"
msgstr ""
-#: part/templates/part/part_base.html:140
+#: part/templates/part/part_base.html:130
msgid "Underway"
msgstr ""
+#: part/templates/part/part_thumb.html:16
+msgid "Select from existing images"
+msgstr ""
+
+#: part/templates/part/part_thumb.html:17
+msgid "Upload new image"
+msgstr ""
+
+#: part/templates/part/stock.html:75
+msgid "New Part"
+msgstr ""
+
+#: part/templates/part/stock.html:76
+msgid "Create New Part"
+msgstr ""
+
#: part/templates/part/tabs.html:9
msgid "Parameters"
msgstr ""
@@ -1242,151 +1508,175 @@ msgstr ""
msgid "Attachments"
msgstr ""
-#: part/views.py:77
+#: part/views.py:75
+msgid "Add part attachment"
+msgstr ""
+
+#: part/views.py:80
msgid "Added attachment"
msgstr ""
-#: part/views.py:119
+#: part/views.py:122
msgid "Part attachment updated"
msgstr ""
-#: part/views.py:196
+#: part/views.py:137
+msgid "Delete Part Attachment"
+msgstr ""
+
+#: part/views.py:143
+msgid "Deleted part attachment"
+msgstr ""
+
+#: part/views.py:151
+msgid "Set Part Category"
+msgstr ""
+
+#: part/views.py:199
#, python-brace-format
msgid "Set category for {n} parts"
msgstr ""
-#: part/views.py:306
+#: part/views.py:234
+msgid "Create Variant"
+msgstr ""
+
+#: part/views.py:304
+msgid "Duplicate Part"
+msgstr ""
+
+#: part/views.py:309
msgid "Copied part"
msgstr ""
-#: part/views.py:414
+#: part/views.py:417
msgid "Create new part"
msgstr ""
-#: part/views.py:419
+#: part/views.py:422
msgid "Created new part"
msgstr ""
-#: part/views.py:609
+#: part/views.py:595
+msgid "Part QR Code"
+msgstr ""
+
+#: part/views.py:612
msgid "Upload Part Image"
msgstr ""
-#: part/views.py:614
+#: part/views.py:617 part/views.py:652
msgid "Updated part image"
msgstr ""
-#: part/views.py:623
+#: part/views.py:626
msgid "Select Part Image"
msgstr ""
-#: part/views.py:627
-msgid "Selected part image"
+#: part/views.py:655
+msgid "Part image not found"
msgstr ""
-#: part/views.py:637
+#: part/views.py:666
msgid "Edit Part Properties"
msgstr ""
-#: part/views.py:659
+#: part/views.py:688
msgid "Validate BOM"
msgstr ""
-#: part/views.py:821
+#: part/views.py:850
msgid "No BOM file provided"
msgstr ""
-#: part/views.py:1082
+#: part/views.py:1111
msgid "Enter a valid quantity"
msgstr ""
-#: part/views.py:1106 part/views.py:1109
+#: part/views.py:1135 part/views.py:1138
msgid "Select valid part"
msgstr ""
-#: part/views.py:1115
+#: part/views.py:1144
msgid "Duplicate part selected"
msgstr ""
-#: part/views.py:1143
+#: part/views.py:1172
msgid "Select a part"
msgstr ""
-#: part/views.py:1147
+#: part/views.py:1176
msgid "Specify quantity"
msgstr ""
-#: part/views.py:1324
+#: part/views.py:1356
+msgid "Export Bill of Materials"
+msgstr ""
+
+#: part/views.py:1396
msgid "Confirm Part Deletion"
msgstr ""
-#: part/views.py:1331
+#: part/views.py:1403
msgid "Part was deleted"
msgstr ""
-#: part/views.py:1340
+#: part/views.py:1412
msgid "Part Pricing"
msgstr ""
-#: part/views.py:1462
+#: part/views.py:1534
msgid "Create Part Parameter Template"
msgstr ""
-#: part/views.py:1470
+#: part/views.py:1542
msgid "Edit Part Parameter Template"
msgstr ""
-#: part/views.py:1477
+#: part/views.py:1549
msgid "Delete Part Parameter Template"
msgstr ""
-#: part/views.py:1485
+#: part/views.py:1557
msgid "Create Part Parameter"
msgstr ""
-#: part/views.py:1535
+#: part/views.py:1607
msgid "Edit Part Parameter"
msgstr ""
-#: part/views.py:1549
+#: part/views.py:1621
msgid "Delete Part Parameter"
msgstr ""
-#: part/views.py:1565
+#: part/views.py:1637
msgid "Edit Part Category"
msgstr ""
-#: part/views.py:1600
+#: part/views.py:1672
msgid "Delete Part Category"
msgstr ""
-#: part/views.py:1606
+#: part/views.py:1678
msgid "Part category was deleted"
msgstr ""
-#: part/views.py:1614
+#: part/views.py:1686
msgid "Create new part category"
msgstr ""
-#: part/views.py:1665
+#: part/views.py:1737
msgid "Create BOM item"
msgstr ""
-#: part/views.py:1731
+#: part/views.py:1803
msgid "Edit BOM item"
msgstr ""
-#: part/views.py:1779
+#: part/views.py:1851
msgid "Confim BOM item deletion"
msgstr ""
-#: stock/forms.py:91
-msgid "File Format"
-msgstr ""
-
-#: stock/forms.py:91
-msgid "Select output file format"
-msgstr ""
-
#: stock/forms.py:93
msgid "Include stock items in sub locations"
msgstr ""
@@ -1616,134 +1906,134 @@ msgstr ""
msgid "Stock Export Options"
msgstr ""
-#: stock/views.py:264
+#: stock/views.py:278
msgid "Stock Item QR Code"
msgstr ""
-#: stock/views.py:287
+#: stock/views.py:301
msgid "Adjust Stock"
msgstr ""
-#: stock/views.py:396
+#: stock/views.py:410
msgid "Move Stock Items"
msgstr ""
-#: stock/views.py:397
+#: stock/views.py:411
msgid "Count Stock Items"
msgstr ""
-#: stock/views.py:398
+#: stock/views.py:412
msgid "Remove From Stock"
msgstr ""
-#: stock/views.py:399
+#: stock/views.py:413
msgid "Add Stock Items"
msgstr ""
-#: stock/views.py:400
+#: stock/views.py:414
msgid "Delete Stock Items"
msgstr ""
-#: stock/views.py:428
+#: stock/views.py:442
msgid "Must enter integer value"
msgstr ""
-#: stock/views.py:433
+#: stock/views.py:447
msgid "Quantity must be positive"
msgstr ""
-#: stock/views.py:440
+#: stock/views.py:454
#, python-brace-format
msgid "Quantity must not exceed {x}"
msgstr ""
-#: stock/views.py:448
+#: stock/views.py:462
msgid "Confirm stock adjustment"
msgstr ""
-#: stock/views.py:519
+#: stock/views.py:533
#, python-brace-format
msgid "Added stock to {n} items"
msgstr ""
-#: stock/views.py:534
+#: stock/views.py:548
#, python-brace-format
msgid "Removed stock from {n} items"
msgstr ""
-#: stock/views.py:547
+#: stock/views.py:561
#, python-brace-format
msgid "Counted stock for {n} items"
msgstr ""
-#: stock/views.py:575
+#: stock/views.py:589
msgid "No items were moved"
msgstr ""
-#: stock/views.py:578
+#: stock/views.py:592
#, python-brace-format
msgid "Moved {n} items to {dest}"
msgstr ""
-#: stock/views.py:597
+#: stock/views.py:611
#, python-brace-format
msgid "Deleted {n} stock items"
msgstr ""
-#: stock/views.py:609
+#: stock/views.py:623
msgid "Edit Stock Item"
msgstr ""
-#: stock/views.py:645
+#: stock/views.py:659
msgid "Create new Stock Location"
msgstr ""
-#: stock/views.py:666
+#: stock/views.py:680
msgid "Serialize Stock"
msgstr ""
-#: stock/views.py:746
+#: stock/views.py:760
msgid "Create new Stock Item"
msgstr ""
-#: stock/views.py:810
+#: stock/views.py:824
msgid "Copy Stock Item"
msgstr ""
-#: stock/views.py:860
+#: stock/views.py:892
msgid "Invalid quantity"
msgstr ""
-#: stock/views.py:863
+#: stock/views.py:895
msgid "Invalid part selection"
msgstr ""
-#: stock/views.py:910
+#: stock/views.py:942
#, python-brace-format
msgid "Created {n} new stock items"
msgstr ""
-#: stock/views.py:927 stock/views.py:940
+#: stock/views.py:959 stock/views.py:972
msgid "Created new stock item"
msgstr ""
-#: stock/views.py:957
+#: stock/views.py:989
msgid "Delete Stock Location"
msgstr ""
-#: stock/views.py:970
+#: stock/views.py:1002
msgid "Delete Stock Item"
msgstr ""
-#: stock/views.py:981
+#: stock/views.py:1013
msgid "Delete Stock Tracking Entry"
msgstr ""
-#: stock/views.py:998
+#: stock/views.py:1030
msgid "Edit Stock Tracking Entry"
msgstr ""
-#: stock/views.py:1007
+#: stock/views.py:1039
msgid "Add Stock Tracking Entry"
msgstr ""
@@ -1779,10 +2069,6 @@ msgstr ""
msgid "View Code on GitHub"
msgstr ""
-#: templates/navbar.html:14
-msgid "Orders"
-msgstr ""
-
#: templates/navbar.html:23
msgid "Admin"
msgstr ""
@@ -1806,3 +2092,31 @@ msgstr ""
#: templates/navbar.html:33
msgid "Statistics"
msgstr ""
+
+#: templates/stock_table.html:7
+msgid "New Stock Item"
+msgstr ""
+
+#: templates/stock_table.html:12
+msgid "Add stock"
+msgstr ""
+
+#: templates/stock_table.html:13
+msgid "Remove stock"
+msgstr ""
+
+#: templates/stock_table.html:14
+msgid "Count stock"
+msgstr ""
+
+#: templates/stock_table.html:15
+msgid "Move stock"
+msgstr ""
+
+#: templates/stock_table.html:16
+msgid "Order stock"
+msgstr ""
+
+#: templates/stock_table.html:17
+msgid "Delete Stock"
+msgstr ""
diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po
index 930ff589f8..99c6de1be1 100644
--- a/InvenTree/locale/es/LC_MESSAGES/django.po
+++ b/InvenTree/locale/es/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-02-10 11:09+0000\n"
+"POT-Creation-Date: 2020-02-12 00:31+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -104,7 +104,7 @@ msgstr ""
#: InvenTree/status_codes.py:92 build/templates/build/allocate_edit.html:28
#: build/templates/build/allocate_view.html:21
-#: part/templates/part/part_base.html:116 part/templates/part/tabs.html:21
+#: part/templates/part/part_base.html:106 part/templates/part/tabs.html:21
msgid "Allocated"
msgstr ""
@@ -149,59 +149,59 @@ msgstr ""
msgid "Confirm build completion"
msgstr ""
-#: build/models.py:53
+#: build/models.py:54
msgid "Brief description of the build"
msgstr ""
-#: build/models.py:62
+#: build/models.py:63
msgid "Select part to build"
msgstr ""
-#: build/models.py:68
+#: build/models.py:69
msgid ""
"Select location to take stock from for this build (leave blank to take from "
"any stock location)"
msgstr ""
-#: build/models.py:74
+#: build/models.py:75
msgid "Number of parts to build"
msgstr ""
-#: build/models.py:80
+#: build/models.py:81
msgid "Build status"
msgstr ""
-#: build/models.py:83
+#: build/models.py:84
msgid "Batch code for this build output"
msgstr ""
-#: build/models.py:95
+#: build/models.py:96
msgid "Link to external URL"
msgstr ""
-#: build/models.py:97
+#: build/models.py:98
msgid "Extra build notes"
msgstr ""
-#: build/models.py:382
+#: build/models.py:383
#, python-brace-format
msgid "Selected stock item not found in BOM for part '{p}'"
msgstr ""
-#: build/models.py:385
+#: build/models.py:386
#, python-brace-format
msgid "Allocated quantity ({n}) must not exceed available quantity ({q})"
msgstr ""
-#: build/models.py:403
+#: build/models.py:404
msgid "Build to allocate parts"
msgstr ""
-#: build/models.py:410
+#: build/models.py:411
msgid "Stock Item to allocate to build"
msgstr ""
-#: build/models.py:418
+#: build/models.py:419
msgid "Stock quantity to allocate to build"
msgstr ""
@@ -244,23 +244,27 @@ msgid "Allocate"
msgstr ""
#: build/templates/build/allocate_view.html:10
-#: company/templates/company/detail_part.html:18
+#: company/templates/company/detail_part.html:18 order/views.py:448
msgid "Order Parts"
msgstr ""
#: build/templates/build/allocate_view.html:18
#: company/templates/company/index.html:54
-#: company/templates/company/partdetail.html:57
+#: company/templates/company/supplier_part_detail.html:27
#: order/templates/order/purchase_order_detail.html:26
#: part/templates/part/detail.html:33
msgid "Description"
msgstr ""
#: build/templates/build/allocate_view.html:22
-#: part/templates/part/part_base.html:122
+#: part/templates/part/part_base.html:112
msgid "On Order"
msgstr ""
+#: build/templates/build/delete_build_item.html:6
+msgid "Are you sure you want to unallocate these parts?"
+msgstr ""
+
#: build/templates/build/detail.html:8
msgid "Build Details"
msgstr ""
@@ -270,7 +274,7 @@ msgid "Title"
msgstr ""
#: build/templates/build/detail.html:20
-#: company/templates/company/partdetail.html:85
+#: company/templates/company/supplier_part_pricing.html:27
#: order/templates/order/purchase_order_detail.html:29
#: stock/templates/stock/item_base.html:90
#: stock/templates/stock/stock_adjust.html:18
@@ -297,8 +301,8 @@ msgstr ""
#: build/templates/build/detail.html:42
#: company/templates/company/detail_part.html:90
-#: company/templates/company/partdetail.html:54
-#: part/templates/part/detail.html:50 part/templates/part/part_base.html:91
+#: company/templates/company/supplier_part_detail.html:24
+#: part/templates/part/detail.html:50 part/templates/part/part_base.html:81
#: stock/templates/stock/item_base.html:120
msgid "URL"
msgstr ""
@@ -340,8 +344,9 @@ msgstr ""
msgid "Edit notes"
msgstr ""
-#: build/templates/build/tabs.html:5 company/templates/company/tabs.html:5
-#: part/templates/part/tabs.html:6
+#: build/templates/build/tabs.html:5
+#: company/templates/company/supplier_part_tabs.html:5
+#: company/templates/company/tabs.html:5 part/templates/part/tabs.html:6
msgid "Details"
msgstr ""
@@ -355,11 +360,107 @@ msgstr ""
msgid "Assign Parts"
msgstr ""
-#: build/views.py:290 stock/views.py:884
+#: build/templates/build/unallocate.html:8
+msgid "Are you sure you wish to unallocate all stock for this build?"
+msgstr ""
+
+#: build/views.py:56
+msgid "Cancel Build"
+msgstr ""
+
+#: build/views.py:74
+msgid "Confirm build cancellation"
+msgstr ""
+
+#: build/views.py:79
+msgid "Build was cancelled"
+msgstr ""
+
+#: build/views.py:95
+msgid "Allocate Stock"
+msgstr ""
+
+#: build/views.py:108
+msgid "No matching build found"
+msgstr ""
+
+#: build/views.py:127
+msgid "Confirm stock allocation"
+msgstr ""
+
+#: build/views.py:128
+msgid "Check the confirmation box at the bottom of the list"
+msgstr ""
+
+#: build/views.py:148 build/views.py:442
+msgid "Unallocate Stock"
+msgstr ""
+
+#: build/views.py:161
+msgid "Confirm unallocation of build stock"
+msgstr ""
+
+#: build/views.py:162
+msgid "Check the confirmation box"
+msgstr ""
+
+#: build/views.py:185
+msgid "Complete Build"
+msgstr ""
+
+#: build/views.py:258
+msgid "Confirm completion of build"
+msgstr ""
+
+#: build/views.py:265
+msgid "Invalid location selected"
+msgstr ""
+
+#: build/views.py:290 stock/views.py:916
#, python-brace-format
msgid "The following serial numbers already exist: ({sn})"
msgstr ""
+#: build/views.py:309
+msgid "Build marked as COMPLETE"
+msgstr ""
+
+#: build/views.py:385
+msgid "Start new Build"
+msgstr ""
+
+#: build/views.py:408
+msgid "Created new build"
+msgstr ""
+
+#: build/views.py:418
+msgid "Edit Build Details"
+msgstr ""
+
+#: build/views.py:423
+msgid "Edited build"
+msgstr ""
+
+#: build/views.py:432
+msgid "Delete Build"
+msgstr ""
+
+#: build/views.py:447
+msgid "Removed parts from build allocation"
+msgstr ""
+
+#: build/views.py:457
+msgid "Allocate new Part"
+msgstr ""
+
+#: build/views.py:573
+msgid "Edit Stock Allocation"
+msgstr ""
+
+#: build/views.py:577
+msgid "Updated Build Item"
+msgstr ""
+
#: common/models.py:69
msgid "Settings key (must be unique - case insensitive"
msgstr ""
@@ -396,6 +497,18 @@ msgstr ""
msgid "Use this currency as the base currency"
msgstr ""
+#: common/views.py:21
+msgid "Create new Currency"
+msgstr ""
+
+#: common/views.py:29
+msgid "Edit Currency"
+msgstr ""
+
+#: common/views.py:36
+msgid "Delete Currency"
+msgstr ""
+
#: company/models.py:74
msgid "Company name"
msgstr ""
@@ -449,7 +562,7 @@ msgid "Supplier stock keeping unit"
msgstr ""
#: company/models.py:240 company/templates/company/detail_part.html:81
-#: company/templates/company/partdetail.html:60
+#: company/templates/company/supplier_part_detail.html:30
msgid "Manufacturer"
msgstr ""
@@ -509,7 +622,7 @@ msgstr ""
#: company/templates/company/detail.html:17
#: company/templates/company/index.html:46
-#: company/templates/company/partdetail.html:51
+#: company/templates/company/supplier_part_detail.html:21
#: order/templates/order/order_base.html:67
#: stock/templates/stock/item_base.html:126
msgid "Supplier"
@@ -521,10 +634,11 @@ msgid "Supplier Parts"
msgstr ""
#: company/templates/company/detail_part.html:13
+#: part/templates/part/stock.html:81
msgid "New Supplier Part"
msgstr ""
-#: company/templates/company/detail_part.html:15
+#: company/templates/company/detail_part.html:15 templates/stock_table.html:10
msgid "Options"
msgstr ""
@@ -533,12 +647,11 @@ msgid "Delete Parts"
msgstr ""
#: company/templates/company/detail_part.html:73
-#: company/templates/company/partdetail.html:52
+#: company/templates/company/supplier_part_detail.html:22
msgid "SKU"
msgstr ""
#: company/templates/company/detail_purchase_orders.html:8
-#: company/templates/company/partdetail.html:116
#: company/templates/company/tabs.html:15 part/templates/part/tabs.html:43
msgid "Purchase Orders"
msgstr ""
@@ -552,6 +665,8 @@ msgid "Supplier Stock"
msgstr ""
#: company/templates/company/detail_stock.html:33
+#: company/templates/company/supplier_part_stock.html:38
+#: part/templates/part/stock.html:53 templates/stock_table.html:5
msgid "Export"
msgstr ""
@@ -568,10 +683,8 @@ msgstr ""
msgid "ID"
msgstr ""
-#: company/templates/company/index.html:69
-#: company/templates/company/partdetail.html:6
-#: part/templates/part/category.html:73 templates/navbar.html:10
-#: templates/stats.html:7 templates/stats.html:10
+#: company/templates/company/index.html:69 part/templates/part/category.html:73
+#: templates/navbar.html:10 templates/stats.html:7 templates/stats.html:10
msgid "Parts"
msgstr ""
@@ -584,65 +697,150 @@ msgstr ""
msgid "Are you sure you want to delete the following Supplier Parts?"
msgstr ""
-#: company/templates/company/partdetail.html:13
+#: company/templates/company/supplier_part_base.html:6
+#: company/templates/company/supplier_part_base.html:13
#: stock/templates/stock/item_base.html:130
msgid "Supplier Part"
msgstr ""
-#: company/templates/company/partdetail.html:41
+#: company/templates/company/supplier_part_detail.html:11
msgid "Supplier Part Details"
msgstr ""
-#: company/templates/company/partdetail.html:44
+#: company/templates/company/supplier_part_detail.html:14
msgid "Internal Part"
msgstr ""
-#: company/templates/company/partdetail.html:61
+#: company/templates/company/supplier_part_detail.html:31
msgid "MPN"
msgstr ""
-#: company/templates/company/partdetail.html:64
+#: company/templates/company/supplier_part_detail.html:34
#: order/templates/order/purchase_order_detail.html:33
msgid "Note"
msgstr ""
-#: company/templates/company/partdetail.html:70
+#: company/templates/company/supplier_part_orders.html:11
+msgid "Supplier Part Orders"
+msgstr ""
+
+#: company/templates/company/supplier_part_pricing.html:12
msgid "Pricing Information"
msgstr ""
-#: company/templates/company/partdetail.html:72
+#: company/templates/company/supplier_part_pricing.html:14
msgid "Order Multiple"
msgstr ""
-#: company/templates/company/partdetail.html:74
+#: company/templates/company/supplier_part_pricing.html:16
msgid "Base Price (Flat Fee)"
msgstr ""
-#: company/templates/company/partdetail.html:77
+#: company/templates/company/supplier_part_pricing.html:19
msgid "Price Breaks"
msgstr ""
-#: company/templates/company/partdetail.html:80
+#: company/templates/company/supplier_part_pricing.html:22
msgid "New Price Break"
msgstr ""
-#: company/templates/company/partdetail.html:86
+#: company/templates/company/supplier_part_pricing.html:28
msgid "Price"
msgstr ""
-#: company/templates/company/partdetail.html:106
+#: company/templates/company/supplier_part_pricing.html:48
msgid "No price breaks have been added for this part"
msgstr ""
+#: company/templates/company/supplier_part_stock.html:11
+msgid "Supplier Part Stock"
+msgstr ""
+
+#: company/templates/company/supplier_part_stock.html:61
+#: part/templates/part/stock.html:90
+msgid "New Location"
+msgstr ""
+
+#: company/templates/company/supplier_part_stock.html:62
+#: part/templates/part/stock.html:91
+msgid "Create New Location"
+msgstr ""
+
+#: company/templates/company/supplier_part_tabs.html:8
+msgid "Pricing"
+msgstr ""
+
+#: company/templates/company/supplier_part_tabs.html:11
#: company/templates/company/tabs.html:12 part/templates/part/tabs.html:17
#: templates/navbar.html:11
msgid "Stock"
msgstr ""
+#: company/templates/company/supplier_part_tabs.html:14
+#: templates/navbar.html:14
+msgid "Orders"
+msgstr ""
+
#: company/templates/company/tabs.html:21
msgid "Sales Orders"
msgstr ""
+#: company/views.py:97
+msgid "Update Company Image"
+msgstr ""
+
+#: company/views.py:102
+msgid "Updated company image"
+msgstr ""
+
+#: company/views.py:112
+msgid "Edit Company"
+msgstr ""
+
+#: company/views.py:116
+msgid "Edited company information"
+msgstr ""
+
+#: company/views.py:126
+msgid "Create new Company"
+msgstr ""
+
+#: company/views.py:130
+msgid "Created new company"
+msgstr ""
+
+#: company/views.py:140
+msgid "Delete Company"
+msgstr ""
+
+#: company/views.py:145
+msgid "Company was deleted"
+msgstr ""
+
+#: company/views.py:170
+msgid "Edit Supplier Part"
+msgstr ""
+
+#: company/views.py:179 part/templates/part/stock.html:82
+msgid "Create new Supplier Part"
+msgstr ""
+
+#: company/views.py:236
+msgid "Delete Supplier Part"
+msgstr ""
+
+#: company/views.py:306
+msgid "Add Price Break"
+msgstr ""
+
+#: company/views.py:341
+msgid "Edit Price Break"
+msgstr ""
+
+#: company/views.py:356
+msgid "Delete Price Break"
+msgstr ""
+
#: order/forms.py:21
msgid "Place order"
msgstr ""
@@ -675,7 +873,7 @@ msgstr ""
msgid "Order notes"
msgstr ""
-#: order/models.py:159 order/models.py:210 part/views.py:1080
+#: order/models.py:159 order/models.py:210 part/views.py:1109
#: stock/models.py:440
msgid "Quantity must be greater than zero"
msgstr ""
@@ -730,7 +928,7 @@ msgstr ""
msgid "Order Notes"
msgstr ""
-#: order/templates/order/purchase_order_detail.html:15
+#: order/templates/order/purchase_order_detail.html:15 order/views.py:747
msgid "Add Line Item"
msgstr ""
@@ -754,14 +952,38 @@ msgstr ""
msgid "Items"
msgstr ""
+#: order/views.py:99
+msgid "Create Purchase Order"
+msgstr ""
+
+#: order/views.py:129
+msgid "Edit Purchase Order"
+msgstr ""
+
+#: order/views.py:149
+msgid "Cancel Order"
+msgstr ""
+
#: order/views.py:164
msgid "Confirm order cancellation"
msgstr ""
+#: order/views.py:182
+msgid "Issue Order"
+msgstr ""
+
#: order/views.py:197
msgid "Confirm order placement"
msgstr ""
+#: order/views.py:218
+msgid "Complete Order"
+msgstr ""
+
+#: order/views.py:284
+msgid "Receive Parts"
+msgstr ""
+
#: order/views.py:351
msgid "Items received"
msgstr ""
@@ -794,220 +1016,248 @@ msgstr ""
msgid "Invalid SupplierPart selection"
msgstr ""
-#: part/bom.py:107
+#: order/views.py:862
+msgid "Edit Line Item"
+msgstr ""
+
+#: order/views.py:878
+msgid "Delete Line Item"
+msgstr ""
+
+#: order/views.py:883
+msgid "Deleted line item"
+msgstr ""
+
+#: part/bom.py:140
#, python-brace-format
msgid "Unsupported file format: {f}"
msgstr ""
-#: part/bom.py:112
+#: part/bom.py:145
msgid "Error reading BOM file (invalid data)"
msgstr ""
-#: part/bom.py:114
+#: part/bom.py:147
msgid "Error reading BOM file (incorrect row size)"
msgstr ""
-#: part/forms.py:37
+#: part/forms.py:37 stock/forms.py:91
+msgid "File Format"
+msgstr ""
+
+#: part/forms.py:37 stock/forms.py:91
+msgid "Select output file format"
+msgstr ""
+
+#: part/forms.py:39
+msgid "Cascading"
+msgstr ""
+
+#: part/forms.py:39
+msgid "Download cascading / multi-level BOM"
+msgstr ""
+
+#: part/forms.py:58
msgid "Confirm that the BOM is correct"
msgstr ""
-#: part/forms.py:49
+#: part/forms.py:70
msgid "Select BOM file to upload"
msgstr ""
-#: part/forms.py:73
+#: part/forms.py:94
msgid "Select part category"
msgstr ""
-#: part/forms.py:81
+#: part/forms.py:102
msgid "Perform 'deep copy' which will duplicate all BOM data for this part"
msgstr ""
-#: part/forms.py:86
+#: part/forms.py:107
msgid "Confirm part creation"
msgstr ""
-#: part/forms.py:172
+#: part/forms.py:193
msgid "Input quantity for price calculation"
msgstr ""
-#: part/forms.py:175
+#: part/forms.py:196
msgid "Select currency for price calculation"
msgstr ""
-#: part/models.py:57
+#: part/models.py:59
msgid "Default location for parts in this category"
msgstr ""
-#: part/models.py:60
+#: part/models.py:62
msgid "Default keywords for parts in this category"
msgstr ""
-#: part/models.py:309
+#: part/models.py:323
msgid "Part must be unique for name, IPN and revision"
msgstr ""
-#: part/models.py:323
+#: part/models.py:337
msgid "Part cannot be a template part if it is a variant of another part"
msgstr ""
-#: part/models.py:324
+#: part/models.py:338
msgid "Part cannot be a variant of another part if it is already a template"
msgstr ""
-#: part/models.py:328 part/templates/part/detail.html:17
+#: part/models.py:342 part/templates/part/detail.html:17
msgid "Part name"
msgstr ""
-#: part/models.py:332
+#: part/models.py:346
msgid "Is this part a template part?"
msgstr ""
-#: part/models.py:341
+#: part/models.py:355
msgid "Is this part a variant of another part?"
msgstr ""
-#: part/models.py:343
+#: part/models.py:357
msgid "Part description"
msgstr ""
-#: part/models.py:345
+#: part/models.py:359
msgid "Part keywords to improve visibility in search results"
msgstr ""
-#: part/models.py:350
+#: part/models.py:364
msgid "Part category"
msgstr ""
-#: part/models.py:352
+#: part/models.py:366
msgid "Internal Part Number"
msgstr ""
-#: part/models.py:354
+#: part/models.py:368
msgid "Part revision or version number"
msgstr ""
-#: part/models.py:356
+#: part/models.py:370
msgid "Link to extenal URL"
msgstr ""
-#: part/models.py:362
+#: part/models.py:376
msgid "Where is this item normally stored?"
msgstr ""
-#: part/models.py:406
+#: part/models.py:420
msgid "Default supplier part"
msgstr ""
-#: part/models.py:409
+#: part/models.py:423
msgid "Minimum allowed stock level"
msgstr ""
-#: part/models.py:411
+#: part/models.py:425
msgid "Stock keeping units for this part"
msgstr ""
-#: part/models.py:413
+#: part/models.py:427
msgid "Can this part be built from other parts?"
msgstr ""
-#: part/models.py:415
+#: part/models.py:429
msgid "Can this part be used to build other parts?"
msgstr ""
-#: part/models.py:417
+#: part/models.py:431
msgid "Does this part have tracking for unique items?"
msgstr ""
-#: part/models.py:419
+#: part/models.py:433
msgid "Can this part be purchased from external suppliers?"
msgstr ""
-#: part/models.py:421
+#: part/models.py:435
msgid "Can this part be sold to customers?"
msgstr ""
-#: part/models.py:423
+#: part/models.py:437
msgid "Is this part active?"
msgstr ""
-#: part/models.py:425
+#: part/models.py:439
msgid "Is this a virtual part, such as a software product or license?"
msgstr ""
-#: part/models.py:427
+#: part/models.py:441
msgid "Part notes - supports Markdown formatting"
msgstr ""
-#: part/models.py:429
+#: part/models.py:443
msgid "Stored BOM checksum"
msgstr ""
-#: part/models.py:936
+#: part/models.py:948
msgid "Select file to attach"
msgstr ""
-#: part/models.py:938
+#: part/models.py:950
msgid "File comment"
msgstr ""
-#: part/models.py:993
+#: part/models.py:1005
msgid "Parameter template name must be unique"
msgstr ""
-#: part/models.py:998
+#: part/models.py:1010
msgid "Parameter Name"
msgstr ""
-#: part/models.py:1000
+#: part/models.py:1012
msgid "Parameter Units"
msgstr ""
-#: part/models.py:1026
+#: part/models.py:1038
msgid "Parent Part"
msgstr ""
-#: part/models.py:1028
+#: part/models.py:1040
msgid "Parameter Template"
msgstr ""
-#: part/models.py:1030
+#: part/models.py:1042
msgid "Parameter Value"
msgstr ""
-#: part/models.py:1054
+#: part/models.py:1066
msgid "Select parent part"
msgstr ""
-#: part/models.py:1062
+#: part/models.py:1074
msgid "Select part to be used in BOM"
msgstr ""
-#: part/models.py:1068
+#: part/models.py:1080
msgid "BOM quantity for this BOM item"
msgstr ""
-#: part/models.py:1071
+#: part/models.py:1083
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr ""
-#: part/models.py:1074
+#: part/models.py:1086
msgid "BOM item reference"
msgstr ""
-#: part/models.py:1077
+#: part/models.py:1089
msgid "BOM item notes"
msgstr ""
-#: part/models.py:1079
+#: part/models.py:1091
msgid "BOM line checksum"
msgstr ""
-#: part/models.py:1142
+#: part/models.py:1154
msgid "Part cannot be added to its own Bill of Materials"
msgstr ""
-#: part/models.py:1149
+#: part/models.py:1161
#, python-brace-format
msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)"
msgstr ""
@@ -1028,7 +1278,7 @@ msgstr ""
msgid "Comment"
msgstr ""
-#: part/templates/part/attachments.html:34
+#: part/templates/part/attachments.html:34 part/views.py:118
msgid "Edit attachment"
msgstr ""
@@ -1077,7 +1327,7 @@ msgstr ""
msgid "Part Details"
msgstr ""
-#: part/templates/part/detail.html:22 part/templates/part/part_base.html:85
+#: part/templates/part/detail.html:22 part/templates/part/part_base.html:75
msgid "IPN"
msgstr ""
@@ -1181,34 +1431,50 @@ msgstr ""
msgid "This part is not active"
msgstr ""
-#: part/templates/part/part_base.html:47
+#: part/templates/part/part_base.html:37
msgid "Star this part"
msgstr ""
-#: part/templates/part/part_base.html:53
+#: part/templates/part/part_base.html:43
msgid "Show pricing information"
msgstr ""
-#: part/templates/part/part_base.html:105
+#: part/templates/part/part_base.html:95
msgid "Available Stock"
msgstr ""
-#: part/templates/part/part_base.html:110
+#: part/templates/part/part_base.html:100
msgid "In Stock"
msgstr ""
-#: part/templates/part/part_base.html:131
+#: part/templates/part/part_base.html:121
msgid "Build Status"
msgstr ""
-#: part/templates/part/part_base.html:135
+#: part/templates/part/part_base.html:125
msgid "Can Build"
msgstr ""
-#: part/templates/part/part_base.html:140
+#: part/templates/part/part_base.html:130
msgid "Underway"
msgstr ""
+#: part/templates/part/part_thumb.html:16
+msgid "Select from existing images"
+msgstr ""
+
+#: part/templates/part/part_thumb.html:17
+msgid "Upload new image"
+msgstr ""
+
+#: part/templates/part/stock.html:75
+msgid "New Part"
+msgstr ""
+
+#: part/templates/part/stock.html:76
+msgid "Create New Part"
+msgstr ""
+
#: part/templates/part/tabs.html:9
msgid "Parameters"
msgstr ""
@@ -1242,151 +1508,175 @@ msgstr ""
msgid "Attachments"
msgstr ""
-#: part/views.py:77
+#: part/views.py:75
+msgid "Add part attachment"
+msgstr ""
+
+#: part/views.py:80
msgid "Added attachment"
msgstr ""
-#: part/views.py:119
+#: part/views.py:122
msgid "Part attachment updated"
msgstr ""
-#: part/views.py:196
+#: part/views.py:137
+msgid "Delete Part Attachment"
+msgstr ""
+
+#: part/views.py:143
+msgid "Deleted part attachment"
+msgstr ""
+
+#: part/views.py:151
+msgid "Set Part Category"
+msgstr ""
+
+#: part/views.py:199
#, python-brace-format
msgid "Set category for {n} parts"
msgstr ""
-#: part/views.py:306
+#: part/views.py:234
+msgid "Create Variant"
+msgstr ""
+
+#: part/views.py:304
+msgid "Duplicate Part"
+msgstr ""
+
+#: part/views.py:309
msgid "Copied part"
msgstr ""
-#: part/views.py:414
+#: part/views.py:417
msgid "Create new part"
msgstr ""
-#: part/views.py:419
+#: part/views.py:422
msgid "Created new part"
msgstr ""
-#: part/views.py:609
+#: part/views.py:595
+msgid "Part QR Code"
+msgstr ""
+
+#: part/views.py:612
msgid "Upload Part Image"
msgstr ""
-#: part/views.py:614
+#: part/views.py:617 part/views.py:652
msgid "Updated part image"
msgstr ""
-#: part/views.py:623
+#: part/views.py:626
msgid "Select Part Image"
msgstr ""
-#: part/views.py:627
-msgid "Selected part image"
+#: part/views.py:655
+msgid "Part image not found"
msgstr ""
-#: part/views.py:637
+#: part/views.py:666
msgid "Edit Part Properties"
msgstr ""
-#: part/views.py:659
+#: part/views.py:688
msgid "Validate BOM"
msgstr ""
-#: part/views.py:821
+#: part/views.py:850
msgid "No BOM file provided"
msgstr ""
-#: part/views.py:1082
+#: part/views.py:1111
msgid "Enter a valid quantity"
msgstr ""
-#: part/views.py:1106 part/views.py:1109
+#: part/views.py:1135 part/views.py:1138
msgid "Select valid part"
msgstr ""
-#: part/views.py:1115
+#: part/views.py:1144
msgid "Duplicate part selected"
msgstr ""
-#: part/views.py:1143
+#: part/views.py:1172
msgid "Select a part"
msgstr ""
-#: part/views.py:1147
+#: part/views.py:1176
msgid "Specify quantity"
msgstr ""
-#: part/views.py:1324
+#: part/views.py:1356
+msgid "Export Bill of Materials"
+msgstr ""
+
+#: part/views.py:1396
msgid "Confirm Part Deletion"
msgstr ""
-#: part/views.py:1331
+#: part/views.py:1403
msgid "Part was deleted"
msgstr ""
-#: part/views.py:1340
+#: part/views.py:1412
msgid "Part Pricing"
msgstr ""
-#: part/views.py:1462
+#: part/views.py:1534
msgid "Create Part Parameter Template"
msgstr ""
-#: part/views.py:1470
+#: part/views.py:1542
msgid "Edit Part Parameter Template"
msgstr ""
-#: part/views.py:1477
+#: part/views.py:1549
msgid "Delete Part Parameter Template"
msgstr ""
-#: part/views.py:1485
+#: part/views.py:1557
msgid "Create Part Parameter"
msgstr ""
-#: part/views.py:1535
+#: part/views.py:1607
msgid "Edit Part Parameter"
msgstr ""
-#: part/views.py:1549
+#: part/views.py:1621
msgid "Delete Part Parameter"
msgstr ""
-#: part/views.py:1565
+#: part/views.py:1637
msgid "Edit Part Category"
msgstr ""
-#: part/views.py:1600
+#: part/views.py:1672
msgid "Delete Part Category"
msgstr ""
-#: part/views.py:1606
+#: part/views.py:1678
msgid "Part category was deleted"
msgstr ""
-#: part/views.py:1614
+#: part/views.py:1686
msgid "Create new part category"
msgstr ""
-#: part/views.py:1665
+#: part/views.py:1737
msgid "Create BOM item"
msgstr ""
-#: part/views.py:1731
+#: part/views.py:1803
msgid "Edit BOM item"
msgstr ""
-#: part/views.py:1779
+#: part/views.py:1851
msgid "Confim BOM item deletion"
msgstr ""
-#: stock/forms.py:91
-msgid "File Format"
-msgstr ""
-
-#: stock/forms.py:91
-msgid "Select output file format"
-msgstr ""
-
#: stock/forms.py:93
msgid "Include stock items in sub locations"
msgstr ""
@@ -1616,134 +1906,134 @@ msgstr ""
msgid "Stock Export Options"
msgstr ""
-#: stock/views.py:264
+#: stock/views.py:278
msgid "Stock Item QR Code"
msgstr ""
-#: stock/views.py:287
+#: stock/views.py:301
msgid "Adjust Stock"
msgstr ""
-#: stock/views.py:396
+#: stock/views.py:410
msgid "Move Stock Items"
msgstr ""
-#: stock/views.py:397
+#: stock/views.py:411
msgid "Count Stock Items"
msgstr ""
-#: stock/views.py:398
+#: stock/views.py:412
msgid "Remove From Stock"
msgstr ""
-#: stock/views.py:399
+#: stock/views.py:413
msgid "Add Stock Items"
msgstr ""
-#: stock/views.py:400
+#: stock/views.py:414
msgid "Delete Stock Items"
msgstr ""
-#: stock/views.py:428
+#: stock/views.py:442
msgid "Must enter integer value"
msgstr ""
-#: stock/views.py:433
+#: stock/views.py:447
msgid "Quantity must be positive"
msgstr ""
-#: stock/views.py:440
+#: stock/views.py:454
#, python-brace-format
msgid "Quantity must not exceed {x}"
msgstr ""
-#: stock/views.py:448
+#: stock/views.py:462
msgid "Confirm stock adjustment"
msgstr ""
-#: stock/views.py:519
+#: stock/views.py:533
#, python-brace-format
msgid "Added stock to {n} items"
msgstr ""
-#: stock/views.py:534
+#: stock/views.py:548
#, python-brace-format
msgid "Removed stock from {n} items"
msgstr ""
-#: stock/views.py:547
+#: stock/views.py:561
#, python-brace-format
msgid "Counted stock for {n} items"
msgstr ""
-#: stock/views.py:575
+#: stock/views.py:589
msgid "No items were moved"
msgstr ""
-#: stock/views.py:578
+#: stock/views.py:592
#, python-brace-format
msgid "Moved {n} items to {dest}"
msgstr ""
-#: stock/views.py:597
+#: stock/views.py:611
#, python-brace-format
msgid "Deleted {n} stock items"
msgstr ""
-#: stock/views.py:609
+#: stock/views.py:623
msgid "Edit Stock Item"
msgstr ""
-#: stock/views.py:645
+#: stock/views.py:659
msgid "Create new Stock Location"
msgstr ""
-#: stock/views.py:666
+#: stock/views.py:680
msgid "Serialize Stock"
msgstr ""
-#: stock/views.py:746
+#: stock/views.py:760
msgid "Create new Stock Item"
msgstr ""
-#: stock/views.py:810
+#: stock/views.py:824
msgid "Copy Stock Item"
msgstr ""
-#: stock/views.py:860
+#: stock/views.py:892
msgid "Invalid quantity"
msgstr ""
-#: stock/views.py:863
+#: stock/views.py:895
msgid "Invalid part selection"
msgstr ""
-#: stock/views.py:910
+#: stock/views.py:942
#, python-brace-format
msgid "Created {n} new stock items"
msgstr ""
-#: stock/views.py:927 stock/views.py:940
+#: stock/views.py:959 stock/views.py:972
msgid "Created new stock item"
msgstr ""
-#: stock/views.py:957
+#: stock/views.py:989
msgid "Delete Stock Location"
msgstr ""
-#: stock/views.py:970
+#: stock/views.py:1002
msgid "Delete Stock Item"
msgstr ""
-#: stock/views.py:981
+#: stock/views.py:1013
msgid "Delete Stock Tracking Entry"
msgstr ""
-#: stock/views.py:998
+#: stock/views.py:1030
msgid "Edit Stock Tracking Entry"
msgstr ""
-#: stock/views.py:1007
+#: stock/views.py:1039
msgid "Add Stock Tracking Entry"
msgstr ""
@@ -1779,10 +2069,6 @@ msgstr ""
msgid "View Code on GitHub"
msgstr ""
-#: templates/navbar.html:14
-msgid "Orders"
-msgstr ""
-
#: templates/navbar.html:23
msgid "Admin"
msgstr ""
@@ -1806,3 +2092,31 @@ msgstr ""
#: templates/navbar.html:33
msgid "Statistics"
msgstr ""
+
+#: templates/stock_table.html:7
+msgid "New Stock Item"
+msgstr ""
+
+#: templates/stock_table.html:12
+msgid "Add stock"
+msgstr ""
+
+#: templates/stock_table.html:13
+msgid "Remove stock"
+msgstr ""
+
+#: templates/stock_table.html:14
+msgid "Count stock"
+msgstr ""
+
+#: templates/stock_table.html:15
+msgid "Move stock"
+msgstr ""
+
+#: templates/stock_table.html:16
+msgid "Order stock"
+msgstr ""
+
+#: templates/stock_table.html:17
+msgid "Delete Stock"
+msgstr ""
diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py
index 69580c3bb2..2e8deb05c8 100644
--- a/InvenTree/order/api.py
+++ b/InvenTree/order/api.py
@@ -18,6 +18,7 @@ from InvenTree.status_codes import OrderStatus
import os
from part.models import Part
+from company.models import SupplierPart
from .models import PurchaseOrder, PurchaseOrderLineItem
from .serializers import POSerializer, POLineItemSerializer
@@ -62,6 +63,14 @@ class POList(generics.ListCreateAPIView):
except (Part.DoesNotExist, ValueError):
pass
+ # Attempt to filter by supplier part
+ if 'supplier_part' in request.GET:
+ try:
+ supplier_part = SupplierPart.objects.get(pk=request.GET['supplier_part'])
+ queryset = queryset.filter(id__in=[p.id for p in supplier_part.purchase_orders()])
+ except (ValueError, SupplierPart.DoesNotExist):
+ pass
+
data = queryset.values(
'pk',
'supplier',
diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py
index bb1702c8a2..2b31740bd2 100644
--- a/InvenTree/order/views.py
+++ b/InvenTree/order/views.py
@@ -96,7 +96,7 @@ class PurchaseOrderCreate(AjaxCreateView):
""" View for creating a new PurchaseOrder object using a modal form """
model = PurchaseOrder
- ajax_form_title = "Create Purchase Order"
+ ajax_form_title = _("Create Purchase Order")
form_class = order_forms.EditPurchaseOrderForm
def get_initial(self):
@@ -126,7 +126,7 @@ class PurchaseOrderEdit(AjaxUpdateView):
""" View for editing a PurchaseOrder using a modal form """
model = PurchaseOrder
- ajax_form_title = 'Edit Purchase Order'
+ ajax_form_title = _('Edit Purchase Order')
form_class = order_forms.EditPurchaseOrderForm
def get_form(self):
@@ -146,7 +146,7 @@ class PurchaseOrderCancel(AjaxUpdateView):
""" View for cancelling a purchase order """
model = PurchaseOrder
- ajax_form_title = 'Cancel Order'
+ ajax_form_title = _('Cancel Order')
ajax_template_name = 'order/order_cancel.html'
form_class = order_forms.CancelPurchaseOrderForm
@@ -179,7 +179,7 @@ class PurchaseOrderIssue(AjaxUpdateView):
""" View for changing a purchase order from 'PENDING' to 'ISSUED' """
model = PurchaseOrder
- ajax_form_title = 'Issue Order'
+ ajax_form_title = _('Issue Order')
ajax_template_name = "order/order_issue.html"
form_class = order_forms.IssuePurchaseOrderForm
@@ -215,7 +215,7 @@ class PurchaseOrderComplete(AjaxUpdateView):
form_class = order_forms.CompletePurchaseOrderForm
model = PurchaseOrder
ajax_template_name = "order/order_complete.html"
- ajax_form_title = "Complete Order"
+ ajax_form_title = _("Complete Order")
context_object_name = 'order'
def get_context_data(self):
@@ -281,7 +281,7 @@ class PurchaseOrderReceive(AjaxUpdateView):
"""
form_class = order_forms.ReceivePurchaseOrderForm
- ajax_form_title = "Receive Parts"
+ ajax_form_title = _("Receive Parts")
ajax_template_name = "order/receive_parts.html"
# Where the parts will be going (selected in POST request)
@@ -445,7 +445,7 @@ class OrderParts(AjaxView):
"""
- ajax_form_title = "Order Parts"
+ ajax_form_title = _("Order Parts")
ajax_template_name = 'order/order_wizard/select_parts.html'
# List of Parts we wish to order
@@ -744,7 +744,7 @@ class POLineItemCreate(AjaxCreateView):
model = PurchaseOrderLineItem
context_object_name = 'line'
form_class = order_forms.EditPurchaseOrderLineItemForm
- ajax_form_title = 'Add Line Item'
+ ajax_form_title = _('Add Line Item')
def post(self, request, *arg, **kwargs):
@@ -859,7 +859,7 @@ class POLineItemEdit(AjaxUpdateView):
model = PurchaseOrderLineItem
form_class = order_forms.EditPurchaseOrderLineItemForm
ajax_template_name = 'modal_form.html'
- ajax_form_title = 'Edit Line Item'
+ ajax_form_title = _('Edit Line Item')
def get_form(self):
form = super().get_form()
@@ -875,10 +875,10 @@ class POLineItemDelete(AjaxDeleteView):
"""
model = PurchaseOrderLineItem
- ajax_form_title = 'Delete Line Item'
+ ajax_form_title = _('Delete Line Item')
ajax_template_name = 'order/po_lineitem_delete.html'
def get_data(self):
return {
- 'danger': 'Deleted line item',
+ 'danger': _('Deleted line item'),
}
diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py
index 6f9d2369e5..fc5727bd9d 100644
--- a/InvenTree/part/admin.py
+++ b/InvenTree/part/admin.py
@@ -131,11 +131,13 @@ class BomItemResource(ModelResource):
level = Field(attribute='level', readonly=True)
- part = Field(attribute='part', widget=widgets.ForeignKeyWidget(Part))
+ bom_id = Field(attribute='pk')
+
+ parent_part_id = Field(attribute='part', widget=widgets.ForeignKeyWidget(Part))
parent_part_name = Field(attribute='part__full_name', readonly=True)
- id = Field(attribute='sub_part', widget=widgets.ForeignKeyWidget(Part))
+ sub_part_id = Field(attribute='sub_part', widget=widgets.ForeignKeyWidget(Part))
sub_part_name = Field(attribute='sub_part__full_name', readonly=True)
@@ -147,7 +149,12 @@ class BomItemResource(ModelResource):
report_skipped = False
clean_model_instances = True
- exclude = ['checksum', ]
+ exclude = [
+ 'checksum',
+ 'id',
+ 'part',
+ 'sub_part',
+ ]
class BomItemAdmin(ImportExportModelAdmin):
diff --git a/InvenTree/part/bom.py b/InvenTree/part/bom.py
index a1f8b5ec6a..85d7e23dbb 100644
--- a/InvenTree/part/bom.py
+++ b/InvenTree/part/bom.py
@@ -53,12 +53,18 @@ def ExportBom(part, fmt='csv', cascade=False):
bom_items = []
+ uids = []
+
def add_items(items, level):
# Add items at a given layer
for item in items:
item.level = '-' * level
+ # Avoid circular BOM references
+ if item.pk in uids:
+ continue
+
bom_items.append(item)
if item.sub_part.assembly:
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 3a59db0cc6..d21a250c31 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -35,6 +35,7 @@ from InvenTree import helpers
from InvenTree import validators
from InvenTree.models import InvenTreeTree
from InvenTree.fields import InvenTreeURLField
+from InvenTree.helpers import decimal2string
from InvenTree.status_codes import BuildStatus, StockStatus, OrderStatus
@@ -1242,11 +1243,11 @@ class BomItem(models.Model):
pmin, pmax = prange
- # remove trailing zeros
- pmin = pmin.normalize()
- pmax = pmax.normalize()
-
if pmin == pmax:
- return str(pmin)
+ return decimal2string(pmin)
+
+ # Convert to better string representation
+ pmin = decimal2string(pmin)
+ pmax = decimal2string(pmax)
return "{pmin} to {pmax}".format(pmin=pmin, pmax=pmax)
diff --git a/InvenTree/part/templates/part/allocation.html b/InvenTree/part/templates/part/allocation.html
index c87d71814b..913469997f 100644
--- a/InvenTree/part/templates/part/allocation.html
+++ b/InvenTree/part/templates/part/allocation.html
@@ -39,6 +39,9 @@
{
title: 'Allocated',
sortable: false,
+ formatter: function(value, row, index, field) {
+ return parseFloat(value);
+ },
},
{
title: 'Status',
diff --git a/InvenTree/part/templates/part/stock.html b/InvenTree/part/templates/part/stock.html
index 6050137b69..a692b11b01 100644
--- a/InvenTree/part/templates/part/stock.html
+++ b/InvenTree/part/templates/part/stock.html
@@ -1,5 +1,6 @@
{% extends "part/part_base.html" %}
{% load static %}
+{% load i18n %}
{% block details %}
{% include 'part/tabs.html' with tab='stock' %}
@@ -49,7 +50,7 @@
$("#stock-export").click(function() {
launchModalForm("{% url 'stock-export-options' %}", {
- submit_text: "Export",
+ submit_text: "{% trans 'Export' %}",
success: function(response) {
var url = "{% url 'stock-export' %}";
@@ -71,14 +72,14 @@
secondary: [
{
field: 'part',
- label: 'New Part',
- title: 'Create New Part',
+ label: '{% trans "New Part" %}',
+ title: '{% trans "Create New Part" %}',
url: "{% url 'part-create' %}",
},
{
field: 'supplier_part',
- label: 'New Supplier Part',
- title: 'Create new Supplier Part',
+ label: '{% trans "New Supplier Part" %}',
+ title: '{% trans "Create new Supplier Part" %}',
url: "{% url 'supplier-part-create' %}",
data: {
part: {{ part.id }}
@@ -86,8 +87,8 @@
},
{
field: 'location',
- label: 'New Location',
- title: 'Create New Location',
+ label: '{% trans "New Location" %}',
+ title: '{% trans "Create New Location" %}',
url: "{% url 'stock-location-create' %}",
}
]
diff --git a/InvenTree/part/templates/part/used_in.html b/InvenTree/part/templates/part/used_in.html
index 872288723e..bad93b17ec 100644
--- a/InvenTree/part/templates/part/used_in.html
+++ b/InvenTree/part/templates/part/used_in.html
@@ -53,6 +53,9 @@
sortable: true,
field: 'quantity',
title: 'Uses',
+ formatter: function(value, row, index, field) {
+ return parseFloat(value);
+ },
}
],
diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
index 0a111bfb0e..d508452e80 100644
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -27,7 +27,7 @@ def inrange(n, *args, **kwargs):
@register.simple_tag()
def multiply(x, y, *args, **kwargs):
""" Multiply two numbers together """
- return x * y
+ return decimal2string(x * y)
@register.simple_tag()
@@ -40,7 +40,7 @@ def add(x, y, *args, **kwargs):
def part_allocation_count(build, part, *args, **kwargs):
""" Return the total number of allocated to """
- return build.getAllocatedQuantity(part)
+ return decimal2string(build.getAllocatedQuantity(part))
@register.simple_tag()
diff --git a/InvenTree/part/test_part.py b/InvenTree/part/test_part.py
index 2d3e5408bd..c7c3c014a1 100644
--- a/InvenTree/part/test_part.py
+++ b/InvenTree/part/test_part.py
@@ -1,6 +1,7 @@
# Tests for the Part model
# -*- coding: utf-8 -*-
+
from __future__ import unicode_literals
from django.test import TestCase
@@ -16,7 +17,7 @@ class TemplateTagTest(TestCase):
""" Tests for the custom template tag code """
def test_multiply(self):
- self.assertEqual(inventree_extras.multiply(3, 5), 15)
+ self.assertEqual(int(inventree_extras.multiply(3, 5)), 15)
def test_version(self):
self.assertEqual(type(inventree_extras.inventree_version()), str)
diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py
index 584c8fe62f..5bdb101398 100644
--- a/InvenTree/part/views.py
+++ b/InvenTree/part/views.py
@@ -72,7 +72,7 @@ class PartAttachmentCreate(AjaxCreateView):
"""
model = PartAttachment
form_class = part_forms.EditPartAttachmentForm
- ajax_form_title = "Add part attachment"
+ ajax_form_title = _("Add part attachment")
ajax_template_name = "modal_form.html"
def get_data(self):
@@ -115,7 +115,7 @@ class PartAttachmentEdit(AjaxUpdateView):
model = PartAttachment
form_class = part_forms.EditPartAttachmentForm
ajax_template_name = 'modal_form.html'
- ajax_form_title = 'Edit attachment'
+ ajax_form_title = _('Edit attachment')
def get_data(self):
return {
@@ -134,13 +134,13 @@ class PartAttachmentDelete(AjaxDeleteView):
""" View for deleting a PartAttachment """
model = PartAttachment
- ajax_form_title = "Delete Part Attachment"
+ ajax_form_title = _("Delete Part Attachment")
ajax_template_name = "part/attachment_delete.html"
context_object_name = "attachment"
def get_data(self):
return {
- 'danger': 'Deleted part attachment'
+ 'danger': _('Deleted part attachment')
}
@@ -148,7 +148,7 @@ class PartSetCategory(AjaxUpdateView):
""" View for settings the part category for multiple parts at once """
ajax_template_name = 'part/set_category.html'
- ajax_form_title = 'Set Part Category'
+ ajax_form_title = _('Set Part Category')
form_class = part_forms.SetPartCategoryForm
category = None
@@ -231,7 +231,7 @@ class MakePartVariant(AjaxCreateView):
model = Part
form_class = part_forms.EditPartForm
- ajax_form_title = 'Create Variant'
+ ajax_form_title = _('Create Variant')
ajax_template_name = 'part/variant_part.html'
def get_part_template(self):
@@ -301,7 +301,7 @@ class PartDuplicate(AjaxCreateView):
model = Part
form_class = part_forms.EditPartForm
- ajax_form_title = "Duplicate Part"
+ ajax_form_title = _("Duplicate Part")
ajax_template_name = "part/copy_part.html"
def get_data(self):
@@ -592,7 +592,7 @@ class PartDetail(DetailView):
class PartQRCode(QRCodeView):
""" View for displaying a QR code for a Part object """
- ajax_form_title = "Part QR Code"
+ ajax_form_title = _("Part QR Code")
def get_qr_data(self):
""" Generate QR code data for the Part """
diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py
index b691041bde..af2d724f58 100644
--- a/InvenTree/stock/api.py
+++ b/InvenTree/stock/api.py
@@ -301,6 +301,7 @@ class StockList(generics.ListCreateAPIView):
'part__category',
'part__category__name',
'part__category__description',
+ 'supplier_part',
)
# Reduce the number of lookups we need to do for categories
@@ -371,7 +372,13 @@ class StockList(generics.ListCreateAPIView):
except PartCategory.DoesNotExist:
pass
- # Filter by supplier
+ # Filter by supplier_part ID
+ supplier_part_id = self.request.query_params.get('supplier_part', None)
+
+ if supplier_part_id:
+ stock_list = stock_list.filter(supplier_part=supplier_part_id)
+
+ # Filter by supplier ID
supplier_id = self.request.query_params.get('supplier', None)
if supplier_id:
diff --git a/InvenTree/stock/templates/stock/item_notes.html b/InvenTree/stock/templates/stock/item_notes.html
index a5abd13781..c97830a59c 100644
--- a/InvenTree/stock/templates/stock/item_notes.html
+++ b/InvenTree/stock/templates/stock/item_notes.html
@@ -35,7 +35,9 @@
+ {% if item.notes %}
{{ item.notes | markdownify }}
+ {% endif %}
diff --git a/InvenTree/stock/templates/stock/tracking.html b/InvenTree/stock/templates/stock/tracking.html
deleted file mode 100644
index ecd9772897..0000000000
--- a/InvenTree/stock/templates/stock/tracking.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "stock/stock_app_base.html" %}
-{% load static %}
-
-{% block content %}
-
-Stock list here!
-
-
-
-{% endblock %}
-
-{% block js_ready %}
-{{ block.super }}
-
- loadStockTrackingTable($("#tracking-table"), {
- params: function(p) {
- return {
- ordering: '-date',
- };
- },
- partColumn: true,
- url: "{% url 'api-stock-track' %}",
- });
-
-{% endblock %}
\ No newline at end of file
diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py
index 9d5e2b5dc4..4ac415ef23 100644
--- a/InvenTree/stock/views.py
+++ b/InvenTree/stock/views.py
@@ -24,7 +24,7 @@ from InvenTree.helpers import ExtractSerialNumbers
from decimal import Decimal, InvalidOperation
from datetime import datetime
-from company.models import Company
+from company.models import Company, SupplierPart
from part.models import Part
from .models import StockItem, StockLocation, StockItemTracking
@@ -212,6 +212,16 @@ class StockExport(AjaxView):
except (ValueError, Company.DoesNotExist):
pass
+ # Check if a particular supplier_part was specified
+ sup_part_id = request.GET.get('supplier_part', None)
+ supplier_part = None
+
+ if sup_part_id:
+ try:
+ supplier_part = SupplierPart.objects.get(pk=sup_part_id)
+ except (ValueError, SupplierPart.DoesNotExist):
+ pass
+
# Check if a particular part was specified
part_id = request.GET.get('part', None)
part = None
@@ -244,7 +254,11 @@ class StockExport(AjaxView):
if supplier:
stock_items = stock_items.filter(supplier_part__supplier=supplier)
+ if supplier_part:
+ stock_items = stock_items.filter(supplier_part=supplier_part)
+
# Filter out stock items that are not 'in stock'
+ # TODO - This might need some more thought in the future...
stock_items = stock_items.filter(customer=None)
stock_items = stock_items.filter(belongs_to=None)
@@ -816,6 +830,11 @@ class StockItemCreate(AjaxCreateView):
part_id = self.request.GET.get('part', None)
loc_id = self.request.GET.get('location', None)
+ sup_part_id = self.request.GET.get('supplier_part', None)
+
+ part = None
+ location = None
+ supplier_part = None
# Part field has been specified
if part_id:
@@ -824,14 +843,27 @@ class StockItemCreate(AjaxCreateView):
initials['part'] = part
initials['location'] = part.get_default_location()
initials['supplier_part'] = part.default_supplier
- except Part.DoesNotExist:
+ except (ValueError, Part.DoesNotExist):
+ pass
+
+ # SupplierPart field has been specified
+ # It must match the Part, if that has been supplied
+ if sup_part_id:
+ try:
+ supplier_part = SupplierPart.objects.get(pk=sup_part_id)
+
+ if part is None or supplier_part.part == part:
+ initials['supplier_part'] = supplier_part
+
+ except (ValueError, SupplierPart.DoesNotExist):
pass
# Location has been specified
if loc_id:
try:
- initials['location'] = StockLocation.objects.get(pk=loc_id)
- except StockLocation.DoesNotExist:
+ location = StockLocation.objects.get(pk=loc_id)
+ initials['location'] = location
+ except (ValueError, StockLocation.DoesNotExist):
pass
return initials
diff --git a/InvenTree/templates/stock_table.html b/InvenTree/templates/stock_table.html
index b3b214c031..31eaf30bb7 100644
--- a/InvenTree/templates/stock_table.html
+++ b/InvenTree/templates/stock_table.html
@@ -1,18 +1,18 @@
+{% load i18n %}
+